spec-first-copilot 0.6.0-beta.2 → 0.6.0-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-first-copilot",
3
- "version": "0.6.0-beta.2",
3
+ "version": "0.6.0-beta.3",
4
4
  "description": "Spec-first workflow kit for GitHub Copilot — AI-driven development with specs, not guesswork",
5
5
  "bin": {
6
6
  "spec-first-copilot": "bin/cli.js"
@@ -8,6 +8,38 @@
8
8
 
9
9
  ---
10
10
 
11
+ ## 0.6.0-beta.3 (2026-04-13)
12
+
13
+ ### Fix: `/sf-mcp confluence` idempotente com `root_page_id` como âncora
14
+
15
+ Antes a skill era linear e podia pular a coleta do Page ID raiz do projeto depois de
16
+ um restart (caso user tivesse que reiniciar o Claude após criar `.mcp.json`), resultando
17
+ em `sfw.config.yml` sem `project.root_page_id` — framework ficava sem âncora.
18
+
19
+ Novo fluxo:
20
+ 1. Detecta estado de `sfw.config.yml` (tem root_page_id?) + `.mcp.json` (tem credenciais?)
21
+ 2. Se AMBOS existem → testa conexão e reconfirma Input/Output
22
+ 3. Se algo falta → pede só o que falta (idempotente)
23
+ 4. `root_page_id` validado contra `get_page(id)` antes de mapear árvore
24
+ 5. Handler explícito pra 401 (credencial expirou) e 404 (root inválido)
25
+
26
+ ### Fix: Auto-publish imperativo em `/sf-extract`, `/sf-design`, `/sf-plan`
27
+
28
+ Antes a instrução era "Se `sfw.config.yml` com output.targets[] ativo: Executar /sf-publish" —
29
+ ambígua, agent podia interpretar como opcional e pular.
30
+
31
+ Agora:
32
+ - Instrução imperativa: "Se `sfw.config.yml` existe → Chamar `/sf-publish`. Execute."
33
+ - Cada skill adiciona **seção "Saída obrigatória"** reportando status do publish
34
+ (CREATED/UPDATED/SKIPPED/CONFLICT/ERROR) ou "SKIPPED (no sfw.config.yml)"
35
+ - User vê explicitamente o que aconteceu no Confluence
36
+
37
+ ### Fix: `publishes: [PRD, PRD, SDD, Progresso]` → `[PRD, SDD, Progresso]`
38
+
39
+ Resquício do rename `TRD → PRD` na seção de template do `/sf-mcp confluence`. Agora gera yaml correto.
40
+
41
+ ---
42
+
11
43
  ## 0.6.0-beta.2 (2026-04-12)
12
44
 
13
45
  ### Fix: CLI `init` output
@@ -31,7 +31,7 @@ Note: **não validar** presença de `docs/` — ausência é válida (first_run)
31
31
  - `docs/` se existir (feature mode: usa como baseline pra §Sistema; não preenche subseções que não mudam)
32
32
  - `workspace/Output/$ARGUMENTS/sf-discovery.md` se existir
33
33
  - `.github/rules.md`
34
- - Template `.github/templates/feature/sdd.template.md`
34
+ - Template `.github/templates/sf-feature/sdd.template.md`
35
35
 
36
36
  ### 2. Checkpoint de aprovação
37
37
 
@@ -66,7 +66,7 @@ SDD §Área-X: popular apenas áreas tocadas (GATE=SIM); resto marca N/A.
66
66
 
67
67
  ### 5. Gerar SDD
68
68
 
69
- Usar template `.github/templates/feature/sdd.template.md`:
69
+ Usar template `.github/templates/sf-feature/sdd.template.md`:
70
70
 
71
71
  **Meta**: preencher `first_run`, `PRD empty`, `áreas tocadas`.
72
72
 
@@ -120,7 +120,7 @@ Cada serviço = 1 repo. Repos serão criados/clonados pelo `/sf-dev` (INFRA-001)
120
120
  - Organização/usuário do GitHub (ex: `empresa`)
121
121
  - Nome base do projeto (ex: `meu-projeto`)
122
122
  - Se algum repo já existe (pra clonar em vez de criar)
123
- 3. Gerar `projetos.yaml` na raiz usando template `.github/templates/feature/projetos.template.yaml`
123
+ 3. Gerar `projetos.yaml` na raiz usando template `.github/templates/sf-feature/projetos.template.yaml`
124
124
  4. Mapear áreas de task para repos:
125
125
  - BACK → api (ou worker, se separado)
126
126
  - DB → api (se usa migrations) ou repo próprio
@@ -157,14 +157,41 @@ ultima_skill: "/sf-design"
157
157
  atualizado_em: "{{ISO_DATETIME}}"
158
158
  ```
159
159
 
160
- ### 10. Publicar SDD no backend
160
+ ### 10. Publicar SDD no backend (OBRIGATÓRIO quando config existe)
161
161
 
162
- Se `sfw.config.yml` com `output.targets[]` ativo:
163
- - Executar `/sf-publish $ARGUMENTS SDD`
164
- - `/sf-publish` respeita `mode` (auto/manual/off) de cada target
165
- - Se não existe `sfw.config.yml` → pular silenciosamente
162
+ **Este passo NÃO é opcional**. Tomar decisão baseada em arquivo:
166
163
 
167
- Ver `.github/skills/sf-publish/SKILL.md`.
164
+ | Detecção | Ação |
165
+ |----------|------|
166
+ | `sfw.config.yml` NÃO existe | Pular silenciosamente. Registrar no output: "publish: skipped (no sfw.config.yml)" |
167
+ | `sfw.config.yml` existe | **Chamar `/sf-publish $ARGUMENTS SDD`** — sem condicional. Execute. |
168
+
169
+ `/sf-publish` respeita `mode` de cada target. Ver `.github/skills/sf-publish/SKILL.md`.
170
+
171
+ ### 11. Saída obrigatória
172
+
173
+ Antes de terminar, a skill DEVE reportar:
174
+
175
+ ```
176
+ /sf-design $ARGUMENTS — completo (first_run={true|false})
177
+
178
+ Artefatos locais:
179
+ - workspace/Output/$ARGUMENTS/sdd.md
180
+ - specs/$ARGUMENTS/{brief,contracts,scenarios}.md
181
+ {se first_run: + docs/*.md (5 arquivos) + projetos.yaml}
182
+
183
+ Áreas tocadas: [{lista do Meta do SDD}]
184
+
185
+ Publish:
186
+ - {target-name}: {CREATED|UPDATED|SKIPPED|CONFLICT|ERROR} — ver .ai/sf-publish-log.md
187
+ OU
188
+ - SKIPPED (no sfw.config.yml)
189
+
190
+ Próximo passo:
191
+ /sf-plan $ARGUMENTS ← gerar tasks por área
192
+ ```
193
+
194
+ Se `/sf-publish` retornou ERROR, a skill NÃO falha — artefato local está salvo.
168
195
 
169
196
  ## Notas
170
197
 
@@ -27,9 +27,9 @@ Skill atômica de extração. Lê insumos brutos de `workspace/Input/$ARGUMENTS/
27
27
  - `discovery.md` (se existir) → análise profunda prévia dos insumos
28
28
  - **`docs/` se existir** — usar como baseline pra responder checklist sem perguntar ao user
29
29
  - Templates:
30
- - `.github/templates/feature/PRD.template.md` (destino principal)
31
- - `.github/templates/feature/sf-extract-log.template.md` (append-only)
32
- - `.github/templates/feature/backlog-extraido.template.md` (condicional, ver passo 6)
30
+ - `.github/templates/sf-feature/PRD.template.md` (destino principal)
31
+ - `.github/templates/sf-feature/sf-extract-log.template.md` (append-only)
32
+ - `.github/templates/sf-feature/backlog-extraido.template.md` (condicional, ver passo 6)
33
33
 
34
34
  > Se `discovery.md` existir: usar mapa do sistema e perguntas respondidas como contexto
35
35
  > enriquecido. Resultado: menos ambiguidades, melhor estruturação.
@@ -110,7 +110,7 @@ Temas não cobertos nem por insumos nem por `docs/` viram ambiguidades:
110
110
 
111
111
  ### 5. Gerar PRD.md
112
112
 
113
- Usar template `.github/templates/feature/PRD.template.md`:
113
+ Usar template `.github/templates/sf-feature/PRD.template.md`:
114
114
 
115
115
  - Meta: preencher `empty` com resultado do 4.1
116
116
  - Se `empty: true`: só preencher Meta + adicionar nota rodapé "scope puro-técnico"
@@ -124,7 +124,7 @@ Gerar `backlog_extraido.md` **APENAS** se:
124
124
  - `first_run = true` (detectado do `.context.md`) E
125
125
  - Insumos mencionam features/funcionalidades que extrapolam o escopo atual
126
126
 
127
- Usar template `.github/templates/feature/backlog-extraido.template.md`:
127
+ Usar template `.github/templates/sf-feature/backlog-extraido.template.md`:
128
128
  - Funcionalidades fora-de-escopo organizadas em roadmap faseado
129
129
  - Cada item sugere `/sf-start <nome>` futuro
130
130
  - Máximo 4-5 fases, priorizando cadastros/fundação na fase 1
@@ -163,16 +163,42 @@ ultima_skill: "/sf-extract"
163
163
  atualizado_em: "{{ISO_DATETIME}}"
164
164
  ```
165
165
 
166
- ### 9. Publicar no backend
166
+ ### 9. Publicar PRD no backend (OBRIGATÓRIO quando config existe)
167
167
 
168
- Se `sfw.config.yml` com `output.targets[]` ativo:
169
- - Executar `/sf-publish $ARGUMENTS PRD`
170
- - `/sf-publish` respeita `mode` (auto/manual/off) de cada target
171
- - Se `empty: true`: publicar mesmo assim — Meta + rodapé já informam o estado ao humano
172
- - Se não existe `sfw.config.yml` pular silenciosamente (projeto 100% local)
168
+ **Este passo NÃO é opcional**. Tomar decisão baseada em arquivo, não em intenção:
169
+
170
+ | Detecção | Ação |
171
+ |----------|------|
172
+ | `sfw.config.yml` NÃO existe | Pular silenciosamente (projeto 100% local). Registrar no output da skill: "publish: skipped (no sfw.config.yml)" |
173
+ | `sfw.config.yml` existe | **Chamar `/sf-publish $ARGUMENTS PRD`** — sem "se", sem "talvez". Execute. |
174
+
175
+ `/sf-publish` internamente respeita `mode` de cada target (`auto`/`manual`/`off`) e lida com `empty: true` (publica com nota).
173
176
 
174
177
  Ver `.github/skills/sf-publish/SKILL.md`.
175
178
 
179
+ ### 10. Saída obrigatória
180
+
181
+ Antes de terminar, a skill DEVE reportar:
182
+
183
+ ```
184
+ /sf-extract $ARGUMENTS — completo
185
+
186
+ Artefatos locais:
187
+ - workspace/Output/$ARGUMENTS/PRD.md (empty: {true|false})
188
+ - workspace/Output/$ARGUMENTS/.extract-log.md
189
+ - workspace/Output/$ARGUMENTS/backlog_extraido.md (se aplicável)
190
+
191
+ Publish:
192
+ - {target-name}: {CREATED|UPDATED|SKIPPED|CONFLICT|ERROR} — ver .ai/sf-publish-log.md
193
+ OU
194
+ - SKIPPED (no sfw.config.yml) — projeto 100% local
195
+
196
+ Próximo passo:
197
+ /sf-design $ARGUMENTS ← após revisar PRD e responder ambiguidades §14
198
+ ```
199
+
200
+ Se `/sf-publish` retornou ERROR, a skill NÃO falha — apenas reporta no output pro user decidir. Artefato local está salvo.
201
+
176
202
  ## Re-extração
177
203
 
178
204
  - Merge ADITIVO com PRD existente (nunca remove info de inalterados)
@@ -1,6 +1,6 @@
1
1
  # /sf-mcp <provider>
2
2
 
3
- Setup interativo de backend externo. Pergunta os dados necessários, descobre a estrutura do projeto e cria todos os arquivos de configuração.
3
+ Setup interativo de backend externo. Idempotente pode rodar múltiplas vezes, pergunta o que falta.
4
4
 
5
5
  ## Providers disponíveis
6
6
 
@@ -11,57 +11,79 @@ Setup interativo de backend externo. Pergunta os dados necessários, descobre a
11
11
  ## Uso
12
12
 
13
13
  ```
14
- /sf-mcp confluence
15
- /sf-mcp confluence test ← só testa conexão
14
+ /sf-mcp confluence ← setup ou reconfiguração (idempotente)
15
+ /sf-mcp confluence test ← só testa conexão
16
16
  ```
17
17
 
18
18
  ---
19
19
 
20
20
  ## Provider: Confluence
21
21
 
22
- ### Passo 1 — Verificar pré-requisitos
22
+ ### Passo 1 — Detectar estado atual
23
+
24
+ Ler os 2 arquivos âncora:
25
+
26
+ | Arquivo | O que extrair | Se ausente |
27
+ |---------|---------------|------------|
28
+ | `sfw.config.yml` | `project.root_page_id`, `project.name`, credenciais do space (`space_key`) | marcar como "falta config" |
29
+ | `.mcp.json` | entry `mcpServers.atlassian` com `CONFLUENCE_URL`, `CONFLUENCE_USERNAME`, `CONFLUENCE_API_TOKEN` | marcar como "falta credenciais" |
30
+
31
+ Calcular `state`:
32
+ - **COMPLETO** — `sfw.config.yml` tem `root_page_id` E `.mcp.json` tem credenciais → ir pro Passo 2
33
+ - **INCOMPLETO** — algo falta → ir pro Passo 3
34
+
35
+ ### Passo 2 — Estado COMPLETO: validar conexão
36
+
37
+ Testar:
38
+ ```
39
+ mcp__atlassian__confluence_get_page(page_id={root_page_id})
40
+ ```
41
+
42
+ | Resultado | Ação |
43
+ |-----------|------|
44
+ | 200 OK | → Passo 4 (remapear árvore, reconfirmar Input/Output) |
45
+ | 401 Unauthorized | Credencial expirou. Perguntar novo token, atualizar `.mcp.json`, avisar pra reiniciar Claude Code, PARAR |
46
+ | 404 Not Found | `root_page_id` inválido. Perguntar novo ID, atualizar `sfw.config.yml`, retry teste |
47
+ | MCP não responde | `.mcp.json` foi atualizado mas Claude não recarregou. Avisar pra reiniciar Claude Code, PARAR |
48
+ | Network error | Mostrar erro, instruir troubleshooting (`.github/adapters/SETUP.md`) |
49
+
50
+ ### Passo 3 — Estado INCOMPLETO: coletar o que falta
51
+
52
+ #### 3.1 Verificar `uvx`
23
53
 
24
- Verificar se `uvx` está instalado:
25
54
  ```bash
26
55
  uvx --version
27
56
  ```
28
57
 
29
- Se NÃO está instalado:
58
+ Se não instalado:
30
59
  ```
31
60
  uvx não encontrado. Instale com:
32
61
  pip install uv
33
62
 
34
63
  Depois rode /sf-mcp confluence novamente.
35
64
  ```
36
- **Parar aqui** se uvx não estiver disponível.
65
+ **PARAR**.
37
66
 
38
- ### Passo 2 Coletar credenciais
67
+ #### 3.2 Se FALTA credenciais (`.mcp.json` ausente ou incompleto)
39
68
 
40
69
  Perguntar uma por uma:
41
-
42
70
  ```
43
- Configurando Confluence para o SFW.
71
+ Configurando acesso ao Confluence.
44
72
 
45
73
  1. URL do Confluence (ex: https://sua-empresa.atlassian.net/wiki):
46
74
  >
47
75
 
48
- 2. Email da conta Atlassian (ex: dev@empresa.com):
76
+ 2. Email da conta Atlassian:
49
77
  >
50
78
 
51
- 3. API Token (gere em https://id.atlassian.com/manage-profile/security/api-tokens):
79
+ 3. API Token (https://id.atlassian.com/manage-profile/security/api-tokens):
52
80
  >
53
81
 
54
- 4. Space Key (as letras na URL: /wiki/spaces/XX/...):
82
+ 4. Space Key (letras na URL: /wiki/spaces/XX/...):
55
83
  >
56
84
  ```
57
85
 
58
- ### Passo 3 — Criar `.mcp.json`
59
-
60
- Verificar se `.mcp.json` já existe:
61
- - Se existe e já tem entrada `atlassian` → perguntar se quer atualizar
62
- - Se existe sem `atlassian` → adicionar entrada
63
- - Se não existe → criar
64
-
86
+ Criar/atualizar `.mcp.json`:
65
87
  ```json
66
88
  {
67
89
  "mcpServers": {
@@ -78,95 +100,100 @@ Verificar se `.mcp.json` já existe:
78
100
  }
79
101
  ```
80
102
 
81
- **IMPORTANTE**: Credenciais hardcoded — `${VAR}` NÃO funciona no Claude Code.
103
+ **IMPORTANTE**: credenciais hardcoded — `${VAR}` NÃO funciona no Claude Code.
82
104
 
83
- ### Passo 4 Testar conexão e descobrir projeto
84
-
85
- Testar chamando:
86
- ```
87
- mcp__atlassian__confluence_search(query="space.key={space_key}", limit=5)
88
- ```
89
- ou
90
- ```
91
- mcp__atlassian__confluence_get_page_children(page_id=<root do space>)
105
+ Se `.mcp.json` acabou de ser criado/atualizado:
92
106
  ```
107
+ .mcp.json pronto. Preciso que você reinicie o Claude Code para o MCP carregar.
93
108
 
94
- **Se MCP não disponível** (primeira vez — `.mcp.json` acabou de ser criado):
109
+ 1. Feche o Claude Code
110
+ 2. Abra novamente na mesma pasta
111
+ 3. Rode /sf-mcp confluence — vou continuar de onde paramos (credenciais já salvas,
112
+ só vou pedir o que ainda falta)
95
113
  ```
96
- .mcp.json criado. O Claude Code precisa ser reiniciado para carregar o MCP.
114
+ **PARAR**.
115
+
116
+ #### 3.3 Se FALTA root_page_id (credenciais OK mas config sem root)
97
117
 
98
- 1. Reinicie o Claude Code (feche e abra)
99
- 2. Rode /sf-mcp confluence novamente — vou continuar de onde paramos
118
+ Testar conexão básica primeiro:
119
+ ```
120
+ mcp__atlassian__confluence_search(query="space.key={space_key}", limit=1)
100
121
  ```
101
- **Parar aqui.**
102
122
 
103
- **Se MCP funcionar** pedir o projeto:
123
+ Se falha Passo 2 error table (401/MCP não responde/etc).
124
+ Se OK:
104
125
 
105
126
  ```
106
- Conexão OK!
127
+ Conexão OK.
107
128
 
108
- 5. Qual é a page raiz do seu projeto no Confluence?
109
- Cole o Page ID (número na URL) ou o título exato:
110
- >
129
+ Qual é a page RAIZ do seu projeto no Confluence?
130
+ Cole o Page ID (número na URL) ou o título exato:
131
+ >
111
132
  ```
112
133
 
113
- ### Passo 5 — Mapear a árvore do projeto
134
+ Validar:
135
+ ```
136
+ mcp__atlassian__confluence_get_page(page_id={resposta})
137
+ ```
138
+ - Se 404 e user colou título → usar `confluence_search` pra achar
139
+ - Se 404 e user colou ID → pedir de novo
140
+ - Se OK → seguir
114
141
 
115
- Após receber o Page ID ou título da raiz:
142
+ ### Passo 4 Mapear árvore do projeto
116
143
 
117
- 1. Chamar `mcp__atlassian__confluence_get_page` pra confirmar que existe
118
- 2. Chamar `mcp__atlassian__confluence_get_page_children` na raiz
119
- 3. Chamar recursivamente nos filhos pra mapear a árvore completa
144
+ Chamar recursivamente:
145
+ ```
146
+ mcp__atlassian__confluence_get_page_children(page_id={root_page_id})
147
+ → pra cada filho, chamar get_page_children até bater em folha
148
+ ```
120
149
 
121
150
  Mostrar ao usuário:
122
-
123
151
  ```
124
- Projeto: "Barbearia Digital" (page_id: 65708)
152
+ Projeto: "Barbearia Digital" (root_page_id: 65708)
125
153
 
126
154
  Estrutura encontrada:
127
- ├── Requisitos (page_id: 360668)
128
- │ ├── App mobile (page_id: 294950)
129
- │ └── Painel admin (page_id: 131084)
130
- ├── Documentação técnica (page_id: 294931)
131
- ├── Referências (page_id: 557057)
132
- └── Decisões (page_id: 425998)
155
+ ├── Requisitos (360668)
156
+ │ ├── App mobile (294950)
157
+ │ └── Painel admin (131084)
158
+ ├── Documentação técnica (294931)
159
+ ├── Referências (557057)
160
+ └── Decisões (425998)
133
161
  ```
134
162
 
135
- ### Passo 6 — Identificar Input e Output
163
+ ### Passo 5 — Identificar Input e Output
136
164
 
137
- Perguntar ao usuário:
165
+ **Se existe config com Input/Output**: mostrar o que está salvo + opção de mudar:
166
+ ```
167
+ Config atual:
168
+ Input: Requisitos (360668)
169
+ Output: Documentação técnica (294931)
138
170
 
171
+ Manter? (s/n)
139
172
  ```
140
- Preciso saber qual pasta contém os INSUMOS (Input) e onde devo PUBLICAR os artefatos (Output).
141
173
 
142
- Qual dessas é o Input (onde estão os insumos do PM/PO)?
174
+ Se `s` pular pro Passo 7.
175
+ Se `n` → continuar perguntando (como se fosse setup novo).
176
+
177
+ **Se é setup novo**:
178
+ ```
179
+ Qual dessas pages contém os INSUMOS (Input, onde PM/PO publica)?
143
180
  1. Requisitos (360668)
144
181
  2. Documentação técnica (294931)
145
182
  3. Referências (557057)
146
183
  4. Decisões (425998)
147
- 5. Criar nova page "Input"
184
+ 5. Criar nova page "Input" (filha da raiz)
148
185
  >
149
186
  ```
150
187
 
151
- Após o user escolher Input:
188
+ Após escolher Input, perguntar Output com as pages restantes + opção "Criar nova page 'Output'".
152
189
 
153
- ```
154
- Qual dessas é o Output (onde publico PRD, SDD, Progresso)?
155
- 1. Documentação técnica (294931)
156
- 2. Referências (557057)
157
- 3. Decisões (425998)
158
- 4. Criar nova page "Output"
159
- >
160
- ```
161
-
162
- **Se o user escolher "Criar nova"** → usar `mcp__atlassian__confluence_create_page` como filha da raiz.
190
+ Se escolher "Criar nova" → `mcp__atlassian__confluence_create_page` como filha da raiz.
163
191
 
164
- ### Passo 7 — Sugerir mapeamento de páginas úteis (opcional)
165
-
166
- Se a árvore tem outras pages relevantes, sugerir:
192
+ ### Passo 6 — Sugerir context_pages (opcional)
167
193
 
194
+ Pages da árvore que não viraram Input nem Output:
168
195
  ```
169
- Encontrei outras páginas que podem ser úteis durante o desenvolvimento:
196
+ Encontrei outras pages que podem ser úteis durante o desenvolvimento:
170
197
 
171
198
  - "Referências" (557057) → posso consultar durante /sf-extract e /sf-design
172
199
  - "Decisões" (425998) → posso consultar para ADRs no /sf-design
@@ -174,9 +201,11 @@ Encontrei outras páginas que podem ser úteis durante o desenvolvimento:
174
201
  Quer que eu mapeie essas páginas como contexto adicional? (s/n)
175
202
  ```
176
203
 
177
- Se sim, registrar no `sfw.config.yml` como `context_pages`.
204
+ Se sim, incluir em `context_pages[]` no `sfw.config.yml`.
205
+
206
+ ### Passo 7 — Escrever `sfw.config.yml`
178
207
 
179
- ### Passo 8 Criar `sfw.config.yml`
208
+ Preservar seções existentes (naming, etc) se já havia arquivo. Atualizar/criar:
180
209
 
181
210
  ```yaml
182
211
  project:
@@ -191,12 +220,12 @@ input:
191
220
  adapter: confluence
192
221
  config:
193
222
  space_key: "{space_key}"
194
- parent_page_id: "{page_id escolhido como Input}"
223
+ parent_page_id: "{page_id do Input}"
195
224
  recursive: true
196
225
  include_attachments: true
197
226
  cache:
198
227
  local_dir: "workspace/Input/"
199
- log: ".ai/load-log.md"
228
+ log: ".ai/sf-load-log.md"
200
229
  incremental: true
201
230
 
202
231
  output:
@@ -205,44 +234,41 @@ output:
205
234
  adapter: confluence
206
235
  config:
207
236
  space_key: "{space_key}"
208
- parent_page_id: "{page_id escolhido como Output}"
209
- publishes: [PRD, PRD, SDD, Progresso]
237
+ parent_page_id: "{page_id do Output}"
238
+ publishes: [PRD, SDD, Progresso]
210
239
  mode: auto
211
240
  conflict_detection: version
212
241
  approval_mechanism: label
213
242
  approval_label: "sfw-approved"
214
243
 
215
- # Pages de contexto adicional (consultadas pelo /sf-extract e /sf-design)
244
+ # Descomente se tiver selecionado context_pages no Passo 6
216
245
  # context_pages:
217
246
  # - id: "557057"
218
247
  # title: "Referências"
219
248
  # use_in: [extract, design]
220
- # - id: "425998"
221
- # title: "Decisões"
222
- # use_in: [design]
223
249
  ```
224
250
 
225
- ### Passo 9 — Ajustar `.gitignore`
251
+ ### Passo 8 — Ajustar `.gitignore`
226
252
 
227
- Adicionar se não existem:
228
- - `.mcp.json`
229
- - Bloco workspace ignored:
230
- ```
231
- # SFW: workspace ignored (external backend detected)
232
- workspace/Output/**
233
- !workspace/Output/.gitkeep
234
- ```
253
+ Adicionar se não existe:
254
+ ```
255
+ .mcp.json
256
+
257
+ # SFW: workspace ignored (external backend detected)
258
+ workspace/Output/**
259
+ !workspace/Output/.gitkeep
260
+ ```
235
261
 
236
- ### Passo 10 — Resumir
262
+ ### Passo 9 — Resumir
237
263
 
238
264
  ```
239
265
  Confluence configurado!
240
266
 
241
- Projeto: {nome} ({page_id raiz})
267
+ Projeto: {nome} ({root_page_id})
242
268
  Input: {título Input} ({page_id})
243
269
  Output: {título Output} ({page_id})
244
270
 
245
- Arquivos criados/atualizados:
271
+ Arquivos:
246
272
  .mcp.json ← credenciais (gitignored)
247
273
  sfw.config.yml ← configuração do projeto
248
274
  .gitignore ← atualizado
@@ -251,42 +277,50 @@ O projeto tem {N} scopes no Input:
251
277
  - {lista dos filhos do Input}
252
278
 
253
279
  Próximo passo:
254
- /sf-start <nome-do-scope> ← bootstrap técnico
255
- /sf-feature <nome-do-scope> ← nova feature
280
+ /sf-start <nome-do-scope>
256
281
  ```
257
282
 
258
283
  ---
259
284
 
260
285
  ## Subcomando: `/sf-mcp confluence test`
261
286
 
262
- Apenas testa a conexão sem criar/modificar arquivos:
263
-
264
- 1. Verificar que `.mcp.json` existe
265
- 2. Verificar que `sfw.config.yml` existe e tem `adapter: confluence`
266
- 3. Chamar `mcp__atlassian__confluence_get_page_children(page_id={input.parent_page_id})`
267
- 4. Se OK"Conexão OK! {N} scopes encontrados em Input: {lista}"
268
- 5. Se falha → orientar troubleshooting (ver `.github/adapters/SETUP.md`)
287
+ Apenas testa sem modificar arquivos:
288
+
289
+ 1. Verificar que `sfw.config.yml` existe com `project.root_page_id` e `input.config.parent_page_id`
290
+ 2. Verificar que `.mcp.json` existe com credenciais
291
+ 3. Testar `confluence_get_page(root_page_id)` → root acessível?
292
+ 4. Testar `confluence_get_page_children(input.config.parent_page_id)`listar scopes
293
+ 5. Reportar:
294
+ ```
295
+ Conexão OK!
296
+ Root: "{nome}" ({root_page_id})
297
+ Input: {N} scopes encontrados
298
+ Output: {M} artefatos publicados anteriormente
299
+ ```
300
+ 6. Se falha: mostrar qual check falhou + link pro troubleshooting
269
301
 
270
302
  ---
271
303
 
272
304
  ## Notas
273
305
 
306
+ - **`/sf-mcp confluence` é idempotente** — pode rodar N vezes. Só pergunta o que falta baseado em `sfw.config.yml` + `.mcp.json`
307
+ - **`root_page_id` é âncora** — sem ele o framework não sabe os limites do projeto no space
274
308
  - `.mcp.json` é SEMPRE gitignored — contém credenciais
275
309
  - `sfw.config.yml` é commitável — zero segredos
276
- - Após criar `.mcp.json`, Claude Code PRECISA ser reiniciado
310
+ - Após criar/atualizar `.mcp.json`, Claude Code PRECISA ser reiniciado
277
311
  - O framework conhece o projeto INTEIRO (raiz + toda a árvore), não só Input/Output
278
- - `context_pages` permite que /sf-extract e /sf-design consultem páginas extras como referência
279
- - Token Atlassian pode expirar — se der 401, gerar novo e atualizar `.mcp.json`
312
+ - Token Atlassian pode expirar se der 401, skill pede novo e atualiza `.mcp.json`
280
313
 
281
314
  ## Erros
282
315
 
283
316
  | Erro | Ação |
284
317
  |------|------|
285
318
  | uvx não instalado | Parar, instruir instalação |
286
- | MCP não disponível | Pedir reinício do Claude Code |
287
- | Page raiz não encontrada | Pedir ID/título correto |
288
- | Sem permissão de escrita | Informar, pedir ao admin |
289
- | Space key errado | Listar spaces disponíveis se possível |
319
+ | MCP não responde após `.mcp.json` novo | Pedir reinício, retomar depois |
320
+ | `root_page_id` 404 | Pedir ID/título correto, validar |
321
+ | Token expirado (401) | Pedir novo token, atualizar .mcp.json, pedir reinício |
322
+ | Sem permissão de escrita no space | Informar, pedir ao admin |
323
+ | Space key inválido | Listar spaces disponíveis se possível |
290
324
 
291
325
  ## Referências
292
326
 
@@ -20,8 +20,8 @@ Metódico e exaustivo. Cada task auto-contida. Prioriza ordem correta.
20
20
  ### 1. Ler contexto
21
21
  - `workspace/Output/{nome}/sdd.md` completo (fonte humana)
22
22
  - `specs/{nome}/contracts.md` e `scenarios.md` (projeções já geradas pelo /sf-design)
23
- - `projetos.yaml` + `docs/` (architecture, domain, conventions) + `.claude/rules.md`
24
- - Template `.claude/templates/specs/tasks.template.md`
23
+ - `projetos.yaml` + `docs/` (architecture, domain, conventions) + `.github/rules.md`
24
+ - Template `.github/templates/specs/tasks.template.md`
25
25
 
26
26
  ### 2. Identificar fases de entrega
27
27
  Ler PRD §11 (Fases de Entrega) — cada fase vira um agrupamento de tasks:
@@ -88,15 +88,39 @@ status: "plan_done"
88
88
  ultima_skill: "/sf-plan"
89
89
  ```
90
90
 
91
- ### 7. Publicar Progresso no(s) backend(s)
91
+ ### 7. Publicar Progresso no backend (OBRIGATÓRIO quando config existe)
92
92
 
93
- Se existe `sfw.config.yml` com `output.targets[]` ativo:
94
- - Executar `/sf-publish $ARGUMENTS Progresso`
95
- - O `/sf-publish` respeita o `mode` (auto/manual/off) de cada target
96
- - Se não existe `sfw.config.yml` → pular silenciosamente
97
- - **Nota**: `tasks.md`, `specs/`, `docs/`, `projetos.yaml` são LOCAL ONLY — nunca publicados
93
+ **Este passo NÃO é opcional**. Tomar decisão baseada em arquivo:
98
94
 
99
- Ver `.github/skills/sf-publish.md`.
95
+ | Detecção | Ação |
96
+ |----------|------|
97
+ | `sfw.config.yml` NÃO existe | Pular silenciosamente. Registrar: "publish: skipped (no sfw.config.yml)" |
98
+ | `sfw.config.yml` existe | **Chamar `/sf-publish $ARGUMENTS Progresso`** — sem condicional. Execute. |
99
+
100
+ `/sf-publish` respeita `mode` de cada target. Ver `.github/skills/sf-publish/SKILL.md`.
101
+
102
+ **Nota**: `tasks.md`, `specs/`, `docs/`, `projetos.yaml` são LOCAL ONLY — `/sf-publish` nunca toca neles.
103
+
104
+ ### 8. Saída obrigatória
105
+
106
+ Antes de terminar, a skill DEVE reportar:
107
+
108
+ ```
109
+ /sf-plan $ARGUMENTS — completo
110
+
111
+ Artefatos locais:
112
+ - specs/$ARGUMENTS/tasks.md ({N} tasks em {F} fases, áreas: [{lista}])
113
+ - workspace/Output/$ARGUMENTS/Progresso.md
114
+
115
+ Publish:
116
+ - {target-name}: {CREATED|UPDATED|SKIPPED|CONFLICT|ERROR} — ver .ai/sf-publish-log.md
117
+ OU
118
+ - SKIPPED (no sfw.config.yml)
119
+
120
+ Próximo passo:
121
+ /sf-dev $ARGUMENTS ← implementa tudo
122
+ /sf-dev $ARGUMENTS --fase 1 ← só fase 1
123
+ ```
100
124
 
101
125
  ## Saídas
102
126
  - `specs/{nome}/tasks.md` — tabela única