@luanpdd/kit-mcp 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/kit/agents/schema-checker.md +159 -0
- package/kit/commands/publicar-rapido.md +207 -0
- package/kit/commands/publicar.md +123 -3
- package/kit/file-manifest.json +223 -215
- package/kit/hooks/post-apply-migration.js +191 -0
- package/package.json +1 -1
- package/src/ui/static/index.html +413 -139
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,69 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.5.0] - 2026-05-05
|
|
10
|
+
|
|
11
|
+
UI sidecar — bug fixes visuais + tokens + histórico de sessão.
|
|
12
|
+
|
|
13
|
+
### Adicionado
|
|
14
|
+
|
|
15
|
+
- **Tokens chip** em cada row da timeline e card de active run quando o evento traz `payload.tokens` (também aceita `payload.usage.total_tokens` e `payload.cost.tokens` para compatibilidade com diferentes wrappers). Formato `1.2k` / `5.3k` / `1.5M`.
|
|
16
|
+
- **Soma cumulativa de tokens da sessão** no footer (`6.2k tokens nesta sessão`). Aparece só quando algum evento veio com tokens — quem não usa LLM continua vendo o footer enxuto.
|
|
17
|
+
- **Histórico desta sessão** — drawer flutuante (botão de relógio na toolbar). Persiste em `sessionStorage` (não cross-tab, não cross-session); cada run terminada vira uma row com status (✓/✗/·), título, timestamp, duração, tokens, contagem de eventos e runId truncado. Click expande pra mostrar até os 100 últimos eventos da run com %, label e tokens. Cap em 50 runs (mais antigos são descartados).
|
|
18
|
+
- **Footer mostra runs concluídas** total da sessão (`3 runs concluídas`).
|
|
19
|
+
|
|
20
|
+
### Corrigido
|
|
21
|
+
|
|
22
|
+
- **Mojibake (`�`) em payloads** — eventos publicados via shells com locale ruim podiam vazar U+FFFD. Helper `safeStr()` agora limpa esses bytes antes de qualquer renderização.
|
|
23
|
+
- **Rows vazias na timeline** — `milestone` event que vinha com `payload.label` mas sem `payload.name` rendia em branco. Cascata defensiva agora tenta `name → title → label → name → tipo humanizado` em todos os tipos. Garantia: nenhuma row sai sem texto.
|
|
24
|
+
- **Active card sem título** — antes mostrava `—` sozinho se `payload.tool` estava vazio. Helper `runTitle(run)` cascata `humanizeTool(tool) → lastTitle → lastLabel → lastName → "Processo"`.
|
|
25
|
+
- **Tool inline mostrava `—` em vez de fallback** — `escapeHtml(safeStr(run.tool) || "processo")` no rc-tool, `escapeHtml(safeStr(run.tool) || "")` no rc-foot.
|
|
26
|
+
|
|
27
|
+
### Removido
|
|
28
|
+
|
|
29
|
+
- **Painel "Cenário (mock)" do Tweaks** — apenas cenários reais agora; sem botões de demo.
|
|
30
|
+
- **Botão "▸ replay"** — dependia de mock.
|
|
31
|
+
- **Funções `scenarioSync` / `scenarioMulti` / `scenarioError` / `scenarioIdle` / `runScenario` / `mockTimers` / `later` / `clearMock`** — toda infraestrutura de mock event generator (~80 LOC). `EventSource('/events')` é a única fonte de verdade.
|
|
32
|
+
- **Fallback `file://` boot** — sidecar não é mais aberto via `file://`; só via servidor.
|
|
33
|
+
|
|
34
|
+
### Sem mudanças de API runtime
|
|
35
|
+
|
|
36
|
+
Mudanças concentradas em `src/ui/static/index.html`. `src/core/`, `src/cli/`, `src/mcp-server/`, `src/ui/server.js` intocados. Stable API v1.0+ preservada.
|
|
37
|
+
|
|
38
|
+
### Migration
|
|
39
|
+
|
|
40
|
+
Wrappers que quiserem expor cost/tokens podem agora popular `payload.tokens` (number) em qualquer evento. Quem não popula continua funcionando idêntico — chips não aparecem, footer não mostra a linha de tokens. Histórico é per-tab via `sessionStorage` — fechar a aba apaga (intencional, não persistir é a feature).
|
|
41
|
+
|
|
42
|
+
## [1.4.0] - 2026-05-05
|
|
43
|
+
|
|
44
|
+
Framework velocity — 7 melhorias para os comandos / agentes do kit, focadas em reduzir fricção, evitar conflitos com main, e auto-detectar configs que hoje exigem env var manual.
|
|
45
|
+
|
|
46
|
+
### Adicionado
|
|
47
|
+
|
|
48
|
+
- **`/publicar-rapido`** — variante leve de `/publicar` para hotfix / quick-task. Não exige ROADMAP arquivado, MILESTONE-AUDIT.md nem `STATE.md`. Infere `TIPO_MUDANCA` (`fix:`/`feat:`/`refactor:`/...) do prefix do commit, gera Notion enxuto + PR + nota Obsidian em ~30s. Pre-flight de sync com `main` herdado do `/publicar`. (REQ F-01) `kit/commands/publicar-rapido.md`, ~210 LOC.
|
|
49
|
+
|
|
50
|
+
- **Pre-flight `main` sync no `/publicar` (Passo 0)** — antes de criar PR, faz `git fetch origin main` e detecta commits novos. Se houver, apresenta a lista e pergunta via `AskUserQuestion`: integrar via rebase (recomendado), via merge, ignorar (com flag `SYNC_SKIPPED` registrada na descrição do PR), ou cancelar. Trava de segurança contra conflitos tardios em times com vários devs em paralelo. (REQ F-07)
|
|
51
|
+
|
|
52
|
+
- **Auto-detect `notion-config.json` (Passo 0.5)** — se o config está ausente, em vez de encerrar com erro, busca a página do projeto via `notion-search`, apresenta candidatos via `AskUserQuestion`, lista subpáginas via `notion-fetch`, e gera o config automaticamente. `/setup-notion` continua existindo para quando a estrutura Notion ainda não existe. (REQ F-02)
|
|
53
|
+
|
|
54
|
+
- **Auto-detect cofre Obsidian (Passo 0.7)** — se `$OBSIDIAN_TEAM_VAULT` está ausente, tenta caminhos canônicos antes de pular o passo: `~/Documentos/Obsidian/chat-trynux`, `~/Documents/Obsidian/chat-trynux`, variantes `$USERPROFILE` (Windows), `/mnt/c/Users/$USER/...` (WSL). Funciona out-of-the-box em qualquer máquina (Linux/macOS/Windows/WSL) que siga o layout padrão `Documentos/Obsidian/chat-trynux`. (REQ F-03)
|
|
55
|
+
|
|
56
|
+
- **`schema-checker` agent** — sub-agente novo invocável via `Task(subagent_type="schema-checker")`. Lê uma migration SQL, extrai FKs / JOINs / refs implícitas, consulta o schema real em produção via Supabase MCP (`information_schema` + `pg_constraint`), cruza, e devolve veredito GO / NO-GO / NEEDS-REVIEW com diff por referência. Pega o caso clássico do "comentário do dev errado" (`contact_id → conversations.id` em comentário, mas em prod aponta para `contacts.id`) ANTES de aplicar a migration e ver falhar silenciosamente. (REQ F-04) `kit/agents/schema-checker.md`, ~160 LOC.
|
|
57
|
+
|
|
58
|
+
- **Hook `post-apply-migration` (PostToolUse)** — dispara automaticamente depois de qualquer `apply_migration` bem-sucedido via Supabase MCP e faz os 3 passos manuais que devs sempre esquecem: (a) escreve a SQL em `supabase/migrations/{TIMESTAMP}_{name}.sql`, (b) cria stub no cofre Obsidian em `07 - Banco de Dados/Migrations/{YYYY}/{TIMESTAMP}_{name}.md` (se vault detectado), (c) `git add` no projeto. Soft-fails — nunca bloqueia o tool call. (REQ F-05) `kit/hooks/post-apply-migration.js`, ~190 LOC.
|
|
59
|
+
|
|
60
|
+
### Alterado
|
|
61
|
+
|
|
62
|
+
- **Heurística de gatilho do `/publicar`** — documentada explicitamente: "publicar" depois de aplicar mudança = pipeline completo, NÃO apenas push. Para push isolado em outra branch sem cerimônia, dev precisa pedir explicitamente "só fazer push" OU usar `/publicar-rapido`. (REQ F-06)
|
|
63
|
+
|
|
64
|
+
### Sem mudanças de API runtime
|
|
65
|
+
|
|
66
|
+
Todas as adições são em `kit/` (templates de prompt distribuídos). `src/core/`, `src/cli/`, `src/mcp-server/`, e `src/ui/` permanecem intocados. Stable API v1.0+ preservada literalmente.
|
|
67
|
+
|
|
68
|
+
### Migration
|
|
69
|
+
|
|
70
|
+
Usuários da v1.3 não precisam fazer nada — re-rodar `kit sync install <ide>` no projeto puxa as adições. Quem usa `/publicar` em produção colhe os 3 passos novos automaticamente (pre-flight sync, auto-detect notion-config, auto-detect Obsidian) sem mudar workflow.
|
|
71
|
+
|
|
9
72
|
## [1.3.0] - 2026-05-05
|
|
10
73
|
|
|
11
74
|
UI redesign completo entregue por handoff do Claude Design (claude.ai/design). Layout repensado, paleta OKLCH, painel de tweaks (acento/densidade/movimento) acessível, timeline com rail + nó por evento, hero card de active runs com borda cônica animada e barra com gradient + shimmer, empty state com heartbeat bars, e cenários de demo (`Sync` / `Multi` / `Erro` / `Idle`) mockáveis pelo painel de tweaks.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: schema-checker
|
|
3
|
+
description: Valida foreign keys, colunas e tabelas referenciadas em uma migration SQL ANTES de aplicá-la em produção. Lê a SQL, extrai refs (FK, JOIN, INSERT INTO ... SELECT), consulta o schema real via Supabase MCP, e devolve um veredito GO/NO-GO com diff entre o que a migration assume e o que existe. Invocar antes de qualquer `apply_migration` que toque dados existentes.
|
|
4
|
+
tools: Read, Bash, Grep, Glob, mcp__0a712001-6cbb-44ef-a5f4-a24ea40894fa__execute_sql, mcp__0a712001-6cbb-44ef-a5f4-a24ea40894fa__list_tables
|
|
5
|
+
color: red
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Você é um schema-checker pré-migration. O caller (orquestrador, geralmente Claude) entrega um caminho de arquivo `.sql` (ou conteúdo cru de SQL) e o `project_id` Supabase. Você responde com um veredito estruturado **antes** que a migration seja aplicada.
|
|
9
|
+
|
|
10
|
+
## Por que existe
|
|
11
|
+
|
|
12
|
+
Migrations escritas com base em comentário ou memória do dev frequentemente assumem schema que não bate com produção. Ex: comentário diz `contact_id → conversations.id`, mas a tabela real tem `contact_id → contacts.id`. Aplicar e ver falhar custa 1 retry no melhor caso, dados sujos no pior. Este agente faz a validação cruzada antes do apply.
|
|
13
|
+
|
|
14
|
+
## Inputs esperados (do caller)
|
|
15
|
+
|
|
16
|
+
- `migration_path`: caminho do arquivo SQL (ou string com a SQL inline).
|
|
17
|
+
- `project_id`: identificador do projeto Supabase (ex: `cqxmojtvfqxyvkuljkzs`).
|
|
18
|
+
- (Opcional) `expected_branch`: se a migration deve rodar em uma branch Supabase específica.
|
|
19
|
+
|
|
20
|
+
## Passos
|
|
21
|
+
|
|
22
|
+
### 1. Ler a migration
|
|
23
|
+
|
|
24
|
+
- Ler arquivo SQL via Read.
|
|
25
|
+
- Normalizar (remover comentários `--` e `/* */`, lowercase).
|
|
26
|
+
|
|
27
|
+
### 2. Extrair referências
|
|
28
|
+
|
|
29
|
+
Identifique três classes de referências que podem estar erradas:
|
|
30
|
+
|
|
31
|
+
#### 2.1 — Foreign keys declaradas
|
|
32
|
+
Patterns:
|
|
33
|
+
- `references <schema>.<table>(<col>)`
|
|
34
|
+
- `references <table>(<col>)`
|
|
35
|
+
- `foreign key (<col>) references <table>`
|
|
36
|
+
|
|
37
|
+
Para cada uma, capture: `(local_col, target_table, target_col)`.
|
|
38
|
+
|
|
39
|
+
#### 2.2 — JOINs
|
|
40
|
+
Patterns:
|
|
41
|
+
- `join <table> on <alias>.<col> = <other_alias>.<col>`
|
|
42
|
+
- `join <table> using (<col>)`
|
|
43
|
+
|
|
44
|
+
Para cada JOIN, capture: `(left_table, left_col, right_table, right_col)`.
|
|
45
|
+
|
|
46
|
+
#### 2.3 — INSERT/UPDATE/DELETE com refs implícitas
|
|
47
|
+
Patterns:
|
|
48
|
+
- `insert into <table> (...)` — verifique se `<table>` existe.
|
|
49
|
+
- `update <table> set <col> = ... where <col2> = ...` — verifique `<col>` e `<col2>` existem em `<table>`.
|
|
50
|
+
- `delete from <table> where ...` — idem.
|
|
51
|
+
|
|
52
|
+
### 3. Consultar schema real (via Supabase MCP)
|
|
53
|
+
|
|
54
|
+
Para cada referência extraída no passo 2:
|
|
55
|
+
|
|
56
|
+
#### 3.1 — Existência de tabela e coluna
|
|
57
|
+
|
|
58
|
+
```sql
|
|
59
|
+
SELECT
|
|
60
|
+
EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '{table}') AS table_exists,
|
|
61
|
+
EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '{table}' AND column_name = '{col}') AS col_exists;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use `mcp__0a712001-...__execute_sql` com o `project_id`.
|
|
65
|
+
|
|
66
|
+
#### 3.2 — Tipo da coluna referenciada (FK target)
|
|
67
|
+
|
|
68
|
+
```sql
|
|
69
|
+
SELECT data_type, is_nullable, column_default
|
|
70
|
+
FROM information_schema.columns
|
|
71
|
+
WHERE table_schema = 'public' AND table_name = '{target_table}' AND column_name = '{target_col}';
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### 3.3 — FK existente vs FK proposta
|
|
75
|
+
|
|
76
|
+
Para cada FK que a migration declara, busque se já existe uma constraint similar:
|
|
77
|
+
|
|
78
|
+
```sql
|
|
79
|
+
SELECT conname, conrelid::regclass AS local_table,
|
|
80
|
+
confrelid::regclass AS target_table,
|
|
81
|
+
a.attname AS local_col, b.attname AS target_col
|
|
82
|
+
FROM pg_constraint c
|
|
83
|
+
JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY(c.conkey)
|
|
84
|
+
JOIN pg_attribute b ON b.attrelid = c.confrelid AND b.attnum = ANY(c.confkey)
|
|
85
|
+
WHERE c.contype = 'f' AND c.conrelid::regclass::text = '{local_table}';
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 4. Cruzar e diferenciar
|
|
89
|
+
|
|
90
|
+
Para cada referência da migration:
|
|
91
|
+
|
|
92
|
+
- **OK** — tabela existe, coluna existe, tipo bate, e (se FK declarada) o target da FK na migration bate com o que `pg_constraint` reporta.
|
|
93
|
+
- **MISMATCH-TARGET** — coluna existe, mas a FK aponta para `<X>.<Y>` na migration enquanto produção tem essa coluna referenciando `<W>.<Z>`. Este é o caso clássico do "comentário do dev errado".
|
|
94
|
+
- **MISSING-TABLE** — tabela citada não existe no schema.
|
|
95
|
+
- **MISSING-COLUMN** — coluna citada não existe na tabela.
|
|
96
|
+
- **TYPE-MISMATCH** — coluna existe mas tipo bate diferente do que a migration assume (ex: `uuid` vs `bigint`).
|
|
97
|
+
- **WARN-ONLY** — referência a sistema (ex: `auth.users`) onde permissions podem complicar — registre como warning sem bloquear.
|
|
98
|
+
|
|
99
|
+
### 5. Veredito
|
|
100
|
+
|
|
101
|
+
Imprima um relatório estruturado:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
═══════════════════════════════════════════════════════════
|
|
105
|
+
SCHEMA-CHECK · {migration_path}
|
|
106
|
+
projeto: {project_id} · validado em {timestamp}
|
|
107
|
+
═══════════════════════════════════════════════════════════
|
|
108
|
+
|
|
109
|
+
VEREDITO: GO | NO-GO | NEEDS-REVIEW
|
|
110
|
+
|
|
111
|
+
Resumo:
|
|
112
|
+
- {N} referências analisadas
|
|
113
|
+
- {OK} ok
|
|
114
|
+
- {WARN} warnings
|
|
115
|
+
- {FAIL} falhas
|
|
116
|
+
|
|
117
|
+
═══════════════════════════════════════════════════════════
|
|
118
|
+
DETALHES POR REFERÊNCIA
|
|
119
|
+
═══════════════════════════════════════════════════════════
|
|
120
|
+
|
|
121
|
+
[1] LINHA 7 — FK declarada: contact_prefs.contact_id → conversations.id
|
|
122
|
+
STATUS: ✗ MISMATCH-TARGET
|
|
123
|
+
Em produção: contact_prefs.contact_id → contacts.id (constraint: fk_contact_prefs_contact)
|
|
124
|
+
Comentário da migration sugere conversations.id mas o schema real liga contacts.id.
|
|
125
|
+
AÇÃO: corrigir comentário OU mudar a migration se a intenção era de fato ligar a conversations.
|
|
126
|
+
|
|
127
|
+
[2] LINHA 14 — JOIN: contact_prefs.user_id = users.id
|
|
128
|
+
STATUS: ⚠ WARN-ONLY
|
|
129
|
+
users é tabela de auth — permissions podem aplicar. Verificar `current_user` ou usar `service_role`.
|
|
130
|
+
|
|
131
|
+
[3] LINHA 22 — INSERT INTO contact_prefs (channel, value)
|
|
132
|
+
STATUS: ✓ OK
|
|
133
|
+
|
|
134
|
+
═══════════════════════════════════════════════════════════
|
|
135
|
+
RECOMENDAÇÃO
|
|
136
|
+
═══════════════════════════════════════════════════════════
|
|
137
|
+
{Texto curto: aplicar agora? aplicar com mudanças? não aplicar?}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 6. Regras de veredito
|
|
141
|
+
|
|
142
|
+
- **GO**: 0 falhas, 0 mismatches. Warnings podem existir mas com mitigação clara.
|
|
143
|
+
- **NEEDS-REVIEW**: 1+ mismatches OU 1+ warns sem mitigação clara. Devolva o relatório e DEVOLVA o controle ao caller — não bloqueie, mas peça revisão humana.
|
|
144
|
+
- **NO-GO**: 1+ MISSING-TABLE / MISSING-COLUMN / TYPE-MISMATCH. A migration vai falhar no apply de qualquer forma. Recomende corrigir antes.
|
|
145
|
+
|
|
146
|
+
### 7. Saída
|
|
147
|
+
|
|
148
|
+
Apenas o relatório. Sem preâmbulo. Sem "vou analisar agora". Sem "espero ter ajudado". Direto ao ponto — o caller precisa do veredito pra decidir.
|
|
149
|
+
|
|
150
|
+
## Quando o caller deve invocar
|
|
151
|
+
|
|
152
|
+
- Antes de chamar `mcp__0a712001-...__apply_migration` em qualquer migration que toque dados existentes.
|
|
153
|
+
- Antes de mergear PR que contém migration que vai pra produção.
|
|
154
|
+
- Manualmente, quando o dev pediu uma sanity check ("essa migration tá OK?").
|
|
155
|
+
|
|
156
|
+
**Não invocar para:**
|
|
157
|
+
- Migrations vazias / só de schema novo (sem FK ou JOIN).
|
|
158
|
+
- DROP TABLE / TRUNCATE — nada a checar de schema.
|
|
159
|
+
- Seeds / fixtures — schema-checker valida estrutura, não dados.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: publicar-rapido
|
|
3
|
+
description: Variante leve de /publicar para hotfix/quick-task — sem dependência de ROADMAP/MILESTONE-AUDIT. Infere tipo do commit, gera Notion + cofre + PR cross-linkados.
|
|
4
|
+
argument-hint: "[branch destino opcional, padrão: detectado/sugerido]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
- Write
|
|
11
|
+
- AskUserQuestion
|
|
12
|
+
- mcp__claude_ai_Notion__notion-create-pages
|
|
13
|
+
- mcp__claude_ai_Notion__notion-search
|
|
14
|
+
- mcp__claude_ai_Notion__notion-fetch
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# /publicar-rapido — Pipeline Notion + PR + Cofre, sem cerimônia de milestone
|
|
18
|
+
|
|
19
|
+
Variante de `/publicar` para mudanças que **não passaram pelo fluxo completo de milestone**: hotfix em produção, fix expresso (1 migration / 1 PR), refatoração curta, mudança trivial que precisa cross-link Notion + Obsidian + PR mesmo sem ROADMAP arquivado.
|
|
20
|
+
|
|
21
|
+
## Quando usar
|
|
22
|
+
|
|
23
|
+
- Hotfix em produção: 1-3 commits, branch curta, sem milestone aberto.
|
|
24
|
+
- Pequena feature isolada que não justificou abrir milestone.
|
|
25
|
+
- Correção de bug urgente que precisa ir documentada mas o overhead do `/publicar` não compensa.
|
|
26
|
+
|
|
27
|
+
**Não use** quando o trabalho foi um milestone de várias fases — use `/publicar` (que valida MILESTONE-AUDIT.md, ROADMAP arquivado, etc).
|
|
28
|
+
|
|
29
|
+
## Diferenças vs /publicar
|
|
30
|
+
|
|
31
|
+
| Aspecto | `/publicar` | `/publicar-rapido` |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| Pré-requisitos de planejamento | ROADMAP + MILESTONE-AUDIT obrigatórios | Apenas commit(s) na branch |
|
|
34
|
+
| Detecção de versão | De `STATE.md` | De `package.json` ou git tag mais recente |
|
|
35
|
+
| Detecção de tipo | Inferido do milestone | **Inferido do commit message** (`fix:`/`feat:`/`refactor:`/`chore:` prefix) |
|
|
36
|
+
| Notion | Página de changelog do milestone | Entrada curta na página de **changelog** com 1 parágrafo |
|
|
37
|
+
| Cofre Obsidian | Nota de PR + Changelog completo + componentes afetados | Apenas nota de PR + entrada no Changelog |
|
|
38
|
+
| Pre-flight sync com `main` | Sim (Passo 0) | **Sim — herdado** |
|
|
39
|
+
| Tempo médio | 60-90s | **~30s** |
|
|
40
|
+
|
|
41
|
+
## Processo
|
|
42
|
+
|
|
43
|
+
### Passo 0 — Pre-flight: sincronizar com main (obrigatório, herdado de /publicar)
|
|
44
|
+
|
|
45
|
+
Igual ao Passo 0 do `/publicar`: `git fetch origin main`, lista commits novos, oferece rebase/merge/ignorar/cancelar via `AskUserQuestion`. **Não pule** — esse é exatamente o cenário onde dev paralelo causa conflito tardio em hotfix.
|
|
46
|
+
|
|
47
|
+
### Passo 1 — Detectar contexto
|
|
48
|
+
|
|
49
|
+
#### 1.1 — Tipo do commit
|
|
50
|
+
|
|
51
|
+
Leia o commit mais recente (`git log -1 --format=%B`). Se houver múltiplos commits desde `origin/main`, leia todos (`git log origin/main..HEAD --format=%B`).
|
|
52
|
+
|
|
53
|
+
Inferir `TIPO_MUDANCA` por prefix do **primeiro commit** ou pelo padrão majoritário se múltiplos:
|
|
54
|
+
|
|
55
|
+
| Prefix | TIPO_MUDANCA | Notion section |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `fix:` / `bugfix:` | `Corrigido` | Bug fix |
|
|
58
|
+
| `feat:` / `feature:` | `Adicionado` | Feature |
|
|
59
|
+
| `perf:` | `Melhorado` | Performance |
|
|
60
|
+
| `refactor:` | `Alterado` | Refactor |
|
|
61
|
+
| `chore:` / `docs:` / `style:` | `Alterado` | Manutenção |
|
|
62
|
+
| `revert:` | `Removido` | Revert |
|
|
63
|
+
| Sem prefix | `Alterado` | (perguntar via AskUserQuestion) |
|
|
64
|
+
|
|
65
|
+
Se não conseguir inferir (nenhum prefix), use `AskUserQuestion`:
|
|
66
|
+
- **header:** "Tipo"
|
|
67
|
+
- **question:** "Tipo da mudança?"
|
|
68
|
+
- **options:** "Correção (fix)", "Feature (feat)", "Refator (refactor)", "Outro"
|
|
69
|
+
|
|
70
|
+
#### 1.2 — Título resumido
|
|
71
|
+
|
|
72
|
+
Extraia o **primeiro commit message** sem o prefix. Se múltiplos commits, use o **mais descritivo** (mais longo). Limite a 60 chars.
|
|
73
|
+
|
|
74
|
+
Exemplos:
|
|
75
|
+
- `fix: corrige FK em contact_prefs migration` → `Corrige FK em contact_prefs migration`
|
|
76
|
+
- `feat: adiciona índice em contacts.phone` → `Adiciona índice em contacts.phone`
|
|
77
|
+
|
|
78
|
+
Apresente ao user via `AskUserQuestion`:
|
|
79
|
+
- **question:** "Título sugerido: \"{TITULO}\". Confirma?"
|
|
80
|
+
- **options:** Confirmar, Editar (text input)
|
|
81
|
+
|
|
82
|
+
#### 1.3 — Versão
|
|
83
|
+
|
|
84
|
+
Detecte `VERSION` (ordem de prioridade):
|
|
85
|
+
1. `package.json` campo `version` (incremente o patch — ex: `1.2.3` → `1.2.4`)
|
|
86
|
+
2. Tag git mais recente: `git describe --tags --abbrev=0` (incremente patch)
|
|
87
|
+
3. Sem fonte: use timestamp `YYYY-MM-DD-HHMMSS`
|
|
88
|
+
|
|
89
|
+
Apresente via `AskUserQuestion`:
|
|
90
|
+
- **question:** "Próxima versão: {VERSION}. Confirma ou pula bump de package.json?"
|
|
91
|
+
- **options:** Bump+commit, Sem bump (só Notion+PR)
|
|
92
|
+
|
|
93
|
+
Se "Bump+commit", execute:
|
|
94
|
+
```bash
|
|
95
|
+
npm version patch --no-git-tag-version
|
|
96
|
+
git add package.json package-lock.json
|
|
97
|
+
git commit -m "chore: bump {VERSION}"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Passo 2 — Decidir branch
|
|
101
|
+
|
|
102
|
+
Igual ao `/publicar` Passo 2 — usar branch atual ou criar nova baseada no `TIPO_MUDANCA`. Sugestão de nome:
|
|
103
|
+
|
|
104
|
+
- `fix:` → `fix-{slug-do-titulo}`
|
|
105
|
+
- `feat:` → `feat-{slug-do-titulo}`
|
|
106
|
+
- `refactor:` → `refactor-{slug-do-titulo}`
|
|
107
|
+
|
|
108
|
+
### Passo 3 — Criar página Notion (curta)
|
|
109
|
+
|
|
110
|
+
Carregue `.claude/notion-config.json` (com fallback do auto-detect — Passo 0.5 do `/publicar`).
|
|
111
|
+
|
|
112
|
+
Use `notion-create-pages` com `parent.page_id = NOTION_CHANGELOG_PAGE_ID`.
|
|
113
|
+
|
|
114
|
+
**Template enxuto (não confundir com o template completo do /publicar):**
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Título: {VERSION} — {TITULO}
|
|
118
|
+
Ícone: 🩹 (fix) | ✨ (feat) | 🔧 (refactor) | 🧹 (chore)
|
|
119
|
+
|
|
120
|
+
[Callout cinza] Quick fix · {DATA} · Branch: `{BRANCH}` · Tipo: {TIPO_MUDANCA}
|
|
121
|
+
|
|
122
|
+
## O que mudou
|
|
123
|
+
|
|
124
|
+
{1 parágrafo descrevendo a mudança em linguagem direta — extraia do commit body se houver, senão use o título expandido.}
|
|
125
|
+
|
|
126
|
+
## Arquivos tocados
|
|
127
|
+
|
|
128
|
+
[Tabela: Arquivo | O que mudou]
|
|
129
|
+
{lista de `git diff origin/main..HEAD --stat` resumida — primeiros 10 arquivos}
|
|
130
|
+
|
|
131
|
+
## Como verificar
|
|
132
|
+
|
|
133
|
+
{Se TIPO_MUDANCA = fix: instrução curta de smoke test do bug. Se feat: passo a passo de uso. Se refactor: nota dizendo "sem mudança de comportamento esperada".}
|
|
134
|
+
|
|
135
|
+
## Referências
|
|
136
|
+
|
|
137
|
+
- Commit(s): `{lista de hashes curtos}`
|
|
138
|
+
- Branch: `{BRANCH}`
|
|
139
|
+
- PR: (será preenchido pelo dev após o passo 4)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Armazene `NOTION_URL`.
|
|
143
|
+
|
|
144
|
+
Se houver `PENDENTE_COMMIT = true` (Passo 2), execute o commit agora com o link incluído:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
git commit -m "{TIPO_MUDANCA_PREFIX}: {TITULO}
|
|
148
|
+
|
|
149
|
+
Notion: {NOTION_URL}"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Passo 4 — Push + PR
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
git push origin {BRANCH}
|
|
156
|
+
|
|
157
|
+
gh pr create \
|
|
158
|
+
--title "{TIPO_MUDANCA_PREFIX}: {TITULO}" \
|
|
159
|
+
--body "..."
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Body do PR (template enxuto):**
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
## {TITULO}
|
|
166
|
+
|
|
167
|
+
{1 parágrafo do que mudou}
|
|
168
|
+
|
|
169
|
+
### Arquivos
|
|
170
|
+
{lista de até 5 paths}
|
|
171
|
+
|
|
172
|
+
### Documentação
|
|
173
|
+
📄 Notion: {NOTION_URL}
|
|
174
|
+
{Se OBSIDIAN_URL definido: 📚 Cofre: {OBSIDIAN_URL}}
|
|
175
|
+
|
|
176
|
+
### Sync com main
|
|
177
|
+
{Se SYNC_SKIPPED = true: ⚠️ PR aberto sem rebase com origin/main — possível conflito ao revisar.}
|
|
178
|
+
{Senão: ✓ Sincronizado com main em {timestamp}.}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Sem rodapé de IA. Sem assinatura de tooling.
|
|
182
|
+
|
|
183
|
+
### Passo 5 — Cofre Obsidian (curto)
|
|
184
|
+
|
|
185
|
+
Igual ao Passo 0.7 + 5 do `/publicar`, mas com escrita reduzida:
|
|
186
|
+
|
|
187
|
+
- **Nota de PR** (obrigatória): `01 - PRs/YYYY/YYYY-MM-DD-pr-{PR_NUMBER}-{slug}.md` com frontmatter `notion: {NOTION_URL}`.
|
|
188
|
+
- **Changelog**: adicionar 1 linha em `03 - Changelog/YYYY.md` na seção apropriada (`### Corrigido` / `### Adicionado` / etc baseado em `TIPO_MUDANCA`), referenciando PR.
|
|
189
|
+
- **Componentes afetados**: PULAR. /publicar-rapido não atualiza notas de componente — usar `/publicar` quando o escopo justificar.
|
|
190
|
+
|
|
191
|
+
Mesma cerimônia de commit + push do cofre.
|
|
192
|
+
|
|
193
|
+
### Passo 6 — Reportar
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
🩹 Quick publish concluída em ~{TEMPO_TOTAL}s
|
|
197
|
+
|
|
198
|
+
📄 Notion: {NOTION_URL}
|
|
199
|
+
🔗 PR: {PR_URL}
|
|
200
|
+
📚 Obsidian: {OBSIDIAN_URL} ← ou ⚠️ pulado: {motivo}
|
|
201
|
+
🌿 Branch: {BRANCH}
|
|
202
|
+
🏷 Tipo: {TIPO_MUDANCA}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Para projetos novos
|
|
206
|
+
|
|
207
|
+
Mesmo `notion-config.json` do `/publicar`. Auto-detect (Passo 0.5 herdado) cobre o caso de config ausente — basta a página existir no Notion.
|
package/kit/commands/publicar.md
CHANGED
|
@@ -20,10 +20,11 @@ Publica o milestone atual: cria documentação no Notion, abre PR no GitHub e in
|
|
|
20
20
|
|
|
21
21
|
Após concluir e arquivar um milestone com `/concluir-marco`.
|
|
22
22
|
|
|
23
|
+
**Heurística de gatilho (importante):** quando o usuário diz "publicar" depois de aplicar mudanças de código (commits novos, migration aplicada, branch atual com diff vs `main`), interprete como **pipeline completo** — não apenas `git push`. Faça Notion + PR + Obsidian. Para push isolado em outra branch sem cerimônia, o usuário deve pedir explicitamente "só fazer push" ou usar `git push` ele mesmo. Para fix expresso sem milestone, use `/publicar-rapido` (variante leve sem dependência de ROADMAP/MILESTONE-AUDIT).
|
|
24
|
+
|
|
23
25
|
## Dependências obrigatórias
|
|
24
26
|
|
|
25
|
-
- `.claude/notion-config.json` presente e preenchido — se
|
|
26
|
-
> "⛔ notion-config.json não encontrado. Execute /setup-notion para configurar o Notion deste projeto."
|
|
27
|
+
- `.claude/notion-config.json` presente e preenchido — **fluxo de fallback novo (1.4):** se ausente, NÃO encerre. Em vez disso, vá para o **Passo 0.5 (auto-detect Notion)** abaixo: tente buscar a página do projeto via Notion MCP `notion-search` no workspace e ofereça gerar o config automaticamente. Encerrar é fallback de último recurso.
|
|
27
28
|
- Notion MCP configurado na sessão Claude Code
|
|
28
29
|
- `gh` CLI autenticado (`gh auth status`)
|
|
29
30
|
- Milestone arquivado com `/concluir-marco`
|
|
@@ -31,10 +32,129 @@ Após concluir e arquivar um milestone com `/concluir-marco`.
|
|
|
31
32
|
## Dependências opcionais
|
|
32
33
|
|
|
33
34
|
- `$OBSIDIAN_TEAM_VAULT` — caminho absoluto do cofre Obsidian do time (sincronizado via Git).
|
|
34
|
-
-
|
|
35
|
+
- **Fallback novo (1.4):** se ausente, antes de pular o Passo 5, o **Passo 0.7 (auto-detect Obsidian)** tenta caminhos canônicos (`~/Documentos/Obsidian/chat-trynux/`, `~/Documents/Obsidian/chat-trynux/`, e variantes Windows). Só se nenhum bater é que o Passo 5 é pulado com aviso.
|
|
35
36
|
|
|
36
37
|
## Processo
|
|
37
38
|
|
|
39
|
+
### Passo 0 — Pre-flight: sincronizar com `main` ⚠️ NOVO 1.4
|
|
40
|
+
|
|
41
|
+
**Por que isso existe:** vários devs trabalhando no mesmo projeto significa que `origin/main` pode ter avançado desde sua última sincronização. Antes de abrir PR, descubra se há trabalho novo e dê ao dev a chance de integrar (evita conflitos grandes mais tarde).
|
|
42
|
+
|
|
43
|
+
**Quando pular:** se `BRANCH = main` (vai pushar direto pra main, sem PR), pode pular este passo. Em qualquer outro fluxo, execute.
|
|
44
|
+
|
|
45
|
+
#### 0.1 — Buscar atualizações de origin
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git fetch origin main 2>&1
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### 0.2 — Detectar commits novos em main
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
NEW_COMMITS=$(git log HEAD..origin/main --oneline 2>/dev/null)
|
|
55
|
+
COUNT=$(echo "$NEW_COMMITS" | grep -c . 2>/dev/null || echo 0)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### 0.3 — Roteamento
|
|
59
|
+
|
|
60
|
+
**Se `COUNT == 0`:** sem commits novos. Continue silenciosamente para o Passo 1.
|
|
61
|
+
|
|
62
|
+
**Se `COUNT > 0`:** apresente a lista ao usuário e pergunte como prosseguir.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
⚠️ {COUNT} commit(s) novo(s) em origin/main desde sua última sync:
|
|
66
|
+
|
|
67
|
+
{lista dos commits, primeiros 10}
|
|
68
|
+
|
|
69
|
+
Como deseja prosseguir?
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use `AskUserQuestion`:
|
|
73
|
+
- **header:** "Sync"
|
|
74
|
+
- **question:** "Há {COUNT} commit(s) novo(s) em main. Como prosseguir antes de abrir PR?"
|
|
75
|
+
- **options:**
|
|
76
|
+
- **"Integrar agora (Recomendado)"** — `git rebase origin/main` na branch atual. Se conflito: pausa, instrui resolver, retoma.
|
|
77
|
+
- **"Mesclar via merge commit"** — `git merge origin/main` (preserva histórico ao custo de um merge commit no PR).
|
|
78
|
+
- **"Ignorar e continuar"** — segue direto para Passo 1 (assume responsabilidade pelo conflito tardio).
|
|
79
|
+
- **"Cancelar publicação"** — exit limpo. Dev integra manualmente, depois reroda /publicar.
|
|
80
|
+
|
|
81
|
+
**Em "Integrar agora":**
|
|
82
|
+
```bash
|
|
83
|
+
git rebase origin/main
|
|
84
|
+
```
|
|
85
|
+
- Se exit 0: continue para Passo 1 com confirmação `✓ Rebase OK`.
|
|
86
|
+
- Se conflito: imprima `⚠️ Conflito durante rebase. Resolva os arquivos listados, rode \`git rebase --continue\` (ou \`git rebase --abort\` para desfazer), e reinvoque /publicar.` e exit limpo.
|
|
87
|
+
|
|
88
|
+
**Em "Mesclar":**
|
|
89
|
+
```bash
|
|
90
|
+
git merge origin/main --no-edit
|
|
91
|
+
```
|
|
92
|
+
- Mesmo tratamento de conflito.
|
|
93
|
+
|
|
94
|
+
**Em "Ignorar":** registre `SYNC_SKIPPED = true` (será mencionado na descrição do PR como heads-up: "PR aberto sem sync com main — possível conflito ao revisar").
|
|
95
|
+
|
|
96
|
+
**Em "Cancelar":** exit limpo, sem efeito colateral.
|
|
97
|
+
|
|
98
|
+
### Passo 0.5 — Auto-detect notion-config.json (se ausente) ⚠️ NOVO 1.4
|
|
99
|
+
|
|
100
|
+
Se `.claude/notion-config.json` existe, pule para Passo 0.7.
|
|
101
|
+
|
|
102
|
+
Se ausente:
|
|
103
|
+
|
|
104
|
+
#### 0.5.1 — Buscar página do projeto via Notion MCP
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
notion-search { query: "{NOME_PROJETO}", filter: "page" }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Onde `{NOME_PROJETO}` vem do `.planning/PROJECT.md` (campo `name` ou primeira frase).
|
|
111
|
+
|
|
112
|
+
#### 0.5.2 — Apresentar candidatos
|
|
113
|
+
|
|
114
|
+
Filtre resultados pra páginas com título que contenha o nome do projeto (case-insensitive). Mostre top 3 com URL e last-edited.
|
|
115
|
+
|
|
116
|
+
Use `AskUserQuestion`:
|
|
117
|
+
- **question:** "Encontrei essas páginas no Notion. Qual é a página raiz deste projeto?"
|
|
118
|
+
- **options:** uma por candidato + "Nenhuma — abrir /setup-notion"
|
|
119
|
+
|
|
120
|
+
Em candidato escolhido:
|
|
121
|
+
- Use `notion-fetch` na página escolhida pra listar subpáginas (espera-se `changelog/`, `features/`, `adr/`, `runbooks/`).
|
|
122
|
+
- Para cada subpágina conhecida, capture o ID.
|
|
123
|
+
- Gere `.claude/notion-config.json` com o template do `/setup-notion`.
|
|
124
|
+
- Confirme: "✓ notion-config.json criado a partir das páginas existentes."
|
|
125
|
+
|
|
126
|
+
Em "Nenhuma": exit limpo com mensagem `⛔ Execute /setup-notion para criar a estrutura Notion deste projeto, depois rerun /publicar.`
|
|
127
|
+
|
|
128
|
+
### Passo 0.7 — Auto-detect cofre Obsidian (se env var ausente) ⚠️ NOVO 1.4
|
|
129
|
+
|
|
130
|
+
Se `$OBSIDIAN_TEAM_VAULT` está definida E o caminho existe, pule para Passo 1.
|
|
131
|
+
|
|
132
|
+
Se ausente, tente caminhos canônicos em ordem (primeiro que existir vence):
|
|
133
|
+
|
|
134
|
+
| Plataforma | Caminho |
|
|
135
|
+
|---|---|
|
|
136
|
+
| Linux/macOS | `$HOME/Documentos/Obsidian/chat-trynux` |
|
|
137
|
+
| Linux/macOS | `$HOME/Documents/Obsidian/chat-trynux` |
|
|
138
|
+
| Windows | `$USERPROFILE/Documentos/Obsidian/chat-trynux` |
|
|
139
|
+
| Windows | `$USERPROFILE/Documents/Obsidian/chat-trynux` |
|
|
140
|
+
| WSL | `/mnt/c/Users/$USER/Documents/Obsidian/chat-trynux` |
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
for CANDIDATE in \
|
|
144
|
+
"$HOME/Documentos/Obsidian/chat-trynux" \
|
|
145
|
+
"$HOME/Documents/Obsidian/chat-trynux" \
|
|
146
|
+
"$USERPROFILE/Documentos/Obsidian/chat-trynux" \
|
|
147
|
+
"$USERPROFILE/Documents/Obsidian/chat-trynux" \
|
|
148
|
+
"/mnt/c/Users/$USER/Documents/Obsidian/chat-trynux"; do
|
|
149
|
+
[ -n "$CANDIDATE" ] && [ -d "$CANDIDATE" ] && { export OBSIDIAN_TEAM_VAULT="$CANDIDATE"; break; }
|
|
150
|
+
done
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
- Se uma das variantes bateu: registre `OBSIDIAN_AUTO_DETECTED = true` e prossiga normalmente para Passo 1.
|
|
154
|
+
- Se nenhuma bateu: comportamento legado (Passo 5 será pulado com `OBSIDIAN_SKIP_REASON = "OBSIDIAN_TEAM_VAULT não configurada e nenhum caminho canônico encontrado"`).
|
|
155
|
+
|
|
156
|
+
> **Nota:** o nome `chat-trynux` é o cofre canônico padrão. Para usar outro nome, defina `$OBSIDIAN_TEAM_VAULT` explicitamente — a auto-detecção não tenta diretórios alternativos.
|
|
157
|
+
|
|
38
158
|
### Passo 1 — Ler contexto
|
|
39
159
|
|
|
40
160
|
Leia os seguintes arquivos:
|