Skip to content

Referência da API do Plannotator

O Que Você Vai Aprender

  • Conhecer todos os endpoints da API fornecidos pelo servidor local do Plannotator
  • Visualizar os formatos de requisição e resposta de cada API
  • Entender as diferenças entre as interfaces de revisão de planos e revisão de código
  • Obter referências para integração ou desenvolvimento de extensões

Visão Geral

O Plannotator executa um servidor HTTP local (usando Bun.serve), fornecendo APIs RESTful para revisão de planos e revisão de código. Todas as respostas da API são em formato JSON, sem necessidade de autenticação (ambiente isolado local).

Métodos de inicialização do servidor:

  • Porta aleatória (modo local)
  • Porta fixa 19432 (modo remoto/Devcontainer, pode ser substituída via PLANNOTATOR_PORT)

URL base da API: http://localhost:<PORT>/api/

Dica

As APIs abaixo estão categorizadas por módulo funcional. O comportamento do mesmo caminho pode diferir entre os servidores de revisão de planos e revisão de código.

API de Revisão de Planos

GET /api/plan

Obtém o conteúdo do plano atual e metadados relacionados.

Requisição: Nenhuma

Exemplo de resposta:

json
{
  "plan": "# Implementation Plan: User Authentication\n...",
  "origin": "claude-code",
  "permissionMode": "read-write",
  "sharingEnabled": true
}
CampoTipoDescrição
planstringConteúdo do plano em Markdown
originstringIdentificador de origem ("claude-code" ou "opencode")
permissionModestringModo de permissão atual (exclusivo do Claude Code)
sharingEnabledbooleanSe o compartilhamento por URL está habilitado

POST /api/approve

Aprova o plano atual, com opção de salvar em um aplicativo de notas.

Corpo da requisição:

json
{
  "obsidian": {
    "vaultPath": "/Users/xxx/Documents/Obsidian",
    "folder": "Plans",
    "tags": ["plannotator"],
    "plan": "Plan content..."
  },
  "bear": {
    "plan": "Plan content..."
  },
  "feedback": "Observação ao aprovar (apenas OpenCode)",
  "agentSwitch": "gpt-4",
  "permissionMode": "read-write",
  "planSave": {
    "enabled": true,
    "customPath": "/path/to/custom/folder"
  }
}

Exemplo de resposta:

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

Descrição dos campos:

CampoTipoObrigatórioDescrição
obsidianobjectNãoConfiguração de salvamento no Obsidian
bearobjectNãoConfiguração de salvamento no Bear
feedbackstringNãoObservação anexada à aprovação (apenas OpenCode)
agentSwitchstringNãoNome do Agent para alternar (apenas OpenCode)
permissionModestringNãoModo de permissão solicitado (apenas Claude Code)
planSaveobjectNãoConfiguração de salvamento do plano

Campos de configuração do Obsidian:

CampoTipoObrigatórioDescrição
vaultPathstringSimCaminho do arquivo do Vault
folderstringNãoPasta de destino (raiz por padrão)
tagsstring[]NãoTags geradas automaticamente
planstringSimConteúdo do plano

POST /api/deny

Rejeita o plano atual e fornece feedback.

Corpo da requisição:

json
{
  "feedback": "Necessário adicionar cobertura de testes unitários",
  "planSave": {
    "enabled": true,
    "customPath": "/path/to/custom/folder"
  }
}

Exemplo de resposta:

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

Descrição dos campos:

CampoTipoObrigatórioDescrição
feedbackstringNãoMotivo da rejeição (padrão: "Plan rejected by user")
planSaveobjectNãoConfiguração de salvamento do plano

GET /api/obsidian/vaults

Detecta os vaults do Obsidian configurados localmente.

Requisição: Nenhuma

Exemplo de resposta:

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

Caminhos do arquivo de configuração:

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

API de Revisão de Código

GET /api/diff

Obtém o conteúdo atual do git diff.

Requisição: Nenhuma

Exemplo de resposta:

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
}
CampoTipoDescrição
rawPatchstringPatch em formato unificado do Git diff
gitRefstringReferência Git utilizada
originstringIdentificador de origem
diffTypestringTipo de diff atual
gitContextobjectInformações de contexto do Git
sharingEnabledbooleanSe o compartilhamento por URL está habilitado

Descrição dos campos de gitContext:

CampoTipoDescrição
currentBranchstringNome da branch atual
defaultBranchstringNome da branch padrão (main ou master)
diffOptionsobject[]Opções de tipos de diff disponíveis (contém id e label)

POST /api/diff/switch

Alterna para um tipo diferente de git diff.

Corpo da requisição:

json
{
  "diffType": "staged"
}

Tipos de diff suportados:

TipoComando GitDescrição
uncommittedgit diff HEADAlterações não commitadas (padrão)
stagedgit diff --stagedAlterações em staging
last-commitgit diff HEAD~1..HEADÚltimo commit
vs maingit diff main..HEADBranch atual vs main

Exemplo de resposta:

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

POST /api/feedback

Envia feedback de revisão de código para o AI Agent.

Corpo da requisição:

json
{
  "feedback": "Sugestão: adicionar lógica de tratamento de erros",
  "annotations": [
    {
      "id": "1",
      "type": "suggestion",
      "filePath": "src/index.ts",
      "lineStart": 42,
      "lineEnd": 45,
      "side": "new",
      "text": "Deveria usar try-catch aqui",
      "suggestedCode": "try {\n  // ...\n} catch (err) {\n  console.error(err);\n}"
    }
  ],
  "agentSwitch": "gpt-4"
}

Descrição dos campos:

CampoTipoObrigatórioDescrição
feedbackstringNãoFeedback em texto (LGTM ou outro)
annotationsarrayNãoArray de anotações estruturadas
agentSwitchstringNãoNome do Agent para alternar (apenas OpenCode)

Campos do objeto annotation:

CampoTipoObrigatórioDescrição
idstringSimIdentificador único
typestringSimTipo: comment, suggestion, concern
filePathstringSimCaminho do arquivo
lineStartnumberSimNúmero da linha inicial
lineEndnumberSimNúmero da linha final
sidestringSimLado: "old" ou "new"
textstringNãoConteúdo do comentário
suggestedCodestringNãoCódigo sugerido (tipo suggestion)

Exemplo de resposta:

json
{
  "ok": true
}

APIs Compartilhadas

GET /api/image

Obtém uma imagem (caminho de arquivo local ou arquivo temporário enviado).

Parâmetros da requisição:

ParâmetroTipoObrigatórioDescrição
pathstringSimCaminho do arquivo de imagem

Exemplo de requisição: GET /api/image?path=/tmp/plannotator/abc-123.png

Resposta: Arquivo de imagem (PNG/JPEG/WebP)

Respostas de erro:

  • 400 - Parâmetro path ausente
  • 404 - Arquivo não encontrado
  • 500 - Falha ao ler o arquivo

POST /api/upload

Envia uma imagem para o diretório temporário e retorna o caminho acessível.

Requisição: multipart/form-data

CampoTipoObrigatórioDescrição
fileFileSimArquivo de imagem

Formatos suportados: PNG, JPEG, WebP

Exemplo de resposta:

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

Respostas de erro:

  • 400 - Nenhum arquivo fornecido
  • 500 - Falha no upload

Observação

As imagens enviadas são salvas no diretório /tmp/plannotator e não são limpas automaticamente quando o servidor é encerrado.


GET /api/agents

Obtém a lista de Agents disponíveis do OpenCode (apenas OpenCode).

Requisição: Nenhuma

Exemplo de resposta:

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"
    }
  ]
}

Regras de filtragem:

  • Retorna apenas agents com mode === "primary"
  • Exclui agents com hidden === true

Resposta de erro:

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

Tratamento de Erros

Códigos de Status HTTP

CódigoDescrição
200Requisição bem-sucedida
400Falha na validação de parâmetros
404Recurso não encontrado
500Erro interno do servidor

Formato de Resposta de Erro

json
{
  "error": "Mensagem de descrição do erro"
}

Erros Comuns

ErroCondição de Disparo
Missing path parameter/api/image sem parâmetro path
File not foundArquivo especificado em /api/image não existe
No file provided/api/upload sem arquivo enviado
Missing diffType/api/diff/switch sem campo diffType
Port ${PORT} in usePorta já em uso (falha na inicialização do servidor)

Comportamento do Servidor

Mecanismo de Retry de Porta

  • Número máximo de tentativas: 5
  • Atraso entre tentativas: 500 milissegundos
  • Erro de timeout: Port ${PORT} in use after 5 retries

Aviso para Modo Remoto

No modo remoto/Devcontainer, se a porta estiver ocupada, você pode usar outra porta definindo a variável de ambiente PLANNOTATOR_PORT.

Aguardando Decisão

Após a inicialização, o servidor entra em estado de espera pela decisão do usuário:

Servidor de Revisão de Planos:

  • Aguarda chamada de /api/approve ou /api/deny
  • Após a chamada, retorna a decisão e encerra o servidor

Servidor de Revisão de Código:

  • Aguarda chamada de /api/feedback
  • Após a chamada, retorna o feedback e encerra o servidor

Fallback SPA

Todos os caminhos não correspondidos retornam HTML incorporado (Single Page Application):

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

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

Isso garante que o roteamento do frontend funcione corretamente.


Variáveis de Ambiente

VariávelDescriçãoValor Padrão
PLANNOTATOR_REMOTEHabilita modo remotoNão definido
PLANNOTATOR_PORTNúmero de porta fixaAleatório (local) / 19432 (remoto)
PLANNOTATOR_ORIGINIdentificador de origem"claude-code" ou "opencode"
PLANNOTATOR_SHAREDesabilita compartilhamento por URLNão definido (habilitado)

Dica

Para mais configurações de variáveis de ambiente, consulte a seção Configuração de Variáveis de Ambiente.


Resumo da Lição

O Plannotator fornece uma API HTTP local completa, suportando duas funcionalidades principais: revisão de planos e revisão de código:

  • API de Revisão de Planos: Obter plano, decisões de aprovar/rejeitar, integração com Obsidian/Bear
  • API de Revisão de Código: Obter diff, alternar tipo de diff, enviar feedback estruturado
  • APIs Compartilhadas: Upload e download de imagens, consulta de lista de Agents
  • Tratamento de Erros: Códigos de status HTTP e formato de erro unificados

Todas as APIs são executadas localmente, sem upload de dados, garantindo segurança e confiabilidade.


Apêndice: Referência do Código-Fonte

Clique para expandir e ver a localização do código-fonte

Data de atualização: 2026-01-24

FuncionalidadeCaminho do ArquivoLinhas
Entrada do servidor de revisão de planospackages/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 (revisão de planos)packages/server/index.ts182-198
Entrada do servidor de revisão de códigopackages/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 (revisão de código)packages/server/review.ts203-219

Constantes principais:

  • MAX_RETRIES = 5: Número máximo de tentativas de inicialização do servidor (packages/server/index.ts:79, packages/server/review.ts:68)
  • RETRY_DELAY_MS = 500: Atraso de retry de porta (packages/server/index.ts:80, packages/server/review.ts:69)

Funções principais:

  • startPlannotatorServer(options): Inicia o servidor de revisão de planos (packages/server/index.ts:91)
  • startReviewServer(options): Inicia o servidor de revisão de código (packages/server/review.ts:79)