@spec-wave/cli 0.10.0 → 0.11.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/README.md +8 -0
- package/bin/spec-wave.mjs +20 -0
- package/package.json +2 -2
- package/src/api/github-graphql.mjs +4 -0
- package/src/api/github-rest.mjs +13 -0
- package/src/commands/decompose.mjs +183 -19
- package/src/commands/dev-agent.mjs +568 -0
- package/src/commands/doctor.mjs +11 -0
- package/src/commands/generate-plan.mjs +21 -1
- package/src/commands/generate-spec.mjs +24 -1
- package/src/commands/validate.mjs +9 -0
- package/src/config.mjs +5 -0
- package/src/lib/claude.mjs +216 -19
- package/src/lib/critique.mjs +5 -1
- package/src/lib/doc-completeness.mjs +54 -0
- package/src/lib/force.mjs +34 -0
- package/src/templates/agent/dev.specwave.agent.plist +17 -0
- package/src/templates/agent/spec-wave-agent.service +18 -0
- package/src/templates/skill/SKILL.md +60 -7
|
@@ -67,6 +67,10 @@ Exemplo de `.spec-wave.json`:
|
|
|
67
67
|
|
|
68
68
|
Exceção: se o usuário pedir explicitamente para revisar ou melhorar um documento já gerado, use o Write tool para editar o arquivo local.
|
|
69
69
|
|
|
70
|
+
**Nunca crie Story ou Task avulsa com `/spec-wave issue`.** Story e Task nascem do `decompose`, já na Etapa **✅ Ready** e vinculadas ao pai. Criadas à mão elas caem em **📥 Backlog**, que é a coluna de descoberta de *produto* — e ali **não aparecem em tela nenhuma** da UI do spec-wave: o inbox do PM lista só Features, a tela do Dev lê a etapa 🚧 Desenvolvimento e a fila do TL lê ✅ Ready. Se o usuário insistir numa Story/Task avulsa, crie-a **com `--parent <n>`** e, logo em seguida, avance-a para ✅ Ready — explicando por que esse passo extra é necessário.
|
|
71
|
+
|
|
72
|
+
**Nunca use `gh issue create` para criar work items.** Ele não adiciona a issue ao Project, então ela fica **sem Etapa** — e some de todas as telas da UI. Use sempre `npx @spec-wave/cli issue` (ou os atalhos `initiative` / `feature`).
|
|
73
|
+
|
|
70
74
|
---
|
|
71
75
|
|
|
72
76
|
## Fluxo Kanban
|
|
@@ -77,6 +81,20 @@ Exceção: se o usuário pedir explicitamente para revisar ou melhorar um docume
|
|
|
77
81
|
→ 🧪 QA → 📋 Homologação → 🚀 Deploy → 🎉 Done
|
|
78
82
|
```
|
|
79
83
|
|
|
84
|
+
Essa é a sequência completa, mas **cada tipo de artefato percorre só um trecho dela** — e, principalmente, **nasce numa Etapa diferente**. Consulte esta tabela antes de criar ou mover qualquer item.
|
|
85
|
+
|
|
86
|
+
| Artefato | Nasce em | Percorre | Observações |
|
|
87
|
+
|----------|----------|----------|-------------|
|
|
88
|
+
| **Initiative / Epic** | 📥 Backlog | — | Agrupadores. Não têm fluxo próprio; acompanham os filhos. |
|
|
89
|
+
| **Feature** | 📥 Backlog | 🎯 Priorizado → 📋 Spec → 📋 Plan → ✅ Ready → 🚧 Desenvolvimento → 👀 Code Review → 🧪 QA → 📋 Homologação → 🚀 Deploy → 🎉 Done | Fica parada em **✅ Ready** esperando um dev assumir — é ali que ela aparece na fila do TL. Só avança para 👀 Code Review quando **TODAS** as suas Stories já estiverem lá. |
|
|
90
|
+
| **Story** | **✅ Ready** (criada pelo `decompose`) | 🚧 Desenvolvimento → 👀 Code Review → 🧪 QA → 📋 Homologação → 🎉 Done | **Nunca nasce em 📥 Backlog.** |
|
|
91
|
+
| **Task** | **✅ Ready** (criada pelo `decompose`) | 🚧 Desenvolvimento → 🎉 Done | **Não** passa por Code Review, QA nem Homologação — só `task start` e `task done`. |
|
|
92
|
+
| **RFC** | 📥 Backlog | decompõe direto em **Tasks** (que nascem em ✅ Ready) | Não usa spec/plan. |
|
|
93
|
+
| **Bug** | 📥 Backlog | 🚧 Desenvolvimento → 🎉 Done | Ao aprovar, vai direto para Done (não passa por Homologação). |
|
|
94
|
+
| **Spike** | 📥 Backlog | **movido só à mão pelo usuário** | Nunca avance a Etapa de um Spike por conta própria. |
|
|
95
|
+
|
|
96
|
+
**Regra da Etapa:** a Etapa **só avança, nunca retrocede**. O campo **Status** (Todo / In Progress / Done) mede o progresso *dentro* da Etapa e reinicia a cada avanço. Prefira sempre os comandos da CLI (`task start|done`, `story review`) a mutações manuais no board — eles embutem essas regras.
|
|
97
|
+
|
|
80
98
|
Labels de gatilho:
|
|
81
99
|
- `spec-wave:spec` → dispara `generate-spec.yml` → gera `spec.md` (especificação funcional, primeiro)
|
|
82
100
|
- `spec-wave:plan` → dispara `generate-plan.yml` → gera `plan.md` (plano técnico, a partir da spec)
|
|
@@ -87,6 +105,12 @@ Labels de **estado** (gravadas pelas automações — **não** são gatilhos, n
|
|
|
87
105
|
- `spec-wave:critique-failed` → a crítica adversarial apontou contradições **graves** nos documentos; **bloqueia** o `spec-wave:ready` até ser removida (veja *Crítica adversarial* abaixo)
|
|
88
106
|
- `spec-wave:decomposed` → a Feature/RFC já foi decomposta; o `decompose` pula silenciosamente enquanto ela existir (veja *Guard de idempotência* abaixo)
|
|
89
107
|
|
|
108
|
+
Label **modificadora** — `spec-wave:force`: sozinha **não dispara nada**; adicionada **junto** de uma label de gatilho, manda o comando **re-executar a etapa ignorando os guards**. É **consumida** (removida) pelo run que a leu, então vale para uma execução só. Adicione-a **antes ou junto** do gatilho, nunca depois (o evento do gatilho já teria disparado):
|
|
109
|
+
```bash
|
|
110
|
+
gh issue edit <n> --add-label "spec-wave:force" --add-label "spec-wave:decompose"
|
|
111
|
+
```
|
|
112
|
+
Efeito por comando: no **decompose**, ignora o guard e **fecha as sub-issues da decomposição anterior** antes de gerar as novas (veja *Guard de idempotência*); em **spec** e **plan**, não muda nada na prática — eles já regeram e sobrescrevem o arquivo a cada acionamento da label.
|
|
113
|
+
|
|
90
114
|
A etapa **🚧 Desenvolvimento** é coberta pelo comando **local** `npx @spec-wave/cli@latest implement <número>` (não é uma label/Action): lê uma **Feature** (todas as Stories pendentes, em ordem de dependência), uma Story ou uma Task e aciona o spec-kit para implementar. Veja `/spec-wave implement`.
|
|
91
115
|
|
|
92
116
|
---
|
|
@@ -115,7 +139,9 @@ Esta skill é um **wrapper** da CLI `@spec-wave/cli`, sempre invocada como `npx
|
|
|
115
139
|
| `--priority <p>` | string | **Opcional.** `P0`, `P1`, `P2` ou `P3`. Omita se o usuário não pediu — a prioridade fica `null` (sem prioridade). Nunca atribua por conta própria. |
|
|
116
140
|
| `--area <area>` | string | `Frontend`, `Backend`, `Mobile`, `Infra`, `DevOps` ou `Data`. |
|
|
117
141
|
|
|
118
|
-
> Faz tudo: cria a issue (label de tipo — e de prioridade **apenas se `--priority` for informado**), vincula ao parent como sub-issue, adiciona ao Project e define os campos **Etapa
|
|
142
|
+
> Faz tudo: cria a issue (label de tipo — e de prioridade **apenas se `--priority` for informado**), vincula ao parent como sub-issue, adiciona ao Project e define os campos **Etapa**, **Work Item Type**, **Area** e, **só se informada, Priority**. Grava `Parent: #N` no corpo. Lê o Project do `.spec-wave.json`. **Não use `gh issue create` direto** — ele não adiciona ao board nem vincula o parent.
|
|
143
|
+
>
|
|
144
|
+
> ⚠️ **A Etapa inicial é sempre 📥 Backlog, para qualquer `--type`.** Isso é o correto para **Initiative, Epic, Feature, RFC, Bug e Spike**. Para **Story e Task está errado** — elas pertencem a ✅ Ready (veja a *Regra fundamental*): prefira criá-las via `decompose`; se criar à mão, avance a Etapa logo depois.
|
|
119
145
|
|
|
120
146
|
### `@spec-wave/cli initiative` — atalho de `issue --type initiative`
|
|
121
147
|
Cria o nó raiz da hierarquia (agrupa Epics). Mesmas flags do `issue` exceto `--type` (fixo em `initiative`) e `--parent` (Initiative é raiz, não tem pai).
|
|
@@ -163,6 +189,7 @@ Mesmas flags do `issue` (exceto `--type`, fixo em `feature`). Mantido para o flu
|
|
|
163
189
|
| Flag | Tipo | Descrição |
|
|
164
190
|
|------|------|-----------|
|
|
165
191
|
| `--issue-number <n>` | string (obrigatório) | Número da issue no GitHub. |
|
|
192
|
+
| `--force` | flag | Re-executa a etapa ignorando os guards. No fluxo por label o equivalente é a label `spec-wave:force` (a linha de comando do workflow é fixa) — prefira a label. |
|
|
166
193
|
|
|
167
194
|
> ⚠️ Esses quatro comandos são executados pelos **GitHub Actions** (disparados por labels), **não** pela skill diretamente. Veja a *Regra fundamental*: para gerar plan/spec/decompor, adicione a **label** correspondente — não rode o comando à mão (a não ser para debug local).
|
|
168
195
|
>
|
|
@@ -180,7 +207,7 @@ Mesmas flags do `issue` (exceto `--type`, fixo em `feature`). Mantido para o flu
|
|
|
180
207
|
> Diferente dos quatro acima, `implement` roda **localmente** (lê `.spec-wave.json`, como `issue`), não por Action. Detecta o tipo da issue: **Feature** → lista as Stories (sub-issues), **ordena topologicamente pelas dependências** (`Depende de:` + *blocked by*), **pula** as já em 👀 Code Review+ (listadas no contexto como "não tocar") e monta **um único** contexto com todas as pendentes (cada uma com suas Tasks), acionando o spec-kit **uma vez** com `{issue}/{type}/{title}` da Feature — **ciclo de dependências entre Stories pendentes aborta o comando (exit 1)**; **Story** → coleta todas as Tasks (sub-issues) e aciona o spec-kit uma única vez; **Task** → só aquela task. Monta o contexto em `.spec-wave/implement-<n>.md` e chama o comando configurado em `specKit.command` (no `.spec-wave.json`) ou na env `SPEC_WAVE_IMPLEMENT_CMD`. Placeholders disponíveis no template: `{tasksFile} {specFile} {planFile} {issue} {type} {title}`. Se nada estiver configurado, ele apenas monta o contexto e mostra como configurar (não executa). O contexto inclui os **comentários da issue**, um **digest do código recente** e um **aviso de dependências pendentes** quando a issue depende (linha `Depende de: #N` ou relação nativa *blocked by*) de outra que ainda não foi concluída — nesse caso, confirme com o usuário antes de seguir. Inclui também instruções para o agente implementar as Tasks **sequencialmente, uma por vez** (nunca duas com Status "In Progress" ao mesmo tempo): cada Task usa o **Status** (In Progress) *dentro* da Etapa 🚧 Desenvolvimento e, **ao concluir, avança para a Etapa 🎉 Done com Status Done**. **Ao concluir toda a Story**: fazer o commit, abrir o PR e **avançar a Etapa da Story para 👀 Code Review** (Status → Todo) — as Tasks já estão em 🎉 Done. A **Feature só avança** para Code Review quando **TODAS as suas Stories** já estiverem em Code Review — enquanto houver Story pendente, a Feature fica em 🚧 Desenvolvimento. Etapa só avança (nunca volta); Status mede o progresso dentro da etapa.
|
|
181
208
|
|
|
182
209
|
### `@spec-wave/cli doctor` — preflight de auth e configuração (comando LOCAL)
|
|
183
|
-
Sem flags. Roda um checklist de diagnóstico no repositório atual: token GitHub (e a fonte dele), escopos (`repo`, `project`, `workflow` — com degradação para checks funcionais em fine-grained PATs), conta ativa do `gh` vs. owner, `.spec-wave.json` (campos e sincronia com o Project real), acesso ao repositório, configuração de IA (provider/modelo/`ai.models
|
|
210
|
+
Sem flags. Roda um checklist de diagnóstico no repositório atual: token GitHub (e a fonte dele), escopos (`repo`, `project`, `workflow` — com degradação para checks funcionais em fine-grained PATs), conta ativa do `gh` vs. owner, `.spec-wave.json` (campos e sincronia com o Project real), acesso ao repositório, configuração de IA (provider/modelo/`ai.models`/teto de saída + secrets do Actions), **spec-kit** (`specKit.command` / env `SPEC_WAVE_IMPLEMENT_CMD` — se ausente, avisa e sugere exemplos por agente: Claude Code, opencode, Codex, Copilot CLI, Kiro CLI, Qwen Code) e presença dos workflows.
|
|
184
211
|
|
|
185
212
|
> Saída: `✓` ok, `✗` problema confirmado, `!` não verificável (best-effort — falha de rede nunca derruba o doctor). **Exit 1** se houver algum `✗`. **Quando rodar:** no início de uma sessão de trabalho, ou sempre que aparecer um erro estranho (ex.: **404 ao criar issues** — causa típica: token sem acesso ao repo/org, que o doctor aponta). É o primeiro passo de troubleshooting — prefira-o a depurar `gh api` na mão.
|
|
186
213
|
|
|
@@ -223,7 +250,11 @@ Após o `generate-plan` e **antes** da criação de issues no `decompose`, um se
|
|
|
223
250
|
|
|
224
251
|
O evento `labeled` pode redisparar (re-add da label, retry de runner). Para não duplicar Stories/Tasks, o `decompose` **pula** quando a issue já tem a label **`spec-wave:decomposed`** ou já tem sub-issues do tipo-alvo (`[STORY]` para Feature, `[TASK]` para RFC). Ao concluir com sucesso, o Action grava a label. Os workflows ainda usam `concurrency` por issue para serializar runs simultâneos.
|
|
225
252
|
|
|
226
|
-
**Para forçar um re-decompose
|
|
253
|
+
**Para forçar um re-decompose**, adicione a label `spec-wave:force` junto com o gatilho:
|
|
254
|
+
```bash
|
|
255
|
+
gh issue edit <n> --add-label "spec-wave:force" --add-label "spec-wave:decompose"
|
|
256
|
+
```
|
|
257
|
+
O comando então: (1) ignora os dois guards; (2) **fecha** as sub-issues abertas do tipo-alvo da decomposição anterior **e os filhos delas** (as Tasks de cada Story), comentando na issue o que foi fechado; (3) gera a nova decomposição. **É destrutivo** — se alguma Story já tiver saído de ✅ Ready, o comentário destaca quais, para você conferir se descartou trabalho em andamento. Confirme com o usuário antes de acionar em Features com desenvolvimento em curso.
|
|
227
258
|
|
|
228
259
|
### Dependências entre Stories (`Depende de: #N`)
|
|
229
260
|
|
|
@@ -253,6 +284,25 @@ Cada ação de IA (`spec`, `plan`, `decompose`, `critique`) pode usar um modelo
|
|
|
253
284
|
|
|
254
285
|
Edite o bloco `ai` no `.spec-wave.json` (e commite) — o `doctor` mostra o provider, o modelo e os overrides de `ai.models` resolvidos.
|
|
255
286
|
|
|
287
|
+
### Teto de saída (`ai.maxTokens`) e truncamento
|
|
288
|
+
|
|
289
|
+
O teto de tokens de saída é **32.768** por padrão, ajustável globalmente por `ai.maxTokens` e por ação em `ai.maxTokensByAction` (mesma forma de `model`/`models`; `SPEC_WAVE_MAX_TOKENS` na env tem precedência):
|
|
290
|
+
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"ai": {
|
|
294
|
+
"maxTokens": 32768,
|
|
295
|
+
"maxTokensByAction": { "spec": 49152 }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Quando a saída não cabe no teto, a geração FALHA — nada é gravado.** Os dois provedores sinalizam o corte (`finish_reason: "length"` no OpenRouter, `stop_reason: "max_tokens"` na Anthropic) e a CLI transforma isso em erro: um documento cortado no meio de uma frase passaria na validação de seções e valeria menos que documento nenhum. O erro é comentado na issue e a label de gatilho é removida, então basta corrigir e re-aplicar a label.
|
|
301
|
+
|
|
302
|
+
Se acontecer, as saídas são: **aumentar o teto** (`ai.maxTokens`) ou **reduzir o tamanho da issue de origem** — corpo muito grande gera documento muito grande. Modelos com raciocínio (Opus 4.7+, deepseek-r1) gastam parte do teto "pensando" antes de escrever, então o teto precisa cobrir raciocínio + documento.
|
|
303
|
+
|
|
304
|
+
O `validate` também recusa documento com sinal objetivo de corte (bloco de código não fechado, parêntese aberto na última linha) — rede de segurança para documento editado à mão ou gerado por versão antiga da CLI.
|
|
305
|
+
|
|
256
306
|
---
|
|
257
307
|
|
|
258
308
|
## Sub-comandos
|
|
@@ -314,7 +364,7 @@ Configura o spec-wave no repositório. Você dirige o `init` com flags — **nun
|
|
|
314
364
|
|
|
315
365
|
### `/spec-wave issue <tipo> <descrição>` · `/spec-wave initiative <descrição>` · `/spec-wave feature <descrição>`
|
|
316
366
|
|
|
317
|
-
Crie um work item tipado (Initiative/Epic/Feature/Story/Task/...) já adicionado ao board
|
|
367
|
+
Crie um work item tipado (Initiative/Epic/Feature/Story/Task/...) já adicionado ao board, opcionalmente como sub-issue de um parent. A Etapa inicial é **📥 Backlog** — correta para Initiative, Epic, Feature, RFC, Bug e Spike. **Story e Task não devem ser criadas por aqui** (nascem do `decompose`, em ✅ Ready — veja a *Regra fundamental*).
|
|
318
368
|
|
|
319
369
|
**Hierarquia típica:** Initiative → Epic → Feature → Story → Task. A **Initiative** é o nó raiz e agrupa Epics. Use `--parent <n>` para criar como sub-issue do nível acima (ex.: um Epic filho de uma Initiative, ou uma Story filha de uma Feature). O GitHub mostra o parent na issue filha e vice-versa; a CLI ainda grava `Parent: #N` no corpo.
|
|
320
370
|
|
|
@@ -334,6 +384,7 @@ Crie um work item tipado (Initiative/Epic/Feature/Story/Task/...) já adicionado
|
|
|
334
384
|
```
|
|
335
385
|
Para Features, pode usar o atalho `npx @spec-wave/cli@latest feature --title ...` (equivale a `--type feature`).
|
|
336
386
|
A CLI cria a issue (label de tipo — e de prioridade **apenas se `--priority` for informado**), vincula como sub-issue do parent, adiciona ao Project e define Etapa = 📥 Backlog + Work Item Type + Area (+ Priority só se informada). **Não use `gh issue create`** (não adiciona ao board nem vincula o parent).
|
|
387
|
+
**Se o tipo for `story` ou `task`**, avise o usuário que o caminho normal é o `decompose` e, se ele confirmar mesmo assim, avance a Etapa para ✅ Ready depois de criar — senão o item fica invisível na UI.
|
|
337
388
|
3. Informe o número criado e o vínculo com o pai (se houver).
|
|
338
389
|
4. Para Features: "Quando quiser iniciar, mova para **📋 Spec** e use `/spec-wave spec <número>` para gerar a especificação funcional (o plano técnico vem depois)".
|
|
339
390
|
|
|
@@ -365,7 +416,8 @@ Inicia a geração da **especificação funcional** para uma Feature. É o **pri
|
|
|
365
416
|
```
|
|
366
417
|
3. Informe: "Label `spec-wave:spec` adicionada. O GitHub Action `generate-spec.yml` irá gerar o `spec.md` automaticamente."
|
|
367
418
|
4. Após a conclusão, ofereça revisar o spec.md gerado em `docs/features/<slug>/spec.md`.
|
|
368
|
-
5.
|
|
419
|
+
5. **Para regerar** (a spec já existe e o usuário quer outra versão): basta re-adicionar a label — o Action sobrescreve o arquivo. A label `spec-wave:force` é aceita, mas aqui não muda nada; **avise que o spec.md atual será perdido** (inclusive edições manuais) e confirme antes.
|
|
420
|
+
6. Próximo passo: gerar o plano técnico — mova para **📋 Plan** e use `/spec-wave plan <número>`.
|
|
369
421
|
|
|
370
422
|
---
|
|
371
423
|
|
|
@@ -384,7 +436,8 @@ O plano técnico segue o schema do RFC-002 §3.2: **Estratégia Técnica** (com
|
|
|
384
436
|
```
|
|
385
437
|
4. Informe: "Label `spec-wave:plan` adicionada. O GitHub Action `generate-plan.yml` irá gerar o `plan.md` automaticamente. Acompanhe em: Actions → Generate Plan."
|
|
386
438
|
5. Após a conclusão (cheque comentários na issue ou aguarde confirmação do usuário), ofereça revisar o plan.md gerado em `docs/features/<slug>/plan.md`.
|
|
387
|
-
6.
|
|
439
|
+
6. **Para regerar**: re-adicione a label — o Action sobrescreve o `plan.md` (mesma ressalva do spec: edições manuais se perdem, confirme antes).
|
|
440
|
+
7. Próximo passo: validar a Feature — mova para **✅ Ready** e use `/spec-wave ready <número>`.
|
|
388
441
|
|
|
389
442
|
---
|
|
390
443
|
|
|
@@ -476,7 +529,7 @@ Para qualquer outro tipo (Spike, Bug, Story, Task, …) o Action **recusa** e co
|
|
|
476
529
|
```
|
|
477
530
|
3. Informe: "Decomposição iniciada — Feature gera Stories+Tasks; RFC gera Tasks."
|
|
478
531
|
4. Após a conclusão, as issues filhas aparecerão como comentário na issue pai, junto com o comentário 🔎 da crítica adversarial. A issue pai e as Stories/Tasks criadas entram no board na Etapa **✅ Ready** (Status Todo; a Etapa nunca retrocede — itens já adiante não são tocados). As Stories geradas trazem a linha `Depende de: #N` (+ relação *blocked by*) — use `npx @spec-wave/cli@latest order <número>` para ver a ordem de execução.
|
|
479
|
-
5. A issue recebe a label `spec-wave:decomposed` (guard de idempotência): rodar de novo **não** duplica as issues. Para
|
|
532
|
+
5. A issue recebe a label `spec-wave:decomposed` (guard de idempotência): rodar de novo **não** duplica as issues. Para re-decompor, adicione `spec-wave:force` junto com o gatilho — isso **fecha** a decomposição anterior antes de gerar a nova (veja *Guard de idempotência*; confirme com o usuário, é destrutivo).
|
|
480
533
|
|
|
481
534
|
---
|
|
482
535
|
|