@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 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.
@@ -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 não existir, encerre com:
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
- - Se ausente ou inválido: o **Passo 5 (Obsidian)** é pulado com aviso, sem quebrar PR/Notion.
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: