spec-first-copilot 0.6.0-beta.9 → 0.7.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/README.md +252 -167
- package/bin/cli.js +70 -70
- package/lib/init.js +92 -92
- package/lib/update.js +132 -132
- package/package.json +1 -1
- package/templates/.ai/memory/napkin.md +68 -68
- package/templates/.github/CHANGELOG.md +121 -0
- package/templates/.github/adapters/SETUP.md +314 -314
- package/templates/.github/adapters/confluence.md +295 -295
- package/templates/.github/adapters/errors.md +234 -234
- package/templates/.github/adapters/filesystem.md +353 -353
- package/templates/.github/adapters/interface.md +301 -301
- package/templates/.github/adapters/naming.md +241 -241
- package/templates/.github/adapters/registry.md +244 -244
- package/templates/.github/agents/backend-coder.md +14 -14
- package/templates/.github/agents/db-coder.md +165 -165
- package/templates/.github/agents/doc-writer.md +66 -53
- package/templates/.github/agents/frontend-coder.md +5 -5
- package/templates/.github/agents/infra-coder.md +341 -341
- package/templates/.github/agents/reviewer.md +6 -6
- package/templates/.github/agents/security-reviewer.md +153 -153
- package/templates/.github/copilot-instructions.md +272 -262
- package/templates/.github/instructions/docs.instructions.md +147 -145
- package/templates/.github/instructions/sensitive-files.instructions.md +32 -32
- package/templates/.github/rules.md +229 -229
- package/templates/.github/scripts/bootstrap-confluence.js +289 -223
- package/templates/.github/skills/sf-design/SKILL.md +161 -216
- package/templates/.github/skills/sf-dev/SKILL.md +204 -351
- package/templates/.github/skills/sf-discovery/SKILL.md +415 -414
- package/templates/.github/skills/sf-extract/SKILL.md +225 -249
- package/templates/.github/skills/sf-load/SKILL.md +296 -295
- package/templates/.github/skills/sf-mcp/SKILL.md +386 -385
- package/templates/.github/skills/sf-merge-docs/SKILL.md +152 -100
- package/templates/.github/skills/sf-plan/SKILL.md +152 -128
- package/templates/.github/skills/sf-publish/SKILL.md +144 -143
- package/templates/.github/skills/sf-session-finish/SKILL.md +93 -120
- package/templates/.github/skills/sf-start/SKILL.md +192 -145
- package/templates/.github/templates/estrutura/apiContracts.template.md +160 -159
- package/templates/.github/templates/estrutura/architecture.template.md +169 -168
- package/templates/.github/templates/estrutura/conventions.template.md +214 -212
- package/templates/.github/templates/estrutura/decisions.template.md +107 -107
- package/templates/.github/templates/estrutura/domain.template.md +161 -160
- package/templates/.github/templates/feature/PRD.template.md +279 -286
- package/templates/.github/templates/feature/Progresso.template.md +141 -141
- package/templates/.github/templates/feature/TRD.template.md +358 -0
- package/templates/.github/templates/feature/context.template.md +89 -48
- package/templates/.github/templates/feature/extract-log.template.md +49 -39
- package/templates/.github/templates/feature/projetos.template.yaml +79 -79
- package/templates/.github/templates/global/progresso_global.template.md +59 -57
- package/templates/.github/templates/specs/brief.template.md +66 -59
- package/templates/.github/templates/specs/contracts.template.md +147 -141
- package/templates/.github/templates/specs/scenarios.template.md +125 -117
- package/templates/.github/templates/specs/tasks.template.md +65 -63
- package/templates/_gitignore +35 -35
- package/templates/sfw.config.yml.example +147 -147
- package/templates/.github/templates/feature/backlog-extraido.template.md +0 -156
- package/templates/.github/templates/feature/sdd.template.md +0 -559
package/README.md
CHANGED
|
@@ -1,167 +1,252 @@
|
|
|
1
|
-
# spec-first-copilot
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
1
|
+
# spec-first-copilot
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/spec-first-copilot)
|
|
4
|
+
[](https://github.com/gustavomaritan-labs/spec-first-workflow/blob/main/LICENSE)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
|
|
7
|
+
Kit completo de desenvolvimento **spec-first** para [GitHub Copilot](https://github.com/features/copilot).
|
|
8
|
+
Pipeline disciplinado do insumo bruto ao código — com checkpoints humanos,
|
|
9
|
+
agents especializados por área, security review e rastreabilidade ponta a ponta.
|
|
10
|
+
|
|
11
|
+
> **v0.7.0 (estável)** — TRD ressuscitado como peer do PRD, aprovação por persona,
|
|
12
|
+
> SDD eliminado. Ver [CHANGELOG](templates/.github/CHANGELOG.md) para detalhes da migração v3→v4.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Conteúdo
|
|
17
|
+
|
|
18
|
+
- [Pra quem é isso](#pra-quem-é-isso)
|
|
19
|
+
- [O que você ganha](#o-que-você-ganha)
|
|
20
|
+
- [Instalação](#instalação)
|
|
21
|
+
- [Estrutura gerada](#estrutura-gerada)
|
|
22
|
+
- [Pipeline passo a passo](#pipeline-passo-a-passo)
|
|
23
|
+
- [Skills disponíveis](#skills-disponíveis)
|
|
24
|
+
- [Agents especializados](#agents-especializados)
|
|
25
|
+
- [Backends plugáveis (adapters)](#backends-plugáveis-adapters)
|
|
26
|
+
- [Troubleshooting](#troubleshooting)
|
|
27
|
+
- [Links](#links)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Pra quem é isso
|
|
32
|
+
|
|
33
|
+
Você gerencia projetos onde PMs/POs entregam requisitos em formatos
|
|
34
|
+
heterogêneos (docs no Confluence, SQLs de modelagem, wireframes, notas
|
|
35
|
+
dispersas) e quer que o desenvolvimento assistido por IA siga um processo
|
|
36
|
+
previsível. Sem "a IA adivinhou" — com specs aprovadas antes de uma linha
|
|
37
|
+
de código.
|
|
38
|
+
|
|
39
|
+
**Use-cases cobertos**:
|
|
40
|
+
- Bootstrap de projeto novo (define stack + arquitetura + primeiras features)
|
|
41
|
+
- Features novas em projeto existente (merge aditivo em docs cross-feature)
|
|
42
|
+
- Bugs e tasks técnicas (mesmo pipeline, escopo menor)
|
|
43
|
+
- Times multi-dev (contratos firmes via `specs/` + `projetos.yaml`)
|
|
44
|
+
|
|
45
|
+
## O que você ganha
|
|
46
|
+
|
|
47
|
+
| Benefício | Como entrega |
|
|
48
|
+
|-----------|--------------|
|
|
49
|
+
| **Spec-first rígido** | Nenhum código sem PRD/TRD aprovados + `specs/` gerado |
|
|
50
|
+
| **Dois revisores, dois docs** | PM aprova PRD (produto), dev aprova TRD (técnico) |
|
|
51
|
+
| **Rastreabilidade total** | Cada RN, ADR, endpoint, task aponta pro insumo-fonte via hash SHA-256 |
|
|
52
|
+
| **Security by default** | Security Reviewer audita 6 categorias pós-dev (Auth, AuthZ, Injeção, PII, Headers, Banco) |
|
|
53
|
+
| **Backend-agnóstico** | Rode local (filesystem) ou sincronize com Confluence via MCP |
|
|
54
|
+
| **Multi-repo nativo** | `projetos.yaml` mapeia serviços → repos; cada repo com branch/PR próprio |
|
|
55
|
+
| **Entregáveis contínuos** | Features obrigatoriamente faseadas (P1/P2/P3) — nunca "tudo ou nada" |
|
|
56
|
+
| **Re-executável** | Toda skill pode rodar de novo; hashes detectam incremental |
|
|
57
|
+
|
|
58
|
+
## Instalação
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm i -g spec-first-copilot
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Pré-requisitos**: Node.js 18+, Git, [GitHub Copilot](https://github.com/features/copilot) com acesso a Copilot Chat.
|
|
65
|
+
|
|
66
|
+
**Windows (PowerShell)** — se o CLI não rodar por política de execução:
|
|
67
|
+
```powershell
|
|
68
|
+
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Primeiros passos
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# 1. Criar o projeto
|
|
75
|
+
spec-first-copilot init --name=MeuProjeto
|
|
76
|
+
cd MeuProjeto
|
|
77
|
+
|
|
78
|
+
# 2. Jogar insumos brutos (qualquer formato)
|
|
79
|
+
# em workspace/Input/<nome>/
|
|
80
|
+
# Ex: workspace/Input/app_barbearia/visao.md + modelo.sql + decisoes.md
|
|
81
|
+
|
|
82
|
+
# 3. Abrir com VS Code + Copilot Chat e iniciar o pipeline
|
|
83
|
+
# /sf-start app_barbearia
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Opções do CLI**:
|
|
87
|
+
|
|
88
|
+
| Opção | Descrição |
|
|
89
|
+
|-------|-----------|
|
|
90
|
+
| `--name` | Nome do projeto (obrigatório) |
|
|
91
|
+
| `--target` | Diretório destino (default: `./<name>`) |
|
|
92
|
+
|
|
93
|
+
## Estrutura gerada
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
MeuProjeto/
|
|
97
|
+
├── .ai/memory/napkin.md <- Memória persistente (curada continuamente)
|
|
98
|
+
├── .github/ <- AI OPERATIONAL CONFIG
|
|
99
|
+
│ ├── copilot-instructions.md <- Meta-regras pro agente
|
|
100
|
+
│ ├── rules.md <- Regras invioláveis + quality gate
|
|
101
|
+
│ ├── CHANGELOG.md <- Histórico do framework
|
|
102
|
+
│ ├── instructions/ <- Regras por contexto (docs, arquivos sensíveis)
|
|
103
|
+
│ ├── templates/ <- 17 templates do workflow
|
|
104
|
+
│ │ ├── feature/ <- PRD, TRD, context, extract-log, Progresso, projetos.yaml
|
|
105
|
+
│ │ ├── specs/ <- brief, contracts, scenarios, tasks (projeções pro coder)
|
|
106
|
+
│ │ ├── estrutura/ <- 5 docs cross-feature (architecture, domain, conventions, apiContracts, decisions)
|
|
107
|
+
│ │ └── global/ <- progresso_global
|
|
108
|
+
│ ├── adapters/ <- SourceAdapter interface + 2 implementations built-in
|
|
109
|
+
│ ├── skills/ <- 11 skills do workflow (ver tabela abaixo)
|
|
110
|
+
│ └── agents/ <- 7 perfis especializados (ver tabela abaixo)
|
|
111
|
+
├── docs/ <- SÍNTESE CROSS-FEATURE (atualizada pelo /sf-merge-docs)
|
|
112
|
+
│ ├── architecture.md <- Containers C4 + stack + ambientes + deploy
|
|
113
|
+
│ ├── domain.md <- Visão de negócio + modelo de dados consolidado
|
|
114
|
+
│ ├── conventions.md <- Auth, authz, LGPD, env vars, códigos de erro, monitoramento
|
|
115
|
+
│ ├── apiContracts.md <- Convenções de API + catálogo de endpoints
|
|
116
|
+
│ └── decisions.md <- ADRs (append-only)
|
|
117
|
+
├── specs/ <- AGENT CONTRACTS (projeções de PRD+TRD pro coder)
|
|
118
|
+
│ └── {scope}/
|
|
119
|
+
│ ├── brief.md <- Problema/Solução
|
|
120
|
+
│ ├── contracts.md <- Sistema + áreas tocadas (schema, endpoints, integrações, RNs)
|
|
121
|
+
│ ├── scenarios.md <- Jornadas + CAs + estratégia de testes
|
|
122
|
+
│ └── tasks.md <- Tabela única com coluna Área (gerado pelo /sf-plan)
|
|
123
|
+
├── workspace/ <- TEAM CONTENT
|
|
124
|
+
│ ├── Input/ <- Insumos brutos (QUALQUER formato — nunca modificar)
|
|
125
|
+
│ │ └── {scope}/ <- Nome livre (app_barbearia, feat_login, bug_checkout)
|
|
126
|
+
│ └── Output/ <- Docs narrativos pro humano
|
|
127
|
+
│ └── {scope}/
|
|
128
|
+
│ ├── PRD.md <- Requirements de produto (se insumos têm produto)
|
|
129
|
+
│ ├── TRD.md <- Requirements técnicos (se insumos têm técnica)
|
|
130
|
+
│ ├── Progresso.md <- Tracking de execução
|
|
131
|
+
│ └── .context.md <- Estado da pipeline (YAML)
|
|
132
|
+
├── projetos/ <- Repos de código (gitignored, cada um com .git)
|
|
133
|
+
├── projetos.yaml <- Manifesto de repos (gerado no first-run)
|
|
134
|
+
├── sfw.config.yml.example <- Manifesto de adapters (input/output)
|
|
135
|
+
└── .gitignore
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Três zonas, zero ambiguidade**:
|
|
139
|
+
- `.github/` + `.ai/` → config operacional + memória (time edita raro)
|
|
140
|
+
- `docs/` → síntese cross-feature (atualizada pelo `/sf-merge-docs`)
|
|
141
|
+
- `workspace/` → content compartilhável (Input = time, Output = workflow)
|
|
142
|
+
|
|
143
|
+
## Pipeline passo a passo
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
workspace/Input/<scope>/ (seus arquivos)
|
|
147
|
+
│
|
|
148
|
+
▼
|
|
149
|
+
/sf-start <scope> ──▶ /sf-load ──▶ /sf-discovery ──▶ /sf-extract
|
|
150
|
+
│
|
|
151
|
+
▼
|
|
152
|
+
PRD + TRD gerados
|
|
153
|
+
│
|
|
154
|
+
┌──────── CHECKPOINT DUPLO ────────┐
|
|
155
|
+
│ PM aprova PRD | dev aprova TRD │
|
|
156
|
+
└──────────────────────────────────┘
|
|
157
|
+
│
|
|
158
|
+
▼
|
|
159
|
+
/sf-design ──▶ specs/ (sempre)
|
|
160
|
+
docs/ + projetos.yaml (first-run)
|
|
161
|
+
│
|
|
162
|
+
▼
|
|
163
|
+
/sf-plan ──▶ tasks.md + Progresso.md
|
|
164
|
+
│
|
|
165
|
+
▼
|
|
166
|
+
/sf-dev ──▶ código nos repos
|
|
167
|
+
+ Security Review
|
|
168
|
+
+ /sf-merge-docs automático
|
|
169
|
+
(diff PRD+TRD ↔ docs/)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Mesmo comando pra bootstrap e feature — `first_run` é derivado da
|
|
173
|
+
ausência/presença de `docs/`.
|
|
174
|
+
|
|
175
|
+
**Apresentação visual**: abra
|
|
176
|
+
[`apresentacao.html`](https://github.com/gustavomaritan-labs/spec-first-workflow/blob/main/packages/apresentacao.html)
|
|
177
|
+
pra ver o fluxo completo com personas, artefatos e adapters.
|
|
178
|
+
|
|
179
|
+
## Skills disponíveis
|
|
180
|
+
|
|
181
|
+
| Skill | Tipo | Função |
|
|
182
|
+
|-------|------|--------|
|
|
183
|
+
| `/sf-mcp <provider>` | Setup | Configura backend externo (Confluence). Cria `.mcp.json` + `sfw.config.yml` |
|
|
184
|
+
| `/sf-load <scope>` | Utilitária | Puxa Input do backend (incremental via hash) |
|
|
185
|
+
| `/sf-publish <scope> <tipo>` | Utilitária | Publica PRD/TRD/Progresso nos targets. Auto-chamada por extract/plan |
|
|
186
|
+
| `/sf-start <scope>` | Orquestrador | Entrada única. Cria `.context.md`, chama `/sf-load` + `/sf-discovery` + `/sf-extract` |
|
|
187
|
+
| `/sf-discovery <path>` | Atômica | Análise profunda prévia dos insumos (obrigatório em v4) |
|
|
188
|
+
| `/sf-extract <scope>` | Atômica | Gera PRD e/ou TRD conforme conteúdo dos insumos |
|
|
189
|
+
| `/sf-design <scope>` | Atômica | PRD+TRD aprovados → `specs/`. First-run também cria `docs/` + `projetos.yaml` |
|
|
190
|
+
| `/sf-plan <scope>` | Atômica | Lê PRD + TRD + specs/ → tasks por área + Progresso.md |
|
|
191
|
+
| `/sf-dev <scope>` | Atômica | Implementa tasks com loop (implement → test → review). Merge-docs automático no fim |
|
|
192
|
+
| `/sf-merge-docs <scope>` | Atômica | Diff semântico PRD+TRD ↔ docs/ → atualiza síntese cross-feature |
|
|
193
|
+
| `/sf-session-finish` | Utilitária | Encerra sessão: salva estado, atualiza napkin, gera retomada.md |
|
|
194
|
+
|
|
195
|
+
## Agents especializados
|
|
196
|
+
|
|
197
|
+
| Agent | Área | Stack padrão | Modelo |
|
|
198
|
+
|-------|------|--------------|--------|
|
|
199
|
+
| Backend Coder | BACK | .NET 8 / C# (editável) | Sonnet (S/M) · Opus (L) |
|
|
200
|
+
| Frontend Coder | FRONT | React + Fusion (editável) | Sonnet (S/M) · Opus (L) |
|
|
201
|
+
| DB Coder | DB | PostgreSQL 16 (editável) | Sonnet (S/M) · Opus (L) |
|
|
202
|
+
| Infra Coder | INFRA | Docker | Sonnet (S/M) · Opus (L) |
|
|
203
|
+
| Doc Writer | DOC | — | Sonnet |
|
|
204
|
+
| Reviewer | Todas | — (quality gate) | Sonnet |
|
|
205
|
+
| Security Reviewer | Todas | — (gate pós-dev) | Opus |
|
|
206
|
+
|
|
207
|
+
Perfis em `.github/agents/` — editáveis pelo time pra ajustar stack
|
|
208
|
+
específica do projeto (ex: Node.js em vez de .NET, Angular em vez de React).
|
|
209
|
+
|
|
210
|
+
## Backends plugáveis (adapters)
|
|
211
|
+
|
|
212
|
+
Arquitetura de **adapter layer** via `sfw.config.yml`. Skills não conhecem
|
|
213
|
+
Confluence ou filesystem — chamam uma interface padrão. Novos backends
|
|
214
|
+
entram como plugins sem tocar o pipeline.
|
|
215
|
+
|
|
216
|
+
**Built-in**:
|
|
217
|
+
- **`FilesystemAdapter`** — zero dependência externa. Ideal pra times
|
|
218
|
+
offline, testes automatizados (mock natural), ou diretório compartilhado.
|
|
219
|
+
- **`ConfluenceAdapter`** — via MCP Atlassian. Conflict detection client-side.
|
|
220
|
+
PM edita Input no Confluence, agent auto-publica Output (PRD/TRD/Progresso)
|
|
221
|
+
após cada skill.
|
|
222
|
+
|
|
223
|
+
**Roadmap**: `NotionAdapter`, `JIRAAdapter`, `SharePointAdapter`,
|
|
224
|
+
`GitHubIssuesAdapter` (formalizados quando surgir 3º caso real).
|
|
225
|
+
|
|
226
|
+
Setup do Confluence:
|
|
227
|
+
```
|
|
228
|
+
/sf-mcp confluence
|
|
229
|
+
```
|
|
230
|
+
Guia o setup interativo (space key, parent IDs, credenciais gitignored).
|
|
231
|
+
|
|
232
|
+
## Troubleshooting
|
|
233
|
+
|
|
234
|
+
| Problema | Solução |
|
|
235
|
+
|----------|---------|
|
|
236
|
+
| `/sf-start` reclama que pasta Input está vazia | Verifique que há pelo menos 1 arquivo em `workspace/Input/<scope>/` |
|
|
237
|
+
| Pipeline trava em ambiguidade | PRD §12 ou TRD §10 têm linhas sem resposta. Preencher coluna "Resposta" e rodar `/sf-design` de novo |
|
|
238
|
+
| PM quer mudar algo depois do PRD aprovado | Criar `workspace/Input/<scope>/ajustes_v1.md` e rodar `/sf-extract` → merge aditivo preserva IDs |
|
|
239
|
+
| `/sf-publish` não envia TRD pro Confluence | Verificar `publishes: [PRD, TRD, Progresso]` no `sfw.config.yml` |
|
|
240
|
+
| Coder pede algo que não está nas specs/ | Não é bug — é feature. Significa que spec ficou incompleto. Completar via `/sf-extract` e re-rodar `/sf-design` |
|
|
241
|
+
| Security Review bloqueia merge | CRÍTICO/ALTO são bloqueantes. MÉDIO/BAIXO são recomendações. Ver `agents/security-reviewer.md` |
|
|
242
|
+
|
|
243
|
+
## Links
|
|
244
|
+
|
|
245
|
+
- **Repositório**: [gustavomaritan-labs/spec-first-workflow](https://github.com/gustavomaritan-labs/spec-first-workflow)
|
|
246
|
+
- **Kit Claude** (equivalente pra Claude Code): [spec-first-claude](https://www.npmjs.com/package/spec-first-claude)
|
|
247
|
+
- **Apresentação do pipeline**: [apresentacao.html](https://github.com/gustavomaritan-labs/spec-first-workflow/blob/main/packages/apresentacao.html)
|
|
248
|
+
- **Issues**: [github.com/.../issues](https://github.com/gustavomaritan-labs/spec-first-workflow/issues)
|
|
249
|
+
|
|
250
|
+
## Licença
|
|
251
|
+
|
|
252
|
+
MIT © [Gustavo Maritan](https://github.com/GustavoMaritan)
|
package/bin/cli.js
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const { init } = require('../lib/init');
|
|
5
|
-
const { update } = require('../lib/update');
|
|
6
|
-
|
|
7
|
-
const args = process.argv.slice(2);
|
|
8
|
-
const command = args[0];
|
|
9
|
-
|
|
10
|
-
function printUsage() {
|
|
11
|
-
console.log('Uso:');
|
|
12
|
-
console.log(' spec-first-copilot init --name=<nome-do-projeto> [--target=<caminho>]');
|
|
13
|
-
console.log(' spec-first-copilot update [--target=<caminho>] [--force]');
|
|
14
|
-
console.log('');
|
|
15
|
-
console.log('Comandos:');
|
|
16
|
-
console.log(' init Cria um novo projeto spec-first');
|
|
17
|
-
console.log(' update Atualiza projeto existente com arquivos novos do framework');
|
|
18
|
-
console.log(' (adiciona faltantes, atualiza skills/adapters/agents/templates)');
|
|
19
|
-
console.log('');
|
|
20
|
-
console.log('Opções:');
|
|
21
|
-
console.log(' --name=<nome> Nome do projeto (obrigatório no init)');
|
|
22
|
-
console.log(' --target=<path> Diretório destino (default: ./<nome> no init, cwd no update)');
|
|
23
|
-
console.log(' --force Força atualizar TODOS arquivos, não só os do framework (cuidado)');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function parseArgs(args) {
|
|
27
|
-
const parsed = { flags: [] };
|
|
28
|
-
for (const arg of args) {
|
|
29
|
-
const match = arg.match(/^--(\w+)=(.+)$/);
|
|
30
|
-
if (match) {
|
|
31
|
-
parsed[match[1]] = match[2];
|
|
32
|
-
} else if (arg.startsWith('--')) {
|
|
33
|
-
parsed.flags.push(arg.slice(2));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return parsed;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (command === 'init') {
|
|
40
|
-
const opts = parseArgs(args.slice(1));
|
|
41
|
-
|
|
42
|
-
if (!opts.name) {
|
|
43
|
-
console.error('Erro: --name é obrigatório.\n');
|
|
44
|
-
printUsage();
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
49
|
-
|
|
50
|
-
init({
|
|
51
|
-
name: opts.name,
|
|
52
|
-
templatesDir,
|
|
53
|
-
targetDir: opts.target || undefined,
|
|
54
|
-
});
|
|
55
|
-
} else if (command === 'update') {
|
|
56
|
-
const opts = parseArgs(args.slice(1));
|
|
57
|
-
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
58
|
-
|
|
59
|
-
update({
|
|
60
|
-
templatesDir,
|
|
61
|
-
targetDir: opts.target || undefined,
|
|
62
|
-
force: opts.flags.includes('force'),
|
|
63
|
-
});
|
|
64
|
-
} else {
|
|
65
|
-
printUsage();
|
|
66
|
-
if (command) {
|
|
67
|
-
console.error(`\nComando desconhecido: "${command}"`);
|
|
68
|
-
}
|
|
69
|
-
process.exit(command ? 1 : 0);
|
|
70
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { init } = require('../lib/init');
|
|
5
|
+
const { update } = require('../lib/update');
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const command = args[0];
|
|
9
|
+
|
|
10
|
+
function printUsage() {
|
|
11
|
+
console.log('Uso:');
|
|
12
|
+
console.log(' spec-first-copilot init --name=<nome-do-projeto> [--target=<caminho>]');
|
|
13
|
+
console.log(' spec-first-copilot update [--target=<caminho>] [--force]');
|
|
14
|
+
console.log('');
|
|
15
|
+
console.log('Comandos:');
|
|
16
|
+
console.log(' init Cria um novo projeto spec-first');
|
|
17
|
+
console.log(' update Atualiza projeto existente com arquivos novos do framework');
|
|
18
|
+
console.log(' (adiciona faltantes, atualiza skills/adapters/agents/templates)');
|
|
19
|
+
console.log('');
|
|
20
|
+
console.log('Opções:');
|
|
21
|
+
console.log(' --name=<nome> Nome do projeto (obrigatório no init)');
|
|
22
|
+
console.log(' --target=<path> Diretório destino (default: ./<nome> no init, cwd no update)');
|
|
23
|
+
console.log(' --force Força atualizar TODOS arquivos, não só os do framework (cuidado)');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseArgs(args) {
|
|
27
|
+
const parsed = { flags: [] };
|
|
28
|
+
for (const arg of args) {
|
|
29
|
+
const match = arg.match(/^--(\w+)=(.+)$/);
|
|
30
|
+
if (match) {
|
|
31
|
+
parsed[match[1]] = match[2];
|
|
32
|
+
} else if (arg.startsWith('--')) {
|
|
33
|
+
parsed.flags.push(arg.slice(2));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (command === 'init') {
|
|
40
|
+
const opts = parseArgs(args.slice(1));
|
|
41
|
+
|
|
42
|
+
if (!opts.name) {
|
|
43
|
+
console.error('Erro: --name é obrigatório.\n');
|
|
44
|
+
printUsage();
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
49
|
+
|
|
50
|
+
init({
|
|
51
|
+
name: opts.name,
|
|
52
|
+
templatesDir,
|
|
53
|
+
targetDir: opts.target || undefined,
|
|
54
|
+
});
|
|
55
|
+
} else if (command === 'update') {
|
|
56
|
+
const opts = parseArgs(args.slice(1));
|
|
57
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
58
|
+
|
|
59
|
+
update({
|
|
60
|
+
templatesDir,
|
|
61
|
+
targetDir: opts.target || undefined,
|
|
62
|
+
force: opts.flags.includes('force'),
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
printUsage();
|
|
66
|
+
if (command) {
|
|
67
|
+
console.error(`\nComando desconhecido: "${command}"`);
|
|
68
|
+
}
|
|
69
|
+
process.exit(command ? 1 : 0);
|
|
70
|
+
}
|