Claude Project Status: como eu resolvi o problema de contexto entre projetos no Claude Code
$ claude plugin add kursku/claude-project-status
✓ Plugin installed: claude-project-status v1.0.0
3 skills, 1 hook, 3 scripts
Um comando. A partir de agora, toda sessão do Claude Code sabe onde você parou na última vez.
O cenário que motivou o plugin
Eu gerencio 8 projetos simultâneos com Claude Code. Um SaaS, um blog, automações para clientes, um ebook, um curso. Toda vez que trocava de projeto, perdia 3-5 minutos explicando o contexto: “estamos na fase X, a última decisão foi Y, as próximas tarefas são Z”.
Multiplica isso por 4-5 trocas de contexto por dia. São 15-25 minutos diários gastos repetindo informação que o Claude deveria saber.
O CLAUDE.md resolve parte do problema — ele é lido automaticamente em toda sessão. Mas é um arquivo estático. Não captura o estado dinâmico: em que fase o projeto está agora, o que foi decidido ontem, qual a próxima tarefa concreta.
O Claude Project Status preenche essa lacuna.
O que o plugin faz
Três coisas:
- Mantém um STATUS block machine-readable no
CLAUDE.mdde cada projeto - Acumula um SUMMARY.md com o log de decisões de cada sessão
- Gera um dashboard central (
~/PROJECTS.md) com a visão de todos os projetos
Tudo orquestrado por 3 comandos (/update-status, /dashboard, /prioritize) e um hook automático que detecta quando você editou arquivos numa sessão.
STATUS block — o estado vivo do projeto
O coração do plugin é um bloco YAML dentro de um HTML comment, posicionado no topo do CLAUDE.md:
<!-- STATUS
projeto: meu-saas
fase: MVP - Autenticação
proximas_tarefas:
- implementar OAuth flow com Google
- adicionar session management com refresh tokens
- testes de integração no middleware
ultima_decisao: JWT ao invés de sessions — scaling stateless sem Redis
ultima_sessao: 2026-05-26
prioridade: alta
-->
Por que um HTML comment? Duas razões:
- Invisível no render — o GitHub, editores Markdown e qualquer viewer ignora comments. O
CLAUDE.mdcontinua legível para humanos. - Lido pelo Claude automaticamente — o Claude Code carrega o
CLAUDE.mdinteiro no início de cada sessão. O STATUS block está lá, em texto plano, sem precisar de nenhuma integração extra.
O resultado prático: você abre um projeto e o Claude já sabe a fase atual, as tarefas pendentes e a última decisão tomada. Zero explicação manual.
Campos do STATUS block
| Campo | Tipo | Propósito |
|---|---|---|
projeto | string | Nome do projeto (usado no dashboard) |
fase | string | Fase atual — formato livre, ex: “MVP - Auth”, “Refactor - Data layer” |
proximas_tarefas | lista YAML | 2-3 tarefas concretas e acionáveis |
ultima_decisao | string | A decisão mais relevante da última sessão + motivo |
ultima_sessao | data ISO | Quando o projeto foi tocado pela última vez |
prioridade | enum | alta, média ou baixa |
O formato é deliberadamente simples. Sem IDs, sem timestamps complexos, sem nested objects. Qualquer pessoa (ou LLM) lê e entende em 2 segundos.
SUMMARY.md — o changelog de decisões
Git log registra o que mudou no código. O SUMMARY.md registra por que mudou e para onde vai:
## 2026-05-26
- Implementado middleware de autenticação com JWT + refresh token rotation
- Decisão: refresh tokens com rotação automática (segurança > simplicidade)
- Decisão: rate limiting por IP no login (100 req/15min)
- Próximo: testes de integração e endpoint de logout
## 2026-05-24
- Setup inicial: Next.js 15 + Drizzle ORM + PostgreSQL
- Decisão: PostgreSQL ao invés de SQLite (multi-tenant desde o início)
- Decisão: Drizzle ao invés de Prisma (type-safety sem code generation)
- Próximo: schema de usuários e middleware de auth
## 2026-05-22
- Definição de escopo do MVP: auth + CRUD de projetos + billing básico
- Decisão: Stripe ao invés de implementação própria (compliance PCI)
- Próximo: setup do projeto e escolha de ORM
Cada entrada é append-only. O arquivo cresce com o tempo e se torna uma timeline navegável do projeto. Quando você precisa lembrar por que uma decisão foi tomada há 3 semanas, está aqui — não num chat perdido ou numa memória vaga.
O Claude também lê o SUMMARY.md quando precisa de contexto histórico. Se você perguntar “por que escolhemos JWT?”, ele encontra a resposta sem você precisar explicar de novo.
Dashboard central — a visão de helicóptero
O script generate-dashboard.js escaneia todos os diretórios configurados, encontra projetos com STATUS blocks, e gera um arquivo Markdown centralizado:
# Projects Dashboard
_Updated: 2026-05-26 14:30_
---
## meu-saas — 🔴 alta
**Phase:** MVP - Auth
**Last session:** 2026-05-26
**Last decision:** JWT para scaling stateless
**Next tasks:**
- implementar OAuth flow com Google
- adicionar session management com refresh tokens
## api-clientes — 🔴 alta
**Phase:** Integração - Webhooks
**Last session:** 2026-05-19
**Last decision:** retry exponencial com dead letter queue
**Next tasks:**
- implementar DLQ no BullMQ
- dashboard de webhooks falhados
## blog — 🟢 baixa
**Phase:** Content - SEO
**Last session:** 2026-05-20
**Last decision:** migrar de MDX para MD puro
**Next tasks:**
- otimizar imagens com sharp
- adicionar sitemap dinâmico
---
## Priorities
_Awaiting analysis — run `/prioritize` for updated suggestions._
Projetos ordenados por prioridade. Indicadores visuais por cor. Um olhar e você sabe: o que está quente, o que está parado, onde investir tempo.
Instalação
Via plugin marketplace
claude plugin add kursku/claude-project-status
O Claude Code resolve o repositório, baixa os arquivos, registra skills, commands e hooks automaticamente.
Instalação manual (para quem quer controle total)
# Clone
git clone https://github.com/kursku/claude-project-status.git
# Copie skills
mkdir -p ~/.claude/skills
cp -r claude-project-status/skills/update-status ~/.claude/skills/
cp -r claude-project-status/skills/dashboard ~/.claude/skills/
cp -r claude-project-status/skills/prioritize ~/.claude/skills/
# Copie scripts
mkdir -p ~/.claude/scripts
cp claude-project-status/scripts/*.js ~/.claude/scripts/
Depois, configure o hook Stop no ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "node ~/.claude/scripts/session-summary.js"
}
]
}
}
E defina os diretórios a escanear em ~/.project-status.json:
{
"scanDirs": [
"~/projects",
"~/work",
"~/freelance"
]
}
Os três comandos em detalhe
/update-status — salvar o estado
O comando que você roda no final de cada sessão. Internamente, ele executa 7 passos:
- Lê o
CLAUDE.mddo diretório atual - Analisa a sessão corrente — identifica fase, tarefas, decisões
- Atualiza (ou cria) o
<!-- STATUS ... -->block no topo do arquivo - Cria o
CLAUDE.mdse não existir - Faz append no
SUMMARY.mdcom o resumo da sessão - Executa hooks pós-update (se configurados)
- Regenera o dashboard central
O skill que orquestra isso:
# Update Status — Skill Definition
1. Read CLAUDE.md
2. Analyze current session:
- Current project phase
- Next 2-3 concrete, actionable tasks
- Most relevant decision + why
- Priority level: alta | média | baixa
3. Update <!-- STATUS --> block (create if missing)
4. Append to SUMMARY.md
5. Run post-update hooks
6. Regenerate dashboard
7. Confirm to user
Na prática, leva 5-10 segundos. O Claude analisa o que aconteceu na sessão, propõe o resumo, e você confirma ou ajusta.
/dashboard — visão geral
Gera o dashboard e apresenta um comentário analítico:
- Quantos projetos estão ativos
- Quais têm prioridade alta mas sem atividade recente (projetos “parados”)
- Qual projeto tem mais tarefas pendentes acumuladas
- Sugestão de onde focar agora, com justificativa de uma linha
O script por trás (generate-dashboard.js) faz o trabalho pesado: escaneia diretórios, parseia STATUS blocks com regex, ordena por prioridade, e escreve o Markdown.
/prioritize — análise de prioridades
Vai além do dashboard. Avalia cada projeto por 4 critérios:
| Critério | Peso | Lógica |
|---|---|---|
| Prioridade declarada | Alto | alta > média > baixa |
| Inatividade | Médio | Projetos alta-prioridade parados >7 dias sobem |
| Momentum | Médio | Sessões recentes (≤3 dias) + tarefas concretas = vantagem |
| Volume pendente | Baixo | Mais tarefas = mais bloqueado |
O output é um ranking com justificativa:
1. **meu-saas** — alta prioridade, 3 tarefas pendentes, última sessão ontem (momentum alto)
2. **api-clientes** — alta prioridade mas parado há 9 dias (risco de perder contexto)
3. **blog** — baixa prioridade mas 5 tarefas acumuladas (quick wins disponíveis)
E atualiza a seção ## Priorities no dashboard com a análise datada.
O hook automático — detecção passiva
O plugin registra um hook no evento Stop do Claude Code. Toda vez que uma sessão termina, o script session-summary.js roda automaticamente.
O que ele faz:
// Fluxo simplificado do session-summary.js
1. Recebe o JSON do evento Stop (inclui cwd e transcript_path)
2. Verifica se o diretório tem CLAUDE.md com STATUS block
3. Lê o transcript da sessão
4. Procura por chamadas de "Edit" ou "Write" (houve edição?)
5. Se sim: cria ~/.claude/pending-updates/<projeto>.json
O arquivo de pending:
{
"project": "meu-saas",
"path": "/home/user/projects/meu-saas",
"timestamp": "2026-05-26 14:30"
}
O hook não atualiza o STATUS block sozinho — isso exigiria análise de contexto que só o Claude faz bem. Ele apenas marca que o projeto foi tocado. Na próxima vez que você rodar /dashboard ou /update-status, essa informação está disponível.
É uma rede de segurança para quem esquece de rodar /update-status no final da sessão.
Configuração avançada — hooks pós-update
O ~/.project-status.json aceita hooks que rodam após cada /update-status:
{
"scanDirs": ["~/projects", "~/work"],
"hooks": {
"post-update": [
"node ~/scripts/sync-notion.js",
"curl -s -X POST https://hooks.slack.com/services/T.../B.../xxx -d '{\"text\":\"Project updated\"}'",
"cd $(pwd) && git add SUMMARY.md && git commit -m 'chore: session summary' --no-verify"
]
}
}
Cada hook:
- Roda com
execSync(síncrono, bloqueante) - Tem timeout de 30 segundos
- Falhas são logadas mas não quebram o fluxo
- Recebe o
cwddo projeto como diretório de trabalho
Casos de uso reais:
- Auto-commit do SUMMARY.md — mantém o histórico no git sem esforço manual
- Webhook para Slack/Telegram — notifica a equipe que o projeto foi atualizado
- Sync com Notion/Linear — espelha o STATUS block numa board externa
- Backup — copia o SUMMARY.md para um diretório de backup
Arquitetura interna
O plugin inteiro são 3 scripts JavaScript (~200 linhas total), 3 skills Markdown, e 1 hook JSON:
claude-project-status/
├── .claude-plugin/
│ ├── plugin.json # Metadata do plugin (nome, versão, keywords)
│ └── marketplace.json # Registro no marketplace
├── commands/
│ ├── dashboard.md # Comando /dashboard
│ ├── prioritize.md # Comando /prioritize
│ └── update-status.md # Comando /update-status
├── hooks/
│ └── hooks.json # Hook Stop → session-summary.js
├── scripts/
│ ├── generate-dashboard.js # Scan + parse + gera ~/PROJECTS.md
│ ├── session-summary.js # Detecta edições, marca pending
│ └── run-hooks.js # Executa hooks pós-update do usuário
└── skills/
├── dashboard/SKILL.md
├── prioritize/SKILL.md
└── update-status/SKILL.md
Decisões de design
Zero dependências externas. Os scripts usam apenas módulos nativos do Node.js: node:fs, node:path, node:os, node:child_process. Nenhum npm install. Nenhum node_modules. O plugin funciona em qualquer máquina com Node 18+.
Arquivos como banco de dados. O estado vive em Markdown e JSON — formatos que humanos leem, git versiona, e qualquer ferramenta processa. Sem SQLite, sem Redis, sem serviço rodando em background.
Parsing com regex, não com parser YAML. O STATUS block é simples o suficiente para regex. Isso evita dependência de um parser YAML e mantém o script em ~50 linhas.
A função de parsing no generate-dashboard.js:
function parseStatusBlock(content) {
const match = content.match(/<!--\s*STATUS\s*\n([\s\S]*?)-->/)
if (!match) return null
const block = match[1]
const get = (key) => {
const m = block.match(new RegExp(`^${key}:\\s*(.+)`, 'm'))
return m ? m[1].trim() : ''
}
const tasksMatch = block.match(/proximas_tarefas:\s*\n((?:\s+-\s+.+\n?)+)/)
const tasks = tasksMatch
? tasksMatch[1].split('\n')
.filter(l => l.trim().startsWith('-'))
.map(l => l.replace(/^\s*-\s*/, '').trim())
: []
return {
projeto: get('projeto'),
fase: get('fase'),
prioridade: get('prioridade'),
ultima_decisao: get('ultima_decisao'),
ultima_sessao: get('ultima_sessao'),
proximas_tarefas: tasks
}
}
Cross-platform. Usa path.join e os.homedir() em vez de paths hardcoded. Funciona em macOS, Linux e Windows sem adaptação.
Idempotente. Rodar /update-status duas vezes na mesma sessão sobrescreve o STATUS block (não duplica) e faz append no SUMMARY.md apenas uma vez (o skill verifica a data).
O hook em detalhe
O hooks.json registra o script no evento Stop:
{
"hooks": [
{
"matcher": "Stop",
"hooks": [
{
"type": "command",
"command": "node scripts/session-summary.js"
}
]
}
]
}
O script recebe o evento via stdin como JSON:
// session-summary.js — fluxo completo
let input = ''
process.stdin.on('data', chunk => { input += chunk })
process.stdin.on('end', () => {
const data = JSON.parse(input)
const cwd = data.cwd // diretório do projeto
// 1. Verifica se tem CLAUDE.md com STATUS block
const claudeMd = path.join(cwd, 'CLAUDE.md')
if (!fs.existsSync(claudeMd)) return
if (!fs.readFileSync(claudeMd, 'utf8').includes('<!-- STATUS')) return
// 2. Verifica se houve edições na sessão
const transcript = fs.readFileSync(data.transcript_path, 'utf8')
if (!transcript.includes('"Edit"') && !transcript.includes('"Write"')) return
// 3. Marca como pendente
const pendingDir = path.join(os.homedir(), '.claude', 'pending-updates')
fs.mkdirSync(pendingDir, { recursive: true })
fs.writeFileSync(
path.join(pendingDir, `${path.basename(cwd)}.json`),
JSON.stringify({ project: path.basename(cwd), path: cwd, timestamp: now })
)
})
Leve, rápido, sem side effects visíveis ao usuário.
Fluxo de trabalho na prática
Sessão típica (5 projetos ativos)
09:00 — Abro o terminal
$ claude
> /dashboard
# Projects Dashboard
## meu-saas — 🔴 alta (last: ontem)
## api-clientes — 🔴 alta (last: 5 dias atrás) ← parado
## blog — 🟢 baixa (last: 3 dias)
> /prioritize
1. **api-clientes** — alta prioridade, parado há 5 dias, risco de perder contexto
2. **meu-saas** — alta prioridade, momentum ativo, 3 tarefas pendentes
# Decido trabalhar no api-clientes
$ cd ~/projects/api-clientes
$ claude
# O Claude já sabe:
# - Fase: Integração - Webhooks
# - Última decisão: retry exponencial com DLQ
# - Próximas tarefas: implementar DLQ, dashboard de falhas
# Trabalho por 2 horas...
> /update-status
✓ STATUS block atualizado
✓ SUMMARY.md: entrada de 2026-05-27 adicionada
✓ Dashboard regenerado (5 projetos)
Retomada após 2 semanas de pausa
Você volta de férias. 8 projetos. Não lembra de nada.
$ claude
> /prioritize
1. **meu-saas** — alta prioridade, parado há 14 dias, 3 tarefas pendentes
(OAuth flow estava em andamento antes da pausa)
2. **api-clientes** — alta prioridade, parado há 19 dias
(DLQ implementado parcialmente)
3. **curso** — média prioridade, parado há 16 dias
(módulo 3 em rascunho)
Sem o plugin, você gastaria 30+ minutos relembrando o estado de cada projeto. Com ele, 10 segundos.
Comparação com alternativas
CLAUDE.md manual (sem plugin)
Funciona, mas exige disciplina para atualizar manualmente. O STATUS block fica desatualizado em 2-3 sessões. Sem dashboard, sem priorização, sem hook automático.
Notion/Linear/Jira
Ótimos para gestão de projeto em equipe. Mas o Claude não lê seu Notion no início da sessão. O contexto precisa estar no CLAUDE.md — onde o agente realmente olha.
Os hooks pós-update permitem sincronizar com essas ferramentas. Melhor dos dois mundos: contexto local para o Claude, visibilidade externa para humanos.
Memory do Claude Code
O sistema de memória do Claude Code persiste informações entre sessões, mas é genérico. Não tem estrutura de “fase”, “próximas tarefas”, “prioridade”. Não gera dashboard. Não compara projetos entre si.
O plugin complementa a memória — não compete com ela.
Git log / commit messages
Registra o que mudou no código. Não registra decisões de design, trade-offs considerados, ou o plano para a próxima sessão. São camadas diferentes de informação.
Limitações
Transparência sobre o que o plugin não faz:
- Não é automático — o
/update-statusprecisa ser rodado manualmente. O hook detecta edições mas não atualiza o STATUS sozinho. - Scan shallow — o dashboard escaneia apenas 1 nível de profundidade nos
scanDirs. Projetos em subpastas aninhadas não são encontrados automaticamente. - Sem UI gráfica — tudo é terminal + Markdown. Se você precisa de gráficos, use o dashboard como fonte de dados para outra ferramenta.
- Sem sync entre máquinas — o
~/PROJECTS.mdé local. Para compartilhar, commite osSUMMARY.mdno git ou use hooks para sincronizar. - Regex-based parsing — STATUS blocks com YAML malformado (tabs misturados com espaços, caracteres especiais não-escapados) podem falhar silenciosamente.
Roadmap
Áreas planejadas para as próximas versões:
- Scan recursivo — encontrar projetos em qualquer profundidade
- Auto-detect por
.git/— considerar qualquer repo git como projeto potencial - Templates customizáveis — campos extras no STATUS block por projeto
- Export JSON — dashboard em formato estruturado para integrações
- Pending updates no dashboard — mostrar projetos marcados pelo hook que ainda não foram atualizados
Repositório
Open-source, licença MIT:
github.com/kursku/claude-project-status
Stack: Node.js 18+, zero dependências, ~200 linhas de código total.
Contribuições são bem-vindas — especialmente nos itens do roadmap acima.
claude plugin add kursku/claude-project-status 

COMENTÁRIOS
Nenhum comentário ainda.