@fontdata/ai-harness 2.0.0 → 2.2.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +9 -2
- package/LICENSE +21 -0
- package/README.md +175 -140
- package/{src → dist}/catalog.js +5 -12
- package/dist/cli.js +180 -0
- package/dist/comentarios/command.js +74 -0
- package/dist/comentarios/instalar.js +33 -0
- package/dist/config/config.js +99 -0
- package/dist/contratos/artefatos.js +284 -0
- package/dist/contratos/eventos.js +103 -0
- package/dist/doctor/checks.js +424 -0
- package/dist/init.js +240 -0
- package/dist/install/atomic.js +51 -0
- package/dist/install/flags.js +99 -0
- package/dist/install/hooks.js +47 -0
- package/dist/install/lock.js +39 -0
- package/dist/install/plan.js +209 -0
- package/dist/install/selection.js +77 -0
- package/dist/install/settings.js +112 -0
- package/dist/memoria/indice.js +195 -0
- package/dist/migrar/migrar.js +426 -0
- package/dist/rastro/command.js +46 -0
- package/dist/run.js +86 -0
- package/dist/trabalhos/conflitos.js +115 -0
- package/dist/types.js +1 -0
- package/dist/update/legado.js +74 -0
- package/dist/update/update.js +284 -0
- package/package.json +17 -8
- package/templates/CLAUDE.md +59 -30
- package/templates/agents/auditor-plano.md +44 -0
- package/templates/agents/investigador.md +32 -0
- package/templates/agents/qa.md +44 -0
- package/templates/agents/revisor-testes.md +40 -0
- package/templates/catalog.json +24 -61
- package/templates/commands/atualizar-deps.md +43 -9
- package/templates/commands/diagrama.md +35 -10
- package/templates/commands/gerar-env.md +39 -10
- package/templates/commands/gerar-testes.md +42 -10
- package/templates/commands/git-commit-push.md +0 -0
- package/templates/commands/onboarding.md +44 -15
- package/templates/commands/refatorar.md +50 -10
- package/templates/commands/revisar-pr.md +56 -12
- package/templates/commands/sincronizar-claude-md.md +177 -9
- package/templates/commands/versao.md +0 -0
- package/templates/hooks/comentarios/check.mjs +210 -0
- package/templates/hooks/hooks.json +34 -0
- package/templates/hooks/lembrete.mjs +29 -0
- package/templates/hooks/lib/config.mjs +40 -0
- package/templates/hooks/lib/hook.mjs +85 -0
- package/templates/hooks/lib/rastro.mjs +144 -0
- package/templates/hooks/lib/segredos.mjs +91 -0
- package/templates/hooks/lib/temas.mjs +111 -0
- package/templates/hooks/lib/trabalho.mjs +94 -0
- package/templates/hooks/proteger-contratos.mjs +80 -0
- package/templates/hooks/segredo-no-commit.mjs +76 -0
- package/templates/hooks/sem-jargao.mjs +58 -0
- package/templates/hooks/task-so-fecha-verde.mjs +33 -0
- package/templates/legado/manifesto.json +1267 -0
- package/templates/rules/comentarios.md +166 -0
- package/templates/rules/harness-projeto.md +41 -0
- package/templates/skills/auditar-performance/SKILL.md +53 -0
- package/templates/skills/auditar-performance/references/pontos-quentes.md +35 -0
- package/templates/skills/auditar-performance/templates/relatorios/CLIENTE.md +26 -0
- package/templates/skills/auditar-performance/templates/relatorios/TECNICO.md +27 -0
- package/templates/skills/auditar-seguranca/SKILL.md +67 -0
- package/templates/skills/auditar-seguranca/references/seguranca-tecnica.md +23 -0
- package/templates/skills/auditar-seguranca/templates/relatorios/CLIENTE.md +30 -0
- package/templates/skills/auditar-seguranca/templates/relatorios/TECNICO.md +38 -0
- package/templates/skills/auditar-ui/SKILL.md +64 -0
- package/templates/skills/auditar-ui/references/lentes.md +33 -0
- package/templates/skills/auditar-ui/templates/relatorios/CLIENTE.md +26 -0
- package/templates/skills/auditar-ui/templates/relatorios/TECNICO.md +31 -0
- package/templates/skills/evoluir-harness/SKILL.md +81 -0
- package/templates/skills/evoluir-harness/references/agent.md +83 -0
- package/templates/skills/evoluir-harness/references/auditoria.md +107 -0
- package/templates/skills/evoluir-harness/references/code-reviewer.md +68 -0
- package/templates/skills/evoluir-harness/references/design-system.md +56 -0
- package/templates/skills/evoluir-harness/references/hook.md +95 -0
- package/templates/skills/evoluir-harness/references/rule.md +67 -0
- package/templates/skills/evoluir-harness/references/skill.md +63 -0
- package/templates/skills/executar-plan/SKILL.md +130 -0
- package/templates/skills/executar-plan/references/delegacao.md +43 -0
- package/templates/skills/executar-plan/references/retomada.md +33 -0
- package/templates/skills/executar-plan/templates/BLOQUEIOS.md +30 -0
- package/templates/skills/harness/SKILL.md +75 -0
- package/templates/skills/harness/references/auto-tag.md +118 -0
- package/templates/skills/harness/references/ignores.md +40 -0
- package/templates/skills/harness/references/scaffold.md +29 -0
- package/templates/skills/harness/references/validar-ideia.md +42 -0
- package/templates/skills/memoria/SKILL.md +52 -0
- package/templates/skills/nova-tarefa/SKILL.md +99 -0
- package/templates/skills/nova-tarefa/references/isso-ja-existe.md +24 -0
- package/templates/skills/nova-tarefa/references/regras-do-plano.md +35 -0
- package/templates/skills/nova-tarefa/templates/DECISOES.md +20 -0
- package/templates/skills/nova-tarefa/templates/PLAN.md +58 -0
- package/templates/skills/nova-tarefa/templates/SPEC.md +37 -0
- package/templates/skills/resolver-bug/SKILL.md +104 -0
- package/templates/skills/resolver-bug/references/relatorio-para-cliente.md +26 -0
- package/templates/skills/resolver-bug/templates/PLAN.md +62 -0
- package/templates/skills/resolver-bug/templates/relatorios/CLIENTE.md +29 -0
- package/templates/skills/resolver-bug/templates/relatorios/TECNICO.md +32 -0
- package/bin/cli.js +0 -122
- package/src/init.js +0 -317
- package/src/installer.js +0 -92
- package/src/run.js +0 -99
- package/templates/commands/auditar-performance.md +0 -27
- package/templates/commands/auditar-seguranca.md +0 -64
- package/templates/commands/auditar-ui.md +0 -38
- package/templates/commands/codigo-morto.md +0 -22
- package/templates/commands/configurar-auto-tag.md +0 -185
- package/templates/commands/configurar-comentarios.md +0 -543
- package/templates/commands/configurar-orquestrador.md +0 -13
- package/templates/commands/corrigir-review.md +0 -11
- package/templates/commands/criar-agents.md +0 -42
- package/templates/commands/criar-code-reviewer.md +0 -30
- package/templates/commands/criar-hooks.md +0 -32
- package/templates/commands/criar-rag.md +0 -25
- package/templates/commands/criar-rules.md +0 -31
- package/templates/commands/criar-skill.md +0 -22
- package/templates/commands/design-system.md +0 -27
- package/templates/commands/executar-plan.md +0 -36
- package/templates/commands/gerar-claude-md.md +0 -66
- package/templates/commands/gerar-ignore.md +0 -37
- package/templates/commands/gerar-spec.md +0 -33
- package/templates/commands/harness.md +0 -34
- package/templates/commands/nova-tarefa.md +0 -60
- package/templates/commands/resolver-bug.md +0 -25
- package/templates/commands/review-por-task.md +0 -16
- package/templates/commands/scaffold.md +0 -25
- package/templates/commands/validar-commands.md +0 -24
- package/templates/commands/validar-ideia.md +0 -36
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nova-tarefa
|
|
3
|
+
description: Planeja uma nova funcionalidade antes de implementar — gera a spec e o plano de implementação (start inicial ou nova tarefa) e, se confirmado, dispara o orquestrador.
|
|
4
|
+
argument-hint: "[descrição da funcionalidade ou 'start']"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Nova tarefa — planejar antes de implementar
|
|
8
|
+
|
|
9
|
+
Tarefa / recorte: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
Você transforma um pedido em um **trabalho** com `SPEC.md` e `PLAN.md` prontos para execução com sub-agents.
|
|
12
|
+
Serve para o **start inicial** do projeto e para **cada nova tarefa**. Todo o esforço vai para o planejamento:
|
|
13
|
+
uma pergunta durante a execução é falha do plano.
|
|
14
|
+
|
|
15
|
+
> **🚦 Há GATEs de aprovação.** Nada é implementado nesta skill.
|
|
16
|
+
|
|
17
|
+
## Passo 0 — Contexto (somente leitura)
|
|
18
|
+
|
|
19
|
+
1. Leia o `SPEC.md` e o `CLAUDE.md` da raiz e, se existir, a rule de projeto `.claude/rules/harness-projeto.md`: o
|
|
20
|
+
mapa de agents por domínio e os portões extras entram no plano.
|
|
21
|
+
2. Liste os trabalhos existentes em `docs/trabalhos/` (título, tipo e status no frontmatter) para não duplicar
|
|
22
|
+
nem contradizer um trabalho em andamento.
|
|
23
|
+
3. **Start inicial** (não há trabalho do tipo `feature` ainda, ou o pedido é "start"/"primeira fatia"): derive o
|
|
24
|
+
recorte direto do `SPEC.md` — a primeira fatia vertical. **Nova tarefa:** siga para o Passo 1.
|
|
25
|
+
|
|
26
|
+
## Passo 1 — Isso já existe?
|
|
27
|
+
|
|
28
|
+
Antes de planejar, procure no código evidência de que a funcionalidade — ou parte dela — **já existe**. Siga
|
|
29
|
+
`references/isso-ja-existe.md` e responda com uma de três conclusões, sempre com `arquivo:linha`:
|
|
30
|
+
|
|
31
|
+
- **não existe** → siga;
|
|
32
|
+
- **existe parcialmente** → o recorte passa a ser só o que falta;
|
|
33
|
+
- **já existe** → pare e mostre onde está. Não crie trabalho sem a confirmação do usuário.
|
|
34
|
+
|
|
35
|
+
Consulte também a memória dos arquivos candidatos: `npx @fontdata/ai-harness memoria --arquivo <arquivo>` mostra
|
|
36
|
+
os trabalhos que já os tocaram e por quê.
|
|
37
|
+
|
|
38
|
+
## Passo 2 — Recorte
|
|
39
|
+
|
|
40
|
+
- **Nova tarefa:** faça de 2 a 3 perguntas, uma por vez, para entender o que deve ser feito.
|
|
41
|
+
- Resuma o que foi entendido (o que entra, o que fica fora, critérios de aceite) e **aguarde aprovação**.
|
|
42
|
+
|
|
43
|
+
Toda ambiguidade que você resolver por conta própria vira decisão registrada (Passo 5), sempre com a escolha
|
|
44
|
+
mais conservadora.
|
|
45
|
+
|
|
46
|
+
## Passo 3 — Pasta do trabalho e SPEC.md
|
|
47
|
+
|
|
48
|
+
1. Defina o id `AAAA-MM-DD-<slug>` (data de hoje, slug curto em minúsculas, sem acento).
|
|
49
|
+
2. Crie `docs/trabalhos/<id>/SPEC.md` a partir de `templates/SPEC.md`, preenchendo `{{id}}`, `{{titulo}}` e
|
|
50
|
+
`{{data}}`. Os nomes dos arquivos da pasta são sempre em caixa alta.
|
|
51
|
+
3. Registre o início do trabalho:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx @fontdata/ai-harness evento trabalho_iniciado --trabalho <id> --nome nova-tarefa --dados '{"trabalho_tipo":"feature"}'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Passo 4 — PLAN.md
|
|
58
|
+
|
|
59
|
+
Crie `docs/trabalhos/<id>/PLAN.md` a partir de `templates/PLAN.md`, seguindo `references/regras-do-plano.md`:
|
|
60
|
+
|
|
61
|
+
- as tasks aparecem **no frontmatter** (`tasks`) e na prosa, com os mesmos ids;
|
|
62
|
+
- toda task de código tem pelo menos 2 testes críticos concretos e critério de aceite binário;
|
|
63
|
+
- tasks paralelizáveis da mesma fase não tocam os mesmos arquivos;
|
|
64
|
+
- `arquivos` do frontmatter lista todos os arquivos (ou pastas) que as tasks vão criar ou alterar — é por ele que
|
|
65
|
+
o `/executar-plan` impede dois trabalhos de mexerem no mesmo código ao mesmo tempo;
|
|
66
|
+
- **plano condensado:** com 1 sprint e 1 fase, use `condensado: true` e omita os títulos de sprint e fase — o
|
|
67
|
+
contrato das tasks continua completo.
|
|
68
|
+
|
|
69
|
+
## Passo 5 — Decisões
|
|
70
|
+
|
|
71
|
+
Registre em `docs/trabalhos/<id>/DECISOES.md` (a partir de `templates/DECISOES.md`) cada ambiguidade resolvida:
|
|
72
|
+
decisão, motivo e alternativas descartadas. Para cada decisão:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx @fontdata/ai-harness evento decisao_registrada --trabalho <id> --nome nova-tarefa --dados '{"decisao_id":"D-01"}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Passo 6 — Auditoria do plano
|
|
79
|
+
|
|
80
|
+
1. Delegue ao agent **`auditor-plano`** (no plugin, `fontdata:auditor-plano`) a auditoria de `SPEC.md` e `PLAN.md`.
|
|
81
|
+
2. Corrija os achados BLOQUEANTES e IMPORTANTES no plano e peça nova auditoria até o veredito `APROVADO`.
|
|
82
|
+
3. Grave `auditoria_plano: aprovado` e `status: aguardando-aprovacao` no frontmatter do `PLAN.md`.
|
|
83
|
+
4. Rode `npx @fontdata/ai-harness doctor` e confirme que não há achado `contrato-*` neste trabalho.
|
|
84
|
+
|
|
85
|
+
## Passo 7 — 🚦 GATE de aprovação
|
|
86
|
+
|
|
87
|
+
Mostre ao usuário: os caminhos gravados, as tasks por fase (quais rodam em paralelo), quantos agents serão
|
|
88
|
+
necessários e as decisões registradas. **Peça aprovação explícita.**
|
|
89
|
+
|
|
90
|
+
- Com aprovação, grave `status: aprovado` no `SPEC.md`.
|
|
91
|
+
- **Start inicial (fluxo `/harness`):** o próximo passo normalmente é a etapa scaffold do `/harness` — **não** dispare a execução.
|
|
92
|
+
- **Nova tarefa:** se o usuário confirmar, chame **`/executar-plan <id>`** para executar o plano aprovado.
|
|
93
|
+
|
|
94
|
+
## Guardrails
|
|
95
|
+
|
|
96
|
+
- **Nunca** implementar nesta skill; **nunca** gravar `PLAN.md` na raiz do projeto.
|
|
97
|
+
- **Nunca** criar trabalho para algo que já existe sem a confirmação do usuário.
|
|
98
|
+
- Use os nomes de módulos do `SPEC.md` — sem nomenclatura nova.
|
|
99
|
+
- Conteúdo em **pt-BR**.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Isso já existe?
|
|
2
|
+
|
|
3
|
+
Pedidos de funcionalidade nova muitas vezes descrevem algo que o sistema já faz, de outro jeito ou com outro nome.
|
|
4
|
+
Antes de planejar, procure evidência — nunca presuma.
|
|
5
|
+
|
|
6
|
+
## Onde procurar
|
|
7
|
+
|
|
8
|
+
1. **Vocabulário do pedido:** entidades, ações e telas citadas, com sinônimos (cliente/pessoa/contato,
|
|
9
|
+
pedido/venda/ordem, desconto/abatimento). Busque nomes de classes, funções, rotas, tabelas e rótulos de tela.
|
|
10
|
+
2. **Pontos de entrada:** rotas e controllers, menus e telas, comandos de CLI, jobs agendados.
|
|
11
|
+
3. **Dados:** tabelas e colunas (migrations, models, scripts SQL) que já guardam o que o pedido precisa.
|
|
12
|
+
4. **Configuração e flags:** a funcionalidade pode existir desligada por configuração ou feature flag.
|
|
13
|
+
5. **Trabalhos anteriores:** `docs/trabalhos/*/SPEC.md` e o campo `arquivos` do frontmatter dos planos e relatórios.
|
|
14
|
+
|
|
15
|
+
## Como concluir
|
|
16
|
+
|
|
17
|
+
| Conclusão | Quando | O que fazer |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| **Não existe** | Nenhuma evidência nas cinco frentes | Seguir para o recorte |
|
|
20
|
+
| **Existe parcialmente** | Parte do comportamento já está no código | Recortar só o que falta e citar o que será reaproveitado |
|
|
21
|
+
| **Já existe** | O comportamento pedido está implementado | Parar, mostrar onde está e perguntar se o pedido é outra coisa |
|
|
22
|
+
|
|
23
|
+
Toda conclusão vem com a evidência (`arquivo:linha`, rota, tabela) — inclusive a de "não existe", com o que foi
|
|
24
|
+
buscado.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Regras do plano
|
|
2
|
+
|
|
3
|
+
Um plano aprovado precisa poder ser executado sem que ninguém pergunte nada no meio.
|
|
4
|
+
|
|
5
|
+
## Estrutura
|
|
6
|
+
|
|
7
|
+
- **Sprint** → **Fase** → **Task**. Cada sprint tem um critério de conclusão em uma frase verificável; cada fase
|
|
8
|
+
tem um critério de gate verificável por comando de terminal.
|
|
9
|
+
- Ids de task no formato `T-SS.NN` (sprint e número, com dois dígitos).
|
|
10
|
+
- As tasks ficam **no frontmatter** (`tasks`) e na prosa. O frontmatter é o que hooks, `doctor` e retomada leem;
|
|
11
|
+
quando os dois divergirem, vale o frontmatter.
|
|
12
|
+
|
|
13
|
+
## Regras obrigatórias
|
|
14
|
+
|
|
15
|
+
1. Toda task de código tem **pelo menos 2 testes críticos** definidos antes de qualquer código — entrada e
|
|
16
|
+
resultado esperado, não "testar o fluxo". Os testes são escritos primeiro.
|
|
17
|
+
2. **Critério de aceite binário:** verificável com sim ou não, por comando ou observação.
|
|
18
|
+
3. **Nenhum output vago:** descreva o arquivo, a função ou a estrutura exata que será entregue.
|
|
19
|
+
4. Tasks `paralelizavel: true` da mesma fase **não tocam os mesmos arquivos** nem dependem uma da outra.
|
|
20
|
+
5. `depende_de` declara toda dependência real; a ordem das fases respeita essas dependências.
|
|
21
|
+
6. Use os nomes de módulos do `SPEC.md` — sem nomenclatura nova.
|
|
22
|
+
7. Uma task cabe numa sessão de trabalho; task grande é dividida.
|
|
23
|
+
8. `arquivos` no frontmatter lista todos os arquivos (ou pastas) que as tasks vão criar ou alterar. Trabalhos
|
|
24
|
+
executados em paralelo na mesma pasta são barrados quando essas listas se cruzam.
|
|
25
|
+
|
|
26
|
+
## Plano condensado
|
|
27
|
+
|
|
28
|
+
Quando o trabalho tem **1 sprint e 1 fase**, use `condensado: true`: omita os títulos de sprint e fase e liste as
|
|
29
|
+
tasks direto. O contrato de cada task (testes, critério, dependências) continua completo.
|
|
30
|
+
|
|
31
|
+
## Status
|
|
32
|
+
|
|
33
|
+
- Ao criar: `status: rascunho` e `auditoria_plano: pendente`.
|
|
34
|
+
- Depois do veredito do `auditor-plano`: `auditoria_plano: aprovado` e `status: aguardando-aprovacao`.
|
|
35
|
+
- A execução muda para `em-execucao` e, ao fim, `concluido`. As tasks começam `pendente`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: decisoes
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: feature
|
|
6
|
+
titulo: "Decisões — {{titulo}}"
|
|
7
|
+
status: ativo
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Decisões — {{titulo}}
|
|
14
|
+
|
|
15
|
+
Decisões tomadas durante o planejamento e a execução. Uma decisão que muda não é apagada: registre uma nova
|
|
16
|
+
dizendo qual ela substitui.
|
|
17
|
+
|
|
18
|
+
| # | Data | Decisão | Motivo | Alternativas descartadas |
|
|
19
|
+
|---|---|---|---|---|
|
|
20
|
+
| D-01 | {{data}} | O que foi decidido | Por que, com a opção mais conservadora | O que não foi escolhido |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: plano
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: feature
|
|
6
|
+
titulo: "{{titulo}}"
|
|
7
|
+
status: rascunho
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
condensado: false
|
|
12
|
+
auditoria_plano: pendente
|
|
13
|
+
causa_raiz: null
|
|
14
|
+
tasks:
|
|
15
|
+
- id: T-01.01
|
|
16
|
+
titulo: "Nome curto da primeira task"
|
|
17
|
+
status: pendente
|
|
18
|
+
depende_de: []
|
|
19
|
+
paralelizavel: false
|
|
20
|
+
testes_criticos:
|
|
21
|
+
- "Entrada válida produz o resultado esperado"
|
|
22
|
+
- "Entrada inválida é recusada com a mensagem esperada"
|
|
23
|
+
- id: T-01.02
|
|
24
|
+
titulo: "Nome curto da segunda task"
|
|
25
|
+
status: pendente
|
|
26
|
+
depende_de:
|
|
27
|
+
- T-01.01
|
|
28
|
+
paralelizavel: false
|
|
29
|
+
testes_criticos:
|
|
30
|
+
- "Cenário principal integrado"
|
|
31
|
+
- "Caso de erro tratado"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Plano — {{titulo}}
|
|
35
|
+
|
|
36
|
+
## Sprint 1 — Critério de conclusão em uma frase verificável
|
|
37
|
+
|
|
38
|
+
### Fase 1.1 — Nome da fase
|
|
39
|
+
|
|
40
|
+
> Dependências: nenhuma
|
|
41
|
+
> Paralelismo: quais tasks desta fase rodam juntas
|
|
42
|
+
> Gate: comando de terminal que prova a fase concluída
|
|
43
|
+
|
|
44
|
+
#### T-01.01 — Nome curto da primeira task
|
|
45
|
+
|
|
46
|
+
- **Agent:** papel responsável
|
|
47
|
+
- **Input:** o que precisa estar pronto para começar
|
|
48
|
+
- **Output:** arquivo, função ou estrutura exata entregue
|
|
49
|
+
- **Testes críticos:** os mesmos do frontmatter
|
|
50
|
+
- **Critério de aceite:** verificável com sim ou não
|
|
51
|
+
|
|
52
|
+
#### T-01.02 — Nome curto da segunda task
|
|
53
|
+
|
|
54
|
+
- **Agent:** papel responsável
|
|
55
|
+
- **Input:** saída da T-01.01
|
|
56
|
+
- **Output:** arquivo, função ou estrutura exata entregue
|
|
57
|
+
- **Testes críticos:** os mesmos do frontmatter
|
|
58
|
+
- **Critério de aceite:** verificável com sim ou não
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: spec
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: feature
|
|
6
|
+
titulo: "{{titulo}}"
|
|
7
|
+
status: rascunho
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# {{titulo}}
|
|
14
|
+
|
|
15
|
+
## Contexto
|
|
16
|
+
|
|
17
|
+
Por que este trabalho existe e o que o `SPEC.md` principal diz sobre ele.
|
|
18
|
+
|
|
19
|
+
## Isso já existe?
|
|
20
|
+
|
|
21
|
+
Conclusão (não existe, existe parcialmente ou já existe) e a evidência encontrada.
|
|
22
|
+
|
|
23
|
+
## O que será entregue
|
|
24
|
+
|
|
25
|
+
- Comportamento 1, descrito do ponto de vista de quem usa.
|
|
26
|
+
|
|
27
|
+
## Fora do escopo
|
|
28
|
+
|
|
29
|
+
- O que fica explicitamente para depois.
|
|
30
|
+
|
|
31
|
+
## Critérios de aceite
|
|
32
|
+
|
|
33
|
+
- [ ] Critério verificável com sim ou não.
|
|
34
|
+
|
|
35
|
+
## Riscos e código legado
|
|
36
|
+
|
|
37
|
+
Áreas de código existente tocadas e o padrão local a preservar.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: resolver-bug
|
|
3
|
+
description: Corrige um bug relatado — algo que não funciona, dá erro ou mostra valor errado — investigando a causa raiz, planejando a correção, pedindo aprovação e corrigindo passo a passo.
|
|
4
|
+
argument-hint: "[relato do problema]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Resolver bug
|
|
8
|
+
|
|
9
|
+
Relato: $ARGUMENTS
|
|
10
|
+
|
|
11
|
+
Se o relato não veio, peça os detalhes antes de começar: o que acontece, o que era esperado, onde e desde quando.
|
|
12
|
+
|
|
13
|
+
> **🚦 Há um GATE de aprovação** antes de alterar qualquer código.
|
|
14
|
+
|
|
15
|
+
## Passo 1 — Investigar a causa raiz
|
|
16
|
+
|
|
17
|
+
1. Delegue ao agent **`investigador`** (no plugin, `fontdata:investigador`) o relato completo.
|
|
18
|
+
2. Ele devolve: sintoma, como reproduzir, causa raiz (`comprovada` ou `hipotese`) com evidência, arquivos envolvidos
|
|
19
|
+
e riscos da correção.
|
|
20
|
+
3. **Consulte a memória** sobre cada arquivo envolvido: `npx @fontdata/ai-harness memoria --arquivo <arquivo>` mostra os
|
|
21
|
+
trabalhos anteriores que o tocaram. Depois de criar o trabalho (Passo 2) e com a causa comprovada,
|
|
22
|
+
`npx @fontdata/ai-harness memoria --regressao <id>` indica se algum deles é regressão candidata — registre a
|
|
23
|
+
conclusão no relatório técnico.
|
|
24
|
+
4. **Não há defeito?** Se a apuração mostrar que é comportamento esperado, paridade com legado, medição ou
|
|
25
|
+
levantamento, crie um trabalho do tipo `investigacao` com `relatorios/TECNICO.md`, avise o usuário e encerre.
|
|
26
|
+
|
|
27
|
+
## Passo 2 — Criar o trabalho do tipo bug
|
|
28
|
+
|
|
29
|
+
1. Id `AAAA-MM-DD-<slug>`, com slug que descreve o sintoma.
|
|
30
|
+
2. Crie `docs/trabalhos/<id>/PLAN.md` a partir de `templates/PLAN.md`:
|
|
31
|
+
- `causa_raiz`: `comprovada` ou `hipotese`, conforme o investigador;
|
|
32
|
+
- `arquivos`: os arquivos envolvidos;
|
|
33
|
+
- a **primeira task é sempre o teste de regressão** que reproduz o bug e falha hoje;
|
|
34
|
+
- plano **condensado** para correção simples, com `auditoria_plano: pendente` (ele não passa pelo
|
|
35
|
+
`auditor-plano`); plano completo quando houver mais de uma fase, auditado pelo `auditor-plano`, cujo veredito
|
|
36
|
+
grava `auditoria_plano: aprovado` ou `reprovado`. Não há outros valores.
|
|
37
|
+
3. Registre o início:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx @fontdata/ai-harness evento trabalho_iniciado --trabalho <id> --nome resolver-bug --dados '{"trabalho_tipo":"bug"}'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Passo 3 — 🚦 GATE de aprovação
|
|
44
|
+
|
|
45
|
+
Mostre: sintoma, causa raiz e evidência, o plano de correção e os riscos. Com `causa_raiz: hipotese`, deixe
|
|
46
|
+
explícito que a primeira task confirma ou derruba a hipótese. **Não altere nada sem o "ok".**
|
|
47
|
+
|
|
48
|
+
## Passo 4 — Corrigir com TDD
|
|
49
|
+
|
|
50
|
+
1. **Regressão primeiro (T-01.01):** escreva o teste de regressão, rode e **confirme que falha** pelo motivo do bug.
|
|
51
|
+
Com hipótese, o teste falhando pelo motivo esperado torna a causa `comprovada` — atualize o frontmatter.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx @fontdata/ai-harness evento task_iniciada --trabalho <id> --task T-01.01 --nome resolver-bug
|
|
55
|
+
npx @fontdata/ai-harness evento suite_vermelha --trabalho <id> --task T-01.01 --nome resolver-bug --resultado falha \
|
|
56
|
+
--dados '{"comando":"npm test","total":42,"falhas":1}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. **Correção mínima (T-01.02):** registre `task_iniciada` para a T-01.02, aplique a correção e rode a suíte completa.
|
|
60
|
+
Quando existir `.claude/rules/harness-projeto.md`, delegue ao agent do domínio e use o comando da suíte declarado.
|
|
61
|
+
3. Passe pelos gates: `revisor-testes` e `qa` (no plugin, `fontdata:revisor-testes` e `fontdata:qa`). O `qa`
|
|
62
|
+
registra `suite_verde` para a T-01.02. Plano com várias tasks: execute com `/executar-plan <id>`.
|
|
63
|
+
4. A T-01.01 **fecha junto com a correção**: o critério dela é falhar antes e passar depois, e a mesma suíte verde
|
|
64
|
+
prova as duas coisas. Registre `suite_verde` também para ela e feche as duas:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx @fontdata/ai-harness evento suite_verde --trabalho <id> --task T-01.01 --nome qa --resultado ok \
|
|
68
|
+
--dados '{"comando":"npm test","total":42,"falhas":0}'
|
|
69
|
+
npx @fontdata/ai-harness evento task_concluida --trabalho <id> --task T-01.01 --nome resolver-bug
|
|
70
|
+
npx @fontdata/ai-harness evento task_concluida --trabalho <id> --task T-01.02 --nome resolver-bug
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
5. No frontmatter do `PLAN.md`, cada task vai de `pendente` para `em-andamento` e, com `suite_verde` registrado, para
|
|
74
|
+
`concluida`, no feminino. Os outros valores aceitos são `bloqueada` e `pulada`.
|
|
75
|
+
|
|
76
|
+
## Passo 5 — Relatório duplo
|
|
77
|
+
|
|
78
|
+
Com a correção aprovada, escreva os dois relatórios a partir dos templates:
|
|
79
|
+
|
|
80
|
+
- **`relatorios/TECNICO.md`** (`templates/relatorios/TECNICO.md`): sintoma, reprodução, causa raiz, correção,
|
|
81
|
+
testes que protegem e riscos remanescentes.
|
|
82
|
+
- **`relatorios/CLIENTE.md`** (`templates/relatorios/CLIENTE.md`): o que acontecia, quem foi afetado, o que muda
|
|
83
|
+
e se alguém precisa fazer algo — **sem jargão técnico**, seguindo `references/relatorio-para-cliente.md`.
|
|
84
|
+
|
|
85
|
+
Para cada relatório e para o encerramento:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx @fontdata/ai-harness evento relatorio_gerado --trabalho <id> --nome resolver-bug --dados '{"caminho":"docs/trabalhos/<id>/relatorios/CLIENTE.md"}'
|
|
89
|
+
npx @fontdata/ai-harness evento trabalho_concluido --trabalho <id> --nome resolver-bug
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Troque o `status` do documento `PLAN.md` (o do topo do frontmatter, não o das tasks) para `concluido` e o dos
|
|
93
|
+
relatórios para `final`.
|
|
94
|
+
|
|
95
|
+
## Passo 6 — Evitar que volte
|
|
96
|
+
|
|
97
|
+
Sugira uma rule em `.claude/rules/` que teria evitado o bug (padrão proibido, validação obrigatória, teste
|
|
98
|
+
exigido). **Não grave sem aprovação.**
|
|
99
|
+
|
|
100
|
+
## Guardrails
|
|
101
|
+
|
|
102
|
+
- **Nunca** corrigir antes do teste de regressão falhar pelo motivo do bug.
|
|
103
|
+
- **Nunca** alterar código antes do GATE; nada de refatoração oportunista junto com a correção.
|
|
104
|
+
- Conteúdo em **pt-BR**.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Relatório para o cliente
|
|
2
|
+
|
|
3
|
+
O relatório para o cliente é lido por quem usa o sistema ou decide sobre ele — não por quem o programa. O hook
|
|
4
|
+
`sem-jargao` avisa quando aparecem termos técnicos.
|
|
5
|
+
|
|
6
|
+
## O que responder
|
|
7
|
+
|
|
8
|
+
1. **O que acontecia:** o problema como a pessoa via, com as palavras dela.
|
|
9
|
+
2. **Quem foi afetado e desde quando:** perfis, telas, período, volume aproximado.
|
|
10
|
+
3. **O que muda agora:** o comportamento correto, a partir de quando.
|
|
11
|
+
4. **É preciso fazer algo?** Refazer uma operação, conferir registros de um período, avisar alguém. Se não, diga
|
|
12
|
+
que não.
|
|
13
|
+
|
|
14
|
+
## Como escrever
|
|
15
|
+
|
|
16
|
+
- Frases curtas, voz ativa, sem siglas.
|
|
17
|
+
- Troque o termo técnico pelo efeito: em vez de "a consulta retornava null", "a tela mostrava o campo vazio".
|
|
18
|
+
- Não cite arquivos, funções, versões de biblioteca, commits ou nomes de sistema interno.
|
|
19
|
+
- Não culpe pessoas nem fornecedores.
|
|
20
|
+
|
|
21
|
+
## Exemplo
|
|
22
|
+
|
|
23
|
+
> Entre os dias 3 e 10, o valor do frete aparecia maior do que o correto nos pedidos com mais de um volume.
|
|
24
|
+
> Os pedidos já emitidos nesse período foram listados para conferência. A partir de hoje, o frete considera o
|
|
25
|
+
> peso de todos os volumes corretamente. Não é preciso refazer os pedidos: a equipe financeira vai tratar as
|
|
26
|
+
> diferenças.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: plano
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: bug
|
|
6
|
+
titulo: "{{titulo}}"
|
|
7
|
+
status: rascunho
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
condensado: true
|
|
12
|
+
auditoria_plano: pendente
|
|
13
|
+
causa_raiz: hipotese
|
|
14
|
+
tasks:
|
|
15
|
+
- id: T-01.01
|
|
16
|
+
titulo: "Teste de regressão que reproduz o problema"
|
|
17
|
+
status: pendente
|
|
18
|
+
depende_de: []
|
|
19
|
+
paralelizavel: false
|
|
20
|
+
testes_criticos:
|
|
21
|
+
- "Com a entrada do relato, o resultado é o esperado (falha hoje)"
|
|
22
|
+
- "O caso vizinho que já funcionava continua funcionando"
|
|
23
|
+
- id: T-01.02
|
|
24
|
+
titulo: "Correção mínima da causa raiz"
|
|
25
|
+
status: pendente
|
|
26
|
+
depende_de:
|
|
27
|
+
- T-01.01
|
|
28
|
+
paralelizavel: false
|
|
29
|
+
testes_criticos:
|
|
30
|
+
- "O teste de regressão da T-01.01 passa"
|
|
31
|
+
- "A suíte completa continua verde"
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Correção — {{titulo}}
|
|
35
|
+
|
|
36
|
+
## Sintoma
|
|
37
|
+
|
|
38
|
+
O que acontece, o que era esperado, onde e desde quando.
|
|
39
|
+
|
|
40
|
+
## Como reproduzir
|
|
41
|
+
|
|
42
|
+
Passos, dados ou teste que mostram o problema.
|
|
43
|
+
|
|
44
|
+
## Causa raiz
|
|
45
|
+
|
|
46
|
+
Hipótese ou causa comprovada, com a evidência (`arquivo:linha`, trecho do histórico, saída da reprodução).
|
|
47
|
+
|
|
48
|
+
## Tasks
|
|
49
|
+
|
|
50
|
+
#### T-01.01 — Teste de regressão que reproduz o problema
|
|
51
|
+
|
|
52
|
+
- **Output:** teste automatizado que falha hoje pelo motivo do problema
|
|
53
|
+
- **Critério de aceite:** o teste falha antes da correção e passa depois
|
|
54
|
+
|
|
55
|
+
#### T-01.02 — Correção mínima da causa raiz
|
|
56
|
+
|
|
57
|
+
- **Output:** alteração restrita aos arquivos da causa raiz
|
|
58
|
+
- **Critério de aceite:** regressão verde e suíte completa verde
|
|
59
|
+
|
|
60
|
+
## Riscos
|
|
61
|
+
|
|
62
|
+
O que mais depende do trecho alterado e como foi protegido.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: relatorio_cliente
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: bug
|
|
6
|
+
titulo: "{{titulo}}"
|
|
7
|
+
status: rascunho
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# {{titulo}}
|
|
14
|
+
|
|
15
|
+
## O que acontecia
|
|
16
|
+
|
|
17
|
+
O problema como quem usa o sistema percebia.
|
|
18
|
+
|
|
19
|
+
## Quem foi afetado
|
|
20
|
+
|
|
21
|
+
Perfis, telas e período.
|
|
22
|
+
|
|
23
|
+
## O que muda agora
|
|
24
|
+
|
|
25
|
+
O comportamento correto, a partir de quando.
|
|
26
|
+
|
|
27
|
+
## É preciso fazer algo?
|
|
28
|
+
|
|
29
|
+
O que conferir ou refazer — ou a confirmação de que nada é necessário.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_versao: 1
|
|
3
|
+
tipo: relatorio_tecnico
|
|
4
|
+
id: "{{id}}"
|
|
5
|
+
trabalho_tipo: bug
|
|
6
|
+
titulo: "{{titulo}}"
|
|
7
|
+
status: rascunho
|
|
8
|
+
criado_em: "{{data}}"
|
|
9
|
+
atualizado_em: "{{data}}"
|
|
10
|
+
arquivos: []
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Relatório técnico — {{titulo}}
|
|
14
|
+
|
|
15
|
+
## Sintoma e reprodução
|
|
16
|
+
|
|
17
|
+
## Causa raiz
|
|
18
|
+
|
|
19
|
+
Evidência com `arquivo:linha` e por que a condição produzia o sintoma.
|
|
20
|
+
|
|
21
|
+
## Correção
|
|
22
|
+
|
|
23
|
+
O que mudou e por que é a correção mínima.
|
|
24
|
+
|
|
25
|
+
## Testes que protegem
|
|
26
|
+
|
|
27
|
+
- Teste de regressão: caminho e o que ele verifica.
|
|
28
|
+
- Suíte completa: comando e resultado.
|
|
29
|
+
|
|
30
|
+
## Riscos remanescentes
|
|
31
|
+
|
|
32
|
+
Pontos relacionados que não foram alterados e merecem atenção.
|
package/bin/cli.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
5
|
-
import { loadCatalog, allCommands } from '../src/catalog.js';
|
|
6
|
-
import { runCommand, runnableIds, suggestIds } from '../src/run.js';
|
|
7
|
-
|
|
8
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
|
|
10
|
-
const RESERVED = new Set(['init', 'list', 'run', 'help', '--help', '-h', '--version', '-v']);
|
|
11
|
-
|
|
12
|
-
function pkgVersion() {
|
|
13
|
-
try {
|
|
14
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
15
|
-
return pkg.version;
|
|
16
|
-
} catch {
|
|
17
|
-
return '0.0.0';
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function printHelp() {
|
|
22
|
-
console.log(`
|
|
23
|
-
@fontdata/ai-harness — harness de engenharia com IA para Claude Code
|
|
24
|
-
|
|
25
|
-
Uso:
|
|
26
|
-
npx @fontdata/ai-harness <comando> [contexto] roda o comando na pasta atual
|
|
27
|
-
npx @fontdata/ai-harness init instala os comandos no projeto
|
|
28
|
-
|
|
29
|
-
Executar sem instalar:
|
|
30
|
-
<comando> Abre o Claude Code aqui já executando o comando (ex.: harness)
|
|
31
|
-
run <comando> Forma explícita, útil quando o nome colide com uma palavra reservada
|
|
32
|
-
|
|
33
|
-
Gerenciar:
|
|
34
|
-
init [caminho] Instala os slash commands em .claude/commands do projeto (interativo)
|
|
35
|
-
list Lista todos os comandos disponíveis no catálogo
|
|
36
|
-
--help, -h Mostra esta ajuda
|
|
37
|
-
--version, -v Mostra a versão
|
|
38
|
-
|
|
39
|
-
Exemplos:
|
|
40
|
-
npx @fontdata/ai-harness harness
|
|
41
|
-
npx @fontdata/ai-harness resolver-bug "login 500 no refresh token"
|
|
42
|
-
npx @fontdata/ai-harness run versao minor
|
|
43
|
-
npx @fontdata/ai-harness harness -- --model claude-opus-5
|
|
44
|
-
|
|
45
|
-
Tudo depois de \`--\` é repassado ao Claude Code (--model, --effort, -p, ...).
|
|
46
|
-
`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function printList() {
|
|
50
|
-
const catalog = loadCatalog();
|
|
51
|
-
console.log('\nComandos disponíveis:\n');
|
|
52
|
-
for (const group of catalog.groups) {
|
|
53
|
-
console.log(` ${group.title}`);
|
|
54
|
-
for (const cmd of group.commands) {
|
|
55
|
-
const star = cmd.recommended ? ' *' : ' ';
|
|
56
|
-
console.log(` ${star} ${cmd.title.padEnd(26)} ${cmd.description}`);
|
|
57
|
-
}
|
|
58
|
-
console.log('');
|
|
59
|
-
}
|
|
60
|
-
console.log(` (* = conjunto recomendado · total: ${allCommands(catalog).length} comandos + /harness)\n`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Separa os argumentos do comando dos flags destinados ao Claude Code. */
|
|
64
|
-
function splitArgs(rest) {
|
|
65
|
-
const sep = rest.indexOf('--');
|
|
66
|
-
if (sep === -1) return { args: rest, claudeFlags: [] };
|
|
67
|
-
return { args: rest.slice(0, sep), claudeFlags: rest.slice(sep + 1) };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function main() {
|
|
71
|
-
const argv = process.argv.slice(2);
|
|
72
|
-
const cmd = argv[0];
|
|
73
|
-
|
|
74
|
-
if (cmd === '--version' || cmd === '-v') {
|
|
75
|
-
console.log(pkgVersion());
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {
|
|
79
|
-
printHelp();
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (cmd === 'list') {
|
|
83
|
-
printList();
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (cmd === 'init') {
|
|
87
|
-
// Import dinâmico: só carrega @clack/prompts quando o init é realmente usado.
|
|
88
|
-
const { runInit } = await import('../src/init.js');
|
|
89
|
-
await runInit(argv[1]);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (cmd === 'run') {
|
|
93
|
-
const id = argv[1];
|
|
94
|
-
if (!id) {
|
|
95
|
-
console.error('Informe o comando a executar. Ex.: npx @fontdata/ai-harness run harness\n');
|
|
96
|
-
printHelp();
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
99
|
-
const { args, claudeFlags } = splitArgs(argv.slice(2));
|
|
100
|
-
process.exit(runCommand(id, args, claudeFlags));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const ids = runnableIds();
|
|
104
|
-
if (ids.includes(cmd.replace(/^\//, ''))) {
|
|
105
|
-
const { args, claudeFlags } = splitArgs(argv.slice(1));
|
|
106
|
-
process.exit(runCommand(cmd, args, claudeFlags));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (!RESERVED.has(cmd)) {
|
|
110
|
-
const near = suggestIds(cmd.replace(/^\//, ''), ids);
|
|
111
|
-
console.error(`Comando desconhecido: ${cmd}`);
|
|
112
|
-
if (near.length) console.error(`\nVocê quis dizer: ${near.join(', ')}`);
|
|
113
|
-
console.error('');
|
|
114
|
-
}
|
|
115
|
-
printHelp();
|
|
116
|
-
process.exit(1);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
main().catch((err) => {
|
|
120
|
-
console.error('Erro:', err?.message || err);
|
|
121
|
-
process.exit(1);
|
|
122
|
-
});
|