spec-first-copilot 0.7.0-beta.1 → 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 +560 -533
- 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 +215 -215
- package/templates/.github/agents/db-coder.md +165 -165
- package/templates/.github/agents/doc-writer.md +66 -66
- package/templates/.github/agents/frontend-coder.md +222 -222
- package/templates/.github/agents/infra-coder.md +341 -341
- package/templates/.github/agents/reviewer.md +99 -99
- package/templates/.github/agents/security-reviewer.md +153 -153
- package/templates/.github/copilot-instructions.md +272 -272
- 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 -289
- package/templates/.github/skills/sf-design/SKILL.md +161 -161
- package/templates/.github/skills/sf-dev/SKILL.md +204 -204
- package/templates/.github/skills/sf-discovery/SKILL.md +415 -415
- package/templates/.github/skills/sf-extract/SKILL.md +225 -225
- package/templates/.github/skills/sf-load/SKILL.md +296 -296
- package/templates/.github/skills/sf-mcp/SKILL.md +386 -386
- package/templates/.github/skills/sf-merge-docs/SKILL.md +152 -152
- package/templates/.github/skills/sf-plan/SKILL.md +152 -152
- package/templates/.github/skills/sf-publish/SKILL.md +144 -144
- package/templates/.github/skills/sf-session-finish/SKILL.md +93 -93
- package/templates/.github/skills/sf-start/SKILL.md +192 -192
- 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 -279
- package/templates/.github/templates/feature/Progresso.template.md +141 -141
- package/templates/.github/templates/feature/TRD.template.md +358 -358
- package/templates/.github/templates/feature/context.template.md +89 -89
- package/templates/.github/templates/feature/extract-log.template.md +49 -49
- 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 -66
- package/templates/.github/templates/specs/contracts.template.md +147 -147
- package/templates/.github/templates/specs/scenarios.template.md +125 -125
- package/templates/.github/templates/specs/tasks.template.md +65 -65
- package/templates/_gitignore +35 -35
- package/templates/sfw.config.yml.example +147 -147
|
@@ -1,386 +1,386 @@
|
|
|
1
|
-
|
|
2
|
-
# /sf-mcp <provider>
|
|
3
|
-
|
|
4
|
-
Setup interativo de backend externo. Idempotente — pode rodar múltiplas vezes, só pergunta o que falta.
|
|
5
|
-
|
|
6
|
-
## Providers disponíveis
|
|
7
|
-
|
|
8
|
-
| Provider | O que faz |
|
|
9
|
-
|----------|-----------|
|
|
10
|
-
| `confluence` | Configura MCP Atlassian + descobre projeto + cria `sfw.config.yml` + `.mcp.json` + `.gitignore` |
|
|
11
|
-
|
|
12
|
-
## Uso
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
/sf-mcp confluence ← setup ou reconfiguração (idempotente)
|
|
16
|
-
/sf-mcp confluence test ← só testa conexão
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
> **Dica**: para evitar o ciclo "abrir Claude → descobrir que falta uvx ou credenciais →
|
|
20
|
-
> sair, ajustar, reiniciar", há um script opcional que prepara o ambiente antes:
|
|
21
|
-
>
|
|
22
|
-
> ```bash
|
|
23
|
-
> node .github/scripts/bootstrap-confluence.js
|
|
24
|
-
> ```
|
|
25
|
-
>
|
|
26
|
-
> Ele valida `uvx`, coleta credenciais, gera `.mcp.json` e pré-cacheia o MCP. Depois
|
|
27
|
-
> você abre o VS Code com Copilot Chat e `/sf-mcp confluence` só descobre a árvore do projeto. Uso
|
|
28
|
-
> opcional — `/sf-mcp confluence` sozinho também cobre esses passos, mas demanda reiniciar
|
|
29
|
-
> o Copilot após gerar `.mcp.json` (MCPs só sobem no startup).
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Provider: Confluence
|
|
34
|
-
|
|
35
|
-
### Passo 1 — Detectar estado atual
|
|
36
|
-
|
|
37
|
-
Ler os 2 arquivos âncora:
|
|
38
|
-
|
|
39
|
-
| Arquivo | O que extrair | Se ausente |
|
|
40
|
-
|---------|---------------|------------|
|
|
41
|
-
| `sfw.config.yml` | `project.root_page_id`, `project.name`, credenciais do space (`space_key`) | marcar como "falta config" |
|
|
42
|
-
| `.mcp.json` | entry `mcpServers.atlassian` com `CONFLUENCE_URL`, `CONFLUENCE_USERNAME`, `CONFLUENCE_API_TOKEN` | marcar como "falta credenciais" |
|
|
43
|
-
|
|
44
|
-
Calcular `state`:
|
|
45
|
-
- **COMPLETO** — `sfw.config.yml` tem `root_page_id` E `.mcp.json` tem credenciais → ir pro Passo 2
|
|
46
|
-
- **INCOMPLETO** — algo falta → ir pro Passo 3
|
|
47
|
-
|
|
48
|
-
### Passo 2 — Estado COMPLETO: validar conexão
|
|
49
|
-
|
|
50
|
-
Testar:
|
|
51
|
-
```
|
|
52
|
-
mcp__atlassian__confluence_get_page(page_id={root_page_id})
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
| Resultado | Ação |
|
|
56
|
-
|-----------|------|
|
|
57
|
-
| 200 OK | → Passo 4 (remapear árvore, reconfirmar Input/Output) |
|
|
58
|
-
| 401 Unauthorized | Credencial expirou. Perguntar novo token, atualizar `.mcp.json`, avisar pra reiniciar VS Code com Copilot Chat, PARAR |
|
|
59
|
-
| 404 Not Found | `root_page_id` inválido. Perguntar novo ID, atualizar `sfw.config.yml`, retry teste |
|
|
60
|
-
| MCP não responde | `.mcp.json` foi atualizado mas Claude não recarregou. Avisar pra reiniciar VS Code com Copilot Chat, PARAR |
|
|
61
|
-
| Network error | Mostrar erro, instruir troubleshooting (`.github/adapters/SETUP.md`) |
|
|
62
|
-
|
|
63
|
-
### Passo 3 — Estado INCOMPLETO: coletar o que falta
|
|
64
|
-
|
|
65
|
-
#### 3.1 Verificar `uvx`
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
uvx --version
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Se não instalado:
|
|
72
|
-
```
|
|
73
|
-
uvx não encontrado. Instale com:
|
|
74
|
-
pip install uv
|
|
75
|
-
|
|
76
|
-
Depois rode /sf-mcp confluence novamente.
|
|
77
|
-
```
|
|
78
|
-
**PARAR**.
|
|
79
|
-
|
|
80
|
-
#### 3.2 Se FALTA credenciais (`.mcp.json` ausente ou incompleto)
|
|
81
|
-
|
|
82
|
-
Perguntar uma por uma. Pra cada item, mostrar ao user exatamente ONDE achar:
|
|
83
|
-
```
|
|
84
|
-
Configurando acesso ao Confluence.
|
|
85
|
-
|
|
86
|
-
1. URL do Confluence
|
|
87
|
-
Abra o Confluence no browser. A URL base é algo como:
|
|
88
|
-
https://sua-empresa.atlassian.net/wiki
|
|
89
|
-
Cole essa URL (com /wiki no final):
|
|
90
|
-
>
|
|
91
|
-
|
|
92
|
-
2. Email da conta Atlassian
|
|
93
|
-
É o email que você usa pra logar no Atlassian (não é o token).
|
|
94
|
-
>
|
|
95
|
-
|
|
96
|
-
3. API Token
|
|
97
|
-
Token é diferente de senha. Gere um novo:
|
|
98
|
-
a) Abra https://id.atlassian.com/manage-profile/security/api-tokens
|
|
99
|
-
b) Clique "Create API token"
|
|
100
|
-
c) Dê um nome (ex: "sfw-mcp")
|
|
101
|
-
d) Copie o token que aparece — ele só aparece UMA VEZ
|
|
102
|
-
Cole aqui:
|
|
103
|
-
>
|
|
104
|
-
|
|
105
|
-
4. Space Key
|
|
106
|
-
É o código CURTO do seu espaço Confluence (geralmente 2-4 letras maiúsculas).
|
|
107
|
-
Abra qualquer page do seu espaço. Na URL, você verá:
|
|
108
|
-
https://...atlassian.net/wiki/spaces/XXX/pages/...
|
|
109
|
-
^^^
|
|
110
|
-
esse é o Space Key
|
|
111
|
-
Exemplos comuns: "ST", "DEV", "PROJ", "ENG"
|
|
112
|
-
Qual é o seu?:
|
|
113
|
-
>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Criar/atualizar `.mcp.json`:
|
|
117
|
-
```json
|
|
118
|
-
{
|
|
119
|
-
"mcpServers": {
|
|
120
|
-
"atlassian": {
|
|
121
|
-
"command": "uvx",
|
|
122
|
-
"args": ["mcp-atlassian"],
|
|
123
|
-
"env": {
|
|
124
|
-
"CONFLUENCE_URL": "{url}",
|
|
125
|
-
"CONFLUENCE_USERNAME": "{email}",
|
|
126
|
-
"CONFLUENCE_API_TOKEN": "{token}"
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
**IMPORTANTE**: credenciais hardcoded — `${VAR}` NÃO funciona no VS Code com Copilot Chat.
|
|
134
|
-
|
|
135
|
-
Se `.mcp.json` acabou de ser criado/atualizado:
|
|
136
|
-
```
|
|
137
|
-
.mcp.json pronto. Preciso que você reinicie o VS Code com Copilot Chat para o MCP carregar.
|
|
138
|
-
|
|
139
|
-
1. Feche o VS Code com Copilot Chat
|
|
140
|
-
2. Abra novamente na mesma pasta
|
|
141
|
-
3. Rode /sf-mcp confluence — vou continuar de onde paramos (credenciais já salvas,
|
|
142
|
-
só vou pedir o que ainda falta)
|
|
143
|
-
```
|
|
144
|
-
**PARAR**.
|
|
145
|
-
|
|
146
|
-
#### 3.3 Se FALTA root_page_id (credenciais OK mas config sem root)
|
|
147
|
-
|
|
148
|
-
Testar conexão básica primeiro:
|
|
149
|
-
```
|
|
150
|
-
mcp__atlassian__confluence_search(query="space.key={space_key}", limit=1)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
Se falha → Passo 2 error table (401/MCP não responde/etc).
|
|
154
|
-
Se OK:
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
Conexão OK.
|
|
158
|
-
|
|
159
|
-
Qual é a page RAIZ do seu projeto no Confluence?
|
|
160
|
-
(A page-mãe que contém TUDO do projeto — geralmente tem Input e Output como filhas.)
|
|
161
|
-
|
|
162
|
-
Duas formas de informar:
|
|
163
|
-
|
|
164
|
-
A) Page ID (recomendado — mais confiável):
|
|
165
|
-
Abra a page raiz no Confluence. A URL mostra:
|
|
166
|
-
https://...atlassian.net/wiki/spaces/ST/pages/65708/Nome-da-Page
|
|
167
|
-
^^^^^
|
|
168
|
-
esse número é o Page ID
|
|
169
|
-
Cole só o número (ex: 65708).
|
|
170
|
-
|
|
171
|
-
B) Título exato:
|
|
172
|
-
O título que aparece no topo da page. Tem que bater EXATAMENTE
|
|
173
|
-
(incluindo acentos e maiúsculas/minúsculas).
|
|
174
|
-
|
|
175
|
-
Page ID ou título:
|
|
176
|
-
>
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Validar:
|
|
180
|
-
```
|
|
181
|
-
mcp__atlassian__confluence_get_page(page_id={resposta})
|
|
182
|
-
```
|
|
183
|
-
- Se 404 e user colou título → usar `confluence_search` pra achar
|
|
184
|
-
- Se 404 e user colou ID → pedir de novo
|
|
185
|
-
- Se OK → seguir
|
|
186
|
-
|
|
187
|
-
### Passo 4 — Listar filhos diretos do root (NÃO recursivo)
|
|
188
|
-
|
|
189
|
-
Nesta etapa queremos só o **primeiro nível** da árvore. Pra identificar Input/Output,
|
|
190
|
-
basta saber quais pages estão logo abaixo do root. A árvore profunda vem depois via
|
|
191
|
-
`/sf-load` quando o agent realmente precisa do conteúdo.
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
mcp__atlassian__confluence_get_page_children(page_id={root_page_id})
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**APENAS 1 chamada**. Sem loop recursivo.
|
|
198
|
-
|
|
199
|
-
Mostrar ao usuário:
|
|
200
|
-
```
|
|
201
|
-
Projeto: "Barbearia Digital" (root_page_id: 65708)
|
|
202
|
-
|
|
203
|
-
Filhos diretos do root:
|
|
204
|
-
1. Requisitos (360668)
|
|
205
|
-
2. Documentação técnica (294931)
|
|
206
|
-
3. Referências (557057)
|
|
207
|
-
4. Decisões (425998)
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Se algum desses filhos tiver sub-pages (ex: Requisitos contém scopes), isso será descoberto
|
|
211
|
-
pelo `/sf-load` quando rodar. Aqui só precisamos saber quem é Input e quem é Output no nível 1.
|
|
212
|
-
|
|
213
|
-
### Passo 5 — Identificar Input e Output
|
|
214
|
-
|
|
215
|
-
**Se já existe config com Input/Output**: mostrar o que está salvo + opção de mudar:
|
|
216
|
-
```
|
|
217
|
-
Config atual:
|
|
218
|
-
Input: Requisitos (360668)
|
|
219
|
-
Output: Documentação técnica (294931)
|
|
220
|
-
|
|
221
|
-
Manter? (s/n)
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
Se `s` → pular pro Passo 7.
|
|
225
|
-
Se `n` → continuar perguntando (como se fosse setup novo).
|
|
226
|
-
|
|
227
|
-
**Se é setup novo**:
|
|
228
|
-
```
|
|
229
|
-
Qual dessas pages contém os INSUMOS (Input, onde PM/PO publica)?
|
|
230
|
-
1. Requisitos (360668)
|
|
231
|
-
2. Documentação técnica (294931)
|
|
232
|
-
3. Referências (557057)
|
|
233
|
-
4. Decisões (425998)
|
|
234
|
-
5. Criar nova page "Input" (filha da raiz)
|
|
235
|
-
>
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
Opção 1-4: usar o page_id correspondente.
|
|
239
|
-
Opção 5: criar page nova — `mcp__atlassian__confluence_create_page(parent_id={root}, title="Input", content="")`.
|
|
240
|
-
|
|
241
|
-
Após escolher Input, perguntar Output com as pages **restantes** (remover a escolhida de Input da lista) + opção "Criar nova page 'Output'".
|
|
242
|
-
|
|
243
|
-
Se escolher "Criar nova" → `mcp__atlassian__confluence_create_page` como filha da raiz.
|
|
244
|
-
|
|
245
|
-
### Passo 6 — Sugerir context_pages (opcional)
|
|
246
|
-
|
|
247
|
-
Das pages do nível 1 (filhos diretos do root) que **não** foram escolhidas como Input ou Output,
|
|
248
|
-
sugerir como contexto adicional pro /sf-extract e /sf-design:
|
|
249
|
-
|
|
250
|
-
```
|
|
251
|
-
Das pages restantes no primeiro nível:
|
|
252
|
-
|
|
253
|
-
- "Referências" (557057) → posso consultar durante /sf-extract e /sf-design
|
|
254
|
-
- "Decisões" (425998) → posso consultar para ADRs no /sf-design
|
|
255
|
-
|
|
256
|
-
Quer que eu mapeie alguma dessas como contexto adicional? (listar números, ou "não")
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Se sim, incluir as escolhidas em `context_pages[]` no `sfw.config.yml`.
|
|
260
|
-
|
|
261
|
-
Obs: `/sf-load` descobre a árvore profunda sob Input/Output quando rodar. Aqui só tratamos nível 1.
|
|
262
|
-
|
|
263
|
-
### Passo 7 — Escrever `sfw.config.yml`
|
|
264
|
-
|
|
265
|
-
Preservar seções existentes (naming, etc) se já havia arquivo. Atualizar/criar:
|
|
266
|
-
|
|
267
|
-
```yaml
|
|
268
|
-
project:
|
|
269
|
-
name: "{título da page raiz}"
|
|
270
|
-
root_page_id: "{page_id raiz}"
|
|
271
|
-
|
|
272
|
-
naming:
|
|
273
|
-
output_container: "out_{scope}"
|
|
274
|
-
output_artifact: "{scope} - {type}"
|
|
275
|
-
|
|
276
|
-
input:
|
|
277
|
-
adapter: confluence
|
|
278
|
-
config:
|
|
279
|
-
space_key: "{space_key}"
|
|
280
|
-
parent_page_id: "{page_id do Input}"
|
|
281
|
-
recursive: true
|
|
282
|
-
include_attachments: true
|
|
283
|
-
cache:
|
|
284
|
-
local_dir: "workspace/Input/"
|
|
285
|
-
log: ".ai/load-log.md"
|
|
286
|
-
incremental: true
|
|
287
|
-
|
|
288
|
-
output:
|
|
289
|
-
targets:
|
|
290
|
-
- name: confluence-mirror
|
|
291
|
-
adapter: confluence
|
|
292
|
-
config:
|
|
293
|
-
space_key: "{space_key}"
|
|
294
|
-
parent_page_id: "{page_id do Output}"
|
|
295
|
-
publishes: [PRD, TRD, Progresso]
|
|
296
|
-
mode: auto
|
|
297
|
-
conflict_detection: version
|
|
298
|
-
approval_mechanism: label
|
|
299
|
-
approval_label: "sfw-approved"
|
|
300
|
-
|
|
301
|
-
# Descomente se tiver selecionado context_pages no Passo 6
|
|
302
|
-
# context_pages:
|
|
303
|
-
# - id: "557057"
|
|
304
|
-
# title: "Referências"
|
|
305
|
-
# use_in: [extract, design]
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Passo 8 — Ajustar `.gitignore`
|
|
309
|
-
|
|
310
|
-
Adicionar se não existe:
|
|
311
|
-
```
|
|
312
|
-
.mcp.json
|
|
313
|
-
|
|
314
|
-
# SFW: workspace ignored (external backend detected)
|
|
315
|
-
workspace/Output/**
|
|
316
|
-
!workspace/Output/.gitkeep
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Passo 9 — Resumir
|
|
320
|
-
|
|
321
|
-
```
|
|
322
|
-
Confluence configurado!
|
|
323
|
-
|
|
324
|
-
Projeto: {nome} ({root_page_id})
|
|
325
|
-
Input: {título Input} ({page_id})
|
|
326
|
-
Output: {título Output} ({page_id})
|
|
327
|
-
|
|
328
|
-
Arquivos:
|
|
329
|
-
.mcp.json ← credenciais (gitignored)
|
|
330
|
-
sfw.config.yml ← configuração do projeto
|
|
331
|
-
.gitignore ← atualizado
|
|
332
|
-
|
|
333
|
-
O projeto tem {N} scopes no Input:
|
|
334
|
-
- {lista dos filhos do Input}
|
|
335
|
-
|
|
336
|
-
Próximo passo:
|
|
337
|
-
/sf-start <nome-do-scope>
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Subcomando: `/sf-mcp confluence test`
|
|
343
|
-
|
|
344
|
-
Apenas testa sem modificar arquivos:
|
|
345
|
-
|
|
346
|
-
1. Verificar que `sfw.config.yml` existe com `project.root_page_id` e `input.config.parent_page_id`
|
|
347
|
-
2. Verificar que `.mcp.json` existe com credenciais
|
|
348
|
-
3. Testar `confluence_get_page(root_page_id)` → root acessível?
|
|
349
|
-
4. Testar `confluence_get_page_children(input.config.parent_page_id)` → listar scopes
|
|
350
|
-
5. Reportar:
|
|
351
|
-
```
|
|
352
|
-
Conexão OK!
|
|
353
|
-
Root: "{nome}" ({root_page_id})
|
|
354
|
-
Input: {N} scopes encontrados
|
|
355
|
-
Output: {M} artefatos publicados anteriormente
|
|
356
|
-
```
|
|
357
|
-
6. Se falha: mostrar qual check falhou + link pro troubleshooting
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## Notas
|
|
362
|
-
|
|
363
|
-
- **`/sf-mcp confluence` é idempotente** — pode rodar N vezes. Só pergunta o que falta baseado em `sfw.config.yml` + `.mcp.json`
|
|
364
|
-
- **`root_page_id` é âncora** — sem ele o framework não sabe os limites do projeto no space
|
|
365
|
-
- `.mcp.json` é SEMPRE gitignored — contém credenciais
|
|
366
|
-
- `sfw.config.yml` é commitável — zero segredos
|
|
367
|
-
- Após criar/atualizar `.mcp.json`, VS Code com Copilot Chat PRECISA ser reiniciado
|
|
368
|
-
- O framework conhece o projeto INTEIRO (raiz + toda a árvore), não só Input/Output
|
|
369
|
-
- Token Atlassian pode expirar — se der 401, skill pede novo e atualiza `.mcp.json`
|
|
370
|
-
|
|
371
|
-
## Erros
|
|
372
|
-
|
|
373
|
-
| Erro | Ação |
|
|
374
|
-
|------|------|
|
|
375
|
-
| uvx não instalado | Parar, instruir instalação |
|
|
376
|
-
| MCP não responde após `.mcp.json` novo | Pedir reinício, retomar depois |
|
|
377
|
-
| `root_page_id` 404 | Pedir ID/título correto, validar |
|
|
378
|
-
| Token expirado (401) | Pedir novo token, atualizar .mcp.json, pedir reinício |
|
|
379
|
-
| Sem permissão de escrita no space | Informar, pedir ao admin |
|
|
380
|
-
| Space key inválido | Listar spaces disponíveis se possível |
|
|
381
|
-
|
|
382
|
-
## Referências
|
|
383
|
-
|
|
384
|
-
- Setup guide completo: `.github/adapters/SETUP.md`
|
|
385
|
-
- Confluence adapter: `.github/adapters/confluence.md`
|
|
386
|
-
- Interface do adapter: `.github/adapters/interface.md`
|
|
1
|
+
|
|
2
|
+
# /sf-mcp <provider>
|
|
3
|
+
|
|
4
|
+
Setup interativo de backend externo. Idempotente — pode rodar múltiplas vezes, só pergunta o que falta.
|
|
5
|
+
|
|
6
|
+
## Providers disponíveis
|
|
7
|
+
|
|
8
|
+
| Provider | O que faz |
|
|
9
|
+
|----------|-----------|
|
|
10
|
+
| `confluence` | Configura MCP Atlassian + descobre projeto + cria `sfw.config.yml` + `.mcp.json` + `.gitignore` |
|
|
11
|
+
|
|
12
|
+
## Uso
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
/sf-mcp confluence ← setup ou reconfiguração (idempotente)
|
|
16
|
+
/sf-mcp confluence test ← só testa conexão
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> **Dica**: para evitar o ciclo "abrir Claude → descobrir que falta uvx ou credenciais →
|
|
20
|
+
> sair, ajustar, reiniciar", há um script opcional que prepara o ambiente antes:
|
|
21
|
+
>
|
|
22
|
+
> ```bash
|
|
23
|
+
> node .github/scripts/bootstrap-confluence.js
|
|
24
|
+
> ```
|
|
25
|
+
>
|
|
26
|
+
> Ele valida `uvx`, coleta credenciais, gera `.mcp.json` e pré-cacheia o MCP. Depois
|
|
27
|
+
> você abre o VS Code com Copilot Chat e `/sf-mcp confluence` só descobre a árvore do projeto. Uso
|
|
28
|
+
> opcional — `/sf-mcp confluence` sozinho também cobre esses passos, mas demanda reiniciar
|
|
29
|
+
> o Copilot após gerar `.mcp.json` (MCPs só sobem no startup).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Provider: Confluence
|
|
34
|
+
|
|
35
|
+
### Passo 1 — Detectar estado atual
|
|
36
|
+
|
|
37
|
+
Ler os 2 arquivos âncora:
|
|
38
|
+
|
|
39
|
+
| Arquivo | O que extrair | Se ausente |
|
|
40
|
+
|---------|---------------|------------|
|
|
41
|
+
| `sfw.config.yml` | `project.root_page_id`, `project.name`, credenciais do space (`space_key`) | marcar como "falta config" |
|
|
42
|
+
| `.mcp.json` | entry `mcpServers.atlassian` com `CONFLUENCE_URL`, `CONFLUENCE_USERNAME`, `CONFLUENCE_API_TOKEN` | marcar como "falta credenciais" |
|
|
43
|
+
|
|
44
|
+
Calcular `state`:
|
|
45
|
+
- **COMPLETO** — `sfw.config.yml` tem `root_page_id` E `.mcp.json` tem credenciais → ir pro Passo 2
|
|
46
|
+
- **INCOMPLETO** — algo falta → ir pro Passo 3
|
|
47
|
+
|
|
48
|
+
### Passo 2 — Estado COMPLETO: validar conexão
|
|
49
|
+
|
|
50
|
+
Testar:
|
|
51
|
+
```
|
|
52
|
+
mcp__atlassian__confluence_get_page(page_id={root_page_id})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Resultado | Ação |
|
|
56
|
+
|-----------|------|
|
|
57
|
+
| 200 OK | → Passo 4 (remapear árvore, reconfirmar Input/Output) |
|
|
58
|
+
| 401 Unauthorized | Credencial expirou. Perguntar novo token, atualizar `.mcp.json`, avisar pra reiniciar VS Code com Copilot Chat, PARAR |
|
|
59
|
+
| 404 Not Found | `root_page_id` inválido. Perguntar novo ID, atualizar `sfw.config.yml`, retry teste |
|
|
60
|
+
| MCP não responde | `.mcp.json` foi atualizado mas Claude não recarregou. Avisar pra reiniciar VS Code com Copilot Chat, PARAR |
|
|
61
|
+
| Network error | Mostrar erro, instruir troubleshooting (`.github/adapters/SETUP.md`) |
|
|
62
|
+
|
|
63
|
+
### Passo 3 — Estado INCOMPLETO: coletar o que falta
|
|
64
|
+
|
|
65
|
+
#### 3.1 Verificar `uvx`
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uvx --version
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Se não instalado:
|
|
72
|
+
```
|
|
73
|
+
uvx não encontrado. Instale com:
|
|
74
|
+
pip install uv
|
|
75
|
+
|
|
76
|
+
Depois rode /sf-mcp confluence novamente.
|
|
77
|
+
```
|
|
78
|
+
**PARAR**.
|
|
79
|
+
|
|
80
|
+
#### 3.2 Se FALTA credenciais (`.mcp.json` ausente ou incompleto)
|
|
81
|
+
|
|
82
|
+
Perguntar uma por uma. Pra cada item, mostrar ao user exatamente ONDE achar:
|
|
83
|
+
```
|
|
84
|
+
Configurando acesso ao Confluence.
|
|
85
|
+
|
|
86
|
+
1. URL do Confluence
|
|
87
|
+
Abra o Confluence no browser. A URL base é algo como:
|
|
88
|
+
https://sua-empresa.atlassian.net/wiki
|
|
89
|
+
Cole essa URL (com /wiki no final):
|
|
90
|
+
>
|
|
91
|
+
|
|
92
|
+
2. Email da conta Atlassian
|
|
93
|
+
É o email que você usa pra logar no Atlassian (não é o token).
|
|
94
|
+
>
|
|
95
|
+
|
|
96
|
+
3. API Token
|
|
97
|
+
Token é diferente de senha. Gere um novo:
|
|
98
|
+
a) Abra https://id.atlassian.com/manage-profile/security/api-tokens
|
|
99
|
+
b) Clique "Create API token"
|
|
100
|
+
c) Dê um nome (ex: "sfw-mcp")
|
|
101
|
+
d) Copie o token que aparece — ele só aparece UMA VEZ
|
|
102
|
+
Cole aqui:
|
|
103
|
+
>
|
|
104
|
+
|
|
105
|
+
4. Space Key
|
|
106
|
+
É o código CURTO do seu espaço Confluence (geralmente 2-4 letras maiúsculas).
|
|
107
|
+
Abra qualquer page do seu espaço. Na URL, você verá:
|
|
108
|
+
https://...atlassian.net/wiki/spaces/XXX/pages/...
|
|
109
|
+
^^^
|
|
110
|
+
esse é o Space Key
|
|
111
|
+
Exemplos comuns: "ST", "DEV", "PROJ", "ENG"
|
|
112
|
+
Qual é o seu?:
|
|
113
|
+
>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Criar/atualizar `.mcp.json`:
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"atlassian": {
|
|
121
|
+
"command": "uvx",
|
|
122
|
+
"args": ["mcp-atlassian"],
|
|
123
|
+
"env": {
|
|
124
|
+
"CONFLUENCE_URL": "{url}",
|
|
125
|
+
"CONFLUENCE_USERNAME": "{email}",
|
|
126
|
+
"CONFLUENCE_API_TOKEN": "{token}"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**IMPORTANTE**: credenciais hardcoded — `${VAR}` NÃO funciona no VS Code com Copilot Chat.
|
|
134
|
+
|
|
135
|
+
Se `.mcp.json` acabou de ser criado/atualizado:
|
|
136
|
+
```
|
|
137
|
+
.mcp.json pronto. Preciso que você reinicie o VS Code com Copilot Chat para o MCP carregar.
|
|
138
|
+
|
|
139
|
+
1. Feche o VS Code com Copilot Chat
|
|
140
|
+
2. Abra novamente na mesma pasta
|
|
141
|
+
3. Rode /sf-mcp confluence — vou continuar de onde paramos (credenciais já salvas,
|
|
142
|
+
só vou pedir o que ainda falta)
|
|
143
|
+
```
|
|
144
|
+
**PARAR**.
|
|
145
|
+
|
|
146
|
+
#### 3.3 Se FALTA root_page_id (credenciais OK mas config sem root)
|
|
147
|
+
|
|
148
|
+
Testar conexão básica primeiro:
|
|
149
|
+
```
|
|
150
|
+
mcp__atlassian__confluence_search(query="space.key={space_key}", limit=1)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Se falha → Passo 2 error table (401/MCP não responde/etc).
|
|
154
|
+
Se OK:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
Conexão OK.
|
|
158
|
+
|
|
159
|
+
Qual é a page RAIZ do seu projeto no Confluence?
|
|
160
|
+
(A page-mãe que contém TUDO do projeto — geralmente tem Input e Output como filhas.)
|
|
161
|
+
|
|
162
|
+
Duas formas de informar:
|
|
163
|
+
|
|
164
|
+
A) Page ID (recomendado — mais confiável):
|
|
165
|
+
Abra a page raiz no Confluence. A URL mostra:
|
|
166
|
+
https://...atlassian.net/wiki/spaces/ST/pages/65708/Nome-da-Page
|
|
167
|
+
^^^^^
|
|
168
|
+
esse número é o Page ID
|
|
169
|
+
Cole só o número (ex: 65708).
|
|
170
|
+
|
|
171
|
+
B) Título exato:
|
|
172
|
+
O título que aparece no topo da page. Tem que bater EXATAMENTE
|
|
173
|
+
(incluindo acentos e maiúsculas/minúsculas).
|
|
174
|
+
|
|
175
|
+
Page ID ou título:
|
|
176
|
+
>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Validar:
|
|
180
|
+
```
|
|
181
|
+
mcp__atlassian__confluence_get_page(page_id={resposta})
|
|
182
|
+
```
|
|
183
|
+
- Se 404 e user colou título → usar `confluence_search` pra achar
|
|
184
|
+
- Se 404 e user colou ID → pedir de novo
|
|
185
|
+
- Se OK → seguir
|
|
186
|
+
|
|
187
|
+
### Passo 4 — Listar filhos diretos do root (NÃO recursivo)
|
|
188
|
+
|
|
189
|
+
Nesta etapa queremos só o **primeiro nível** da árvore. Pra identificar Input/Output,
|
|
190
|
+
basta saber quais pages estão logo abaixo do root. A árvore profunda vem depois via
|
|
191
|
+
`/sf-load` quando o agent realmente precisa do conteúdo.
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
mcp__atlassian__confluence_get_page_children(page_id={root_page_id})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**APENAS 1 chamada**. Sem loop recursivo.
|
|
198
|
+
|
|
199
|
+
Mostrar ao usuário:
|
|
200
|
+
```
|
|
201
|
+
Projeto: "Barbearia Digital" (root_page_id: 65708)
|
|
202
|
+
|
|
203
|
+
Filhos diretos do root:
|
|
204
|
+
1. Requisitos (360668)
|
|
205
|
+
2. Documentação técnica (294931)
|
|
206
|
+
3. Referências (557057)
|
|
207
|
+
4. Decisões (425998)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Se algum desses filhos tiver sub-pages (ex: Requisitos contém scopes), isso será descoberto
|
|
211
|
+
pelo `/sf-load` quando rodar. Aqui só precisamos saber quem é Input e quem é Output no nível 1.
|
|
212
|
+
|
|
213
|
+
### Passo 5 — Identificar Input e Output
|
|
214
|
+
|
|
215
|
+
**Se já existe config com Input/Output**: mostrar o que está salvo + opção de mudar:
|
|
216
|
+
```
|
|
217
|
+
Config atual:
|
|
218
|
+
Input: Requisitos (360668)
|
|
219
|
+
Output: Documentação técnica (294931)
|
|
220
|
+
|
|
221
|
+
Manter? (s/n)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Se `s` → pular pro Passo 7.
|
|
225
|
+
Se `n` → continuar perguntando (como se fosse setup novo).
|
|
226
|
+
|
|
227
|
+
**Se é setup novo**:
|
|
228
|
+
```
|
|
229
|
+
Qual dessas pages contém os INSUMOS (Input, onde PM/PO publica)?
|
|
230
|
+
1. Requisitos (360668)
|
|
231
|
+
2. Documentação técnica (294931)
|
|
232
|
+
3. Referências (557057)
|
|
233
|
+
4. Decisões (425998)
|
|
234
|
+
5. Criar nova page "Input" (filha da raiz)
|
|
235
|
+
>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Opção 1-4: usar o page_id correspondente.
|
|
239
|
+
Opção 5: criar page nova — `mcp__atlassian__confluence_create_page(parent_id={root}, title="Input", content="")`.
|
|
240
|
+
|
|
241
|
+
Após escolher Input, perguntar Output com as pages **restantes** (remover a escolhida de Input da lista) + opção "Criar nova page 'Output'".
|
|
242
|
+
|
|
243
|
+
Se escolher "Criar nova" → `mcp__atlassian__confluence_create_page` como filha da raiz.
|
|
244
|
+
|
|
245
|
+
### Passo 6 — Sugerir context_pages (opcional)
|
|
246
|
+
|
|
247
|
+
Das pages do nível 1 (filhos diretos do root) que **não** foram escolhidas como Input ou Output,
|
|
248
|
+
sugerir como contexto adicional pro /sf-extract e /sf-design:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
Das pages restantes no primeiro nível:
|
|
252
|
+
|
|
253
|
+
- "Referências" (557057) → posso consultar durante /sf-extract e /sf-design
|
|
254
|
+
- "Decisões" (425998) → posso consultar para ADRs no /sf-design
|
|
255
|
+
|
|
256
|
+
Quer que eu mapeie alguma dessas como contexto adicional? (listar números, ou "não")
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Se sim, incluir as escolhidas em `context_pages[]` no `sfw.config.yml`.
|
|
260
|
+
|
|
261
|
+
Obs: `/sf-load` descobre a árvore profunda sob Input/Output quando rodar. Aqui só tratamos nível 1.
|
|
262
|
+
|
|
263
|
+
### Passo 7 — Escrever `sfw.config.yml`
|
|
264
|
+
|
|
265
|
+
Preservar seções existentes (naming, etc) se já havia arquivo. Atualizar/criar:
|
|
266
|
+
|
|
267
|
+
```yaml
|
|
268
|
+
project:
|
|
269
|
+
name: "{título da page raiz}"
|
|
270
|
+
root_page_id: "{page_id raiz}"
|
|
271
|
+
|
|
272
|
+
naming:
|
|
273
|
+
output_container: "out_{scope}"
|
|
274
|
+
output_artifact: "{scope} - {type}"
|
|
275
|
+
|
|
276
|
+
input:
|
|
277
|
+
adapter: confluence
|
|
278
|
+
config:
|
|
279
|
+
space_key: "{space_key}"
|
|
280
|
+
parent_page_id: "{page_id do Input}"
|
|
281
|
+
recursive: true
|
|
282
|
+
include_attachments: true
|
|
283
|
+
cache:
|
|
284
|
+
local_dir: "workspace/Input/"
|
|
285
|
+
log: ".ai/load-log.md"
|
|
286
|
+
incremental: true
|
|
287
|
+
|
|
288
|
+
output:
|
|
289
|
+
targets:
|
|
290
|
+
- name: confluence-mirror
|
|
291
|
+
adapter: confluence
|
|
292
|
+
config:
|
|
293
|
+
space_key: "{space_key}"
|
|
294
|
+
parent_page_id: "{page_id do Output}"
|
|
295
|
+
publishes: [PRD, TRD, Progresso]
|
|
296
|
+
mode: auto
|
|
297
|
+
conflict_detection: version
|
|
298
|
+
approval_mechanism: label
|
|
299
|
+
approval_label: "sfw-approved"
|
|
300
|
+
|
|
301
|
+
# Descomente se tiver selecionado context_pages no Passo 6
|
|
302
|
+
# context_pages:
|
|
303
|
+
# - id: "557057"
|
|
304
|
+
# title: "Referências"
|
|
305
|
+
# use_in: [extract, design]
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Passo 8 — Ajustar `.gitignore`
|
|
309
|
+
|
|
310
|
+
Adicionar se não existe:
|
|
311
|
+
```
|
|
312
|
+
.mcp.json
|
|
313
|
+
|
|
314
|
+
# SFW: workspace ignored (external backend detected)
|
|
315
|
+
workspace/Output/**
|
|
316
|
+
!workspace/Output/.gitkeep
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Passo 9 — Resumir
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
Confluence configurado!
|
|
323
|
+
|
|
324
|
+
Projeto: {nome} ({root_page_id})
|
|
325
|
+
Input: {título Input} ({page_id})
|
|
326
|
+
Output: {título Output} ({page_id})
|
|
327
|
+
|
|
328
|
+
Arquivos:
|
|
329
|
+
.mcp.json ← credenciais (gitignored)
|
|
330
|
+
sfw.config.yml ← configuração do projeto
|
|
331
|
+
.gitignore ← atualizado
|
|
332
|
+
|
|
333
|
+
O projeto tem {N} scopes no Input:
|
|
334
|
+
- {lista dos filhos do Input}
|
|
335
|
+
|
|
336
|
+
Próximo passo:
|
|
337
|
+
/sf-start <nome-do-scope>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Subcomando: `/sf-mcp confluence test`
|
|
343
|
+
|
|
344
|
+
Apenas testa sem modificar arquivos:
|
|
345
|
+
|
|
346
|
+
1. Verificar que `sfw.config.yml` existe com `project.root_page_id` e `input.config.parent_page_id`
|
|
347
|
+
2. Verificar que `.mcp.json` existe com credenciais
|
|
348
|
+
3. Testar `confluence_get_page(root_page_id)` → root acessível?
|
|
349
|
+
4. Testar `confluence_get_page_children(input.config.parent_page_id)` → listar scopes
|
|
350
|
+
5. Reportar:
|
|
351
|
+
```
|
|
352
|
+
Conexão OK!
|
|
353
|
+
Root: "{nome}" ({root_page_id})
|
|
354
|
+
Input: {N} scopes encontrados
|
|
355
|
+
Output: {M} artefatos publicados anteriormente
|
|
356
|
+
```
|
|
357
|
+
6. Se falha: mostrar qual check falhou + link pro troubleshooting
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Notas
|
|
362
|
+
|
|
363
|
+
- **`/sf-mcp confluence` é idempotente** — pode rodar N vezes. Só pergunta o que falta baseado em `sfw.config.yml` + `.mcp.json`
|
|
364
|
+
- **`root_page_id` é âncora** — sem ele o framework não sabe os limites do projeto no space
|
|
365
|
+
- `.mcp.json` é SEMPRE gitignored — contém credenciais
|
|
366
|
+
- `sfw.config.yml` é commitável — zero segredos
|
|
367
|
+
- Após criar/atualizar `.mcp.json`, VS Code com Copilot Chat PRECISA ser reiniciado
|
|
368
|
+
- O framework conhece o projeto INTEIRO (raiz + toda a árvore), não só Input/Output
|
|
369
|
+
- Token Atlassian pode expirar — se der 401, skill pede novo e atualiza `.mcp.json`
|
|
370
|
+
|
|
371
|
+
## Erros
|
|
372
|
+
|
|
373
|
+
| Erro | Ação |
|
|
374
|
+
|------|------|
|
|
375
|
+
| uvx não instalado | Parar, instruir instalação |
|
|
376
|
+
| MCP não responde após `.mcp.json` novo | Pedir reinício, retomar depois |
|
|
377
|
+
| `root_page_id` 404 | Pedir ID/título correto, validar |
|
|
378
|
+
| Token expirado (401) | Pedir novo token, atualizar .mcp.json, pedir reinício |
|
|
379
|
+
| Sem permissão de escrita no space | Informar, pedir ao admin |
|
|
380
|
+
| Space key inválido | Listar spaces disponíveis se possível |
|
|
381
|
+
|
|
382
|
+
## Referências
|
|
383
|
+
|
|
384
|
+
- Setup guide completo: `.github/adapters/SETUP.md`
|
|
385
|
+
- Confluence adapter: `.github/adapters/confluence.md`
|
|
386
|
+
- Interface do adapter: `.github/adapters/interface.md`
|