@spec-wave/cli 0.24.0 → 0.26.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.
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: spec-wave-run
3
+ description: "Use para conduzir o fluxo do spec-wave LOCALMENTE, sem gastar minutos de GitHub Actions: `spec-wave run <issue>` executa nesta máquina o passo que a label dispararia (spec, plan, crítica, validate, decompose, apply) e `spec-wave mode local|actions` alterna entre os dois mundos. Gatilhos: 'rodar o spec-wave local', 'qual o próximo passo da issue 12', 'sem gastar Actions', 'desligar os workflows', 'trocar para execução local'."
4
+ allowed-tools:
5
+ - Bash(npx @spec-wave/cli@latest *)
6
+ - Bash(gh issue view *)
7
+ - Read
8
+ ---
9
+
10
+ # spec-wave run — o fluxo inteiro na sua máquina
11
+
12
+ Os workflows do spec-wave nunca fizeram o trabalho: eles instalam a CLI e chamam um comando. O `run` é o mesmo comando, disparado **daqui** — e o `mode` desarma os workflows para o gatilho não acontecer duas vezes.
13
+
14
+ ```bash
15
+ npx @spec-wave/cli@latest mode local # desarma os workflows (0 minutos de Actions)
16
+ npx @spec-wave/cli@latest run <issue> # executa o próximo passo pendente
17
+ npx @spec-wave/cli@latest mode actions # volta tudo para o CI
18
+ ```
19
+
20
+ **Contexto:** leia `.spec-wave.json` (Read). Ausente → skill **setup**. O campo `execution.mode` diz em qual mundo o repositório está.
21
+
22
+ ## Como decidir o que fazer
23
+
24
+ 1. **Sempre comece pelo `--dry-run`.** Ele consulta a issue, olha os documentos e explica o passo sem executar nada nem chamar IA:
25
+ ```bash
26
+ npx @spec-wave/cli@latest run <issue> --dry-run
27
+ ```
28
+ 2. Mostre ao usuário o passo, o motivo e o comando que rodaria. **Só então** execute sem a flag.
29
+ 3. `--json` devolve a decisão em JSON, quando você precisar ramificar programaticamente. É **um** documento: o desfecho no topo (`action`, `command`, `blocked`) e a sequência inteira em `steps` — útil com `--max-steps`.
30
+
31
+ ## O que o `run` decide sozinho
32
+
33
+ | Estado da issue | Passo |
34
+ |---|---|
35
+ | Feature sem `spec.md` | `generate-spec` |
36
+ | spec pronta, sem `plan.md` | `generate-plan` (a crítica roda embutida) |
37
+ | spec+plan sem `spec-wave:plan-approved` | `validate` |
38
+ | validada, sem `decomposition.md` | `decompose` (rascunho) |
39
+ | `spec-wave:decompose-ready` | `decompose-apply` — **exige `--apply`** |
40
+ | `spec-wave:decomposed` | nada: sugere a skill **implement** |
41
+ | Bug sem `bug.md` → com `bug.md` → validado | `generate-bug` → `validate` → `triage` (humano) |
42
+ | RFC | `decompose` → `decompose-apply` |
43
+
44
+ Para PRs: `run --pr <n>` roda `code-review` e, se houver review aprovada, também `qa` — a mesma coisa que os workflows fariam nos eventos do PR.
45
+
46
+ ## Portões (quando ele se recusa a rodar)
47
+
48
+ O comando **explica e para**, saindo com código 2. Não force sem entender:
49
+
50
+ - **`trigger-pending`** — há label de gatilho na issue: um Action está em voo (ou falhou deixando-a). Rodar por cima duplicaria documento e comentário. `--force` fura, quando você tem certeza.
51
+ - **`needs-human` / `critique-failed`** — portões humanos da crítica. O caminho é corrigir o documento e remover a label; para o `critique-failed` o passo de retomada é **re-criticar**, nunca regerar.
52
+ - **`stale-checkout`** — o documento existe no repositório e não no seu clone. `git pull` e repita; seguir sobrescreveria o que já foi publicado.
53
+ - **`needs-confirmation`** — o passo cria issues (`decompose-apply`) ou gasta IA repetindo a crítica de um rascunho existente. Revise antes e confirme com `--apply` / `--yes`.
54
+ - **`inconsistent-state`** — as labels afirmam um documento que não existe. Quase sempre o título da issue mudou depois de gerar (o slug vira outro diretório).
55
+
56
+ ## Regras que o `run` respeita — e você também
57
+
58
+ - **Nunca aplique label de gatilho no modo local.** Ela dispararia o Action e o passo aconteceria duas vezes. O `run` não aplica nenhuma.
59
+ - **Um passo por invocação.** `--max-steps <n>` encadeia, mas cada passo de IA custa dinheiro — encadeie só quando o usuário pedir.
60
+ - A **Regra fundamental** continua valendo: nunca escreva `spec.md`/`plan.md`/`decomposition.md` à mão. Quem gera é a CLI, aqui como no Action.
61
+
62
+ ## `mode` — o interruptor
63
+
64
+ ```bash
65
+ npx @spec-wave/cli@latest mode # estado atual
66
+ npx @spec-wave/cli@latest mode local # config + variável SPEC_WAVE_EXECUTION
67
+ npx @spec-wave/cli@latest mode actions # remove a variável
68
+ ```
69
+
70
+ Ele escreve os **dois** lados: o `.spec-wave.json` (que a CLI e as skills leem) e a variável de repositório que o `if:` de cada job avalia. Com ela setada, o run do workflow aparece como *skipped* — job que não roda não é faturado.
71
+
72
+ - A variável exige **admin** no repositório. Sem permissão o comando grava o config, avisa e aponta Settings → Secrets and variables → Actions → Variables.
73
+ - **Commite o `.spec-wave.json`**: quem clona o repo (inclusive o dev-agent) lê a versão versionada.
74
+ - Se os workflows instalados forem anteriores à guarda, o comando avisa e o conserto é a skill **update**.
75
+
76
+ O `doctor` tem um check dedicado: config e variável em desacordo é problema, não detalhe — é o usuário achando que desligou o CI e continuando a pagar por ele.
@@ -20,7 +20,7 @@ allowed-tools:
20
20
 
21
21
  O modo é detectado pelo ambiente — fora do Actions, a CLI roda em modo local automaticamente. Os dois geram o arquivo, commitam, dão push, comentam na issue e removem a label de gatilho. **Pergunte ao usuário qual ele quer** se não estiver claro; na dúvida numa sessão interativa, prefira o local (o resultado aparece em segundos, em vez de exigir acompanhar o Action).
22
22
 
23
- > Local exige a chave de IA no seu ambiente (`OPENROUTER_API_KEY` ou `ANTHROPIC_API_KEY`) e um `.spec-wave.json` no repositório. O provider `anthropic` **só** funciona local no Action ele precisaria do Claude Code como subprocesso, que o runner não tem.
23
+ > Local exige a credencial de IA no seu ambiente (`OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY` ou o login do Claude Code, se o provider for `claude-oauth`) e um `.spec-wave.json` no repositório. Para conduzir o fluxo inteiro sem gastar minutos de Actions, veja a skill **run**.
24
24
 
25
25
  **Contexto:** leia `.spec-wave.json` (Read). Ausente → skill **setup**.
26
26
 
@@ -61,9 +61,32 @@ Exemplo de `.spec-wave.json`:
61
61
 
62
62
  ---
63
63
 
64
+ ## Modo de execução (Actions × local)
65
+
66
+ Leia `execution.mode` no `.spec-wave.json` **antes** de acionar qualquer passo do fluxo:
67
+
68
+ | `execution.mode` | Como acionar um passo | Custo |
69
+ |---|---|---|
70
+ | `actions` (default) | aplicar a label de gatilho (`spec-wave:spec`, `:plan`, …) | minutos de GitHub Actions |
71
+ | `local` | `npx @spec-wave/cli@latest run <issue>` | nenhum — roda nesta máquina |
72
+
73
+ **No modo `local`, NÃO aplique label de gatilho.** Os workflows estão desarmados por uma variável de repositório, mas a label continua sendo o contrato do outro modo — aplicá-la só polui a issue (e, se alguém religar o CI, dispara tarde).
74
+
75
+ ```bash
76
+ npx @spec-wave/cli@latest mode # estado atual dos dois lados do interruptor
77
+ npx @spec-wave/cli@latest mode local # desarma os workflows
78
+ npx @spec-wave/cli@latest run <issue> --dry-run # explica o próximo passo sem executar
79
+ npx @spec-wave/cli@latest run <issue> # executa
80
+ npx @spec-wave/cli@latest run --pr <n> # code-review (+ qa, se houver aprovação)
81
+ ```
82
+
83
+ O `run` decide o passo pelo estado da issue (documentos existentes + labels), respeita os portões humanos (`needs-human`, `critique-failed`), recusa rodar com uma label de gatilho pendente e **exige `--apply`** para o `decompose-apply`, que cria issues. Sempre mostre o `--dry-run` ao usuário antes de executar.
84
+
85
+ ---
86
+
64
87
  ## Regra fundamental
65
88
 
66
- **Nunca gere `spec.md` ou `plan.md` diretamente.** Sempre acione a label correspondente e deixe o GitHub Action gerar o arquivo. Isso garante que o arquivo seja commitado no repositório e referenciado na issue.
89
+ **Nunca gere `spec.md` ou `plan.md` diretamente.** Acione o passo — a label (modo actions) ou o `run` (modo local) — e deixe o spec-wave gerar o arquivo. Isso garante que o arquivo seja commitado no repositório e referenciado na issue.
67
90
 
68
91
  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
92
 
@@ -15,6 +15,10 @@ jobs:
15
15
  # de concurrency ao job seguinte: `concurrency` de workflow é avaliada no
16
16
  # trigger, quando ainda não se sabe qual issue o PR implementa.
17
17
  resolve:
18
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
19
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
20
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
21
+ if: vars.SPEC_WAVE_EXECUTION != 'local'
18
22
  runs-on: ubuntu-latest
19
23
  permissions:
20
24
  issues: read
@@ -40,7 +44,7 @@ jobs:
40
44
  move:
41
45
  needs: resolve
42
46
  # PR sem vínculo explícito não resolve Feature nenhuma — e não move nada.
43
- if: needs.resolve.outputs.feature != ''
47
+ if: vars.SPEC_WAVE_EXECUTION != 'local' && needs.resolve.outputs.feature != ''
44
48
  runs-on: ubuntu-latest
45
49
  # MESMO namespace do decompose.yml: um `decompose-apply` em curso na Feature
46
50
  # segura este job na fila em vez de disputar a subárvore com ele. Foi essa
@@ -24,7 +24,11 @@ concurrency:
24
24
 
25
25
  jobs:
26
26
  critique:
27
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
28
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
29
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
27
30
  if: >
31
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
28
32
  github.event.label.name == 'spec-wave:critique' &&
29
33
  contains(github.event.issue.title, '[FEATURE]')
30
34
  runs-on: ubuntu-latest
@@ -44,7 +44,11 @@ jobs:
44
44
  # • spec-wave:decompose-apply → cria as Stories/Tasks a partir do rascunho
45
45
  # O `[RFC]` no título também dispara: o caminho RFC → Tasks existe na CLI
46
46
  # desde sempre, mas era inalcançável porque o filtro exigia `[FEATURE]`.
47
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
48
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
49
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
47
50
  if: >
51
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
48
52
  (github.event.label.name == 'spec-wave:decompose' ||
49
53
  github.event.label.name == 'spec-wave:decompose-apply') &&
50
54
  (contains(github.event.issue.title, '[FEATURE]') ||
@@ -31,7 +31,11 @@ concurrency:
31
31
 
32
32
  jobs:
33
33
  generate-bug:
34
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
35
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
36
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
34
37
  if: >
38
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
35
39
  github.event.label.name == 'spec-wave:bug' &&
36
40
  contains(github.event.issue.title, '[BUG]')
37
41
  runs-on: ubuntu-latest
@@ -39,7 +39,11 @@ concurrency:
39
39
 
40
40
  jobs:
41
41
  generate-plan:
42
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
43
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
44
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
42
45
  if: >
46
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
43
47
  github.event.label.name == 'spec-wave:plan' &&
44
48
  contains(github.event.issue.title, '[FEATURE]')
45
49
  runs-on: ubuntu-latest
@@ -39,7 +39,11 @@ concurrency:
39
39
 
40
40
  jobs:
41
41
  generate-spec:
42
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
43
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
44
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
42
45
  if: >
46
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
43
47
  github.event.label.name == 'spec-wave:spec' &&
44
48
  contains(github.event.issue.title, '[FEATURE]')
45
49
  runs-on: ubuntu-latest
@@ -10,7 +10,12 @@ concurrency:
10
10
 
11
11
  jobs:
12
12
  qa:
13
- if: github.event.review.state == 'approved'
13
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
14
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
15
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
16
+ if: >
17
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
18
+ github.event.review.state == 'approved'
14
19
  runs-on: ubuntu-latest
15
20
  permissions:
16
21
  issues: write
@@ -24,7 +24,11 @@ concurrency:
24
24
 
25
25
  jobs:
26
26
  validate:
27
+ # Modo de execução: `spec-wave mode local` cria a variável de repositório
28
+ # SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
29
+ # skipped e job que não roda não é faturado. `mode actions` remove a variável.
27
30
  if: >
31
+ vars.SPEC_WAVE_EXECUTION != 'local' &&
28
32
  github.event.label.name == 'spec-wave:ready' &&
29
33
  (contains(github.event.issue.title, '[FEATURE]') ||
30
34
  contains(github.event.issue.title, '[BUG]'))