Rastreamento de planos via kanban local
O kanban existe para que sessões do Claude em diferentes projetos e diferentes dias possam manter o estado do plano vivo entre sessões: reivindicar planos, movê-los por status, deixar notas. Várias instâncias do Claude podem compartilhar um quadro — sempre agrupe seu trabalho sob um slug de projeto para que planos de repositórios diferentes não colidam.
Quando você estiver trabalhando em um plano não trivial em um projeto em uma máquina onde o kanban está em execução, você deve se comunicar com ele à medida que avança.
O quadro
Fonte: https://github.com/hechtch/kanban — uma SPA Angular mais uma API Go sobre SQLite. Ele executa localmente; não há instância hospedada.
git clone https://github.com/hechtch/kanban.git
cd kanban
make container-build && make container-run # CONTAINER_RUNTIME=podman se você usa podman
make container-run publica -p 8000:8000 e monta
~/.kanban/data para persistência, então um único contêiner atende tanto a
IU quanto a API na porta 8000.
| Modo | IU para o humano | Base da API do agente |
|---|---|---|
Contêiner (make container-run) | http://localhost:8000/board | http://localhost:8000/api/agent |
Desenvolvimento (make run) | http://localhost:4200/board | http://localhost:8000/api/agent |
A API do agente está na porta 8000 em ambos os modos — apenas o link da IU
do humano difere, porque make run serve o servidor de desenvolvimento Angular
separadamente na 4200. Use o link da IU 8000 do contêiner, a menos que saiba
que o usuário está executando make run.
Se o usuário tiver implantado em outro lugar (atrás de um proxy reverso, uma
porta publicada diferente), eles lhe dirão a URL base — use a deles
em vez do padrão e mantenha o sufixo /api/agent.
Está funcionando?
KB=http://localhost:8000/api/agent
curl -sS http://localhost:8000/api/health
# {"status":"ok"}
Se falhar, o kanban não está em execução. Não o inicie você mesmo —
ele escreve em ~/.kanban/data/kanban.db e um segundo processo competindo
por esse banco de dados é pior do que nenhum rastreamento. Informe ao usuário que está
fora do ar, ofereça a linha make container-run acima e continue com o trabalho real
sem rastreamento.
Especificação canônica — leia para qualquer detalhe de endpoint
A API fornece uma especificação OpenAPI 3.1 completa gerada a partir dos manipuladores Go tipados. É a fonte da verdade para caminhos, formatos de requisição/resposta, códigos de status e regras de validação — em caso de dúvida, busque-a em vez de adivinhar ou confiar em documentação desatualizada:
- Especificação (JSON):
http://localhost:8000/api/openapi.json - Especificação (YAML):
http://localhost:8000/api/openapi.yaml - Swagger UI (para humanos):
http://localhost:8000/api/docs
O restante deste arquivo fornece o fluxo de trabalho do agente (slugs, convenções, receitas) para que você não precise aprender a API do zero. Para detalhes de endpoints não cobertos aqui, leia a especificação.
As respostas incluem um campo $schema URL apontando para o esquema JSON
da resposta (convenção do huma). Ignore-o, a menos que esteja validando
respostas contra o esquema.
A convenção de arquivo de plano que esta skill assume
O quadro rastreia planos, e um plano é um arquivo markdown no repositório:
plans/<tópico>.md— um arquivo por plano em andamento discreto, descrevendo o porquê e o quê. Use caixas de seleção (- [ ]/- [x]) para tarefas acionáveis e refine-as no local conforme o trabalho avança.plans/done/<tópico>.md— para onde o arquivo se move quando o trabalho é entregue ou abandonado, com um cabeçalho curto "Entregue em <versão> — " no topo.CHANGELOG.md— o "o que mudou" voltado ao público, emparelhado complans/done/que carrega o porquê.
Se um repositório ainda não usa esse layout, crie plans/ e crie o
arquivo antes de reivindicá-lo no quadro — a regra de slug abaixo depende
no nome do arquivo.
A regra de slug
Tudo é chaveado por slug, nunca por ID numérico. Nunca armazene um
task.id em seus prompts ou código.
- Slug do plano = o nome do arquivo do plano menos
.md, em minúsculas.plans/photo-import.md→photo-import. - Slug do projeto = o nome do repositório ou iniciativa em kebab-case.
~/projects/photo-organizer→photo-organizer. (Para um projeto chamado "Photo Organizer", o servidor deriva automaticamentephoto-organizera partir do nome; você também pode passar um slug explícito.) - Forma (imposta pelo servidor):
^[a-z0-9]([a-z0-9-]*[a-z0-9])?$. Slugs inválidos retornam400. Minúsculas, hífens entre palavras, sem sublinhados ou maiúsculas.
O corpo da tarefa É o plano
Ao reivindicar um plano pela primeira vez, envie o markdown do plano como o campo
body. O banco de dados do kanban é canônico a partir desse momento — não sincronize
edições de volta para o arquivo durante o processo. O arquivo plans/<slug>.md no disco
é a semente (usada uma vez); plans/done/<slug>.md é o instantâneo de arquivamento
que você escreve quando o trabalho é entregue.
Se você fizer um novo PUT depois com um novo body, sua versão vence. Humanos também
podem corrigir erros de digitação na visualização renderizada em /task/<task_id> na IU;
ambas as edições vão para a mesma coluna.
Reivindicar um plano é o que o torna "do Claude"
Não há campo de responsável para definir. O quadro deriva isso: uma tarefa
carregando um plan_slug — que é exatamente o que PUT /plans/<slug>
cria — é renderizada sob Claude no filtro de responsável da barra lateral e ganha
um chip Claude no cartão. Tarefas feitas manualmente pelo humano não têm
plan_slug e permanecem sob você.
Portanto, reivindicar um plano por meio desta API é um ato visível. Não reivindique trabalho que o humano está fazendo por conta própria apenas para deixar uma nota nele.
Status
Cinco colunas fixas do quadro:
todo → doing → blocked → awaiting_merge → done
Além de backlog (fora do quadro, 6ª opcional).
blocked— o trabalho não pode prosseguir; explique o motivo em uma nota.awaiting_merge— o código está escrito e enviado, aguardando um PR ser mesclado ou uma mesclagem manual. Diferente dedoneporque o trabalho ainda não foi entregue.- Mude para
doneapenas quando o branch for realmente mesclado ao tronco principal. Não faça transição automática.
'waiting' não é um status válido — foi renomeado para 'blocked' em uma
migração.
Branch Git
Planos (e qualquer tarefa) podem carregar um campo git_branch — o branch onde
o trabalho está acontecendo. Defina-o ao criar um branch de funcionalidade para que o
humano possa vê-lo no cartão:
curl -sS -X PUT $KB/plans/photo-import \
-H 'Content-Type: application/json' \
-d '{"git_branch":"feat/photo-import"}'
Limpe com {"git_branch": null}. O branch é renderizado como um chip monoespaçado
no cartão.
Modelo e esforço sugeridos
Cada tarefa pode carregar model e effort — uma dica para qualquer
agente que pegar o trabalho a seguir. O humano define esses valores a partir do ticket (ou
você pode, quando souber o peso de um plano), e eles são renderizados como um chip
fable / xhigh no cartão. Respeite-os: ao retomar um plano
cuja tarefa diz sonnet / high, esse é o nível que o proprietário deseja gastar
nele; um plano de auditoria fable / xhigh quer o modelo grande com esforço alto.
curl -sS -X PUT $KB/plans/security-audit \
-H 'Content-Type: application/json' \
-d '{"model":"fable","effort":"xhigh"}'
modelé uma abreviação de forma livre —fable,opus,sonnet,haikusão os internos; o servidor converte para minúsculas e remove espaços, e rejeita qualquer coisa com mais de 40 caracteres.effortdeve ser um delow,medium,high,xhigh,max(níveis de esforço de raciocínio do Claude Code); qualquer outra coisa retorna422.- Ambos são opcionais e independentes; limpe com
null. Ausente significa "nenhuma preferência — use o padrão da sessão".
Projetos: arquivamento e tags padrão
Um projeto carrega dois campos além de nome/cor, ambos configuráveis no mesmo
PUT $KB/projects/<slug> (upsert):
-
archived— o projeto está concluído. Seus planos saem da barra lateral e do quadro (dobrados em uma seção "arquivados" que o humano pode expandir), mas nada é excluído e cada endpoint ainda os retorna. Defina-o quando o trabalho de um projeto for entregue:curl -sS -X PUT $KB/projects/photo-organizer \ -H 'Content-Type: application/json' -d '{"archived":true}' -
tags— marca todas as tarefas no projeto. O servidor as mescla em cada tarefa nostagsna leitura, então um plano sob um projeto marcado["infra"]retorna marcadoinfrasem nunca ter sido marcado individualmente. Substitui o conjunto inteiro, como tags de tarefa:curl -sS -X PUT $KB/projects/photo-organizer \ -H 'Content-Type: application/json' -d '{"tags":["media","infra"]}'Como a mesclagem acontece na leitura, remover uma tag do projeto a remove de todas as tarefas de uma vez. Não defina uma tag de projeto em suas tarefas individualmente — o servidor remove tags herdadas do conjunto próprio de uma tarefa, então você estaria apenas escrevendo uma não operação.
Fluxo de trabalho por sessão
KB=http://localhost:8000/api/agent
# 1. Certifique-se de que seu projeto existe (idempotente — 201 na primeira vez, 200 depois).
curl -sS -X PUT $KB/projects/photo-organizer \
-H 'Content-Type: application/json' \
-d '{"name":"Photo Organizer","color":"#d4654a"}'
# 2. Reivindique o plano + envie seu corpo atual + coloque-o sob seu projeto.
# Primeiro PUT cria com status=todo; PUTs posteriores alteram.
BODY=$(jq -Rs . < plans/photo-import.md)
curl -sS -X PUT $KB/plans/photo-import \
-H 'Content-Type: application/json' \
-d "{\"title\":\"Photo Import\",\"project_slug\":\"photo-organizer\",\"body\":$BODY}"
# 3. Crie um branch de funcionalidade e informe o kanban sobre ele.
git checkout -b feat/photo-import
curl -sS -X PUT $KB/plans/photo-import \
-H 'Content-Type: application/json' \
-d '{"git_branch":"feat/photo-import"}'
# 4. Mude para doing com uma nota. PUTs de status são idempotentes — mesmo status
# sem uma nota é uma não operação; com uma nota, escreve uma entrada de atividade.
curl -sS -X PUT $KB/plans/photo-import/status \
-H 'Content-Type: application/json' \
-d '{"status":"doing","note":"iniciando Fase 2"}'
# 5. Deixe notas conforme avança (mais barato que uma mudança de status).
curl -sS -X POST $KB/plans/photo-import/notes \
-H 'Content-Type: application/json' \
-d '{"text":"fase 2 concluída; executando testes"}'
# 6. Quando o PR estiver aberto, mova para awaiting_merge.
curl -sS -X PUT $KB/plans/photo-import/status \
-H 'Content-Type: application/json' \
-d '{"status":"awaiting_merge","note":"PR #123 aberto"}'
# 7. Uma vez mesclado, mude para done e arquive o arquivo.
curl -sS -X PUT $KB/plans/photo-import/status \
-H 'Content-Type: application/json' \
-d '{"status":"done","note":"mesclado na v0.3.0"}'
# em seguida `git mv plans/photo-import.md plans/done/photo-import.md`
Mencione o link da IU do humano quando você acabou de criar ou mover um plano —
http://localhost:8000/board (ou :4200 no modo de desenvolvimento).
Regras e pegadinhas
- Enum de status é fixo:
todo,doing,blocked,awaiting_merge,done,backlog. Não invente novos. project_slugdesconhecido retorna422 unknown project_slug "X"— crie o projeto antes de atribuir. Sem criação automática silenciosa.project_slug: ""limpa o projeto, equivalente aproject_id: null.- Upsert é upsert real —
PUT /plans/:slugcom{}é sua chamada "reivindicar se ausente, alterar se presente". Reexecutar não duplica; apenas a primeira chamada escreve uma entrada de atividadecreate. - PUT de status com mesmo status é uma não operação a menos que você passe um
note. Use isso a seu favor — você pode tentar novamente com segurança. - Log de atividade é somente anexação e visível em
$KB/plans/<slug>/activity. Use notas para deixar migalhas ("Fase 2 concluída; iniciando Fase 3") em vez de narrar no corpo. - O corpo é markdown renderizado em
/task/<task_id>na IU. Use markdown padrão: cabeçalhos, listas (incluindo- [ ]/- [x]), blocos de código, links. Tabelas e citações em bloco também renderizam.
Quando não se preocupar
- Correções de bugs pontuais, refatorações, ajustes de documentação. O kanban rastreia planos — iniciativas de várias etapas que abrangem sessões ou carregam contexto significativo. Trabalho de commit único não precisa de um ticket.
- Se o repositório do kanban é o próprio projeto em que você está trabalhando, ele
documenta suas próprias convenções em seu
CLAUDE.md— leia isso em vez disso e ignore este arquivo. - Se a verificação de saúde falhar, o quadro não está em execução. Não tente iniciá-lo; apenas continue e informe o usuário.