Skip to content

Plannotator API 참조 ​

학습 후 할 수 있는 것 ​

  • Plannotator 로컬 서버가 제공하는 모든 API 엔드포인트 이해
  • 각 API의 요청 및 응답 형식 확인
  • 계획 검토와 코드 검토의 인터페이스 차이점 이해
  • 통합 또는 확장 개발을 위한 참고 자료 제공

개요 ​

Plannotator는 로컬에서 HTTP 서버(Bun.serve 사용)를 실행하여 계획 검토와 코드 검토를 위한 RESTful API를 제공합니다. 모든 API 응답 형식은 JSON이며 인증이 필요 없습니다(로컬 격리 환경).

서버 시작 방식:

  • 랜덤 포트(로컬 모드)
  • 고정 포트 19432(원격/Devcontainer 모드, PLANNOTATOR_PORT로 재정의 가능)

API 기본 URL: http://localhost:<PORT>/api/

팁

아래 API는 기능 모듈별로 분류되어 있으며, 동일한 경로가 계획 검토와 코드 검토 서버에서 다르게 동작할 수 있습니다.

계획 검토 API ​

GET /api/plan ​

현재 계획 내용 및 관련 메타 정보를 가져옵니다.

요청: 없음

응답 예시:

json
{
  "plan": "# Implementation Plan: User Authentication\n...",
  "origin": "claude-code",
  "permissionMode": "read-write",
  "sharingEnabled": true
}
필드타입설명
planstring계획의 Markdown 내용
originstring출처 식별자("claude-code" 또는 "opencode")
permissionModestring현재 권한 모드(Claude Code 전용)
sharingEnabledbooleanURL 공유 활성화 여부

POST /api/approve ​

현재 계획을 승인하고 선택적으로 메모 앱에 저장합니다.

요청 본문:

json
{
  "obsidian": {
    "vaultPath": "/Users/xxx/Documents/Obsidian",
    "folder": "Plans",
    "tags": ["plannotator"],
    "plan": "Plan content..."
  },
  "bear": {
    "plan": "Plan content..."
  },
  "feedback": "승인 시 비고(OpenCode 전용)",
  "agentSwitch": "gpt-4",
  "permissionMode": "read-write",
  "planSave": {
    "enabled": true,
    "customPath": "/path/to/custom/folder"
  }
}

응답 예시:

json
{
  "ok": true,
  "savedPath": "/Users/xxx/.plannotator/plans/approved-plan-20260124.md"
}

필드 설명:

필드타입필수설명
obsidianobject아니요Obsidian 저장 설정
bearobject아니요Bear 저장 설정
feedbackstring아니요승인 시 첨부된 비고(OpenCode 전용)
agentSwitchstring아니요전환할 Agent 이름(OpenCode 전용)
permissionModestring아니요요청된 권한 모드(Claude Code 전용)
planSaveobject아니요계획 저장 설정

Obsidian 설정 필드:

필드타입필수설명
vaultPathstring예Vault 파일 경로
folderstring아니요대상 폴더(기본값 루트 디렉토리)
tagsstring[]아니요자동 생성된 태그
planstring예계획 내용

POST /api/deny ​

현재 계획을 거부하고 의견을 피드백합니다.

요청 본문:

json
{
  "feedback": "단위 테스트 커버리지 보완 필요",
  "planSave": {
    "enabled": true,
    "customPath": "/path/to/custom/folder"
  }
}

응답 예시:

json
{
  "ok": true,
  "savedPath": "/Users/xxx/.plannotator/plans/denied-plan-20260124.md"
}

필드 설명:

필드타입필수설명
feedbackstring아니요거부 사유(기본값 "Plan rejected by user")
planSaveobject아니요계획 저장 설정

GET /api/obsidian/vaults ​

로컬에 구성된 Obsidian vaults를 감지합니다.

요청: 없음

응답 예시:

json
{
  "vaults": [
    "/Users/xxx/Documents/Obsidian",
    "/Users/xxx/Documents/OtherVault"
  ]
}

구성 파일 경로:

  • macOS: ~/Library/Application Support/obsidian/obsidian.json
  • Windows: %APPDATA%\obsidian\obsidian.json
  • Linux: ~/.config/obsidian/obsidian.json

코드 검토 API ​

GET /api/diff ​

현재 git diff 내용을 가져옵니다.

요청: 없음

응답 예시:

json
{
  "rawPatch": "diff --git a/src/index.ts b/src/index.ts\n...",
  "gitRef": "HEAD",
  "origin": "opencode",
  "diffType": "uncommitted",
  "gitContext": {
    "currentBranch": "feature/auth",
    "defaultBranch": "main",
    "diffOptions": [
      { "id": "uncommitted", "label": "Uncommitted changes" },
      { "id": "last-commit", "label": "Last commit" },
      { "id": "branch", "label": "vs main" }
    ]
  },
  "sharingEnabled": true
}
필드타입설명
rawPatchstringGit diff 통일 형식 patch
gitRefstring사용된 Git 참조
originstring출처 식별자
diffTypestring현재 diff 타입
gitContextobjectGit 컨텍스트 정보
sharingEnabledbooleanURL 공유 활성화 여부

gitContext 필드 설명:

필드타입설명
currentBranchstring현재 브랜치 이름
defaultBranchstring기본 브랜치 이름(main 또는 master)
diffOptionsobject[]사용 가능한 diff 타입 옵션(id와 label 포함)

POST /api/diff/switch ​

다른 타입의 git diff로 전환합니다.

요청 본문:

json
{
  "diffType": "staged"
}

지원하는 diff 타입:

타입Git 명령설명
uncommittedgit diff HEAD커밋되지 않은 변경(기본값)
stagedgit diff --staged스테이징된 변경
last-commitgit diff HEAD~1..HEAD마지막 커밋
vs maingit diff main..HEAD현재 브랜치 vs main

응답 예시:

json
{
  "rawPatch": "diff --git a/src/index.ts b/src/index.ts\n...",
  "gitRef": "--staged",
  "diffType": "staged"
}

POST /api/feedback ​

코드 검토 피드백을 AI Agent에 제출합니다.

요청 본문:

json
{
  "feedback": "오류 처리 로직 추가 제안",
  "annotations": [
    {
      "id": "1",
      "type": "suggestion",
      "filePath": "src/index.ts",
      "lineStart": 42,
      "lineEnd": 45,
      "side": "new",
      "text": "여기는 try-catch를 사용해야 함",
      "suggestedCode": "try {\n  // ...\n} catch (err) {\n  console.error(err);\n}"
    }
  ],
  "agentSwitch": "gpt-4"
}

필드 설명:

필드타입필수설명
feedbackstring아니요텍스트 피드백(LGTM 또는 기타)
annotationsarray아니요구조화된 주석 배열
agentSwitchstring아니요전환할 Agent 이름(OpenCode 전용)

annotation 객체 필드:

필드타입필수설명
idstring예고유 식별자
typestring예타입: comment, suggestion, concern
filePathstring예파일 경로
lineStartnumber예시작 행 번호
lineEndnumber예끝 행 번호
sidestring예측: "old" 또는 "new"
textstring아니요댓글 내용
suggestedCodestring아니요제안 코드(suggestion 타입)

응답 예시:

json
{
  "ok": true
}

공유 API ​

GET /api/image ​

이미지를 가져옵니다(로컬 파일 경로 또는 업로드된 임시 파일).

요청 매개변수:

매개변수타입필수설명
pathstring예이미지 파일 경로

요청 예시: GET /api/image?path=/tmp/plannotator/abc-123.png

응답: 이미지 파일(PNG/JPEG/WebP)

오류 응답:

  • 400 - path 매개변수 누락
  • 404 - 파일 존재하지 않음
  • 500 - 파일 읽기 실패

POST /api/upload ​

이미지를 임시 디렉토리에 업로드하고 접근 가능한 경로를 반환합니다.

요청: multipart/form-data

필드타입필수설명
fileFile예이미지 파일

지원하는 형식: PNG, JPEG, WebP

응답 예시:

json
{
  "path": "/tmp/plannotator/abc-123-def456.png"
}

오류 응답:

  • 400 - 파일 제공되지 않음
  • 500 - 업로드 실패

참고

업로드된 이미지는 /tmp/plannotator 디렉토리에 저장되며, 서버가 닫힌 후 자동으로 정리되지 않습니다.


GET /api/agents ​

사용 가능한 OpenCode Agents 목록을 가져옵니다(OpenCode 전용).

요청: 없음

응답 예시:

json
{
  "agents": [
    {
      "id": "gpt-4",
      "name": "GPT-4",
      "description": "Most capable model for complex tasks"
    },
    {
      "id": "gpt-4o",
      "name": "GPT-4o",
      "description": "Fast and efficient multimodal model"
    }
  ]
}

필터링 규칙:

  • mode === "primary"인 agents만 반환
  • hidden === true인 agents 제외

오류 응답:

json
{
  "agents": [],
  "error": "Failed to fetch agents"
}

오류 처리 ​

HTTP 상태 코드 ​

상태 코드설명
200요청 성공
400매개변수 검증 실패
404리소스 존재하지 않음
500서버 내부 오류

오류 응답 형식 ​

json
{
  "error": "오류 설명 메시지"
}

일반적인 오류 ​

오류트리거 조건
Missing path parameter/api/image에 path 매개변수 누락
File not found/api/image에서 지정된 파일 존재하지 않음
No file provided/api/upload에 파일 업로드되지 않음
Missing diffType/api/diff/switch에 diffType 필드 누락
Port ${PORT} in use포트 이미 사용 중(서버 시작 실패)

서버 동작 ​

포트 재시도 메커니즘 ​

  • 최대 재시도 횟수: 5회
  • 재시도 지연: 500밀리초
  • 시간 초과 오류: Port ${PORT} in use after 5 retries

원격 모드 팁

원격/Devcontainer 모드에서 포트가 사용 중인 경우 PLANNOTATOR_PORT 환경 변수를 설정하여 다른 포트를 사용할 수 있습니다.

의사결정 대기 ​

서버가 시작된 후 사용자 의사결정 대기 상태로 진입:

계획 검토 서버:

  • /api/approve 또는 /api/deny 호출 대기
  • 호출 후 의사결정 반환 및 서버 종료

코드 검토 서버:

  • /api/feedback 호출 대기
  • 호출 후 피드백 반환 및 서버 종료

SPA 폴백 ​

일치하지 않는 모든 경로는 임베디드 HTML(단일 페이지 애플리케이션)을 반환:

http
HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>
...
</html>

이는 프론트엔드 라우팅이 정상적으로 작동하도록 보장합니다.


환경 변수 ​

변수설명기본값
PLANNOTATOR_REMOTE원격 모드 활성화설정되지 않음
PLANNOTATOR_PORT고정 포트 번호랜덤(로컬) / 19432(원격)
PLANNOTATOR_ORIGIN출처 식별자"claude-code" 또는 "opencode"
PLANNOTATOR_SHAREURL 공유 비활성화설정되지 않음(활성화)

팁

더 많은 환경 변수 구성은 환경 변수 구성 장을 참조하세요.


요약 ​

Plannotator는 계획 검토와 코드 검토 두 가지 핵심 기능을 지원하는 완전한 로컬 HTTP API를 제공합니다:

  • 계획 검토 API: 계획 가져오기, 승인/거부 의사결정, Obsidian/Bear 통합
  • 코드 검토 API: diff 가져오기, diff 타입 전환, 구조화된 피드백 제출
  • 공유 API: 이미지 업로드/다운로드, Agent 목록 조회
  • 오류 처리: 통합된 HTTP 상태 코드 및 오류 형식

모든 API는 로컬에서 실행되며 데이터 업로드가 없어 안전하고 신뢰할 수 있습니다.


부록: 소스 코드 참조 ​

클릭하여 소스 코드 위치 펼치기

업데이트 시간: 2026-01-24

기능파일 경로행 번호
계획 검토 서버 진입점packages/server/index.ts91-355
GET /api/planpackages/server/index.ts132-134
POST /api/approvepackages/server/index.ts200-277
POST /api/denypackages/server/index.ts279-309
GET /api/imagepackages/server/index.ts136-151
POST /api/uploadpackages/server/index.ts153-174
GET /api/obsidian/vaultspackages/server/index.ts176-180
GET /api/agents(계획 검토)packages/server/index.ts182-198
코드 검토 서버 진입점packages/server/review.ts79-288
GET /api/diffpackages/server/review.ts117-127
POST /api/diff/switchpackages/server/review.ts129-161
POST /api/feedbackpackages/server/review.ts221-242
GET /api/agents(코드 검토)packages/server/review.ts203-219

주요 상수:

  • MAX_RETRIES = 5: 서버 시작 최대 재시도 횟수(packages/server/index.ts:79, packages/server/review.ts:68)
  • RETRY_DELAY_MS = 500: 포트 재시도 지연(packages/server/index.ts:80, packages/server/review.ts:69)

주요 함수:

  • startPlannotatorServer(options): 계획 검토 서버 시작(packages/server/index.ts:91)
  • startReviewServer(options): 코드 검토 서버 시작(packages/server/review.ts:79)