ganbatte-os 0.2.41 → 0.2.43
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/.gos/README.md +2 -6
- package/.gos/agents/profiles/ganbatte-os-master.md +91 -58
- package/.gos/agents/profiles/index.json +3 -1
- package/.gos/agents/profiles/perf-optimizer.md +10 -0
- package/.gos/agents/profiles/po.md +1 -1
- package/.gos/agents/profiles/security-auditor.md +11 -0
- package/.gos/agents/profiles/sm.md +4 -4
- package/.gos/agents/profiles/squad-creator.md +2 -2
- package/.gos/config.json +23 -2
- package/.gos/docs/curation.md +8 -6
- package/.gos/docs/gos_installation_guide.md +1 -1
- package/.gos/docs/plan-distribuicao-publica.md +2 -3
- package/.gos/docs/toolchain-map.md +2 -2
- package/.gos/libraries/doc-sync-policy.md +31 -0
- package/.gos/libraries/lazy-dev-policy.md +38 -0
- package/.gos/libraries/lucide-icons-policy.md +1 -1
- package/.gos/libraries/performance-audit-playbook.md +54 -0
- package/.gos/libraries/security-audit-playbook.md +63 -0
- package/.gos/manifests/g-os-runtime-manifest.json +29 -8
- package/.gos/playbooks/plan-creation-playbook.md +3 -5
- package/.gos/prompts/01-search.md +2 -2
- package/.gos/prompts/03-tasks.md +4 -4
- package/.gos/prompts/05-reviews.md +1 -1
- package/.gos/scripts/cli/gos-cli.js +16 -0
- package/.gos/scripts/hooks/claude-stop-summary.js +0 -16
- package/.gos/scripts/integrations/check-plan.js +15 -5
- package/.gos/scripts/integrations/setup-ide-adapters.js +72 -75
- package/.gos/scripts/tools/model-router.js +122 -0
- package/.gos/skills/execute-plan/SKILL.md +37 -23
- package/.gos/skills/perf-review/SKILL.md +58 -0
- package/.gos/skills/plan-blueprint/SKILL.md +26 -26
- package/.gos/skills/plan-to-tasks/SKILL.md +4 -1
- package/.gos/skills/progress-tracker/SKILL.md +3 -3
- package/.gos/skills/registry.json +3 -4
- package/.gos/skills/security-review/SKILL.md +59 -0
- package/.gos/skills/simplify-review/SKILL.md +59 -0
- package/.gos/skills/validate-plan/SKILL.md +29 -30
- package/.gos/squads/code-quality/README.md +20 -0
- package/.gos/squads/code-quality/squad.yaml +32 -0
- package/.gos/squads/code-quality/workflows/wf-code-quality.yaml +19 -0
- package/.gos/squads/design-delivery/README.md +1 -1
- package/.gos/squads/design-delivery/squad.yaml +4 -3
- package/.gos/squads/design-delivery/workflows/wf-design-delivery.yaml +6 -6
- package/.gos/templates/planTemplate.md +14 -5
- package/.gos/templates/specTemplate.md +68 -0
- package/.gos/templates/taskTemplate.md +8 -5
- package/AGENTS.md +30 -40
- package/CLAUDE.md +36 -14
- package/GEMINI.md +11 -5
- package/LICENSE +1 -1
- package/README.md +74 -442
- package/package.json +2 -3
- package/.gos/docs/slack-notifications.md +0 -219
- package/.gos/playbooks/sprint-planner-playbook.md +0 -127
- package/.gos/scripts/hooks/post-commit-notify.js +0 -175
- package/.gos/scripts/tools/clickup-preprocess.js +0 -218
- package/.gos/scripts/tools/clickup.js +0 -1058
- package/.gos/scripts/tools/slack-notify.js +0 -271
- package/.gos/skills/clickup/SKILL.md +0 -151
- package/.gos/skills/slack-review/SKILL.md +0 -91
- package/.gos/skills/sprint-planner/SKILL.md +0 -434
- package/.gos/skills/weekly-update/CHANGELOG.md +0 -165
- package/.gos/skills/weekly-update/SKILL.md +0 -361
- package/.gos/squads/sprint-planning/agents/sprint-chief.md +0 -47
- package/.gos/squads/sprint-planning/agents/sprint-planner-agent.md +0 -43
- package/.gos/squads/sprint-planning/agents/sprint-tracker.md +0 -43
- package/.gos/squads/sprint-planning/agents/task-importer.md +0 -44
- package/.gos/squads/sprint-planning/checklists/sprint-readiness.md +0 -27
- package/.gos/squads/sprint-planning/config/config.yaml +0 -65
- package/.gos/squads/sprint-planning/data/clickup-field-mapping.yaml +0 -94
- package/.gos/squads/sprint-planning/squad.yaml +0 -52
- package/.gos/squads/sprint-planning/tasks/close-sprint.md +0 -43
- package/.gos/squads/sprint-planning/tasks/create-sprint.md +0 -42
- package/.gos/squads/sprint-planning/tasks/import-tasks.md +0 -39
- package/.gos/squads/sprint-planning/tasks/sync-status.md +0 -31
- package/.gos/squads/sprint-planning/workflows/wf-sprint-creation.yaml +0 -59
- package/.gos/squads/sprint-planning/workflows/wf-sprint-sync.yaml +0 -35
- package/.gos/templates/sprint-clickup.template.md +0 -80
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
# Slack Notifications — Pipeline com aprovação
|
|
2
|
-
|
|
3
|
-
Workflow de notificações Slack que disparam a partir de commits com `T-NNN` no message. Tudo passa por uma fila de aprovação — nada é enviado sem revisão humana.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
git commit -m "fix: ... Refs T-NNN"
|
|
9
|
-
│
|
|
10
|
-
▼
|
|
11
|
-
.git/hooks/post-commit (shim bash, define GANBATTE_ROOT)
|
|
12
|
-
│
|
|
13
|
-
▼
|
|
14
|
-
scripts/hooks/post-commit-sync.js
|
|
15
|
-
│ 1. extrai T-NNN do message
|
|
16
|
-
│ 2. lê registry.taskDetails + taskStatus
|
|
17
|
-
│ 3. constrói payload via slack-notify.buildTaskDonePayload
|
|
18
|
-
│ (sanitiza texto com text-sanitize.js)
|
|
19
|
-
│ 4. chama slack-notify.enqueueDraft
|
|
20
|
-
▼
|
|
21
|
-
.gos/slack-queue/<timestamp>-<taskId>-<hash>.json (status: pending)
|
|
22
|
-
│
|
|
23
|
-
│ [commit termina — nada foi enviado]
|
|
24
|
-
│
|
|
25
|
-
▼
|
|
26
|
-
/slack-review (Douglas roda quando quiser)
|
|
27
|
-
│ lista drafts, mostra preview, AskUserQuestion
|
|
28
|
-
│ ações: approve / edit / reject / skip
|
|
29
|
-
▼
|
|
30
|
-
node slack-queue.js approve <id>
|
|
31
|
-
│ POST webhook Slack
|
|
32
|
-
▼
|
|
33
|
-
Slack #cspo-tech ← notificação enriquecida e revisada
|
|
34
|
-
│
|
|
35
|
-
▼
|
|
36
|
-
.gos/slack-queue/sent/<id>.json (histórico)
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Anatomia do payload
|
|
40
|
-
|
|
41
|
-
Campos extraídos de `data/sprints/registry.json`:
|
|
42
|
-
|
|
43
|
-
| Fonte | Campo | Uso no payload |
|
|
44
|
-
|---|---|---|
|
|
45
|
-
| `taskDetails[T-NNN].name` | nome da task | linha 2 do payload |
|
|
46
|
-
| `taskDetails[T-NNN].assignee` | responsável | linha meta (primeiro nome) |
|
|
47
|
-
| `taskDetails[T-NNN].sprint` | sprint | linha meta |
|
|
48
|
-
| `taskDetails[T-NNN].ac[]` | array de ACs | rodapé — "N ACs" |
|
|
49
|
-
| `taskStatus[T-NNN].points` | story points | linha meta |
|
|
50
|
-
| `taskStatus[T-NNN].dueDate` | prazo | linha meta (MM/DD) |
|
|
51
|
-
| `taskMap[T-NNN]` | ID ClickUp | link ClickUp no rodapé |
|
|
52
|
-
|
|
53
|
-
Formato renderizado:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
:white_check_mark: T-110 concluída — S07 · Douglas · 8 pts · due 04/17
|
|
57
|
-
Resolver drift TypeScript + instalar pre-commit hook
|
|
58
|
-
> Commit: 54d8fe6 — fix: drift resolvido
|
|
59
|
-
> 7 ACs · por Douglas Oliveira · <ClickUp>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Pipeline de sanitização
|
|
63
|
-
|
|
64
|
-
`text-sanitize.js` aplica, em ordem, sobre qualquer texto que entra em payload:
|
|
65
|
-
|
|
66
|
-
1. **Protege code fences** (```` ``` ````) e inline code (`` ` ``).
|
|
67
|
-
2. **P17 emoji-bullets**: remove emojis (✅ ❌ ⚠ 🚀 ⭐ 🎯 💡 🔧 🎉 🔥 👍 👌) no início de linhas.
|
|
68
|
-
3. **P14 em-dash entre palavras**: `word—word` → `word-word` (mantém travessão legítimo com espaços).
|
|
69
|
-
4. **Acentos pt-BR**: dicionário determinístico — `concluida → concluída`, `atualizacao → atualização`, ~80 termos.
|
|
70
|
-
5. **P07 vocabulário IA**: `aprimorar → melhorar`, `fomentar → estimular`, `crucial → importante`, ~25 termos com preservação de flexão (gerúndio, plural) e case.
|
|
71
|
-
6. **Restaura code spans** intactos.
|
|
72
|
-
|
|
73
|
-
Estender dicionários: editar `AI_VOCAB` e `MISSING_ACCENTS` em `.gos/scripts/tools/text-sanitize.js`.
|
|
74
|
-
|
|
75
|
-
## Fila de aprovação
|
|
76
|
-
|
|
77
|
-
**Localização**: `.gos/slack-queue/` (gitignored)
|
|
78
|
-
|
|
79
|
-
**Estados**:
|
|
80
|
-
|
|
81
|
-
| Estado | Diretório | Remoção |
|
|
82
|
-
|---|---|---|
|
|
83
|
-
| `pending` | `.gos/slack-queue/*.json` | manual (approve/reject) |
|
|
84
|
-
| `sent` | `.gos/slack-queue/sent/*.json` | manual, após confirmação |
|
|
85
|
-
| `rejected` | `.gos/slack-queue/rejected/*.json` | auditoria, manter histórico |
|
|
86
|
-
|
|
87
|
-
**TTL**: sem expiração automática. Limpar manualmente `sent/` e `rejected/` a cada sprint via `rm -rf .gos/slack-queue/{sent,rejected}`.
|
|
88
|
-
|
|
89
|
-
**Estrutura do draft**:
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"id": "20260417T143100-T110-54d8fe6",
|
|
94
|
-
"createdAt": "2026-04-17T14:31:00Z",
|
|
95
|
-
"taskId": "T-110",
|
|
96
|
-
"commit": "54d8fe6",
|
|
97
|
-
"channel": "default",
|
|
98
|
-
"author": "Douglas Oliveira",
|
|
99
|
-
"payload": { "text": "..." },
|
|
100
|
-
"status": "pending"
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Comandos
|
|
105
|
-
|
|
106
|
-
### slack-queue.js
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
# Listar pendentes
|
|
110
|
-
node .gos/scripts/tools/slack-queue.js list
|
|
111
|
-
node .gos/scripts/tools/slack-queue.js list --json
|
|
112
|
-
|
|
113
|
-
# Mostrar um draft
|
|
114
|
-
node .gos/scripts/tools/slack-queue.js show <id>
|
|
115
|
-
|
|
116
|
-
# Editar inline (abre $EDITOR / VISUAL / notepad no Windows)
|
|
117
|
-
node .gos/scripts/tools/slack-queue.js edit <id>
|
|
118
|
-
|
|
119
|
-
# Aprovar e enviar
|
|
120
|
-
node .gos/scripts/tools/slack-queue.js approve <id>
|
|
121
|
-
|
|
122
|
-
# Rejeitar
|
|
123
|
-
node .gos/scripts/tools/slack-queue.js reject <id> --reason "duplicate"
|
|
124
|
-
|
|
125
|
-
# Aprovar todos pendentes (CI, depois de revisão visual)
|
|
126
|
-
node .gos/scripts/tools/slack-queue.js flush
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### slack-notify.js
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
# Enfileirar manualmente (default)
|
|
133
|
-
node .gos/scripts/tools/slack-notify.js task-done \
|
|
134
|
-
--task T-110 --commit 54d8fe6 --author "Douglas Oliveira" \
|
|
135
|
-
--registry data/sprints/registry.json
|
|
136
|
-
|
|
137
|
-
# Envio imediato sem fila (bypass revisão — usar só em CI)
|
|
138
|
-
node .gos/scripts/tools/slack-notify.js task-done \
|
|
139
|
-
--task T-110 --commit 54d8fe6 --author "Douglas Oliveira" \
|
|
140
|
-
--registry data/sprints/registry.json --send-now
|
|
141
|
-
|
|
142
|
-
# Dry-run (monta payload sem enviar nem enfileirar)
|
|
143
|
-
node .gos/scripts/tools/slack-notify.js task-done \
|
|
144
|
-
--task T-110 --commit 54d8fe6 --author "Douglas Oliveira" \
|
|
145
|
-
--registry data/sprints/registry.json --send-now --dry-run
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### text-sanitize.js
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
# CLI
|
|
152
|
-
node .gos/scripts/tools/text-sanitize.js --text "Task concluida aprimorando"
|
|
153
|
-
node .gos/scripts/tools/text-sanitize.js --file path/to/content.md --json
|
|
154
|
-
echo "texto sujo" | node .gos/scripts/tools/text-sanitize.js --stdin
|
|
155
|
-
|
|
156
|
-
# Como módulo
|
|
157
|
-
const { sanitize } = require('./.gos/scripts/tools/text-sanitize.js')
|
|
158
|
-
const { text, changes } = sanitize(input)
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## Skill `/slack-review`
|
|
162
|
-
|
|
163
|
-
Ver `.gos/skills/slack-review/SKILL.md`. Wrapper interativo do `slack-queue.js list|show|edit|approve|reject` com preview renderizado e `AskUserQuestion` para cada ação.
|
|
164
|
-
|
|
165
|
-
## Como pular aprovação
|
|
166
|
-
|
|
167
|
-
**CI / automação** onde revisão humana não faz sentido:
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
node .gos/scripts/tools/slack-notify.js <cmd> --send-now
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Flush programado** (ex: cron de fim de dia):
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
node .gos/scripts/tools/slack-queue.js flush
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
Usar com cuidado — fila existe justamente para evitar envio acidental.
|
|
180
|
-
|
|
181
|
-
## Troubleshooting
|
|
182
|
-
|
|
183
|
-
### Commit rodou mas fila não tem drafts
|
|
184
|
-
|
|
185
|
-
- Verificar que o commit message contém `T-NNN` (regex `\bT-\d{3}\b`).
|
|
186
|
-
- Confirmar hook instalado: `ls packages/fractus/.git/hooks/post-commit`.
|
|
187
|
-
- Confirmar hook aponta para `$GANBATTE_ROOT/scripts/hooks/post-commit-sync.js` e exporta `GANBATTE_ROOT`.
|
|
188
|
-
- Rodar manual: `cd packages/fractus && GANBATTE_ROOT=$(git rev-parse --show-superproject-working-tree || pwd) node ../../scripts/hooks/post-commit-sync.js`.
|
|
189
|
-
|
|
190
|
-
### Approve falha com "SLACK_WEBHOOK_URL not set"
|
|
191
|
-
|
|
192
|
-
- Arquivo `.env` na raiz (`e:\Github\Ganbatte\.env`) contém `SLACK_WEBHOOK_URL=...`?
|
|
193
|
-
- `slack-queue.js` carrega `.env` automaticamente via `loadRootEnv()` — se variável está no `.env` mas não é lida, conferir formatação (sem aspas extras, `KEY=VALUE` puro).
|
|
194
|
-
|
|
195
|
-
### Draft stuck em pending após approve
|
|
196
|
-
|
|
197
|
-
- Abrir o JSON em `.gos/slack-queue/sent/<id>.json` — se existe, o envio OK mas `unlink` do original falhou (permission issue Windows). Remover manualmente.
|
|
198
|
-
- Se não existe, o POST webhook falhou — ver output do comando (status HTTP + body).
|
|
199
|
-
|
|
200
|
-
### Edição travada
|
|
201
|
-
|
|
202
|
-
- `edit` abre `$VISUAL` → `$EDITOR` → `notepad` (Windows) / `vi` (Unix). Se o editor não fechar, o comando fica bloqueado.
|
|
203
|
-
- Alternativa: editar o JSON direto em `.gos/slack-queue/<id>.json` e rodar approve em seguida.
|
|
204
|
-
|
|
205
|
-
### Texto sanitizado incorretamente
|
|
206
|
-
|
|
207
|
-
- Ver `changes[]` do sanitize: `node .gos/scripts/tools/text-sanitize.js --text "..." --json`.
|
|
208
|
-
- Se uma substituição está errada, remover do dicionário em `text-sanitize.js:AI_VOCAB` / `MISSING_ACCENTS`.
|
|
209
|
-
- Code spans (`` ` `` e ```` ``` ````) são preservados — se precisar isolar um termo, envolver em backticks.
|
|
210
|
-
|
|
211
|
-
## Referências
|
|
212
|
-
|
|
213
|
-
- [`text-sanitize.js`](../scripts/tools/text-sanitize.js) — sanitizador
|
|
214
|
-
- [`slack-queue.js`](../scripts/tools/slack-queue.js) — fila
|
|
215
|
-
- [`slack-notify.js`](../scripts/tools/slack-notify.js) — payload + envio
|
|
216
|
-
- [`post-commit-sync.js`](../../scripts/hooks/post-commit-sync.js) — hook
|
|
217
|
-
- [`ai-writing-patterns.md`](../libraries/content/ai-writing-patterns.md) — catálogo base
|
|
218
|
-
- [`humanizer`](../skills/humanizer/SKILL.md) — skill de humanização criativa
|
|
219
|
-
- [`slack-review`](../skills/slack-review/SKILL.md) — skill de aprovação interativa
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# Sprint Planner — Playbook Operacional
|
|
2
|
-
|
|
3
|
-
> Guia a execucao completa do sprint-planner: do input ate sprint montada com PRD, ADR, roadmap e tasks.
|
|
4
|
-
|
|
5
|
-
## Objetivo
|
|
6
|
-
|
|
7
|
-
Transformar qualquer input (caminho de projeto, design Figma, transcricao, documento)
|
|
8
|
-
em um pacote completo de sprint com artefatos prontos para execucao.
|
|
9
|
-
|
|
10
|
-
## Pre-requisitos
|
|
11
|
-
|
|
12
|
-
- [ ] Input disponivel (caminho de projeto, design, transcricao ou descricao)
|
|
13
|
-
- [ ] Acesso ao projeto/codebase (se for project-path)
|
|
14
|
-
- [ ] Usuario disponivel para loops de discovery (15-30 min)
|
|
15
|
-
- [ ] Branch correta (`dev` para framework, feature branch para projetos)
|
|
16
|
-
|
|
17
|
-
## Step 1 — Triage do Input (5 min)
|
|
18
|
-
|
|
19
|
-
- [ ] Classificar tipo: project-path | design | transcription | document | free-text | mixed
|
|
20
|
-
- [ ] Se project-path: executar `/project-brief <path>` para contexto
|
|
21
|
-
- [ ] Se design: analise visual — extrair telas, fluxos, componentes
|
|
22
|
-
- [ ] Se transcription: extrair requisitos, fluxos, restricoes, decisoes
|
|
23
|
-
- [ ] Se document: ler, sumarizar, identificar gaps
|
|
24
|
-
- [ ] Gerar `input-analysis.md`
|
|
25
|
-
- [ ] Apresentar resumo ao usuario
|
|
26
|
-
|
|
27
|
-
## Step 2 — Discovery Loops (15-30 min)
|
|
28
|
-
|
|
29
|
-
- [ ] Loop 1: Contexto e Objetivo (SCQA + Analise de Premissas)
|
|
30
|
-
- [ ] Loop 2: Usuarios e Escopo (Task-Oriented Thought + Brainstorming)
|
|
31
|
-
- [ ] Loop 3: Fluxos e Regras (Verificacao de Consistencia)
|
|
32
|
-
- [ ] Loop 4 (se necessario): Dados e Restricoes (ReAct + Feynman)
|
|
33
|
-
- [ ] Avaliar clarity checklist (>= 70%?)
|
|
34
|
-
- [ ] Se < 70% apos 4 loops: consolidar e sinalizar gaps
|
|
35
|
-
|
|
36
|
-
## Step 3 — PRD (20-30 min)
|
|
37
|
-
|
|
38
|
-
- [ ] Gerar `sprint-planner/<slug>/PRD.md`
|
|
39
|
-
- [ ] Escopo IN/OUT explicito
|
|
40
|
-
- [ ] Criterios de aceite verificaveis (Given/When/Then)
|
|
41
|
-
- [ ] Decisoes menores embedded (contexto, opcoes, escolha)
|
|
42
|
-
- [ ] **GATE: Usuario aprova PRD**
|
|
43
|
-
|
|
44
|
-
## Step 4 — Arquitetura & Schema (15-30 min)
|
|
45
|
-
|
|
46
|
-
- [ ] Identificar decisoes arquiteturais significativas
|
|
47
|
-
- [ ] Gerar `ADR-NNN.md` para cada decisao com 3+ opcoes e trade-offs
|
|
48
|
-
- [ ] Se projeto envolve banco: gerar `schema.dbml`
|
|
49
|
-
- [ ] Se projeto envolve APIs: listar endpoints com contratos
|
|
50
|
-
- [ ] **GATE: Usuario aprova ADRs e schema**
|
|
51
|
-
|
|
52
|
-
## Step 5 — Roadmap (10 min)
|
|
53
|
-
|
|
54
|
-
- [ ] Classificar complexidade: simples | medio | complexo
|
|
55
|
-
- [ ] Gerar `ROADMAP.md` com fases, duracoes e entregaveis
|
|
56
|
-
- [ ] Validar: soma duracoes <= total + 20% margem
|
|
57
|
-
- [ ] Validar: cada fase tem pelo menos 1 entregavel concreto
|
|
58
|
-
- [ ] **GATE: Fases e prazos validados**
|
|
59
|
-
|
|
60
|
-
## Step 6 — Task Decomposition (15-20 min)
|
|
61
|
-
|
|
62
|
-
- [ ] Executar `/plan-to-tasks` no PRD
|
|
63
|
-
- [ ] Validar: cada task max 1 dia, DoD mensuravel
|
|
64
|
-
- [ ] User stories em Given/When/Then
|
|
65
|
-
- [ ] Complexidade scoring (1-25) por story
|
|
66
|
-
- [ ] Ordenar por dependencias
|
|
67
|
-
|
|
68
|
-
## Step 7 — Setup Tasks (10 min)
|
|
69
|
-
|
|
70
|
-
- [ ] Detectar necessidades: contas, credenciais, infra, repos
|
|
71
|
-
- [ ] Gerar tasks P0 com area devops/general
|
|
72
|
-
- [ ] Incluir instrucoes passo-a-passo
|
|
73
|
-
- [ ] Vincular como pre-requisitos das tasks de dev
|
|
74
|
-
|
|
75
|
-
## Step 8 — Sprint Assembly (10 min)
|
|
76
|
-
|
|
77
|
-
- [ ] Gerar `SPRINT-OVERVIEW.md` consolidando tudo
|
|
78
|
-
- [ ] Registrar decisoes no `memory/decision-log.json`
|
|
79
|
-
- [ ] Apresentar resumo final ao usuario
|
|
80
|
-
- [ ] Indicar proximos passos (qual skill usar para executar)
|
|
81
|
-
|
|
82
|
-
## Armadilhas Comuns
|
|
83
|
-
|
|
84
|
-
| Armadilha | Sintoma | Solucao |
|
|
85
|
-
|-----------|---------|---------|
|
|
86
|
-
| Discovery infinito | Mais de 5 loops sem convergir | Consolidar o que tem, sinalizar gaps |
|
|
87
|
-
| Scope creep no PRD | PRD com 20+ tasks | Dividir em 2+ sprints |
|
|
88
|
-
| ADR para tudo | ADR para decisoes triviais | Embedded no PRD se < 3 opcoes |
|
|
89
|
-
| Schema sem RLS | Tabelas sem politicas de seguranca | Sempre incluir nota sobre RLS |
|
|
90
|
-
| Setup esquecido | Dev trava por falta de credencial | Phase 6 existe para isso |
|
|
91
|
-
| Pular gates | Avancar sem aprovacao | Cada fase TEM que ter aprovacao |
|
|
92
|
-
|
|
93
|
-
## Tempo Estimado
|
|
94
|
-
|
|
95
|
-
| Complexidade | Tempo total |
|
|
96
|
-
|-------------|-------------|
|
|
97
|
-
| Simples (escopo claro, 3-5 tasks) | 45-60 min |
|
|
98
|
-
| Medio (ambiguidade moderada, 5-15 tasks) | 60-90 min |
|
|
99
|
-
| Complexo (multi-dominio, 15+ tasks) | 90-150 min |
|
|
100
|
-
|
|
101
|
-
## Continuacao
|
|
102
|
-
|
|
103
|
-
Apos sprint-planner concluir, o usuario escolhe como executar:
|
|
104
|
-
|
|
105
|
-
| Objetivo | Comando |
|
|
106
|
-
|----------|---------|
|
|
107
|
-
| Executar spec-driven (completo) | `/sdd sprint-planner/<slug>/PRD.md` |
|
|
108
|
-
| Orquestrar execucao (composicao) | `/compose TASK-YYYYMM-001` |
|
|
109
|
-
| Refinar backlog | `@sm` ou `@po` |
|
|
110
|
-
| Frontend direto | `/fe` com tasks geradas |
|
|
111
|
-
| Backend direto | `/be` com tasks geradas |
|
|
112
|
-
|
|
113
|
-
## Referencias
|
|
114
|
-
|
|
115
|
-
- `skills/sprint-planner/SKILL.md` — skill completa
|
|
116
|
-
- `templates/adr-tmpl.yaml` — template ADR
|
|
117
|
-
- `playbooks/story-creation-playbook.md` — formato de stories
|
|
118
|
-
- `playbooks/gsd-agent-decomposition-playbook.md` — padrao de handoff por artefatos
|
|
119
|
-
- `skills/sdd/SKILL.md` — para continuacao com execucao
|
|
120
|
-
- `skills/plan-to-tasks/SKILL.md` — decomposicao em tasks
|
|
121
|
-
|
|
122
|
-
## Cadencia Sugerida
|
|
123
|
-
|
|
124
|
-
- Ao iniciar qualquer projeto novo (greenfield)
|
|
125
|
-
- Ao receber novo escopo ou fase de projeto existente (brownfield)
|
|
126
|
-
- Quando receber designs Figma ou transcricoes de reuniao para planejar
|
|
127
|
-
- Antes de sprints que envolvem multiplos dominios (FE + BE + infra)
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// post-commit-notify.js — Post-commit hook: marks tasks done in ClickUp + notifies Slack
|
|
4
|
-
// Trigger: Claude Code Stop hook or git post-commit
|
|
5
|
-
// Rule: ALWAYS exit 0 (observation hook, never blocks)
|
|
6
|
-
|
|
7
|
-
const { execFileSync } = require('node:child_process')
|
|
8
|
-
const { existsSync, readFileSync } = require('node:fs')
|
|
9
|
-
const { resolve } = require('node:path')
|
|
10
|
-
|
|
11
|
-
// Find repo root
|
|
12
|
-
function findRepoRoot() {
|
|
13
|
-
try {
|
|
14
|
-
return execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' }).trim()
|
|
15
|
-
} catch {
|
|
16
|
-
return process.cwd()
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Parse last commit
|
|
21
|
-
function getLastCommit() {
|
|
22
|
-
try {
|
|
23
|
-
const log = execFileSync('git', ['log', '-1', '--format=%H|%s|%an'], { encoding: 'utf-8' }).trim()
|
|
24
|
-
const sepIdx = log.indexOf('|')
|
|
25
|
-
const hash = log.slice(0, sepIdx)
|
|
26
|
-
const rest = log.slice(sepIdx + 1)
|
|
27
|
-
const lastSep = rest.lastIndexOf('|')
|
|
28
|
-
const message = rest.slice(0, lastSep)
|
|
29
|
-
const author = rest.slice(lastSep + 1)
|
|
30
|
-
return { hash, message, author }
|
|
31
|
-
} catch {
|
|
32
|
-
return null
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Extract task refs from commit message (T-NNN pattern)
|
|
37
|
-
function extractTaskRefs(message) {
|
|
38
|
-
const matches = message.match(/\bT-(\d{3})\b/g)
|
|
39
|
-
return matches ? [...new Set(matches)] : []
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Load sprint registry to resolve local IDs -> ClickUp IDs
|
|
43
|
-
function loadRegistry(repoRoot) {
|
|
44
|
-
const paths = [
|
|
45
|
-
resolve(repoRoot, 'data/sprints/registry.json'),
|
|
46
|
-
resolve(repoRoot, '.gos/data/sprints/registry.json'),
|
|
47
|
-
]
|
|
48
|
-
for (const p of paths) {
|
|
49
|
-
if (existsSync(p)) {
|
|
50
|
-
try {
|
|
51
|
-
return { data: JSON.parse(readFileSync(p, 'utf-8')), path: p }
|
|
52
|
-
} catch { continue }
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return { data: { version: '1.0', sprints: [], taskMap: {}, taskSprintMap: {} }, path: paths[0] }
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Run a CLI tool safely (no shell injection)
|
|
59
|
-
function runTool(repoRoot, tool, toolArgs) {
|
|
60
|
-
const toolPaths = [
|
|
61
|
-
resolve(repoRoot, `.gos/scripts/tools/${tool}`),
|
|
62
|
-
resolve(repoRoot, `scripts/tools/${tool}`),
|
|
63
|
-
]
|
|
64
|
-
const toolPath = toolPaths.find(p => existsSync(p))
|
|
65
|
-
if (!toolPath) return null
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const result = execFileSync('node', [toolPath, ...toolArgs], {
|
|
69
|
-
encoding: 'utf-8',
|
|
70
|
-
timeout: 15000,
|
|
71
|
-
env: process.env,
|
|
72
|
-
})
|
|
73
|
-
return JSON.parse(result)
|
|
74
|
-
} catch (e) {
|
|
75
|
-
return { error: e.message }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Detect if commit implies task completion
|
|
80
|
-
function isCompletionCommit(message) {
|
|
81
|
-
const completionPatterns = [
|
|
82
|
-
/^feat[:(]/i,
|
|
83
|
-
/^fix[:(]/i,
|
|
84
|
-
/\b(close[sd]?|complete[sd]?|finish|done|resolve[sd]?)\b/i,
|
|
85
|
-
]
|
|
86
|
-
return completionPatterns.some(p => p.test(message))
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Detect if commit is a start/WIP commit
|
|
90
|
-
function isStartCommit(message) {
|
|
91
|
-
const startPatterns = [
|
|
92
|
-
/^(wip|chore|progress|draft|start|refactor|test|docs|style)[:(]/i,
|
|
93
|
-
/\b(wip|in.?progress|draft|start)\b/i,
|
|
94
|
-
]
|
|
95
|
-
return startPatterns.some(p => p.test(message))
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Find sprint for a task reference
|
|
99
|
-
function findSprintForTask(registry, taskRef) {
|
|
100
|
-
if (registry.taskSprintMap?.[taskRef]) {
|
|
101
|
-
return registry.sprints.find(s => s.id === registry.taskSprintMap[taskRef]) || null
|
|
102
|
-
}
|
|
103
|
-
return registry.sprints.filter(s => !s.end || new Date(s.end) >= new Date())
|
|
104
|
-
.sort((a, b) => new Date(b.start) - new Date(a.start))[0] || null
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function main() {
|
|
108
|
-
const repoRoot = findRepoRoot()
|
|
109
|
-
const commit = getLastCommit()
|
|
110
|
-
if (!commit) return
|
|
111
|
-
|
|
112
|
-
const taskRefs = extractTaskRefs(commit.message)
|
|
113
|
-
if (taskRefs.length === 0) return
|
|
114
|
-
|
|
115
|
-
const hasClickUp = !!process.env.CLICKUP_API_KEY
|
|
116
|
-
const hasSlack = !!process.env.SLACK_WEBHOOK_URL
|
|
117
|
-
if (!hasClickUp && !hasSlack) return
|
|
118
|
-
|
|
119
|
-
const { data: registry } = loadRegistry(repoRoot)
|
|
120
|
-
const shouldComplete = isCompletionCommit(commit.message)
|
|
121
|
-
const shouldStart = isStartCommit(commit.message)
|
|
122
|
-
|
|
123
|
-
for (const ref of taskRefs) {
|
|
124
|
-
const clickupId = registry.taskMap?.[ref]
|
|
125
|
-
|
|
126
|
-
// Update ClickUp task status
|
|
127
|
-
if (hasClickUp && clickupId) {
|
|
128
|
-
if (shouldComplete) {
|
|
129
|
-
runTool(repoRoot, 'clickup.js', ['task', 'update', '--task-id', clickupId, '--status', 'complete'])
|
|
130
|
-
} else if (shouldStart) {
|
|
131
|
-
runTool(repoRoot, 'clickup.js', ['task', 'update', '--task-id', clickupId, '--status', 'in progress'])
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Notify Slack
|
|
136
|
-
if (hasSlack) {
|
|
137
|
-
const status = shouldComplete ? 'concluida' : shouldStart ? 'em andamento' : 'atualizada'
|
|
138
|
-
runTool(repoRoot, 'slack-notify.js', [
|
|
139
|
-
'task-update',
|
|
140
|
-
'--task', ref,
|
|
141
|
-
'--status', status,
|
|
142
|
-
'--commit', commit.hash,
|
|
143
|
-
'--author', commit.author,
|
|
144
|
-
'--message', commit.message,
|
|
145
|
-
])
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Sprint completion check (if task completed)
|
|
149
|
-
if (shouldComplete) {
|
|
150
|
-
const sprint = findSprintForTask(registry, ref)
|
|
151
|
-
if (sprint) {
|
|
152
|
-
const tasksInSprint = Object.entries(registry.taskSprintMap || {})
|
|
153
|
-
.filter(([, sid]) => sid === sprint.id)
|
|
154
|
-
.map(([tid]) => tid)
|
|
155
|
-
const completedTasks = tasksInSprint.filter(tid => {
|
|
156
|
-
const cuId = registry.taskMap?.[tid]
|
|
157
|
-
if (!cuId) return false
|
|
158
|
-
return true
|
|
159
|
-
})
|
|
160
|
-
if (tasksInSprint.length > 0 && completedTasks.length === tasksInSprint.length) {
|
|
161
|
-
if (hasSlack) {
|
|
162
|
-
runTool(repoRoot, 'slack-notify.js', [
|
|
163
|
-
'sprint-complete',
|
|
164
|
-
'--sprint', sprint.id,
|
|
165
|
-
'--name', sprint.name,
|
|
166
|
-
'--tasks', tasksInSprint.join(', '),
|
|
167
|
-
])
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
main().catch(() => {}).finally(() => process.exit(0))
|