spec-first-copilot 0.7.0 → 0.8.0-beta.2
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 +45 -0
- package/bin/cli.js +1 -1
- package/package.json +1 -1
- package/templates/.github/CHANGELOG.md +61 -0
- package/templates/.github/copilot-instructions.md +4 -2
- 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-onboard/SKILL.md +437 -0
- 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/decisions.template.md +140 -107
- package/templates/.github/templates/feature/TRD.template.md +450 -358
- package/templates/.github/templates/feature/context.template.md +118 -89
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
|
|
2
|
-
# /sf-plan $ARGUMENTS
|
|
3
|
-
|
|
4
|
-
Skill atômica de planejamento. Lê **PRD + TRD + specs/{nome}/** e gera
|
|
5
|
-
`specs/{nome}/tasks.md` (arquivo único) + `workspace/Output/{nome}/Progresso.md`.
|
|
6
|
-
`$ARGUMENTS` = nome do scope (ex: `app_barbearia`, `feat_cadastro_cliente`).
|
|
7
|
-
|
|
8
|
-
## Agente: Planner (Opus)
|
|
9
|
-
|
|
10
|
-
Metódico e exaustivo. Cada task auto-contida. Prioriza ordem correta.
|
|
11
|
-
|
|
12
|
-
## Pré-condições
|
|
13
|
-
|
|
14
|
-
| # | Validação | Se falhar |
|
|
15
|
-
|---|-----------|-----------|
|
|
16
|
-
| 1 | $ARGUMENTS informado | Parar |
|
|
17
|
-
| 2 | `.context.md` com status `design_done` | Se anterior → "/sf-design primeiro". Se posterior → "Tasks já geradas" |
|
|
18
|
-
| 3 | Se `prd_existe=true`: PRD.md existe e `prd_aprovado=true` | Parar (não deveria passar pelo /sf-design, mas defensivo) |
|
|
19
|
-
| 4 | Se `trd_existe=true`: TRD.md existe e `trd_aprovado=true` | Parar |
|
|
20
|
-
| 5 | `specs/{nome}/{contracts,scenarios}.md` existem (projeções do /sf-design) | Parar → "/sf-design não gerou projeções — re-rode" |
|
|
21
|
-
|
|
22
|
-
## Passos
|
|
23
|
-
|
|
24
|
-
### 1. Ler contexto
|
|
25
|
-
|
|
26
|
-
- `workspace/Output/{nome}/PRD.md` (se prd_existe) + `TRD.md` (se trd_existe) — fontes
|
|
27
|
-
- `specs/{nome}/{brief,contracts,scenarios}.md` (projeções já geradas pelo /sf-design)
|
|
28
|
-
- `projetos.yaml` + `docs/` (architecture, domain, conventions) + `.github/rules.md`
|
|
29
|
-
- Template `.github/templates/specs/tasks.template.md`
|
|
30
|
-
|
|
31
|
-
### 2. Identificar fases de entrega
|
|
32
|
-
|
|
33
|
-
Ler **PRD §10 (Fases de Entrega)** — cada fase vira um agrupamento de tasks:
|
|
34
|
-
|
|
35
|
-
- Fases são sequenciais: Fase 2 depende de Fase 1 concluída
|
|
36
|
-
- Cada fase tem entregável + critério de done
|
|
37
|
-
- O `/sf-dev` pode rodar por fase: `/sf-dev feat_nome --fase 1`
|
|
38
|
-
|
|
39
|
-
**Se scope não tem PRD** (puro-técnico): toda task vai pra **Fase 1**. Não há
|
|
40
|
-
fases de entrega de produto — é bootstrap/infra em uma leva só.
|
|
41
|
-
|
|
42
|
-
### 3. Identificar áreas (dinâmicas, vêm do TRD)
|
|
43
|
-
|
|
44
|
-
Ler `.context.md → areas_tocadas` (populado pelo /sf-design a partir dos GATEs do TRD).
|
|
45
|
-
|
|
46
|
-
| Seção do TRD | Área |
|
|
47
|
-
|--------------|------|
|
|
48
|
-
| §2 §Área-Backend (GATE=SIM) | BACK |
|
|
49
|
-
| §3 §Área-Frontend (GATE=SIM) | FRONT |
|
|
50
|
-
| §4 §Área-DB (GATE=SIM) | DB |
|
|
51
|
-
| §5 §Área-Infra (GATE=SIM) | INFRA |
|
|
52
|
-
|
|
53
|
-
Áreas com GATE=NÃO não geram tasks nessa área. Se o scope tem apenas PRD (raríssimo
|
|
54
|
-
caso puro-produto sem TRD): área FRONT derivada de PRD §7 Telas.
|
|
55
|
-
|
|
56
|
-
**INFRA em first-run** (detectado via `first_run=true` no .context):
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
- [ ] INFRA-001: Validar ambiente local + setup repos (projetos.yaml)
|
|
60
|
-
- [ ] INFRA-002: Docker-compose dev (só dependências) + Dockerfiles prod
|
|
61
|
-
- [ ] INFRA-003: Hello world — subir stack completa e validar
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
INFRA-001 sempre a PRIMEIRA; INFRA-003 sempre a ÚLTIMA da Fase 1 (validação).
|
|
65
|
-
|
|
66
|
-
### 4. Gerar `specs/{nome}/tasks.md` (arquivo único)
|
|
67
|
-
|
|
68
|
-
Tabela única com coluna `Área` diferenciando:
|
|
69
|
-
|
|
70
|
-
```markdown
|
|
71
|
-
| ID | Área | Fase | Tam | Título | Repo | Arquivos | Depende de | Ref TRD | Ref CA |
|
|
72
|
-
|----|------|------|-----|--------|------|----------|-----------|---------|--------|
|
|
73
|
-
| DB-001 | DB | 1 | S | Migration clientes | api | src/db/migrations/... | — | TRD §4.1 | — |
|
|
74
|
-
| BACK-001 | BACK | 1 | M | Endpoint POST /clientes | api | src/routes/... | DB-001 | TRD §2.1 | CA-001 |
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Regras** (ver `.github/templates/specs/tasks.template.md` pra detalhes):
|
|
78
|
-
|
|
79
|
-
- Cada task é atômica — coder lê `specs/{nome}/` + task, nada mais
|
|
80
|
-
- **Repo obrigatório** — consultar `projetos.yaml`. Caminhos relativos ao repo.
|
|
81
|
-
- Área é COLUNA, não arquivo (DB, BACK, FRONT, INFRA, MOBILE...)
|
|
82
|
-
- Tamanhos: S (≤2h), M (≤4h), L (≤2 dias). L → considerar dividir (INVEST: Small)
|
|
83
|
-
- IDs sequenciais por área, nunca reutilizar
|
|
84
|
-
- Dependências cross-area permitidas
|
|
85
|
-
- `Ref TRD`: seção do TRD (ex: `§2.1`, `§4.2`) — obrigatório quando TRD existe
|
|
86
|
-
- `Ref CA`: ID do CA em `specs/{nome}/scenarios.md` ou `—`
|
|
87
|
-
- Ordenar por Fase → Área → ID (visual)
|
|
88
|
-
|
|
89
|
-
**Tasks L**: preencher bloco "Done When — {TASK-ID}" abaixo da tabela com 3-5
|
|
90
|
-
bullets verificáveis.
|
|
91
|
-
|
|
92
|
-
### 5. Gerar `workspace/Output/{nome}/Progresso.md` (tracking)
|
|
93
|
-
|
|
94
|
-
Progresso.md vive em **workspace/Output** (tracking de execução, não spec).
|
|
95
|
-
|
|
96
|
-
- Resumo Área × Fase com contagem (derivado de `tasks.md`)
|
|
97
|
-
- Ordem de execução com paralelismos
|
|
98
|
-
- Checklist pós-conclusão (já coberto pelo /sf-merge-docs automático no fim do /sf-dev)
|
|
99
|
-
|
|
100
|
-
**Regra**: status das tasks vive SÓ em Progresso.md. `tasks.md` é o plano imutável.
|
|
101
|
-
|
|
102
|
-
### 6. Atualizar `.context.md`
|
|
103
|
-
|
|
104
|
-
```yaml
|
|
105
|
-
status: "plan_done"
|
|
106
|
-
ultima_skill: "/sf-plan"
|
|
107
|
-
atualizado_em: "{{ISO_DATETIME}}"
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### 7. Publicar Progresso no backend (se `sfw.config.yml` existe)
|
|
111
|
-
|
|
112
|
-
Chamar `/sf-publish $ARGUMENTS Progresso`. Respeita `mode` de cada target.
|
|
113
|
-
|
|
114
|
-
**Nota**: `tasks.md`, `specs/*`, `docs/*`, `projetos.yaml` são **LOCAL ONLY** — `/sf-publish`
|
|
115
|
-
nunca toca neles. Apenas PRD/TRD/Progresso vão pro Confluence.
|
|
116
|
-
|
|
117
|
-
### 8. Saída obrigatória
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
/sf-plan $ARGUMENTS — completo
|
|
121
|
-
|
|
122
|
-
Artefatos locais:
|
|
123
|
-
- specs/$ARGUMENTS/tasks.md ({N} tasks em {F} fases, áreas: [{lista}])
|
|
124
|
-
- workspace/Output/$ARGUMENTS/Progresso.md
|
|
125
|
-
|
|
126
|
-
Publish:
|
|
127
|
-
- {target-name}: Progresso: {{status}}
|
|
128
|
-
OU
|
|
129
|
-
- SKIPPED (no sfw.config.yml)
|
|
130
|
-
|
|
131
|
-
Próximo passo:
|
|
132
|
-
/sf-dev $ARGUMENTS ← implementa tudo
|
|
133
|
-
/sf-dev $ARGUMENTS --fase 1 ← só a primeira fase (RECOMENDADO)
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Saídas
|
|
137
|
-
|
|
138
|
-
- `specs/{nome}/tasks.md` — plano (tabela única)
|
|
139
|
-
- `workspace/Output/{nome}/Progresso.md` — tracking
|
|
140
|
-
|
|
141
|
-
## Rastreabilidade
|
|
142
|
-
|
|
143
|
-
Cada task gerada deve ter:
|
|
144
|
-
- **Ref TRD** (se TRD existe): seção do TRD que motivou — garante que nada do TRD
|
|
145
|
-
fica sem task correspondente
|
|
146
|
-
- **Ref CA** (se aplicável): garante que cada CA em `scenarios.md` tem pelo menos
|
|
147
|
-
1 task que o satisfaz
|
|
148
|
-
|
|
149
|
-
Validação final antes de terminar:
|
|
150
|
-
- Todo endpoint do TRD §2.1 tem task BACK correspondente? ✓
|
|
151
|
-
- Toda tabela/migration do TRD §4 tem task DB correspondente? ✓
|
|
152
|
-
- Todo CA em `scenarios.md` tem task Ref CA correspondente (ou justificativa de why not)? ✓
|
|
1
|
+
|
|
2
|
+
# /sf-plan $ARGUMENTS
|
|
3
|
+
|
|
4
|
+
Skill atômica de planejamento. Lê **PRD + TRD + specs/{nome}/** e gera
|
|
5
|
+
`specs/{nome}/tasks.md` (arquivo único) + `workspace/Output/{nome}/Progresso.md`.
|
|
6
|
+
`$ARGUMENTS` = nome do scope (ex: `app_barbearia`, `feat_cadastro_cliente`).
|
|
7
|
+
|
|
8
|
+
## Agente: Planner (Opus)
|
|
9
|
+
|
|
10
|
+
Metódico e exaustivo. Cada task auto-contida. Prioriza ordem correta.
|
|
11
|
+
|
|
12
|
+
## Pré-condições
|
|
13
|
+
|
|
14
|
+
| # | Validação | Se falhar |
|
|
15
|
+
|---|-----------|-----------|
|
|
16
|
+
| 1 | $ARGUMENTS informado | Parar |
|
|
17
|
+
| 2 | `.context.md` com status `design_done` | Se anterior → "/sf-design primeiro". Se posterior → "Tasks já geradas" |
|
|
18
|
+
| 3 | Se `prd_existe=true`: PRD.md existe e `prd_aprovado=true` | Parar (não deveria passar pelo /sf-design, mas defensivo) |
|
|
19
|
+
| 4 | Se `trd_existe=true`: TRD.md existe e `trd_aprovado=true` | Parar |
|
|
20
|
+
| 5 | `specs/{nome}/{contracts,scenarios}.md` existem (projeções do /sf-design) | Parar → "/sf-design não gerou projeções — re-rode" |
|
|
21
|
+
|
|
22
|
+
## Passos
|
|
23
|
+
|
|
24
|
+
### 1. Ler contexto
|
|
25
|
+
|
|
26
|
+
- `workspace/Output/{nome}/PRD.md` (se prd_existe) + `TRD.md` (se trd_existe) — fontes
|
|
27
|
+
- `specs/{nome}/{brief,contracts,scenarios}.md` (projeções já geradas pelo /sf-design)
|
|
28
|
+
- `projetos.yaml` + `docs/` (architecture, domain, conventions) + `.github/rules.md`
|
|
29
|
+
- Template `.github/templates/specs/tasks.template.md`
|
|
30
|
+
|
|
31
|
+
### 2. Identificar fases de entrega
|
|
32
|
+
|
|
33
|
+
Ler **PRD §10 (Fases de Entrega)** — cada fase vira um agrupamento de tasks:
|
|
34
|
+
|
|
35
|
+
- Fases são sequenciais: Fase 2 depende de Fase 1 concluída
|
|
36
|
+
- Cada fase tem entregável + critério de done
|
|
37
|
+
- O `/sf-dev` pode rodar por fase: `/sf-dev feat_nome --fase 1`
|
|
38
|
+
|
|
39
|
+
**Se scope não tem PRD** (puro-técnico): toda task vai pra **Fase 1**. Não há
|
|
40
|
+
fases de entrega de produto — é bootstrap/infra em uma leva só.
|
|
41
|
+
|
|
42
|
+
### 3. Identificar áreas (dinâmicas, vêm do TRD)
|
|
43
|
+
|
|
44
|
+
Ler `.context.md → areas_tocadas` (populado pelo /sf-design a partir dos GATEs do TRD).
|
|
45
|
+
|
|
46
|
+
| Seção do TRD | Área |
|
|
47
|
+
|--------------|------|
|
|
48
|
+
| §2 §Área-Backend (GATE=SIM) | BACK |
|
|
49
|
+
| §3 §Área-Frontend (GATE=SIM) | FRONT |
|
|
50
|
+
| §4 §Área-DB (GATE=SIM) | DB |
|
|
51
|
+
| §5 §Área-Infra (GATE=SIM) | INFRA |
|
|
52
|
+
|
|
53
|
+
Áreas com GATE=NÃO não geram tasks nessa área. Se o scope tem apenas PRD (raríssimo
|
|
54
|
+
caso puro-produto sem TRD): área FRONT derivada de PRD §7 Telas.
|
|
55
|
+
|
|
56
|
+
**INFRA em first-run** (detectado via `first_run=true` no .context):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
- [ ] INFRA-001: Validar ambiente local + setup repos (projetos.yaml)
|
|
60
|
+
- [ ] INFRA-002: Docker-compose dev (só dependências) + Dockerfiles prod
|
|
61
|
+
- [ ] INFRA-003: Hello world — subir stack completa e validar
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
INFRA-001 sempre a PRIMEIRA; INFRA-003 sempre a ÚLTIMA da Fase 1 (validação).
|
|
65
|
+
|
|
66
|
+
### 4. Gerar `specs/{nome}/tasks.md` (arquivo único)
|
|
67
|
+
|
|
68
|
+
Tabela única com coluna `Área` diferenciando:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
| ID | Área | Fase | Tam | Título | Repo | Arquivos | Depende de | Ref TRD | Ref CA |
|
|
72
|
+
|----|------|------|-----|--------|------|----------|-----------|---------|--------|
|
|
73
|
+
| DB-001 | DB | 1 | S | Migration clientes | api | src/db/migrations/... | — | TRD §4.1 | — |
|
|
74
|
+
| BACK-001 | BACK | 1 | M | Endpoint POST /clientes | api | src/routes/... | DB-001 | TRD §2.1 | CA-001 |
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Regras** (ver `.github/templates/specs/tasks.template.md` pra detalhes):
|
|
78
|
+
|
|
79
|
+
- Cada task é atômica — coder lê `specs/{nome}/` + task, nada mais
|
|
80
|
+
- **Repo obrigatório** — consultar `projetos.yaml`. Caminhos relativos ao repo.
|
|
81
|
+
- Área é COLUNA, não arquivo (DB, BACK, FRONT, INFRA, MOBILE...)
|
|
82
|
+
- Tamanhos: S (≤2h), M (≤4h), L (≤2 dias). L → considerar dividir (INVEST: Small)
|
|
83
|
+
- IDs sequenciais por área, nunca reutilizar
|
|
84
|
+
- Dependências cross-area permitidas
|
|
85
|
+
- `Ref TRD`: seção do TRD (ex: `§2.1`, `§4.2`) — obrigatório quando TRD existe
|
|
86
|
+
- `Ref CA`: ID do CA em `specs/{nome}/scenarios.md` ou `—`
|
|
87
|
+
- Ordenar por Fase → Área → ID (visual)
|
|
88
|
+
|
|
89
|
+
**Tasks L**: preencher bloco "Done When — {TASK-ID}" abaixo da tabela com 3-5
|
|
90
|
+
bullets verificáveis.
|
|
91
|
+
|
|
92
|
+
### 5. Gerar `workspace/Output/{nome}/Progresso.md` (tracking)
|
|
93
|
+
|
|
94
|
+
Progresso.md vive em **workspace/Output** (tracking de execução, não spec).
|
|
95
|
+
|
|
96
|
+
- Resumo Área × Fase com contagem (derivado de `tasks.md`)
|
|
97
|
+
- Ordem de execução com paralelismos
|
|
98
|
+
- Checklist pós-conclusão (já coberto pelo /sf-merge-docs automático no fim do /sf-dev)
|
|
99
|
+
|
|
100
|
+
**Regra**: status das tasks vive SÓ em Progresso.md. `tasks.md` é o plano imutável.
|
|
101
|
+
|
|
102
|
+
### 6. Atualizar `.context.md`
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
status: "plan_done"
|
|
106
|
+
ultima_skill: "/sf-plan"
|
|
107
|
+
atualizado_em: "{{ISO_DATETIME}}"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 7. Publicar Progresso no backend (se `sfw.config.yml` existe)
|
|
111
|
+
|
|
112
|
+
Chamar `/sf-publish $ARGUMENTS Progresso`. Respeita `mode` de cada target.
|
|
113
|
+
|
|
114
|
+
**Nota**: `tasks.md`, `specs/*`, `docs/*`, `projetos.yaml` são **LOCAL ONLY** — `/sf-publish`
|
|
115
|
+
nunca toca neles. Apenas PRD/TRD/Progresso vão pro Confluence.
|
|
116
|
+
|
|
117
|
+
### 8. Saída obrigatória
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
/sf-plan $ARGUMENTS — completo
|
|
121
|
+
|
|
122
|
+
Artefatos locais:
|
|
123
|
+
- specs/$ARGUMENTS/tasks.md ({N} tasks em {F} fases, áreas: [{lista}])
|
|
124
|
+
- workspace/Output/$ARGUMENTS/Progresso.md
|
|
125
|
+
|
|
126
|
+
Publish:
|
|
127
|
+
- {target-name}: Progresso: {{status}}
|
|
128
|
+
OU
|
|
129
|
+
- SKIPPED (no sfw.config.yml)
|
|
130
|
+
|
|
131
|
+
Próximo passo:
|
|
132
|
+
/sf-dev $ARGUMENTS ← implementa tudo
|
|
133
|
+
/sf-dev $ARGUMENTS --fase 1 ← só a primeira fase (RECOMENDADO)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Saídas
|
|
137
|
+
|
|
138
|
+
- `specs/{nome}/tasks.md` — plano (tabela única)
|
|
139
|
+
- `workspace/Output/{nome}/Progresso.md` — tracking
|
|
140
|
+
|
|
141
|
+
## Rastreabilidade
|
|
142
|
+
|
|
143
|
+
Cada task gerada deve ter:
|
|
144
|
+
- **Ref TRD** (se TRD existe): seção do TRD que motivou — garante que nada do TRD
|
|
145
|
+
fica sem task correspondente
|
|
146
|
+
- **Ref CA** (se aplicável): garante que cada CA em `scenarios.md` tem pelo menos
|
|
147
|
+
1 task que o satisfaz
|
|
148
|
+
|
|
149
|
+
Validação final antes de terminar:
|
|
150
|
+
- Todo endpoint do TRD §2.1 tem task BACK correspondente? ✓
|
|
151
|
+
- Toda tabela/migration do TRD §4 tem task DB correspondente? ✓
|
|
152
|
+
- Todo CA em `scenarios.md` tem task Ref CA correspondente (ou justificativa de why not)? ✓
|
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
|
|
2
|
-
# /sf-publish <nome> <tipo>
|
|
3
|
-
|
|
4
|
-
Publica um artefato gerado localmente no(s) backend(s) configurado(s) como `output.targets[]` no `sfw.config.yml`.
|
|
5
|
-
|
|
6
|
-
## Argumentos
|
|
7
|
-
|
|
8
|
-
- `<nome>` = scope do artefato (ex: `app_barbearia`, `feat_login`)
|
|
9
|
-
- `<tipo>` = tipo do artefato: `PRD` | `TRD` | `Progresso`
|
|
10
|
-
|
|
11
|
-
## Quando é chamado
|
|
12
|
-
|
|
13
|
-
Automaticamente pelos commands:
|
|
14
|
-
- `/sf-extract` → publica `PRD` (se `prd_existe=true`) E `TRD` (se `trd_existe=true`)
|
|
15
|
-
- `/sf-plan` → publica `Progresso` no fim
|
|
16
|
-
- `/sf-design` → **não publica** (gera apenas artefatos locais: docs/, specs/, projetos.yaml)
|
|
17
|
-
|
|
18
|
-
Manualmente: quando o usuário quer re-publicar um artefato após editar local.
|
|
19
|
-
|
|
20
|
-
## Modo (`mode` no sfw.config.yml)
|
|
21
|
-
|
|
22
|
-
| Mode | Comportamento |
|
|
23
|
-
|------|---------------|
|
|
24
|
-
| `auto` | Publica sem perguntar (default) |
|
|
25
|
-
| `manual` | Gera artefato local, pergunta "Publicar no {target.name}? (s/n)" |
|
|
26
|
-
| `off` | Ignora o target completamente |
|
|
27
|
-
|
|
28
|
-
## Pré-condições
|
|
29
|
-
|
|
30
|
-
| # | Validação | Se falhar |
|
|
31
|
-
|---|-----------|-----------|
|
|
32
|
-
| 1 | `sfw.config.yml` existe | Parar → "Sem sfw.config.yml, publish desabilitado. Artefato local está em workspace/Output/{nome}/{tipo}.md" |
|
|
33
|
-
| 2 | Tipo está na `publishes` do target | Pular target, informar |
|
|
34
|
-
| 3 | Arquivo local existe em `workspace/Output/{nome}/{tipo}.md` (ou .lower) | Parar → "Arquivo não encontrado" |
|
|
35
|
-
|
|
36
|
-
## Execução
|
|
37
|
-
|
|
38
|
-
### 1. Carregar configuração
|
|
39
|
-
|
|
40
|
-
- Ler `sfw.config.yml`
|
|
41
|
-
- Para cada target em `output.targets[]`:
|
|
42
|
-
- Verificar `mode` (se `off` → pular)
|
|
43
|
-
- Verificar `publishes` inclui `<tipo>` (se não → pular)
|
|
44
|
-
- Se `mode: manual` → perguntar ao usuário
|
|
45
|
-
|
|
46
|
-
### 2. Ler artefato local
|
|
47
|
-
|
|
48
|
-
Ler `workspace/Output/{nome}/{arquivo}` onde arquivo depende do tipo:
|
|
49
|
-
- `PRD` → `PRD.md`
|
|
50
|
-
- `TRD` → `TRD.md`
|
|
51
|
-
- `Progresso` → `Progresso.md`
|
|
52
|
-
|
|
53
|
-
### 3. Aplicar naming
|
|
54
|
-
|
|
55
|
-
Usar templates do `naming` no `sfw.config.yml`:
|
|
56
|
-
- `containerTitle = applyNaming(naming.output_container, {scope: nome})`
|
|
57
|
-
- Ex: `"out_app_barbearia"`
|
|
58
|
-
- `artifactTitle = applyNaming(naming.output_artifact, {scope: nome, type: tipo})`
|
|
59
|
-
- Ex: `"app_barbearia - PRD"`
|
|
60
|
-
|
|
61
|
-
### 4. Para cada target ativo — publicar
|
|
62
|
-
|
|
63
|
-
**Confluence**:
|
|
64
|
-
|
|
65
|
-
1. Listar filhos de `target.config.parent_page_id` (Output)
|
|
66
|
-
2. Buscar container pelo `containerTitle`:
|
|
67
|
-
- **Não existe** → `mcp__atlassian__confluence_create_page` como filho de Output
|
|
68
|
-
- **Existe** → pegar `container.id`
|
|
69
|
-
3. Listar filhos do container
|
|
70
|
-
4. Buscar artefato pelo `artifactTitle`:
|
|
71
|
-
- **Não existe** → `mcp__atlassian__confluence_create_page` com `content=markdown local`
|
|
72
|
-
- **Existe** → precisa atualizar (próximo passo)
|
|
73
|
-
|
|
74
|
-
### 5. Conflict detection (update)
|
|
75
|
-
|
|
76
|
-
Se artefato existe no backend:
|
|
77
|
-
|
|
78
|
-
1. Ler `.ai/publish-log.md` pra pegar a última `version` publicada desse artefato
|
|
79
|
-
2. Chamar `mcp__atlassian__confluence_get_page(page_id=artifact.id)` → pega `currentVersion`
|
|
80
|
-
3. **Se `currentVersion != lastPublishedVersion`** → DRIFT detectado
|
|
81
|
-
- Alguém editou no Confluence depois do último publish
|
|
82
|
-
- Mostrar ao usuário:
|
|
83
|
-
```
|
|
84
|
-
CONFLITO: "{artifactTitle}" foi editada no Confluence desde o último publish.
|
|
85
|
-
|
|
86
|
-
Última version publicada por nós: {last}
|
|
87
|
-
Version atual no Confluence: {current}
|
|
88
|
-
|
|
89
|
-
Opções:
|
|
90
|
-
1. Sobrescrever (perde edição manual)
|
|
91
|
-
2. Abortar (edita local depois)
|
|
92
|
-
3. Ver diff
|
|
93
|
-
```
|
|
94
|
-
- Esperar decisão
|
|
95
|
-
4. Se sem drift → `mcp__atlassian__confluence_update_page(page_id, content)`
|
|
96
|
-
5. Ler nova `version` retornada
|
|
97
|
-
|
|
98
|
-
### 6. Registrar em `.ai/publish-log.md`
|
|
99
|
-
|
|
100
|
-
Formato append-only:
|
|
101
|
-
|
|
102
|
-
```markdown
|
|
103
|
-
## Publish: {nome} {tipo} — {ISO_DATETIME}
|
|
104
|
-
|
|
105
|
-
| Target | Container | Artifact ID | Version | Status |
|
|
106
|
-
|--------|-----------|-------------|---------|--------|
|
|
107
|
-
| confluence-mirror | out_app_barbearia (393220) | 393238 | 3 | UPDATED |
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Status: `CREATED`, `UPDATED`, `SKIPPED` (se INALTERADO), `CONFLICT` (se drift não resolvido)
|
|
111
|
-
|
|
112
|
-
### 7. Informar o usuário
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
Publicado: {nome} {tipo}
|
|
116
|
-
|
|
117
|
-
confluence-mirror: app_barbearia - PRD (v3) — UPDATED
|
|
118
|
-
|
|
119
|
-
Link: https://empresa.atlassian.net/wiki/spaces/ST/pages/393238
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Erros
|
|
123
|
-
|
|
124
|
-
| Erro | Ação |
|
|
125
|
-
|------|------|
|
|
126
|
-
| `sfw.config.yml` não existe | Skippa todos os targets, só salva local |
|
|
127
|
-
| Target MCP não disponível | Avisar, pular target |
|
|
128
|
-
| Sem permissão de escrita | Avisar, pular target |
|
|
129
|
-
| Conflict não resolvido | Não publicar, salvar como CONFLICT no log |
|
|
130
|
-
| Container Output não existe | Criar automaticamente como filho de `output.parent_page_id` |
|
|
131
|
-
|
|
132
|
-
## Notas
|
|
133
|
-
|
|
134
|
-
- O `/sf-publish` é **idempotente** pra content sem mudanças — detecta hash igual e marca `SKIPPED`
|
|
135
|
-
- `naming.output_container` e `naming.output_artifact` são aplicados em TODOS os targets
|
|
136
|
-
- Cada target pode ter `publishes: []` diferente (permite segmentar: Confluence recebe 4 artefatos, filesystem recebe todos)
|
|
137
|
-
- `.ai/publish-log.md` é essencial pro conflict detection funcionar
|
|
138
|
-
- Nunca publica tasks.md, docs/, specs/, projetos.yaml — esses são LOCAL ONLY
|
|
139
|
-
|
|
140
|
-
## Referências
|
|
141
|
-
|
|
142
|
-
- Adapter interface: `.github/adapters/interface.md`
|
|
143
|
-
- Confluence adapter: `.github/adapters/confluence.md`
|
|
144
|
-
- Naming engine: `.github/adapters/naming.md`
|
|
1
|
+
|
|
2
|
+
# /sf-publish <nome> <tipo>
|
|
3
|
+
|
|
4
|
+
Publica um artefato gerado localmente no(s) backend(s) configurado(s) como `output.targets[]` no `sfw.config.yml`.
|
|
5
|
+
|
|
6
|
+
## Argumentos
|
|
7
|
+
|
|
8
|
+
- `<nome>` = scope do artefato (ex: `app_barbearia`, `feat_login`)
|
|
9
|
+
- `<tipo>` = tipo do artefato: `PRD` | `TRD` | `Progresso`
|
|
10
|
+
|
|
11
|
+
## Quando é chamado
|
|
12
|
+
|
|
13
|
+
Automaticamente pelos commands:
|
|
14
|
+
- `/sf-extract` → publica `PRD` (se `prd_existe=true`) E `TRD` (se `trd_existe=true`)
|
|
15
|
+
- `/sf-plan` → publica `Progresso` no fim
|
|
16
|
+
- `/sf-design` → **não publica** (gera apenas artefatos locais: docs/, specs/, projetos.yaml)
|
|
17
|
+
|
|
18
|
+
Manualmente: quando o usuário quer re-publicar um artefato após editar local.
|
|
19
|
+
|
|
20
|
+
## Modo (`mode` no sfw.config.yml)
|
|
21
|
+
|
|
22
|
+
| Mode | Comportamento |
|
|
23
|
+
|------|---------------|
|
|
24
|
+
| `auto` | Publica sem perguntar (default) |
|
|
25
|
+
| `manual` | Gera artefato local, pergunta "Publicar no {target.name}? (s/n)" |
|
|
26
|
+
| `off` | Ignora o target completamente |
|
|
27
|
+
|
|
28
|
+
## Pré-condições
|
|
29
|
+
|
|
30
|
+
| # | Validação | Se falhar |
|
|
31
|
+
|---|-----------|-----------|
|
|
32
|
+
| 1 | `sfw.config.yml` existe | Parar → "Sem sfw.config.yml, publish desabilitado. Artefato local está em workspace/Output/{nome}/{tipo}.md" |
|
|
33
|
+
| 2 | Tipo está na `publishes` do target | Pular target, informar |
|
|
34
|
+
| 3 | Arquivo local existe em `workspace/Output/{nome}/{tipo}.md` (ou .lower) | Parar → "Arquivo não encontrado" |
|
|
35
|
+
|
|
36
|
+
## Execução
|
|
37
|
+
|
|
38
|
+
### 1. Carregar configuração
|
|
39
|
+
|
|
40
|
+
- Ler `sfw.config.yml`
|
|
41
|
+
- Para cada target em `output.targets[]`:
|
|
42
|
+
- Verificar `mode` (se `off` → pular)
|
|
43
|
+
- Verificar `publishes` inclui `<tipo>` (se não → pular)
|
|
44
|
+
- Se `mode: manual` → perguntar ao usuário
|
|
45
|
+
|
|
46
|
+
### 2. Ler artefato local
|
|
47
|
+
|
|
48
|
+
Ler `workspace/Output/{nome}/{arquivo}` onde arquivo depende do tipo:
|
|
49
|
+
- `PRD` → `PRD.md`
|
|
50
|
+
- `TRD` → `TRD.md`
|
|
51
|
+
- `Progresso` → `Progresso.md`
|
|
52
|
+
|
|
53
|
+
### 3. Aplicar naming
|
|
54
|
+
|
|
55
|
+
Usar templates do `naming` no `sfw.config.yml`:
|
|
56
|
+
- `containerTitle = applyNaming(naming.output_container, {scope: nome})`
|
|
57
|
+
- Ex: `"out_app_barbearia"`
|
|
58
|
+
- `artifactTitle = applyNaming(naming.output_artifact, {scope: nome, type: tipo})`
|
|
59
|
+
- Ex: `"app_barbearia - PRD"`
|
|
60
|
+
|
|
61
|
+
### 4. Para cada target ativo — publicar
|
|
62
|
+
|
|
63
|
+
**Confluence**:
|
|
64
|
+
|
|
65
|
+
1. Listar filhos de `target.config.parent_page_id` (Output)
|
|
66
|
+
2. Buscar container pelo `containerTitle`:
|
|
67
|
+
- **Não existe** → `mcp__atlassian__confluence_create_page` como filho de Output
|
|
68
|
+
- **Existe** → pegar `container.id`
|
|
69
|
+
3. Listar filhos do container
|
|
70
|
+
4. Buscar artefato pelo `artifactTitle`:
|
|
71
|
+
- **Não existe** → `mcp__atlassian__confluence_create_page` com `content=markdown local`
|
|
72
|
+
- **Existe** → precisa atualizar (próximo passo)
|
|
73
|
+
|
|
74
|
+
### 5. Conflict detection (update)
|
|
75
|
+
|
|
76
|
+
Se artefato existe no backend:
|
|
77
|
+
|
|
78
|
+
1. Ler `.ai/publish-log.md` pra pegar a última `version` publicada desse artefato
|
|
79
|
+
2. Chamar `mcp__atlassian__confluence_get_page(page_id=artifact.id)` → pega `currentVersion`
|
|
80
|
+
3. **Se `currentVersion != lastPublishedVersion`** → DRIFT detectado
|
|
81
|
+
- Alguém editou no Confluence depois do último publish
|
|
82
|
+
- Mostrar ao usuário:
|
|
83
|
+
```
|
|
84
|
+
CONFLITO: "{artifactTitle}" foi editada no Confluence desde o último publish.
|
|
85
|
+
|
|
86
|
+
Última version publicada por nós: {last}
|
|
87
|
+
Version atual no Confluence: {current}
|
|
88
|
+
|
|
89
|
+
Opções:
|
|
90
|
+
1. Sobrescrever (perde edição manual)
|
|
91
|
+
2. Abortar (edita local depois)
|
|
92
|
+
3. Ver diff
|
|
93
|
+
```
|
|
94
|
+
- Esperar decisão
|
|
95
|
+
4. Se sem drift → `mcp__atlassian__confluence_update_page(page_id, content)`
|
|
96
|
+
5. Ler nova `version` retornada
|
|
97
|
+
|
|
98
|
+
### 6. Registrar em `.ai/publish-log.md`
|
|
99
|
+
|
|
100
|
+
Formato append-only:
|
|
101
|
+
|
|
102
|
+
```markdown
|
|
103
|
+
## Publish: {nome} {tipo} — {ISO_DATETIME}
|
|
104
|
+
|
|
105
|
+
| Target | Container | Artifact ID | Version | Status |
|
|
106
|
+
|--------|-----------|-------------|---------|--------|
|
|
107
|
+
| confluence-mirror | out_app_barbearia (393220) | 393238 | 3 | UPDATED |
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Status: `CREATED`, `UPDATED`, `SKIPPED` (se INALTERADO), `CONFLICT` (se drift não resolvido)
|
|
111
|
+
|
|
112
|
+
### 7. Informar o usuário
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
Publicado: {nome} {tipo}
|
|
116
|
+
|
|
117
|
+
confluence-mirror: app_barbearia - PRD (v3) — UPDATED
|
|
118
|
+
|
|
119
|
+
Link: https://empresa.atlassian.net/wiki/spaces/ST/pages/393238
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Erros
|
|
123
|
+
|
|
124
|
+
| Erro | Ação |
|
|
125
|
+
|------|------|
|
|
126
|
+
| `sfw.config.yml` não existe | Skippa todos os targets, só salva local |
|
|
127
|
+
| Target MCP não disponível | Avisar, pular target |
|
|
128
|
+
| Sem permissão de escrita | Avisar, pular target |
|
|
129
|
+
| Conflict não resolvido | Não publicar, salvar como CONFLICT no log |
|
|
130
|
+
| Container Output não existe | Criar automaticamente como filho de `output.parent_page_id` |
|
|
131
|
+
|
|
132
|
+
## Notas
|
|
133
|
+
|
|
134
|
+
- O `/sf-publish` é **idempotente** pra content sem mudanças — detecta hash igual e marca `SKIPPED`
|
|
135
|
+
- `naming.output_container` e `naming.output_artifact` são aplicados em TODOS os targets
|
|
136
|
+
- Cada target pode ter `publishes: []` diferente (permite segmentar: Confluence recebe 4 artefatos, filesystem recebe todos)
|
|
137
|
+
- `.ai/publish-log.md` é essencial pro conflict detection funcionar
|
|
138
|
+
- Nunca publica tasks.md, docs/, specs/, projetos.yaml — esses são LOCAL ONLY
|
|
139
|
+
|
|
140
|
+
## Referências
|
|
141
|
+
|
|
142
|
+
- Adapter interface: `.github/adapters/interface.md`
|
|
143
|
+
- Confluence adapter: `.github/adapters/confluence.md`
|
|
144
|
+
- Naming engine: `.github/adapters/naming.md`
|