@tavaressan/vetor 0.1.0 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vitor Tavares Chaves
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -3,6 +3,7 @@
3
3
  const { detectEngines: defaultDetectEngines } = require('../installer/detector.js');
4
4
  const { runInstallPrompts: defaultRunInstallPrompts } = require('../installer/prompts.js');
5
5
  const { installFiles: defaultInstallFiles } = require('../installer/writer.js');
6
+ const { printBanner: defaultPrintBanner } = require('../banner.js');
6
7
 
7
8
  /**
8
9
  * Comando `install`: detecta engines suportadas no projeto-alvo (ver `ENGINES` em
@@ -16,16 +17,19 @@ const { installFiles: defaultInstallFiles } = require('../installer/writer.js');
16
17
  * por arquivo para updates seguros mais tarde. Engine sem destino de arquivo confirmado
17
18
  * (`enginesSkipped`) é reportada ao usuário em vez de silenciosamente ignorada.
18
19
  *
19
- * `detectEngines`/`runInstallPrompts`/`installFiles`/`input`/`output` são injetáveis para
20
- * testes.
20
+ * `detectEngines`/`runInstallPrompts`/`installFiles`/`printBanner`/`input`/`output` são
21
+ * injetáveis para testes.
21
22
  */
22
23
  async function install(cwd = process.cwd(), options = {}) {
23
24
  const detectEngines = options.detectEngines ?? defaultDetectEngines;
24
25
  const runInstallPrompts = options.runInstallPrompts ?? defaultRunInstallPrompts;
25
26
  const installFiles = options.installFiles ?? defaultInstallFiles;
27
+ const printBanner = options.printBanner ?? defaultPrintBanner;
26
28
  const input = options.input ?? process.stdin;
27
29
  const output = options.output ?? process.stdout;
28
30
 
31
+ printBanner();
32
+
29
33
  const engines = detectEngines(cwd);
30
34
  const detectedNames = engines.filter((engine) => engine.detected).map((engine) => engine.name);
31
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tavaressan/vetor",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Instalador do Vetor: automação de workflow de desenvolvimento (skills para Claude Code, Codex e outras engines).",
5
5
  "bin": {
6
6
  "vetor": "bin/vetor.js"
@@ -11,7 +11,8 @@
11
11
  "files": [
12
12
  "bin/",
13
13
  "lib/",
14
- "templates/"
14
+ "templates/",
15
+ "LICENSE"
15
16
  ],
16
17
  "keywords": [
17
18
  "claude-code",
@@ -263,7 +263,7 @@ do sugerido aqui se estiver `degraded` no momento do dispatch.
263
263
  #### Pergunta sobre teto de workers simultâneos
264
264
 
265
265
  Antes de pedir aprovação:
266
- 1. Calcule `N_rec = min(número de grupos formados, maxConcurrentWorkers de .claude/vetor/config.json
266
+ 1. Calcule `N_rec = min(largura da maior onda, maxConcurrentWorkers de .claude/vetor/config.json
267
267
  — senão 5)`. Acima de ~8 workers, sinalize que custo agregado e ruído de monitoramento crescem
268
268
  mais rápido que o ganho de paralelismo — é recomendação, não limite; a decisão é do usuário.
269
269
  2. **Em `--headless`: não pergunte.** Adote `N = N_rec`, registre no relatório final (Fase 7) o
@@ -498,7 +498,9 @@ ele precisa ser autossuficiente. Acrescente ao formato acima:
498
498
  `issue-worker` no status file, sem checagem automática — issue #156). Ao atingir a 5ª iteração sem
499
499
  verde, o worker deve registrar `BLOCKED_WAITING` ou `FAILED_MAX_ITERATIONS`, nunca decidir sozinho
500
500
  continuar.
501
- - Timeout global de 90 minutos para o coordenador (este sim, hard cap real)
501
+ - Timeout global de 90 minutos para o coordenador (este sim, hard cap real) — configurável via
502
+ `maxSessionMinutes` em `.claude/vetor/config.json` (default 90). O teto restringe novos dispatches e
503
+ o início de novas ondas; ships e workers ativos podem concluir.
502
504
  - Iterações em `BLOCKED_WAITING` não contam contra o orçamento de 5
503
505
 
504
506
  O número de processos simultâneos **não é um hard cap**: é o valor `N` decidido pelo usuário na
@@ -1,18 +1,29 @@
1
1
  #!/usr/bin/env bash
2
2
  # Tabela de monitoramento do issue-coordinator, construída de fontes externas
3
- # (status files + git worktree list) — não de estado em memória. Rodar no root.
3
+ # (status files + git worktree list) — não de estado em memória. Pode rodar no root
4
+ # ou de dentro de qualquer worktree (issue #339).
4
5
  #
5
6
  # Uso: vetor-status.sh
6
7
  # Saída: tabela markdown com uma linha por status file em .claude/vetor/status/.
7
8
  # Worktree correspondente removido manualmente -> "cancelled (worktree removed)".
9
+ # Worktree recém-despachado -> "aguardando worktree" (issue #347).
8
10
  # Worktree sem status file -> ⚠️ WARNING (possível falha anômala, issue #72).
9
11
 
10
12
  set -uo pipefail
11
13
 
12
- STATUS_DIR=".claude/vetor/status"
14
+ # Resolve o root do repositório principal (suporta execução de dentro de worktrees — issue #339)
15
+ REPO_ROOT=$(git worktree list --porcelain 2>/dev/null | head -1 | sed 's/^worktree //')
16
+ if [ -z "$REPO_ROOT" ]; then
17
+ REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
18
+ fi
19
+
20
+ STATUS_DIR="${REPO_ROOT}/.claude/vetor/status"
13
21
 
14
22
  # Branch principal (main worktree) — excluída da lista de workers ativos.
15
- default_branch=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
23
+ default_branch=$(git worktree list --porcelain 2>/dev/null | sed -n '3s#^branch refs/heads/##p')
24
+ if [ -z "$default_branch" ]; then
25
+ default_branch=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##' || git symbolic-ref --short HEAD 2>/dev/null || echo "")
26
+ fi
16
27
 
17
28
  # Branches com worktree ativo (workers), sanitizadas com a mesma convenção dos status files (/ -> -).
18
29
  # Exclui a branch principal do repositório.
@@ -56,7 +67,13 @@ for f in "$STATUS_DIR"/*.md; do
56
67
  if printf '%s\n' "$active" | grep -qx "$name"; then
57
68
  wt="ativo"
58
69
  else
59
- wt="cancelled (worktree removed)"
70
+ # Issue #347: status recém-criado pelo coordinator antes do harness criar o worktree
71
+ iter_n=$(printf '%s' "$iter" | sed -n 's#^\([0-9][0-9]*\)/.*#\1#p')
72
+ if [ "$status" = "RUNNING" ] && { [ -z "$iter_n" ] || [ "$iter_n" -le 1 ]; }; then
73
+ wt="aguardando worktree"
74
+ else
75
+ wt="cancelled (worktree removed)"
76
+ fi
60
77
  fi
61
78
  seen_branches="${seen_branches}${name}
62
79
  "
@@ -99,8 +99,9 @@ Qualquer evidência ao vivo é âncora válida — não se limita a Sentry/Datad
99
99
  uma dessas durante a sessão (não precisa buscar ativamente), use-a para propor issue `fix` ou
100
100
  `chore`. **Para issues `fix`, é obrigatório citar o comando/fonte exato que reproduz o problema.**
101
101
 
102
- Se houver MCP de observabilidade disponível (`mcp__sentry__*`, `mcp__datadog__*` — ver
103
- `mcp-availability.md`), use-o para obter os erros não resolvidos mais frequentes em produção e
102
+ Se houver MCP de observabilidade disponível (standalone `mcp__<server>__*` ou empacotado em
103
+ plugin `mcp__plugin_<plugin>_<server>__*` para sentry ou datadog — ver `mcp-availability.md` e
104
+ `scripts/lib/mcp.ts`), use-o para obter os erros não resolvidos mais frequentes em produção e
104
105
  ancore issues `fix` neles, incluindo stacktraces. Sem MCP, prossiga normalmente.
105
106
 
106
107
  ### 2.b — Investigação estruturada (grilling)
@@ -67,9 +67,10 @@ uma tela/fluxo de UI compila e roda. Também pode ser invocado manualmente com
67
67
  estética/tipográfica via skill nativa `frontend-design`, aplicada **antes** de escrever o código.
68
68
  O Loop é complementar e roda **depois**: verifica o que foi construído, não decide como desenhar.
69
69
  - `../shared/references/mcp-availability.md` — mecanismo de checagem de
70
- disponibilidade (procurar `mcp__<server>__` na lista de ferramentas). Servidores relevantes aqui:
71
- browser (`mcp__chrome-devtools__`, `mcp__playwright__`) para os passos 4-6 e 9 do Loop, Context7
72
- para qualquer comportamento de framework/lib consultado durante o Fix (Loop, passo 8).
70
+ disponibilidade (procurar `mcp__<server>__` ou `mcp__plugin_<plugin>_<server>__` na lista de
71
+ ferramentas, conforme `scripts/lib/mcp.ts` — issue #336). Servidores relevantes aqui: browser
72
+ (`chrome-devtools`, `playwright`) para os passos 4-6 e 9 do Loop, Context7 para qualquer
73
+ comportamento de framework/lib consultado durante o Fix (Loop, passo 8).
73
74
  - `scripts/lib/design-mode.ts` — lógica de detecção/renderização do Setup (pura, testada em
74
75
  `scripts/tests/design-mode_test.ts`).
75
76
  - `scripts/detect-design-mode.ts` — CLI que orquestra a escrita em disco do Setup a partir da lib
@@ -427,8 +428,9 @@ lista não está vazia — declare exatamente o que foi e o que não foi confirm
427
428
  ### Sem MCP de browser (degradação graciosa)
428
429
 
429
430
  Este loop nunca falha nem trava por falta de MCP de browser, e nunca finge que a inspeção ocorreu.
430
- Quando nenhum servidor de browser (`mcp__chrome-devtools__*`, `mcp__playwright__*`) está na lista de
431
- ferramentas da sessão:
431
+ Quando nenhum servidor de browser (`chrome-devtools`, `playwright` — via prefixo standalone
432
+ `mcp__<server>__*` ou empacotado em plugin `mcp__plugin_*_<server>__*`, conforme `scripts/lib/mcp.ts`)
433
+ está na lista de ferramentas da sessão:
432
434
 
433
435
  1. Os passos 4, 5, 6 e a parte visual do 7/9 usam `reportLoopStep(<step>, <ferramentas>)` de
434
436
  `scripts/lib/design-loop-mcp.ts`, que retorna `verdict: "unverified"` com uma `limitation`
@@ -179,8 +179,9 @@ gh pr view <N> --json mergeable,mergeStateStatus
179
179
 
180
180
  ### 7 — Auditoria de Banco de Dados (via MCP)
181
181
 
182
- Verifique disponibilidade de um MCP de banco (`mcp__<db>__*` — o nome do servidor varia). Se não
183
- houver, ignore este check. Se houver, audite a saúde estrutural (adapte ao dialeto):
182
+ Verifique disponibilidade de um MCP de banco (prefixo standalone `mcp__<db>__*` ou empacotado em
183
+ plugin `mcp__plugin_<plugin>_<db>__*`, conforme `scripts/lib/mcp.ts` — o nome do servidor varia). Se
184
+ não houver, ignore este check. Se houver, audite a saúde estrutural (adapte ao dialeto):
184
185
 
185
186
  - Índices não utilizados.
186
187
  - Tabelas sem chave primária ou índices.
@@ -199,8 +200,9 @@ Se o stack for identificável (`mcp__planetscale__*`, `mcp__postgres__*`, `mcp__
199
200
 
200
201
  ### 8 — Auditoria de Saúde de Containers Docker (via MCP)
201
202
 
202
- Verifique disponibilidade de um MCP Docker (`mcp__docker__*`, diretas ou diferidas). Se não houver,
203
- ignore silenciosamente.
203
+ Verifique disponibilidade de um MCP Docker (`mcp__docker__*` ou `mcp__plugin_<plugin>_docker__*`,
204
+ diretas ou diferidas — sem casar gateways como `mcp__MCP_DOCKER__`, conforme `scripts/lib/mcp.ts`).
205
+ Se não houver, ignore silenciosamente.
204
206
 
205
207
  Se disponível, liste os containers do projeto (equivalente a `docker ps`/`docker inspect`) e
206
208
  identifique quais **não** estão `running`/`healthy` (ex.: `exited`, `restarting`, `unhealthy`).
@@ -51,10 +51,12 @@ Os comandos de teste vêm de `.claude/vetor/module-test-map.md` ou, na ausência
51
51
  auto-detecção a partir do CI — cada primitivo já consome essa referência, sempre resolvendo o
52
52
  arquivo a partir do root do repositório (`vetor-checks.sh repo-root`), nunca do `cwd` do worktree
53
53
  (issue #160), pois arquivos ignorados pelo `.gitignore` do projeto-alvo (ex.: uma entrada
54
- `.claude/`) não são materializados em worktrees linkados. Se `git check-ignore -q .claude` indicar
55
- que `.claude/` está ignorado no projeto-alvo, você pode opcionalmente injetar os comandos de teste
56
- já resolvidos diretamente no prompt de cada worker despachado, como reforço redundante — a fonte de
57
- verdade continua sendo a resolução via root em `project-conventions.md`.
54
+ `.claude/`) ou arquivos untracked (não versionados) não são materializados em worktrees linkados.
55
+ Se `git check-ignore -q .claude` indicar que `.claude/` está ignorado no projeto-alvo, ou se
56
+ `git ls-files --error-unmatch .claude/vetor/module-test-map.md` indicar que o arquivo não está
57
+ rastreado no git (issue #327), injete os comandos de teste já resolvidos diretamente no prompt de
58
+ cada worker despachado, como reforço redundante — a fonte de verdade continua sendo a resolução
59
+ via root em `project-conventions.md`.
58
60
  Regras de economia de tokens e delegação a um runtime externo disponível (Gemini/OpenCode/Codex):
59
61
  `../shared/references/planning-conventions.md` e
60
62
  `../shared/references/delegate-to-runtime.md`.
@@ -285,13 +287,15 @@ origens.
285
287
  Cada subagente paralelo é uma instância Claude completa, sem contexto compartilhado — é o maior
286
288
  driver de custo agregado do coordinator.
287
289
 
288
- 1. **Recomendação** `N_rec` = `min(nº de grupos da Fase 1, maxConcurrentWorkers de
289
- .claude/vetor/config.json se existir — senão 5)`. Acima de ~8 workers, custo agregado e ruído de
290
- monitoramento tendem a crescer mais rápido que o ganho de paralelismo: se `N_rec` > 8, sinalize
291
- isso na pergunta. É recomendação, não limite — a decisão é do usuário.
290
+ 1. **Recomendação** `N_rec` = `min(largura da maior onda, maxConcurrentWorkers de
291
+ .claude/vetor/config.json se existir — senão 5)`. A largura da maior onda é o número máximo de
292
+ grupos que podem rodar em paralelo dentro de uma mesma onda (grupos de ondas distintas nunca rodam
293
+ juntos — Fase 4). Acima de ~8 workers, custo agregado e ruído de monitoramento tendem a crescer
294
+ mais rápido que o ganho de paralelismo: se `N_rec` > 8, sinalize isso na pergunta. É
295
+ recomendação, não limite — a decisão é do usuário.
292
296
  2. **Em `--headless`:** adote `N = N_rec` sem perguntar e registre no relatório qual valor foi usado
293
297
  e como foi calculado. Fora do headless, **pergunte via `AskUserQuestion`** (uma única vez por sessão):
294
- - `"<N_rec> (Recomendado)"` — justifique em 1 linha (nº de grupos, custo por worker, alerta se > 8)
298
+ - `"<N_rec> (Recomendado)"` — justifique em 1 linha (largura da onda, custo por worker, alerta se > 8)
295
299
  - `"1 — serializado"` — mais lento, mais previsível, menor custo
296
300
  - `"<maxConcurrentWorkers de config.json>"` — só se existir e for diferente de `N_rec`
297
301
  - O usuário pode responder valor customizado ("Other"), **inclusive acima de 8** — respeite-o.
@@ -303,7 +307,9 @@ driver de custo agregado do coordinator.
303
307
 
304
308
  **Em `--headless`: pule esta seção** — inclua o plano no relatório final (Fase 7) e siga para a Fase 3.
305
309
 
306
- - **No Claude Code:** apresente o plano e conclua com `ExitPlanMode`.
310
+ - **No Claude Code:** se a sessão já estiver em plan mode, apresente o plano e conclua com
311
+ `ExitPlanMode`. Se a sessão **não** estiver em plan mode, aprove via `AskUserQuestion` (ou chame
312
+ `EnterPlanMode` antes).
307
313
  - **No Antigravity/Gemini:** gere/atualize `implementation_plan.md` com `request_feedback: true` e
308
314
  `user_facing: true`, e aguarde `request_feedback: false` ou "Proceed".
309
315
  - Sem nenhum dos dois: exiba o plano no chat e aguarde resposta afirmativa explícita.
@@ -336,6 +342,12 @@ pela branch) ou pelo retorno do `Agent()`.
336
342
  - Dentro da onda corrente: quando um worker ativo atingir `GREEN`, `FAILED_MAX_ITERATIONS` ou for
337
343
  cancelado, despache o próximo `QUEUED` da mesma onda, mantendo os ativos no teto.
338
344
  - O teto é contabilidade do coordinator, não bloqueio de plataforma: respeite-o a cada ciclo.
345
+ - **Checagem de timeout da sessão.** Antes de despachar um novo grupo `QUEUED` ou iniciar uma nova
346
+ onda (`O_{i+1}`), verifique se o timeout global (default 90 minutos, ou `maxSessionMinutes` em
347
+ `.claude/vetor/config.json`) foi atingido considerando apenas tempo ativo de coordenação (excluindo
348
+ esperas por decisão humana via `AskUserQuestion` — issue #343). Ao atingir o teto: não despache novos
349
+ grupos nem novas ondas; permita que workers ativos terminem suas iterações e que grupos `GREEN` já
350
+ autorizados realizem ship normalmente.
339
351
  - **Transição de onda.** Só inicie o dispatch de `O_{i+1}` depois que:
340
352
  1. Todos os grupos de `O_i` **que foram efetivamente despachados** tiverem chegado a `GREEN` e
341
353
  passado pela Fase 6 (merge) — um grupo de `O_i` em `FAILED_MAX_ITERATIONS` ou `BLOCKED_WAITING`
@@ -377,6 +389,8 @@ pulando dispatch duplicado`) e **pule** o dispatch desse grupo.
377
389
  **Antes de invocar `Agent()`, o coordenador DEVE criar o status file** (path da Fase 3) com
378
390
  `Status: RUNNING` — o sandbox de isolamento pode impedir o worker de criar arquivo fora do worktree.
379
391
  Exemplo: `echo -e "# Agent Status - <branch>\nStatus: RUNNING\nIteration: 1/5 (Issue #<M>)" > <path>`.
392
+ Enquanto o harness inicializa o worktree, `vetor-status.sh` classifica o grupo como `aguardando worktree`
393
+ (e não como `cancelled`, issue #347).
380
394
 
381
395
  ```javascript
382
396
  Agent({
@@ -443,6 +457,11 @@ worker precisar de MCP, adicione-o à lista.
443
457
  é controlado pelo harness, não pelo coordinator — não há como forçar a criação diretamente a
444
458
  partir de `origin/$DEFAULT_BRANCH`), então essa instrução no prompt do worker é a rede de
445
459
  segurança que não depende do root ter avançado a tempo.
460
+ 6. **Comandos de teste pré-resolvidos (se module-test-map untracked/ignorado):** Se `git check-ignore -q .claude`
461
+ indicar que `.claude/` está ignorado ou se `! git ls-files --error-unmatch .claude/vetor/module-test-map.md >/dev/null 2>&1`
462
+ indicar que o mapa de testes não está commitado (issue #327), injete explicitamente os comandos de
463
+ teste resolvidos para os módulos da issue no prompt do worker, evitando que ele fique sem referências
464
+ de teste no worktree.
446
465
 
447
466
  Ao concluir todas as issues com sucesso, o worker marca `GREEN`. Se falhar em alguma, para e marca
448
467
  `FAILED_MAX_ITERATIONS` especificando qual issue falhou.
@@ -456,8 +475,10 @@ bash "$SKILL_DIR/../../scripts/vetor-status.sh"
456
475
  ```
457
476
 
458
477
  O script lê `.claude/vetor/status/*.md`, cruza com `git worktree list` (worktree removido
459
- manualmente → `cancelled (worktree removed)`; não recrie) e com `gh pr list --state all`, e imprime
460
- a tabela. Reproduza-a no chat acrescentando os grupos `QUEUED`, e adicione a coluna `Onda` (Fase 1)
478
+ manualmente → `cancelled (worktree removed)`; recém-despachado → `aguardando worktree`, issue #347)
479
+ e com `gh pr list --state all`, e imprime a tabela. O script resolve o root do repositório
480
+ automaticamente, podendo rodar no root ou dentro de qualquer worktree sem falso alarme (issue #339).
481
+ Reproduza-a no chat acrescentando os grupos `QUEUED`, e adicione a coluna `Onda` (Fase 1)
461
482
  a cada linha — o script não conhece o DAG, então essa coluna vem do plano da Fase 2 mantido em
462
483
  memória pelo coordinator. Grupos `QUEUED` de uma onda posterior aparecem como
463
484
  `QUEUED (aguardando O_i)` para deixar explícita a razão de não terem sido despachados mesmo havendo
@@ -537,7 +558,7 @@ bash "$SKILL_DIR/../../scripts/vetor-checks.sh" sync-root
537
558
  `sync-root` só troca de branch se a atual estiver limpa e já mesclada em `origin/<default>`. Se
538
559
  imprimir `AVISO`, **não force**: reporte a pendência no relatório em vez de descartar trabalho.
539
560
 
540
- Após todos os agentes terminarem (ou timeout de 90 minutos):
561
+ Após todos os agentes terminarem (ou atingido o timeout de 90 minutos / `maxSessionMinutes`):
541
562
 
542
563
  ```
543
564
  ## Coordinator Report
@@ -552,6 +573,18 @@ Após todos os agentes terminarem (ou timeout de 90 minutos):
552
573
  Resumo: <N> merged, <M> falharam, <K> aguardando review, <J> aguardando Spec.
553
574
  ```
554
575
 
576
+ **Checkpoint de fechamento de onda (issue #246).** Após montar o Coordinator Report acima, confirme
577
+ que a lista de grupos originalmente planejados na Fase 2 bate 1:1 com os resultados reportados —
578
+ **nenhum grupo do plano aprovado deve ficar sem uma linha de resultado**. Resultados válidos
579
+ dependem do modo:
580
+ - **Interativo**: `Merged`, `CI failed`, `FAILED_MAX_ITERATIONS`, `Review required`, `BLOCKED_WAITING`, `SKIPPED (aguardando
581
+ Spec)`. Se houver discrepância (grupo do plano não aparece acima), reporte-o como "não
582
+ despachado" e pergunte ao usuário via `AskUserQuestion` se deve despachar agora.
583
+ - **`--headless`**: `Merged`, `CI failed`, `FAILED_MAX_ITERATIONS`, `Review required`, `BLOCKED_WAITING`, `SKIPPED
584
+ (aguardando Spec)`, ou `GREEN (pronto para ship)` — este último status aparece para grupos que
585
+ atingiram verde em modo headless (sem merge nessa fase). Se houver discrepância, apenas reporte o
586
+ grupo como "não despachado" no campo de observações; não pergunte nem redespache.
587
+
555
588
  **Em `--headless`, o relatório é a única saída da execução** — acrescente:
556
589
  - O plano de dispatch da Fase 2 (apenas registrado, não aprovado).
557
590
  - Para cada issue `não-trivial` sem Spec associada (gate de Spec/design, Fase 2): sinalizada, nunca
@@ -570,7 +603,13 @@ Resumo: <N> merged, <M> falharam, <K> aguardando review, <J> aguardando Spec.
570
603
  deve registrar `BLOCKED_WAITING` (não decidir sozinho continuar) e escalar ao coordinator via os
571
604
  blocos `Blocked on`/`Options`/`Recommendation` do status file, em vez de estourar para 6+.
572
605
  - **worktree-ship:** máximo 3 tentativas de fix de CI
573
- - **Coordinator:** timeout global de 90 minutos (este sim, hard cap real)
606
+ - **Coordinator:** timeout global de 90 minutos (este sim, hard cap real) — configurável via
607
+ `maxSessionMinutes` em `.claude/vetor/config.json` (default 90). O teto restringe **novos
608
+ dispatches e o início de novas ondas**: ao atingir o timeout, nenhum novo grupo é despachado e
609
+ nenhuma nova onda é iniciada. Porém, grupos ativos podem concluir sua iteração corrente e ships de
610
+ grupos já em `GREEN` (ou já autorizados pelo usuário) podem prosseguir até a conclusão (issue #343).
611
+ Para a contagem do timeout, considere apenas o tempo ativo de coordenação, excluindo períodos de
612
+ espera por decisões humanas (`AskUserQuestion` ou aprovação de plano).
574
613
  - Agentes em `BLOCKED_WAITING` não consomem iterações do fix-loop
575
614
  - `vetor-status.sh` destaca com `⚠️` na tabela qualquer `Iteration: N/5` com `N` acima do orçamento —
576
615
  sinal de que o agente não escalou como deveria; trate como candidato a redispatch/intervenção.
@@ -104,8 +104,9 @@ Se encontrar equivalente, não proponha criar de novo — anote como "já rastre
104
104
 
105
105
  Apresente a lista de issues candidatas (após remover duplicatas) e obtenha aprovação seguindo o
106
106
  mecanismo do ecossistema atual (`../shared/references/planning-conventions.md`
107
- §2.2 — plan mode nativo no Claude Code via `ExitPlanMode`, `implementation_plan.md` com
108
- `request_feedback: true` no Antigravity, ou confirmação no chat).
107
+ §2.2 — plan mode nativo no Claude Code via `ExitPlanMode` se a sessão já estiver em plan mode, ou
108
+ `AskUserQuestion` caso não esteja, `implementation_plan.md` com `request_feedback: true` no
109
+ Antigravity, ou confirmação no chat).
109
110
 
110
111
  **Pare** até a aprovação. O usuário pode aprovar todas, algumas, ou nenhuma.
111
112
 
@@ -6,23 +6,38 @@ pule) a checagem.
6
6
 
7
7
  ## O mecanismo correto
8
8
 
9
- Ferramentas de servidores MCP aparecem no seu namespace de ferramentas com o prefixo
10
- `mcp__<server>__<tool>` (ex.: `mcp__sentry__list_issues`) — diretas na
11
- lista de ferramentas disponíveis, ou listadas por nome entre as ferramentas diferidas (que você
12
- carrega via `ToolSearch` antes de chamar).
9
+ Ferramentas de servidores MCP aparecem no seu namespace de ferramentas como
10
+ `mcp__<segmento-de-servidor>__<tool>` — diretas na lista de ferramentas disponíveis, ou listadas
11
+ por nome entre as ferramentas diferidas (que você carrega via `ToolSearch` antes de chamar). O
12
+ **segmento de servidor** é o trecho entre `mcp__` e o próximo `__`, e tem duas formas:
13
13
 
14
- **Verificar disponibilidade é simplesmente olhar se algum nome com esse prefixo existe** — não é
15
- necessário rodar comando, nem tentar a chamada MCP "para ver se funciona":
14
+ - **standalone** (registrado direto no projeto/usuário): `<server>` — ex.:
15
+ `mcp__sentry__list_issues` (segmento `sentry`);
16
+ - **empacotado num plugin** (ex.: o próprio vetor): `plugin_<plugin>_<server>` — ex.:
17
+ `mcp__plugin_vetor_context7__query-docs` (segmento `plugin_vetor_context7`).
18
+
19
+ **Verificar disponibilidade é simplesmente olhar se existe uma ferramenta cujo segmento de servidor
20
+ casa com o servidor relevante** — não é necessário rodar comando, nem tentar a chamada MCP "para ver
21
+ se funciona":
16
22
 
17
23
  1. Procure na sua lista de ferramentas (diretas + diferidas, listadas em `<system-reminder>` no
18
- início da conversa e sempre que atualizadas) por qualquer nome começando com `mcp__<server>__`,
19
- onde `<server>` é o servidor relevante para a tarefa (sentry/observabilidade,
20
- banco de dados).
24
+ início da conversa e sempre que atualizadas) por qualquer nome `mcp__…` e extraia o segmento de
25
+ servidor. O servidor `<server>` (ex.: `context7`, `sentry`, `docker`, `chrome-devtools`) casa
26
+ quando o segmento **inteiro** é `<server>` ou começa com `plugin_` e termina com `_<server>`
27
+ (`plugin_<plugin>_<server>`), sem distinguir maiúsculas de minúsculas. **Nunca por substring
28
+ solta:** `docker` **não** casa `mcp__MCP_DOCKER__*` (segmento `MCP_DOCKER`, o gateway de MCPs do
29
+ Docker é outro servidor).
21
30
  2. **Se existir:** o MCP está disponível. Se a ferramenta estiver na lista de diferidas, carregue-a
22
31
  primeiro com `ToolSearch({query: "select:<tool_name>"})` antes de chamá-la.
23
- 3. **Se não existir nenhum nome com esse prefixo:** o MCP não está configurado nesta sessão — vá
32
+ 3. **Se não existir nenhum segmento correspondente:** o MCP não está configurado nesta sessão — vá
24
33
  direto para o fallback documentado na skill (CLI `gh`, query SQL manual, etc.). Não gaste uma
25
34
  chamada tentando invocar uma ferramenta MCP inexistente só para descobrir que falha.
35
+ 4. **Quando houver mais de um segmento correspondente para o mesmo serviço**, use esta ordem de
36
+ preferência (única definição — as skills referenciam este item, não a repetem): (1) o do próprio
37
+ plugin, `plugin_vetor_<server>`, pois compartilha o ciclo de vida e a configuração do plugin;
38
+ (2) o standalone, `<server>`; (3) o de outro plugin, `plugin_<outro>_<server>` (o primeiro na
39
+ lista). Ao chamar mais de uma ferramenta do mesmo serviço (ex.: `resolve-library-id` e
40
+ `query-docs`), use sempre o mesmo segmento.
26
41
 
27
42
  ## Por que não "tentar e capturar erro"
28
43
 
@@ -33,21 +48,29 @@ correta é estática (olhar a lista), não uma tentativa em runtime.
33
48
 
34
49
  ## Servidores relevantes neste plugin
35
50
 
36
- | Observabilidade (Sentry/Datadog) | `mcp__sentry__` / `mcp__datadog__` | `backlog-ideator` §2.a (opcional) |
37
- | Banco de dados | `mcp__<db>__` (nome depende do MCP configurado) | `guardian` (auditoria de schema/queries) |
38
- | Docker | `mcp__docker__` | `guardian` (auditoria de saúde de containers) |
39
- | Browser (chrome-devtools) | `mcp__chrome-devtools__` | `fix-loop-agent` (reproduzir bug de UI antes do fix), `worktree-ship` (checagem e2e leve antes do PR) |
40
- | Pesquisa web (Exa) | `mcp__exa__` | `backlog-ideator` (pesquisar padrões/arquitetura antes de propor issue), `fix-loop-agent` (pesquisar mensagem de erro/documentação de uma lib externa), `issue-worker` (checar docs de API externa durante a implementação) |
41
- | Documentação de ferramentas/libs (Context7) | `mcp__context7__` | **Obrigatório quando disponível** (ver issue vetor#163) — qualquer skill que precise pesquisar comportamento de uma ferramenta/lib/framework/API externa (`issue-worker`, `fix-loop-agent`, `guardian`, `backlog-ideator`) |
42
- | Documentação do próprio Claude Code (`claude-code-docs`) | `mcp__claude-code-docs__` | **Obrigatório quando disponível** (ver issue vetor#164) — qualquer skill que precise responder sobre o funcionamento do próprio Claude Code (hooks, slash commands, MCP, permissões, SDK) (`vetor` (setup), `retro`) |
51
+ Cada servidor abaixo casa pelas duas formas de segmento (ver "O mecanismo correto"): standalone
52
+ `mcp__<server>__` ou empacotado `mcp__plugin_<plugin>_<server>__`. O plugin vetor empacota
53
+ `context7`, `chrome-devtools` e `docker` (`.mcp.json`) — numa sessão com o vetor, o nome real
54
+ desses três é `mcp__plugin_vetor_<server>__`.
55
+
56
+ | Observabilidade (Sentry/Datadog) | `mcp__sentry__` / `mcp__datadog__` (ou `mcp__plugin_<plugin>_sentry__` / `mcp__plugin_<plugin>_datadog__`) | `backlog-ideator` §2.a (opcional) |
57
+ | Banco de dados | `mcp__<db>__` (ou `mcp__plugin_<plugin>_<db>__`; o nome `<db>` depende do MCP configurado) | `guardian` (auditoria de schema/queries) |
58
+ | Docker | `mcp__docker__` (ou `mcp__plugin_<plugin>_docker__`; **não** `mcp__MCP_DOCKER__`) | `guardian` (auditoria de saúde de containers) |
59
+ | Browser (chrome-devtools) | `mcp__chrome-devtools__` (ou `mcp__plugin_<plugin>_chrome-devtools__`) | `fix-loop-agent` (reproduzir bug de UI antes do fix), `worktree-ship` (checagem e2e leve antes do PR) |
60
+ | Pesquisa web (Exa) | `mcp__exa__` (ou `mcp__plugin_<plugin>_exa__`) | `backlog-ideator` (pesquisar padrões/arquitetura antes de propor issue), `fix-loop-agent` (pesquisar mensagem de erro/documentação de uma lib externa), `issue-worker` (checar docs de API externa durante a implementação) |
61
+ | Documentação de ferramentas/libs (Context7) | `mcp__context7__` (ou `mcp__plugin_<plugin>_context7__`) | **Obrigatório quando disponível** (ver issue vetor#163) — qualquer skill que precise pesquisar comportamento de uma ferramenta/lib/framework/API externa (`issue-worker`, `fix-loop-agent`, `guardian`, `backlog-ideator`) |
62
+ | Documentação do próprio Claude Code (`claude-code-docs`) | `mcp__claude-code-docs__` (ou `mcp__plugin_<plugin>_claude-code-docs__`) | **Obrigatório quando disponível** (ver issue vetor#164) — qualquer skill que precise responder sobre o funcionamento do próprio Claude Code (hooks, slash commands, MCP, permissões, SDK) (`vetor` (setup), `retro`) |
43
63
 
44
64
  ### Documentação de ferramentas/libs (Context7)
45
65
 
46
66
  Use antes de afirmar comportamento de uma ferramenta, biblioteca, framework, SDK ou API externa —
47
67
  não confie só no conhecimento pré-treinado do agente, que pode estar desatualizado.
48
68
 
49
- - **Com MCP (obrigatório):** `mcp__context7__resolve-library-id` para achar o library ID, depois
50
- `mcp__context7__query-docs` com uma pergunta específica e escopada a um único conceito.
69
+ - **Com MCP (obrigatório):** localize o servidor `context7` pela regra de segmento acima (ex.:
70
+ `mcp__context7__resolve-library-id` ou `mcp__plugin_vetor_context7__resolve-library-id`; com mais
71
+ de um, siga a ordem do item 4). Use `resolve-library-id` do segmento escolhido para achar o library
72
+ ID, depois `query-docs` do mesmo segmento com uma pergunta específica e escopada a um único
73
+ conceito.
51
74
  - **Sem MCP (fallback):** siga sem o MCP, sinalizando a limitação no resultado entregue ao usuário —
52
75
  não bloqueia a skill.
53
76
 
@@ -54,20 +54,21 @@ Exemplo para Coordinator:
54
54
 
55
55
  #### Para skills de implementação de código (`fix-loop-agent`, `issue-worker`, e similares)
56
56
 
57
- * **No Claude Code**: use o plan mode nativo — apresente o plano acima e conclua com `ExitPlanMode`
58
- para pedir aprovação do usuário. Este é o caminho de primeira classe no Claude Code para código,
59
- não um fallback.
57
+ * **No Claude Code**: use o plan mode nativo se a sessão já estiver em plan mode — apresente o plano
58
+ acima e conclua com `ExitPlanMode` para pedir aprovação do usuário. Se a sessão **não** estiver em
59
+ plan mode, aprove via `AskUserQuestion` (ou chame `EnterPlanMode` antes).
60
60
  * **No Antigravity/Gemini**: salve o plano no artefato `implementation_plan.md` definindo
61
61
  `request_feedback: true` nos metadados. O agente interromperá a chamada até o clique em "Proceed".
62
62
 
63
- #### Para skills de orquestração/ideação (`backlog-ideator`, `issue-coordinator`, `guardian`)
63
+ #### Para skills de orquestração/ideação (`backlog-ideator`, `issue-coordinator`, `guardian`, `retro`)
64
64
 
65
65
  Estas skills realizam mutações estruturais (criar issues, orquestrar subagentes) mas **não implementam
66
66
  código de produto**. Para elas:
67
67
 
68
- * **No Claude Code**: exiba o plano no chat e aguarde uma resposta textual afirmativa do usuário
69
- (ex.: "sim", "prosseguir"). **Não use `ExitPlanMode`** — a ferramenta a desaconselha explicitamente
70
- para tarefas fora do escopo de escrita de código.
68
+ * **No Claude Code**: se a sessão já estiver em plan mode, conclua com `ExitPlanMode`. Se a sessão
69
+ **não** estiver em plan mode, aprove via `AskUserQuestion` (ou exiba o plano no chat e aguarde uma
70
+ resposta textual afirmativa do usuário, ex.: "sim", "prosseguir") — nunca chame `ExitPlanMode`
71
+ fora de plan mode (issue #326).
71
72
  * **No Antigravity/Gemini**: salve o plano no artefato `implementation_plan.md` definindo
72
73
  `request_feedback: true` nos metadados. O agente interromperá a chamada até o clique em "Proceed".
73
74
 
@@ -61,16 +61,36 @@ frameworks web, ORMs, a lib de UI principal — nunca toda dependência declarad
61
61
  transitivas. Uma rule por utilitário/dependência transitiva infla o contexto sem ganho; o escopo
62
62
  é deliberadamente restrito ao mesmo allowlist do detector.
63
63
 
64
+ **Pacotes irmãos (regra única, vale para todos os passos).** Pacotes que compartilham a mesma
65
+ documentação formam um **grupo** e, daqui em diante, contam como **uma** lib: uma resolução e uma
66
+ query (feitas com o nome do líder), um único arquivo `<líder>.md`. Grupos reconhecidos — lista
67
+ fechada, no formato `membro → líder`; qualquer outro pacote é independente: `react-dom → react`.
68
+
69
+ - O grupo entra na lista se qualquer membro foi detectado. O arquivo é sempre `<líder>.md`, mesmo
70
+ que só um membro esteja no projeto. A versão instalada do grupo é a do líder; se o líder não foi
71
+ detectado, a do primeiro membro detectado.
72
+ - No cabeçalho e no título do passo 4, `<lib>@<versão-instalada>` vira a lista dos membros
73
+ detectados, cada um com a sua versão instalada (ex.: `react@19.2.8, react-dom@19.2.8`).
74
+ - Falha ou "sem fonte oficial" no passo 3 pula o grupo inteiro — nunca só um membro.
75
+
64
76
  Sem `--refresh`, filtre a lista às libs que ainda **não** têm arquivo em
65
- `.claude/rules/vetor/best-practices/<lib>.md`. Com `--refresh`, mantenha a lista inteira.
77
+ `.claude/rules/vetor/best-practices/<lib>.md` (`<lib>` = o líder, no caso de um grupo — assim um
78
+ irmão já coberto não reaparece como candidato). Com `--refresh`, mantenha a lista inteira.
66
79
 
67
80
  Se a lista resultante estiver vazia (nenhuma lib estrutural detectada, ou todas já têm regra e não
68
81
  foi passado `--refresh`), reporte e pare — nada a fazer.
69
82
 
70
83
  ### 2 — Checar disponibilidade do Context7
71
84
 
72
- Siga o mecanismo de `mcp-availability.md`: procure por qualquer ferramenta com prefixo
73
- `mcp__context7__` (direta ou diferida via `ToolSearch`).
85
+ Siga o mecanismo de `mcp-availability.md`: procure as ferramentas `resolve-library-id` e
86
+ `query-docs` cujo **segmento de servidor** case com `context7` — `mcp__context7__…` (standalone) ou
87
+ `mcp__plugin_<plugin>_context7__…` (empacotado), nunca por substring solta. Com mais de um segmento
88
+ correspondente, escolha pela ordem de preferência do item 4 daquele documento.
89
+
90
+ Guarde o prefixo completo escolhido (ex.: `mcp__context7__` ou `mcp__plugin_vetor_context7__`) como
91
+ `<ctx7>`. O passo 3 usa **somente** `<ctx7>resolve-library-id` e `<ctx7>query-docs` — nunca um
92
+ prefixo fixo. Se as ferramentas estiverem diferidas, carregue-as antes com `ToolSearch`
93
+ (`select:<ctx7>resolve-library-id,<ctx7>query-docs`).
74
94
 
75
95
  **Se não disponível:** não gere nenhuma regra para as libs afetadas. Reporte a limitação no
76
96
  resultado final ("Context7 indisponível — nenhuma regra de melhores práticas gerada para: <libs>")
@@ -82,19 +102,44 @@ existe para evitar.
82
102
 
83
103
  Para cada lib da lista do passo 1:
84
104
 
85
- 1. `mcp__context7__resolve-library-id` para achar o library ID a partir do nome (e, se disponível
86
- na resposta, restrinja pela versão detectada no passo 1).
87
- 2. `mcp__context7__query-docs` com uma pergunta específica e escopada, no estilo "práticas atuais
88
- recomendadas e APIs deprecated para `<lib>` versão `<versão>`" — nunca uma pergunta genérica que
89
- force o Context7 a devolver um resumo raso.
90
-
91
- Se a resolução ou a query falharem para uma lib específica (lib não indexada, erro transiente),
105
+ 1. **Resolver o library ID versionado.** Chame `<ctx7>resolve-library-id` com o nome da lib.
106
+ Percorra os resultados na ordem devolvida e fique com o primeiro que (a) não seja `/websites/*`
107
+ (site indexado — nunca produz `Source` em tag, ver item 3) e (b) liste em `Versions` ao menos uma
108
+ *versão de release*. Não são release: entradas `__branch__*` e pré-releases (`-canary`, `-rc`,
109
+ `-beta`, `-alpha`, `-next`). Escolha a versão nesta ordem: a igual à instalada (`v<V>` ou
110
+ `<V>`); senão a maior versão de release menor que a instalada e da mesma major (ex.: instalada
111
+ 16.3.6, indexada até `v16.2.9` → `v16.2.9`); se a instalada for `unknown`, a maior de release
112
+ listada. O ID consultado é `/<org>/<projeto>/<versão-docs>` e `<versão-docs>` é esse sufixo.
113
+ Sem resultado que atenda (a) e (b), ou sem versão escolhível: pule a lib e registre "sem fonte
114
+ oficial na versão <V-instalada>" no passo 6 — não consulte o ID sem versão.
115
+ 2. **Consultar.** `<ctx7>query-docs` com o ID versionado e uma pergunta específica e escopada, no
116
+ estilo "práticas atuais recomendadas e APIs deprecated para `<lib>` versão `<versão-docs>`" —
117
+ nunca uma pergunta genérica que force o Context7 a devolver um resumo raso.
118
+ 3. **Filtro de Source.** Cada snippet devolvido traz uma linha `Source: <URL>`. Aceite o snippet só
119
+ se a URL for `https://github.com/<org>/<projeto>/blob/<versão-docs>/<caminho>` (ou
120
+ `/tree/<versão-docs>/…`), com `<org>/<projeto>` e `<versão-docs>` idênticos aos do ID consultado.
121
+ Isso define os dois critérios:
122
+ - **Oficial** = arquivo do repositório do mantenedor (o `<org>/<projeto>` do library ID — a
123
+ skill confia na atribuição do Context7, não verifica a origem do repositório por conta
124
+ própria). Não contam: agregadores (`/websites/*`, deepwiki), blogs, gists, fóruns, repositórios de outra org
125
+ nem snippet sem `Source`. Um site de documentação do mantenedor (ex.: `nextjs.org/docs/…`)
126
+ também não passa, ainda que seja do mantenedor: a URL não fixa versão.
127
+ - **Na tag da versão consultada** = o ref após `blob/`/`tree/` é exatamente `<versão-docs>`. Não
128
+ contam `blob/main/`, `blob/canary/`, qualquer outro branch, outra versão nem SHA.
129
+
130
+ Descarte os demais snippets por inteiro, incluindo texto editorial anexado a eles. Se nenhum
131
+ snippet sobrar: **não grave regra** para a lib e registre "sem fonte oficial na versão
132
+ <versão-docs>" no passo 6. Nunca preencha com snippets descartados nem com conhecimento
133
+ pré-treinado. Sem arquivo gravado, a lib volta como candidata na próxima execução (filtro do
134
+ passo 1) — comportamento esperado, igual ao de uma falha de resolução.
135
+
136
+ Se a resolução ou a query falharem por outro motivo (lib não indexada, erro transiente),
92
137
  **pule só aquela lib** — reporte a falha no resultado e continue com as demais. Uma lib com erro
93
138
  nunca bloqueia a geração das regras das outras.
94
139
 
95
140
  ### 4 — Gravar a regra
96
141
 
97
- Para cada lib com resposta do Context7, escreva `.claude/rules/vetor/best-practices/<lib>.md`:
142
+ Para cada lib com ao menos um snippet aceito pelo filtro de Source (passo 3, item 3), escreva `.claude/rules/vetor/best-practices/<lib>.md`:
98
143
 
99
144
  ```markdown
100
145
  ---
@@ -102,11 +147,11 @@ paths:
102
147
  - "<globs relevantes à lib, ex. '**/*.tsx' para uma lib de UI React>"
103
148
  ---
104
149
 
105
- > Gerado por `/vetor:stack-practices` a partir da documentação de <lib>@<versão> via Context7 em <data ISO>.
150
+ > Gerado por `/vetor:stack-practices` a partir da documentação de <lib>@<versão-instalada> (docs consultadas: <versão-docs>) via Context7 em <data ISO>.
106
151
  > Conhecimento externo, não um fato observado neste repositório — pode ficar desatualizado.
107
152
  > Rode `/vetor:stack-practices --refresh` periodicamente. Editável — não sobrescrito sem `--refresh`.
108
153
 
109
- # Melhores práticas — <lib>@<versão>
154
+ # Melhores práticas — <lib>@<versão-instalada> (docs: <versão-docs>)
110
155
 
111
156
  - <bullet curto e citável, só o que o Context7 retornou como prática atual documentada>
112
157
  - <...>
@@ -117,10 +162,14 @@ Regras:
117
162
  rules factuais de `scripts/lib/rules.ts` — nunca escreva regra de melhor prática no mesmo arquivo
118
163
  `.claude/rules/vetor/<runtime>.md` gerado pelo `/vetor`, cuja regra de ouro é "só fato observado
119
164
  localmente". `.claude/rules/vetor/best-practices/` é um diretório à parte.
165
+ - **O cabeçalho registra a versão instalada e a versão de docs consultada**; se divergirem, o
166
+ passo 6 reporta a divergência.
120
167
  - `<data ISO>` é a data da consulta, não uma data fixa — usada depois pelo guardian para medir
121
168
  staleness (passo 5).
122
169
  - Bullets refletem só o que a fonte (Context7) disse — nunca elaboração ou inferência do agente
123
170
  além do que a resposta retornou.
171
+ - **Source oficial na tag da versão consultada** (regra adicional — não substitui a anterior): só
172
+ entram bullets de snippets aceitos pelo filtro de Source do passo 3 (item 3).
124
173
  - Sem `--refresh`, nunca sobrescreva um arquivo já existente para a mesma lib.
125
174
 
126
175
  ### 5 — Sinalizar staleness no guardian (referência cruzada)
@@ -134,9 +183,13 @@ extra aqui, além de manter a data no cabeçalho (passo 4) precisa e atualizada
134
183
 
135
184
  Ao final, resuma:
136
185
  - Libs detectadas no passo 1 e quais já tinham regra (puladas, sem `--refresh`).
137
- - Libs com regra gerada/atualizada nesta execução, com a versão consultada.
186
+ - Libs com regra gerada/atualizada nesta execução, com a versão instalada e a versão de docs consultada.
187
+ - **Divergências de versão** (versão instalada ≠ versão de docs indexada) — sinalize explicitamente.
138
188
  - Libs puladas por falha de resolução/query no Context7 (passo 3).
189
+ - Libs sem regra por "sem fonte oficial na versão X" (passo 3: sem ID versionado utilizável ou
190
+ nenhum snippet aceito pelo filtro de Source), com a versão X.
139
191
  - Se o Context7 não estava disponível: a lista completa de libs sem regra por esse motivo (passo 2).
192
+ - **Lembrete de commit:** Recomende ao usuário commitar os arquivos gerados em `.claude/rules/vetor/best-practices/` (ou ofereça o commit). Workers rodam em worktrees isolados que só herdam arquivos rastreados no git — regras untracked não ficam disponíveis para eles (issue #327).
140
193
 
141
194
  ---
142
195
 
@@ -156,7 +156,7 @@ Arquivos configurados:
156
156
 
157
157
  Próximos passos recomendados:
158
158
  1. Abra e revise o arquivo `.claude/vetor/module-test-map.md` para garantir que os comandos de teste headless e os mapeamentos de pasta de seu projeto estejam 100% corretos.
159
- 2. Revise e **commite** `.claude/rules/vetor/`. Os issue-workers rodam em worktrees, que só contêm arquivos rastreados pelo git — uma rule não commitada não chega até eles.
159
+ 2. Revise e **commite** os arquivos de configuração e regras (`.claude/vetor/config.json`, `.claude/vetor/module-test-map.md` e `.claude/rules/vetor/`). Os issue-workers rodam em worktrees, que só contêm arquivos rastreados pelo git — arquivos untracked não chegam até eles e deixam os workers sem mapa de testes nem regras (issue #327). Avise ou ofereça o commit caso ainda estejam untracked no git.
160
160
  3. (Opcional) Crie a pasta `.claude/vetor/docs/` e adicione guias de arquitetura, padrões do projeto e gaps em markdown. O comando `/vetor:backlog` lerá automaticamente estes arquivos para propor issues altamente contextualizadas.
161
161
  4. (Opcional) Rode `/vetor:stack-practices` para gerar regras de melhores práticas da stack detectada (via Context7).
162
162
  ```
@@ -168,11 +168,11 @@ Closes #<issue#>
168
168
  🤖 Desenvolvido com [Claude Code](https://claude.ai/code)
169
169
  ```
170
170
 
171
- Anexe `Closes #<issue#>` (se fornecida) e a nota do rodapé ao final. Crie o PR draft:
171
+ Anexe `Closes #<issue#>` (ou uma linha `Closes #N` por issue do grupo; use `Refs #N` se a issue não deve ser fechada automaticamente, issue #338). Grave o corpo num arquivo temporário e passe via `--body-file`, evitando corrupção de backticks e caracteres especiais pelo shell (issue #334):
172
172
  ```bash
173
173
  gh pr create \
174
174
  --title "<type>(<slug>): <resumo dos commits>" \
175
- --body "<descrição gerada e validada>" \
175
+ --body-file "<path-do-arquivo-de-corpo>" \
176
176
  --draft \
177
177
  --base "$DEFAULT_BRANCH"
178
178
  ```
@@ -218,14 +218,25 @@ gh pr checks <PR-number>
218
218
 
219
219
  Para cada falha detectada:
220
220
 
221
- **8.a — Circuit breaker de infraestrutura (antes de ler logs)**
221
+ Verifique se a falha possui `run-id` do GitHub Actions (`gh pr checks <PR-number> --json name,link,state`).
222
+
223
+ **8.a — Falha em check externo sem run-id (Vercel, Netlify etc. — issue #340)**
224
+
225
+ Para provedores de deploy e checks externos sem execução do GitHub Actions:
226
+ 1. Identifique o check externo: extraia link e descrição de erro no `gh pr checks`.
227
+ 2. Se a CLI do provedor (ex.: `npx vercel inspect <id> --logs`) estiver instalada e autenticada, consulte os logs; caso contrário, solicite o trecho de erro ao operador via `AskUserQuestion`.
228
+ 3. Dica: se o build passa localmente mas falha no provedor externo, teste remover temporariamente o `.env.local` para reproduzir ausência de variáveis de ambiente.
229
+ 4. Para retentar o check externo após ajuste, faça um commit vazio e envie:
230
+ `git commit --allow-empty -m "ci: retry external check" && git push origin <branch>`, e volte ao passo 7.
231
+
232
+ **8.b — Circuit breaker de infraestrutura (GitHub Actions com run-id)**
222
233
 
223
234
  ```bash
224
235
  deno run -A scripts/detect-infra-failure.ts <run-id>
225
236
  ```
226
237
 
227
238
  Se retornar exit 0 (JSON com `isInfrastructureFailure: true`), nenhum fix de código resolve:
228
- - **Pule** inteiramente as iterações de fix (§8.b).
239
+ - **Pule** inteiramente as iterações de fix (§8.c).
229
240
  - Escreva o status file:
230
241
  ```markdown
231
242
  Status: BLOCKED_INFRA
@@ -235,7 +246,7 @@ Se retornar exit 0 (JSON com `isInfrastructureFailure: true`), nenhum fix de có
235
246
  - **Escale** via `AskUserQuestion`: `⚠️ Falha de infraestrutura detectada no CI (billing/outage). Não é possível resolver com fix de código. Deseja aguardar a resolução ou prosseguir sem CI (merge manual)?`
236
247
  - **Pare.** Não consuma iterações de fix-loop.
237
248
 
238
- **8.b — Erro de código (só se não for infraestrutura)**
249
+ **8.c — Erro de código (só se não for infraestrutura)**
239
250
 
240
251
  ```bash
241
252
  gh run view <run-id> --log-failed
@@ -333,9 +344,11 @@ Aguardando aprovação antes de prosseguir com merge.
333
344
  bash "$SKILL_DIR/../../scripts/vetor-merge.sh" <PR-number>
334
345
  ```
335
346
 
336
- O script faz `gh pr ready` + `gh pr merge --squash --delete-branch` e verifica o estado real do PR
337
- quando o `gh` sai não-zero (erro de cleanup local da branch não é falha de merge):
338
- - **exit 0** — PR mergeado. Siga para o passo 11.
347
+ O script faz `gh pr ready` + `gh pr merge --squash --delete-branch`, passando `--subject` e
348
+ `--body` do PR (garantindo que o corpo do PR seja a única fonte autoritativa de fechamento de issues
349
+ no squash, issue #338). Verifica o estado real do PR quando o `gh` sai não-zero e, em caso de merge no
350
+ remoto com falha apenas no cleanup local, apaga a branch remota explicitamente (issue #325):
351
+ - **exit 0** — PR mergeado e branch remota verificada/removida. Siga para o passo 11.
339
352
  - **exit 3** — merge não aconteceu. Rode `git merge "$DEFAULT_BRANCH"` localmente no worktree e siga
340
353
  `../shared/references/conflict-resolution.md`. Resolvido e verde, volte ao
341
354
  passo 7.
@@ -361,9 +374,8 @@ localização é do harness). Se invocado pelo `issue-coordinator` (modo headles
361
374
  automaticamente:
362
375
  ```bash
363
376
  bash "$SKILL_DIR/../../scripts/vetor-checks.sh" safe-remove-worktree "<path-do-worktree>"
364
- git branch -d <branch>
365
- rm -f .claude/vetor/status/<branch>.md
366
- rm -f .claude/vetor/status/<branch>-touched-files.json
377
+ bash "$SKILL_DIR/../../scripts/vetor-checks.sh" delete-merged-branch "<branch>"
378
+ bash "$SKILL_DIR/../../scripts/vetor-checks.sh" clean-status "<branch>"
367
379
  ```
368
380
 
369
381
  Se a checagem falhar, **pare o cleanup** e não prossiga com `git branch -d`/remoção dos arquivos de
@@ -371,13 +383,19 @@ status/cache — há dois motivos distintos de falha:
371
383
 
372
384
  - **Worktree filho ativo dentro do path alvo**: mostre os paths e preserve worktree pai, branch e
373
385
  arquivos de status/cache até os filhos serem realocados.
374
- - **Diretório residual em disco após `git worktree remove`** (issue #157): o `git worktree remove`
386
+ - **Diretório residual em disco após `git worktree remove`** (issues #157, #324): o `git worktree remove`
375
387
  desregistrou o worktree do git (não aparece mais em `git worktree list`) mas falhou ao apagar o
376
- diretório — no Windows, tipicamente por `Filename too long` (artefatos como `build/`, `.gradle/`,
377
- `node_modules/` estouram o limite de 260 caracteres). `safe-remove-worktree` já tenta uma remoção
378
- com prefixo de path longo nesse caso; se mesmo assim restar, ela sai não-zero citando o path
379
- residual. Reporte o path ao operador para remoção manual — não tente forçar via `rm -rf` por conta
380
- própria, o diretório pode conter uncommitted work relevante para inspeção.
388
+ diretório — no Windows, por `Filename too long` ou `Permission denied` transitório. `safe-remove-worktree`
389
+ reconsulta o git: como o worktree já foi desregistrado, tenta a remoção segura do resíduo (inclusive
390
+ com prefixo de path longo `\\?\`); se mesmo assim restar, ela sai não-zero citando o path residual
391
+ para remoção manual, sem alegar falsamente uncommitted work (issue #324).
392
+
393
+ - **Remoção segura de branch e status**:
394
+ - `delete-merged-branch <branch>` apaga a branch local apenas se confirmada como `MERGED` no GitHub
395
+ ou se sua árvore for idêntica à branch default, contornando a recusa de `git branch -d` para squash
396
+ e sem acionar o bloqueio incondicional de `-D` (issue #341).
397
+ - `clean-status <branch>` normaliza o nome da branch (`/` substituída por `-`) e apaga o status `.md`,
398
+ a sentinela `.md.stopguard` e o cache `-touched-files.json` (issue #344).
381
399
 
382
400
  Se invocado manualmente pelo usuário: pergunte antes de remover (a confirmação cobre worktree,
383
401
  branch, status file e cache de arquivos tocados).