@spec-wave/cli 0.5.5 → 0.5.8
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 +390 -0
- package/bin/spec-wave.mjs +14 -0
- package/package.json +1 -1
- package/src/commands/code-review.mjs +4 -3
- package/src/commands/decompose.mjs +7 -4
- package/src/commands/init.mjs +1 -1
- package/src/commands/install-skill.mjs +292 -0
- package/src/commands/qa.mjs +4 -3
- package/src/templates/skill/SKILL.md +517 -0
- package/src/templates/workflows/code-review.yml +2 -1
- package/src/templates/workflows/decompose.yml +2 -1
- package/src/templates/workflows/generate-plan.yml +1 -1
- package/src/templates/workflows/generate-spec.yml +1 -1
- package/src/templates/workflows/qa.yml +2 -1
- package/src/templates/workflows/validate.yml +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# @spec-wave/cli
|
|
2
|
+
|
|
3
|
+
CLI e skill para implementar um fluxo **spec-driven** completo no GitHub — do backlog ao deploy — com GitHub Projects v2, labels de gatilho e GitHub Actions com IA.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Conceito
|
|
8
|
+
|
|
9
|
+
Spec Wave é um sistema de processo de desenvolvimento baseado em especificações. Cada Feature passa por um ciclo documentado antes de ser implementada:
|
|
10
|
+
|
|
11
|
+
1. **Spec funcional** gerada por IA a partir do título e descrição da issue
|
|
12
|
+
2. **Plano técnico** gerado por IA a partir da spec e do contexto tecnológico do repositório
|
|
13
|
+
3. **Validação automática** das seções obrigatórias
|
|
14
|
+
4. **Decomposição em Stories e Tasks** gerada por IA
|
|
15
|
+
5. **Automação do board** durante o ciclo de desenvolvimento (Code Review → QA → Done)
|
|
16
|
+
|
|
17
|
+
O resultado é um board Kanban no GitHub Projects v2 que avança automaticamente conforme o trabalho progride, com toda a documentação versionada no próprio repositório.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Fluxo Kanban
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
📥 Backlog
|
|
25
|
+
→ 🎯 Priorizado
|
|
26
|
+
→ 📋 Spec ← label spec-wave:spec → Action gera spec.md
|
|
27
|
+
→ 📋 Plan ← label spec-wave:plan → Action gera plan.md
|
|
28
|
+
→ ✅ Ready ← label spec-wave:ready → Action valida ambos
|
|
29
|
+
→ 📋 Backlog Técnico
|
|
30
|
+
→ 🚧 Desenvolvimento ← comando local: spec-wave implement <n>
|
|
31
|
+
→ 👀 Code Review ← PR aberto → Action move automaticamente
|
|
32
|
+
→ 🧪 QA ← PR aprovado → Action move automaticamente
|
|
33
|
+
→ 📋 Homologação
|
|
34
|
+
→ 🚀 Deploy
|
|
35
|
+
→ 🎉 Done
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Hierarquia de Work Items
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Initiative
|
|
44
|
+
└── Epic
|
|
45
|
+
└── Feature
|
|
46
|
+
├── Story
|
|
47
|
+
│ └── Task
|
|
48
|
+
└── Task
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Cada nível é uma GitHub Issue com prefixo no título (`[FEATURE]`, `[STORY]`, etc.) e vínculo de sub-issue nativo do GitHub.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Componentes
|
|
56
|
+
|
|
57
|
+
### CLI (`@spec-wave/cli`)
|
|
58
|
+
|
|
59
|
+
Ferramenta Node.js que configura e opera o fluxo via linha de comando.
|
|
60
|
+
|
|
61
|
+
| Comando | O que faz |
|
|
62
|
+
|---------|-----------|
|
|
63
|
+
| `init` | Cria o GitHub Project, labels, workflows e `.spec-wave.json` |
|
|
64
|
+
| `info` | Mostra o estado de configuração do repositório atual |
|
|
65
|
+
| `refresh` | Re-sincroniza o `.spec-wave.json` com o GitHub Project |
|
|
66
|
+
| `issue` | Cria qualquer work item (initiative/epic/feature/story/task/bug/spike/rfc) |
|
|
67
|
+
| `initiative` | Atalho para `issue --type initiative` |
|
|
68
|
+
| `feature` | Atalho para `issue --type feature` |
|
|
69
|
+
| `generate-spec` | Gera `spec.md` (usado pelo GitHub Action) |
|
|
70
|
+
| `generate-plan` | Gera `plan.md` (usado pelo GitHub Action) |
|
|
71
|
+
| `validate` | Valida spec.md e plan.md (usado pelo GitHub Action) |
|
|
72
|
+
| `decompose` | Decompõe Feature em Stories e Tasks (usado pelo GitHub Action) |
|
|
73
|
+
| `code-review` | Move Feature para Code Review ao abrir PR (usado pelo GitHub Action) |
|
|
74
|
+
| `qa` | Move Feature para QA ao aprovar PR (usado pelo GitHub Action) |
|
|
75
|
+
| `implement` | Aciona o spec-kit localmente para implementar uma Story ou Task |
|
|
76
|
+
| `uninstall` | Remove labels, workflows e `.spec-wave.json` |
|
|
77
|
+
|
|
78
|
+
### GitHub Actions (instalados pelo `init`)
|
|
79
|
+
|
|
80
|
+
| Workflow | Gatilho | Ação |
|
|
81
|
+
|----------|---------|------|
|
|
82
|
+
| `generate-spec.yml` | label `spec-wave:spec` | Gera `docs/features/<slug>/spec.md` via IA |
|
|
83
|
+
| `generate-plan.yml` | label `spec-wave:plan` | Gera `docs/features/<slug>/plan.md` via IA |
|
|
84
|
+
| `validate.yml` | label `spec-wave:ready` | Valida seções obrigatórias; adiciona `spec-wave:plan-approved` |
|
|
85
|
+
| `decompose.yml` | label `spec-wave:decompose` | Cria Stories e Tasks como sub-issues |
|
|
86
|
+
| `code-review.yml` | PR aberto/reaberto | Move Feature para `👀 Code Review` |
|
|
87
|
+
| `qa.yml` | PR aprovado | Move Feature para `🧪 QA` |
|
|
88
|
+
|
|
89
|
+
### Skill (`src/templates/skill/SKILL.md`)
|
|
90
|
+
|
|
91
|
+
Skill que guia o usuário pelo fluxo via comandos como `/spec-wave spec 42`, `/spec-wave plan 42`, `/spec-wave decompose 42`. A skill lê o `.spec-wave.json` local, detecta o estado atual e executa os comandos corretos sem abrir wizards interativos. Instale-a no seu agente com `install-skill` (ver abaixo).
|
|
92
|
+
|
|
93
|
+
### `.spec-wave.json`
|
|
94
|
+
|
|
95
|
+
Arquivo de configuração gerado pelo `init` na raiz do repositório. Armazena `owner/repo`, dados do GitHub Project (ID, URL, campos) e o provider de IA configurado. Todos os comandos leem este arquivo para operar sem precisar de flags adicionais.
|
|
96
|
+
|
|
97
|
+
### `tech_context.yml`
|
|
98
|
+
|
|
99
|
+
Arquivo em `.github/config/tech_context.yml` que descreve a stack tecnológica do sistema (backend, frontend, banco, infra, roles RBAC, schemas, serviços). O `generate-plan` usa este arquivo para embasar o plano técnico — sem ele, o plano fica genérico.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Pré-requisitos
|
|
104
|
+
|
|
105
|
+
- Node.js >= 20
|
|
106
|
+
- GitHub CLI (`gh`) autenticado com escopos `project`, `repo` e `workflow`:
|
|
107
|
+
```bash
|
|
108
|
+
gh auth refresh --scopes project,repo,workflow
|
|
109
|
+
```
|
|
110
|
+
- Secret no repositório: `ANTHROPIC_API_KEY` ou `OPENROUTER_API_KEY` (Settings → Secrets → Actions)
|
|
111
|
+
- Para repositórios em organizações: criar PAT com escopo `project` e adicionar como secret `GH_PROJECT_TOKEN`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Instalação da CLI
|
|
116
|
+
|
|
117
|
+
Não é necessário instalar globalmente — use `npx`:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx @spec-wave/cli --help
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Para instalar globalmente:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm install -g @spec-wave/cli
|
|
127
|
+
spec-wave --help
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Instalação da Skill
|
|
133
|
+
|
|
134
|
+
A skill permite usar o fluxo diretamente no seu agente via `/spec-wave`.
|
|
135
|
+
|
|
136
|
+
**1. Instale a skill com o comando `install-skill`:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Autodetecta o agente em uso e instala no local/formato correto
|
|
140
|
+
npx @spec-wave/cli install-skill
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
O comando suporta Claude Code, Cursor, opencode, Cline, Kilo Code, Antigravity e o
|
|
144
|
+
padrão genérico `AGENTS.md`. Por padrão instala no escopo do projeto (versionável
|
|
145
|
+
com o time); use `--global` para o escopo do usuário. Escolha alvos com
|
|
146
|
+
`--agent <nomes>` (ex.: `--agent claude,cursor`) ou `--all` para todos os
|
|
147
|
+
detectados. Use `--dry-run` para pré-visualizar sem gravar.
|
|
148
|
+
|
|
149
|
+
**2. Adicione ao `CLAUDE.md` (ou equivalente) do projeto:**
|
|
150
|
+
|
|
151
|
+
```markdown
|
|
152
|
+
# spec-wave skill
|
|
153
|
+
Trigger `/spec-wave` to invoke the spec-wave skill.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**3. Use no seu agente:**
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
/spec-wave setup
|
|
160
|
+
/spec-wave spec 42
|
|
161
|
+
/spec-wave plan 42
|
|
162
|
+
/spec-wave ready 42
|
|
163
|
+
/spec-wave decompose 42
|
|
164
|
+
/spec-wave implement 45
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Exemplo de uso — do início ao fim
|
|
170
|
+
|
|
171
|
+
### Contexto
|
|
172
|
+
|
|
173
|
+
Equipe quer implementar uma feature de "Checkout com PIX" em um repositório `acme/loja`.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### 1. Configurar o repositório
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Verificar autenticação
|
|
181
|
+
gh auth status
|
|
182
|
+
|
|
183
|
+
# Se faltarem escopos:
|
|
184
|
+
gh auth refresh --scopes project,repo,workflow
|
|
185
|
+
|
|
186
|
+
# Configurar spec-wave (cria Project, labels e workflows)
|
|
187
|
+
npx @spec-wave/cli init --repo acme/loja --project-title "Loja — Spec Wave"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
O `init` cria:
|
|
191
|
+
- GitHub Project v2 com 12 colunas Kanban e campos personalizados (Work Item Type, Priority, Story Points, Area)
|
|
192
|
+
- 20+ labels de tipo, prioridade e gatilho
|
|
193
|
+
- 6 GitHub Actions workflows em `.github/workflows/`
|
|
194
|
+
- `.spec-wave.json` com os IDs do Project
|
|
195
|
+
|
|
196
|
+
Adicionar o secret de IA no GitHub: **Settings → Secrets → Actions → `ANTHROPIC_API_KEY`**.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### 2. Criar a hierarquia de issues
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Criar Epic
|
|
204
|
+
npx @spec-wave/cli issue \
|
|
205
|
+
--type epic \
|
|
206
|
+
--title "Checkout e Pagamentos" \
|
|
207
|
+
--priority P1 \
|
|
208
|
+
--area Backend
|
|
209
|
+
# → Issue #5 criada: [EPIC] Checkout e Pagamentos
|
|
210
|
+
|
|
211
|
+
# Criar Feature como sub-issue do Epic
|
|
212
|
+
npx @spec-wave/cli feature \
|
|
213
|
+
--title "Checkout com PIX" \
|
|
214
|
+
--parent 5 \
|
|
215
|
+
--priority P1 \
|
|
216
|
+
--area Backend
|
|
217
|
+
# → Issue #12 criada: [FEATURE] Checkout com PIX (sub-issue de #5)
|
|
218
|
+
# → Adicionada ao board em 📥 Backlog
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
### 3. Gerar a especificação funcional
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
gh issue edit 12 --add-label "spec-wave:spec"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
O GitHub Action `generate-spec.yml` dispara, chama a IA e faz commit de:
|
|
230
|
+
```
|
|
231
|
+
docs/features/checkout-com-pix/spec.md
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
A issue #12 recebe um comentário com o link para o arquivo.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### 4. Gerar o plano técnico
|
|
239
|
+
|
|
240
|
+
Antes de gerar o plano, garanta que `.github/config/tech_context.yml` existe e reflete a stack real. O `init` cria um scaffold — edite-o:
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
system_info:
|
|
244
|
+
name: "Loja ACME"
|
|
245
|
+
stack:
|
|
246
|
+
backend: "Node.js (NestJS v11)"
|
|
247
|
+
frontend: "Next.js 16"
|
|
248
|
+
database: "PostgreSQL (Prisma 5)"
|
|
249
|
+
infra: "Docker / AWS ECS"
|
|
250
|
+
security:
|
|
251
|
+
auth_protocol: "JWT"
|
|
252
|
+
rbac_roles: ["ADMIN", "CUSTOMER"]
|
|
253
|
+
database_schemas:
|
|
254
|
+
- table: "orders"
|
|
255
|
+
columns: "id, customer_id, status, total, created_at"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
git add .github/config/tech_context.yml
|
|
260
|
+
git commit -m "chore: tech_context.yml"
|
|
261
|
+
git push
|
|
262
|
+
|
|
263
|
+
# Acionar geração do plano
|
|
264
|
+
gh issue edit 12 --add-label "spec-wave:plan"
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
O Action gera `docs/features/checkout-com-pix/plan.md` com:
|
|
268
|
+
- Estratégia Técnica e Matriz de Rastreabilidade
|
|
269
|
+
- Detalhamento da Implementação
|
|
270
|
+
- Segurança e Conformidade
|
|
271
|
+
- Estratégia de Testes
|
|
272
|
+
- Rollback e Monitoramento
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
### 5. Validar spec e plan
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
gh issue edit 12 --add-label "spec-wave:ready"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
O Action `validate.yml` verifica se todas as seções obrigatórias estão presentes em spec.md e plan.md. Se passar:
|
|
283
|
+
- Remove a label `spec-wave:ready`
|
|
284
|
+
- Adiciona a label `spec-wave:plan-approved`
|
|
285
|
+
- Comenta "Validação aprovada ✅" na issue
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### 6. Decompor em Stories e Tasks
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
gh issue edit 12 --add-label "spec-wave:decompose"
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
O Action `decompose.yml` usa IA para criar sub-issues da Feature #12:
|
|
296
|
+
|
|
297
|
+
```
|
|
298
|
+
#13 [STORY] Como cliente, quero selecionar PIX como forma de pagamento
|
|
299
|
+
#14 [TASK] Criar endpoint POST /orders/:id/payment/pix
|
|
300
|
+
#15 [TASK] Integrar API do banco via webhook
|
|
301
|
+
#16 [TASK] Exibir QR Code na tela de checkout
|
|
302
|
+
#17 [STORY] Como cliente, quero receber confirmação do pagamento
|
|
303
|
+
#18 [TASK] Webhook de confirmação do banco
|
|
304
|
+
#19 [TASK] Notificação por e-mail ao confirmar
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Todas as Stories e Tasks são adicionadas ao board em **📋 Backlog Técnico** com Status `Todo`.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### 7. Implementar
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Via skill no Claude Code:
|
|
315
|
+
/spec-wave implement 13
|
|
316
|
+
|
|
317
|
+
# Ou direto:
|
|
318
|
+
npx @spec-wave/cli implement 13 --dry-run # ver contexto antes
|
|
319
|
+
npx @spec-wave/cli implement 13 # executar
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
O comando monta um arquivo de contexto com spec.md, plan.md e todas as Tasks da Story, e aciona o spec-kit configurado.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### 8. Code Review automático
|
|
327
|
+
|
|
328
|
+
Ao abrir um PR que referencia `Closes #14` (ou qualquer issue da hierarquia):
|
|
329
|
+
|
|
330
|
+
```markdown
|
|
331
|
+
## Descrição
|
|
332
|
+
Implementa endpoint PIX
|
|
333
|
+
|
|
334
|
+
Closes #14
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
O Action `code-review.yml` detecta a referência, sobe a hierarquia Task → Story → Feature, e move a Feature #12 para **👀 Code Review** no board.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
### 9. QA automático
|
|
342
|
+
|
|
343
|
+
Quando um reviewer aprova o PR, o Action `qa.yml` move a Feature #12 para **🧪 QA**.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### 10. Estado final no board
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
Feature #12: [FEATURE] Checkout com PIX
|
|
351
|
+
Etapa: 🧪 QA
|
|
352
|
+
Status: Todo
|
|
353
|
+
Work Item Type: Feature
|
|
354
|
+
Priority: P1
|
|
355
|
+
Area: Backend
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Após QA passar, mover manualmente para **📋 Homologação → 🚀 Deploy → 🎉 Done**.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Atualizar repositórios existentes
|
|
363
|
+
|
|
364
|
+
Quando uma nova versão da CLI for publicada, rode em cada repositório configurado:
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
npx @spec-wave/cli@latest init --skip-project --skip-labels
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Isso atualiza apenas os arquivos de workflow sem recriar o Project ou as labels.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Providers de IA
|
|
375
|
+
|
|
376
|
+
| Provider | Secret | Modelo padrão |
|
|
377
|
+
|----------|--------|---------------|
|
|
378
|
+
| Anthropic | `ANTHROPIC_API_KEY` | `claude-sonnet-4-6` |
|
|
379
|
+
| OpenRouter | `OPENROUTER_API_KEY` | `anthropic/claude-3.7-sonnet` |
|
|
380
|
+
|
|
381
|
+
Configurar no `init`:
|
|
382
|
+
```bash
|
|
383
|
+
npx @spec-wave/cli init --repo owner/repo --provider openrouter --model anthropic/claude-3.7-sonnet
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Licença
|
|
389
|
+
|
|
390
|
+
MIT
|
package/bin/spec-wave.mjs
CHANGED
|
@@ -86,6 +86,20 @@ program
|
|
|
86
86
|
await feature(options).catch(err => { console.error(err.message); process.exit(1); });
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
program
|
|
90
|
+
.command('install-skill')
|
|
91
|
+
.description('Instala a skill spec-wave no(s) agente(s) detectado(s): Claude Code, Cursor, opencode, Cline, Kilo, Antigravity, AGENTS.md')
|
|
92
|
+
.option('--agent <names>', 'Agente(s) alvo, separados por vírgula (pula a detecção)')
|
|
93
|
+
.option('--all', 'Instala em todos os agentes detectados')
|
|
94
|
+
.option('--global', 'Instala no escopo do usuário (padrão: projeto)')
|
|
95
|
+
.option('--dry-run', 'Mostra o que seria instalado sem gravar')
|
|
96
|
+
.option('--force', 'Sobrescreve arquivos existentes sem confirmar')
|
|
97
|
+
.option('--yes', 'Modo não-interativo')
|
|
98
|
+
.action(async (options) => {
|
|
99
|
+
const { installSkill } = await import('../src/commands/install-skill.mjs');
|
|
100
|
+
await installSkill(options).catch(err => { console.error(err.message); process.exit(1); });
|
|
101
|
+
});
|
|
102
|
+
|
|
89
103
|
program
|
|
90
104
|
.command('uninstall')
|
|
91
105
|
.description('Remove labels, arquivos .github e o .spec-wave.json (mantém o GitHub Project)')
|
package/package.json
CHANGED
|
@@ -69,6 +69,7 @@ async function setCodeReview(token, project, etapaField, statusField, nodeId) {
|
|
|
69
69
|
|
|
70
70
|
export async function codeReview({ prNumber }) {
|
|
71
71
|
const token = await resolveToken();
|
|
72
|
+
const projectToken = process.env.PROJECT_TOKEN || token;
|
|
72
73
|
const [envOwner, envRepo] = (process.env.GITHUB_REPOSITORY || '').split('/');
|
|
73
74
|
const cfgPath = path.join(process.cwd(), CONFIG_FILE);
|
|
74
75
|
let cfg = {};
|
|
@@ -110,8 +111,8 @@ export async function codeReview({ prNumber }) {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
// Resolve campos uma vez, reutiliza em todas as Features.
|
|
113
|
-
const etapaField = await resolveField(
|
|
114
|
-
const statusField = await resolveField(
|
|
114
|
+
const etapaField = await resolveField(projectToken, project, 'Etapa').catch(() => null);
|
|
115
|
+
const statusField = await resolveField(projectToken, project, 'Status').catch(() => null);
|
|
115
116
|
|
|
116
117
|
const seen = new Set();
|
|
117
118
|
const updated = [];
|
|
@@ -121,7 +122,7 @@ export async function codeReview({ prNumber }) {
|
|
|
121
122
|
if (!feature || seen.has(feature.number)) continue;
|
|
122
123
|
seen.add(feature.number);
|
|
123
124
|
try {
|
|
124
|
-
await setCodeReview(
|
|
125
|
+
await setCodeReview(projectToken, project, etapaField, statusField, feature.node_id);
|
|
125
126
|
updated.push(`#${feature.number} ${feature.title}`);
|
|
126
127
|
console.log(`Feature #${feature.number} → "${CODE_REVIEW_STAGE}" / Status "${TODO_STATUS}".`);
|
|
127
128
|
} catch (err) {
|
|
@@ -65,6 +65,9 @@ Regras:
|
|
|
65
65
|
|
|
66
66
|
export async function decompose({ issueNumber }) {
|
|
67
67
|
const token = await resolveToken();
|
|
68
|
+
// PROJECT_TOKEN deve ter scope "project" para atualizar GitHub Projects v2.
|
|
69
|
+
// Fallback para GITHUB_TOKEN (só funciona em repos pessoais sem org restrictions).
|
|
70
|
+
const projectToken = process.env.PROJECT_TOKEN || token;
|
|
68
71
|
const [owner, repo] = (process.env.GITHUB_REPOSITORY || '').split('/');
|
|
69
72
|
|
|
70
73
|
if (!owner || !repo) {
|
|
@@ -83,7 +86,7 @@ export async function decompose({ issueNumber }) {
|
|
|
83
86
|
let statusField = null;
|
|
84
87
|
if (project?.id && READY_STAGE) {
|
|
85
88
|
try {
|
|
86
|
-
statusField = await resolveStatusField(
|
|
89
|
+
statusField = await resolveStatusField(projectToken, project);
|
|
87
90
|
} catch (err) {
|
|
88
91
|
console.warn(`Não foi possível resolver campo Status do board: ${err.message}`);
|
|
89
92
|
}
|
|
@@ -144,7 +147,7 @@ export async function decompose({ issueNumber }) {
|
|
|
144
147
|
|
|
145
148
|
// Move story para Ready no board.
|
|
146
149
|
try {
|
|
147
|
-
await moveToStage(
|
|
150
|
+
await moveToStage(projectToken, project, statusField, createdStory.nodeId, READY_STAGE);
|
|
148
151
|
} catch (err) {
|
|
149
152
|
console.warn(` Falha ao mover story #${createdStory.number} para "${READY_STAGE}": ${err.message}`);
|
|
150
153
|
}
|
|
@@ -164,7 +167,7 @@ export async function decompose({ issueNumber }) {
|
|
|
164
167
|
|
|
165
168
|
// Move task para Ready no board.
|
|
166
169
|
try {
|
|
167
|
-
await moveToStage(
|
|
170
|
+
await moveToStage(projectToken, project, statusField, createdTask.nodeId, READY_STAGE);
|
|
168
171
|
} catch (err) {
|
|
169
172
|
console.warn(` Falha ao mover task #${createdTask.number} para "${READY_STAGE}": ${err.message}`);
|
|
170
173
|
}
|
|
@@ -173,7 +176,7 @@ export async function decompose({ issueNumber }) {
|
|
|
173
176
|
|
|
174
177
|
// Move a própria Feature para Ready no board.
|
|
175
178
|
try {
|
|
176
|
-
await moveToStage(
|
|
179
|
+
await moveToStage(projectToken, project, statusField, featureNodeId, READY_STAGE);
|
|
177
180
|
if (project?.id && statusField) console.log(`Feature movida para "${READY_STAGE}" no board.`);
|
|
178
181
|
} catch (err) {
|
|
179
182
|
console.warn(`Falha ao mover Feature para "${READY_STAGE}": ${err.message}`);
|
package/src/commands/init.mjs
CHANGED
|
@@ -218,6 +218,6 @@ export async function init(options) {
|
|
|
218
218
|
` 2. Configure o board view para agrupar por "Etapa"\n` +
|
|
219
219
|
` 3. Crie uma Feature com o prefixo [FEATURE] no título\n` +
|
|
220
220
|
` 4. Use a skill spec-wave para guiar o fluxo\n\n` +
|
|
221
|
-
` ${chalk.dim('Para
|
|
221
|
+
` ${chalk.dim('Para instalar a skill no seu agente: npx @spec-wave/cli install-skill')}`
|
|
222
222
|
);
|
|
223
223
|
}
|