ganbatte-os 0.2.37 → 0.2.38
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/agents/profiles/ganbatte-os-master.md +100 -0
- package/.gos/libraries/caveman-rules.md +58 -0
- package/.gos/libraries/cloudflare-stack-kb.md +161 -0
- package/.gos/libraries/default-stack-kb.md +98 -0
- package/.gos/libraries/engineering-best-practices.md +208 -0
- package/.gos/libraries/gos-compress-setup.md +62 -0
- package/.gos/libraries/intake-questions-mom-test.md +91 -0
- package/.gos/libraries/lucide-icons-policy.md +174 -0
- package/.gos/libraries/security-best-practices.md +138 -0
- package/.gos/libraries/supabase-stack-kb.md +124 -0
- package/.gos/libraries/timer-pattern-spec.md +252 -0
- package/.gos/libraries/typeform-pattern-spec.md +204 -0
- package/.gos/libraries/ui-guardrails-checklist.md +144 -0
- package/.gos/libraries/visual-diff-lenses.md +114 -0
- package/.gos/skills/adr-tech-decisions/SKILL.md +166 -0
- package/.gos/skills/audit-screenshots/SKILL.md +21 -3
- package/.gos/skills/cloudflare-pages-setup/SKILL.md +180 -0
- package/.gos/skills/figma-print-diff/SKILL.md +165 -0
- package/.gos/skills/gos-caveman/SKILL.md +110 -0
- package/.gos/skills/gos-compress/SKILL.md +134 -0
- package/.gos/skills/gos-compress/scripts/compress.py +346 -0
- package/.gos/skills/gos-compress/scripts/setup.py +91 -0
- package/.gos/skills/idea-intake/SKILL.md +147 -0
- package/.gos/skills/plan-blueprint/SKILL.md +10 -3
- package/.gos/skills/plan-to-tasks/SKILL.md +28 -0
- package/.gos/skills/prd-from-intake/SKILL.md +94 -0
- package/.gos/skills/prototype-orchestrator/SKILL.md +120 -0
- package/.gos/skills/registry.json +12 -1
- package/.gos/skills/timer-component-pattern/SKILL.md +245 -0
- package/.gos/skills/typeform-form-pattern/SKILL.md +210 -0
- package/.gos/skills/ui-guardrails/SKILL.md +111 -0
- package/.gos/templates/intakeTemplate.md +41 -0
- package/.gos/templates/prdLeanTemplate.md +40 -0
- package/package.json +1 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: idea-intake
|
|
3
|
+
description: >
|
|
4
|
+
Entrevista guiada estilo Mom Test + SPIN para extrair a ideia de um usuario nao-tecnico
|
|
5
|
+
e transformar em intake.md estruturado. Pergunta-a-pergunta adaptativo, em PT-BR, ate ter
|
|
6
|
+
problema, persona, jobs-to-be-done, telas-chave e metrica de sucesso. Output unico:
|
|
7
|
+
docs/intake/INTAKE-NNN-<slug>/intake.md.
|
|
8
|
+
argument-hint: "<frase curta da ideia ou 'continuar' para retomar sessao>"
|
|
9
|
+
allowedTools: [Read, Glob, Grep, Bash, Write, Edit, AskUserQuestion]
|
|
10
|
+
sourceDocs:
|
|
11
|
+
- libraries/intake-questions-mom-test.md
|
|
12
|
+
- templates/intakeTemplate.md
|
|
13
|
+
use-when:
|
|
14
|
+
- usuario nao-tecnico chega com uma ideia ainda crua ("queria um app que...")
|
|
15
|
+
- antes de qualquer plan-blueprint ou design quando nao existe PRD
|
|
16
|
+
- quando a saida final esperada e um prototipo descartavel/MVP
|
|
17
|
+
do-not-use-for:
|
|
18
|
+
- quando o usuario ja tem PRD (use prd-from-intake apontando para o doc)
|
|
19
|
+
- tarefas tecnicas concretas (use plan-blueprint direto)
|
|
20
|
+
metadata:
|
|
21
|
+
category: discovery
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
Voce esta executando como **Entrevistador de Discovery** via skill `idea-intake`. Conduz uma entrevista pergunta-a-pergunta com um usuario nao-tecnico, em PT-BR, ate produzir um intake.md completo que servira de input para `prd-from-intake`.
|
|
25
|
+
|
|
26
|
+
## Contrato
|
|
27
|
+
|
|
28
|
+
1. NUNCA pergunte mais de 1 coisa por vez. Uma pergunta. Espera resposta. Proxima pergunta.
|
|
29
|
+
2. Linguagem coloquial, sem jargao tecnico. Se precisar perguntar algo tecnico, traduzir em analogia ("imagina que sua ideia precisa de um caderno onde a informacao fica salva mesmo se voce fechar o app — pra voce isso e importante?").
|
|
30
|
+
3. Maximo de 15 perguntas. Se atingir o teto, fecha com o que tem.
|
|
31
|
+
4. Persistir progresso em `.gos-local/intake-session.json` apos cada pergunta respondida (resume com `*idea-intake continuar`).
|
|
32
|
+
5. Output final unico: `docs/intake/INTAKE-NNN-<slug>/intake.md`. NUNCA escrever em outros lugares.
|
|
33
|
+
|
|
34
|
+
## Estrutura da entrevista (5 blocos, 2-3 perguntas cada)
|
|
35
|
+
|
|
36
|
+
### Bloco 1 — Problema (Mom Test: presente, nao futuro)
|
|
37
|
+
|
|
38
|
+
- "Me conta uma situacao real, nas ultimas semanas, em que voce ou alguem que voce conhece passou por esse problema." (forca historia concreta)
|
|
39
|
+
- "Como voce resolveu na hora? Mesmo que mal resolvido."
|
|
40
|
+
- "O que mais te incomodou nessa hora?"
|
|
41
|
+
|
|
42
|
+
Anti-padrao: nao perguntar "voce pagaria por uma solucao?" ou "seria legal se...?". Mom Test rejeita hipoteticos.
|
|
43
|
+
|
|
44
|
+
### Bloco 2 — Persona
|
|
45
|
+
|
|
46
|
+
- "Quem mais alem de voce viveria isso? Tenta descrever uma pessoa especifica (nao um cargo)."
|
|
47
|
+
- "Essa pessoa esta em qual contexto quando o problema bate? (no celular, na rua, no escritorio, com filho do lado, etc.)"
|
|
48
|
+
|
|
49
|
+
### Bloco 3 — Jobs-to-be-done
|
|
50
|
+
|
|
51
|
+
- "Se essa solucao existisse magicamente amanha, qual seria a primeira coisa que voce faria com ela?"
|
|
52
|
+
- "E o que voce QUERIA que ela NAO fizesse? (limites)"
|
|
53
|
+
|
|
54
|
+
### Bloco 4 — Telas-chave (extracao visual sem jargao)
|
|
55
|
+
|
|
56
|
+
Adaptativo. Pergunta varia conforme tipo de produto (app/site/dashboard/automacao). Padrao:
|
|
57
|
+
|
|
58
|
+
- "Imagina que voce abriu o produto agora. O que voce ESPERA ver na primeira tela?"
|
|
59
|
+
- "Tem alguma tela que voce sabe que vai precisar mas nao sabe explicar como? Tenta desenhar com palavras."
|
|
60
|
+
- "Tem algum produto que ja faz parecido e te inspira? (link, nome, ou descricao)"
|
|
61
|
+
|
|
62
|
+
### Bloco 5 — Sucesso e escopo descartavel
|
|
63
|
+
|
|
64
|
+
CRITICO: explicitar que a maioria dos MVPs serao descartaveis (uso unico). Pergunta:
|
|
65
|
+
|
|
66
|
+
- "Esse produto e pra usar UMA vez (validar uma ideia, mostrar pra alguem, testar conceito) ou voce quer manter rodando por meses?"
|
|
67
|
+
- "Como voce vai saber, depois de usar, que valeu a pena? (metrica em linguagem humana — 'minha mae conseguiu agendar sozinha', 'consegui fechar 1 venda')"
|
|
68
|
+
|
|
69
|
+
## Pre-flight (gate)
|
|
70
|
+
|
|
71
|
+
1. Se `$ARGUMENTS` == "continuar": ler `.gos-local/intake-session.json`. Se nao existir, abortar com "Nenhuma sessao em curso. Comece com `*idea-intake <sua ideia>`."
|
|
72
|
+
2. Se `$ARGUMENTS` e frase curta: criar nova sessao, slug = kebab-case dos primeiros 4 substantivos. Persistir em `.gos-local/intake-session.json`.
|
|
73
|
+
3. Verificar se existe `libraries/intake-questions-mom-test.md` no projeto (em projetos que consomem o G-OS via `.gos/`). Se sim, ler para enriquecer perguntas com banco contextualizado.
|
|
74
|
+
|
|
75
|
+
## Persistencia
|
|
76
|
+
|
|
77
|
+
`.gos-local/intake-session.json`:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"session_id": "intake-2026-05-09T14-22-03",
|
|
82
|
+
"slug": "agendamento-mae",
|
|
83
|
+
"ideia_seed": "queria um app que minha mae use pra...",
|
|
84
|
+
"block": 3,
|
|
85
|
+
"qa": [
|
|
86
|
+
{ "block": 1, "q": "...", "a": "..." }
|
|
87
|
+
],
|
|
88
|
+
"started_at": "<iso>",
|
|
89
|
+
"updated_at": "<iso>"
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Saida final (intake.md)
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
---
|
|
97
|
+
intake_id: INTAKE-NNN-<slug>
|
|
98
|
+
status: pronto-para-prd
|
|
99
|
+
descartavel: true|false
|
|
100
|
+
created_at: <iso>
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# <Titulo curto da ideia>
|
|
104
|
+
|
|
105
|
+
## Problema (em uma frase)
|
|
106
|
+
<sintese feita pelo agente, validada com o usuario antes de fechar>
|
|
107
|
+
|
|
108
|
+
## Historias reais coletadas
|
|
109
|
+
- <bullet 1>
|
|
110
|
+
- <bullet 2>
|
|
111
|
+
|
|
112
|
+
## Persona
|
|
113
|
+
<descricao em prosa, contexto incluido>
|
|
114
|
+
|
|
115
|
+
## Jobs-to-be-done
|
|
116
|
+
- Quando <situacao>, eu quero <acao>, para que <resultado>.
|
|
117
|
+
|
|
118
|
+
## Limites (o que NAO fazer)
|
|
119
|
+
- <bullet>
|
|
120
|
+
|
|
121
|
+
## Telas-chave (visao bruta)
|
|
122
|
+
1. <tela 1 — descricao em palavras leigas>
|
|
123
|
+
2. <tela 2>
|
|
124
|
+
|
|
125
|
+
## Inspiracoes
|
|
126
|
+
- <link ou nome>
|
|
127
|
+
|
|
128
|
+
## Escopo
|
|
129
|
+
- Descartavel: <sim|nao>
|
|
130
|
+
- Vida util esperada: <uma vez|semanas|meses|continuo>
|
|
131
|
+
|
|
132
|
+
## Metrica de sucesso (linguagem humana)
|
|
133
|
+
<frase do usuario>
|
|
134
|
+
|
|
135
|
+
## Proximo passo
|
|
136
|
+
- Rodar `*prd-from-intake INTAKE-NNN-<slug>` para gerar PRD lean.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Regras criticas
|
|
140
|
+
|
|
141
|
+
- **Falsificar antes de fechar**: ao final do bloco 5, mostrar resumo em 5 bullets e perguntar "isso reflete o que voce quer?". Se usuario corrigir algo, voltar 1 bloco.
|
|
142
|
+
- **Sem chumbar tecnologia**: nao mencionar React, Cloudflare, Supabase, banco, API. Decisoes tecnicas sao da `adr-tech-decisions`, NAO daqui.
|
|
143
|
+
- **Descartavel-first**: se usuario indicar uso unico, marcar `descartavel: true` no frontmatter — `prd-from-intake` e `adr-tech-decisions` usam isso para dimensionar arquitetura (sem auth complexa, sem CI/CD elaborado, etc.).
|
|
144
|
+
|
|
145
|
+
## Input
|
|
146
|
+
|
|
147
|
+
$ARGUMENTS
|
|
@@ -27,9 +27,16 @@ Você está executando como **Tech Lead Frontend / Arquiteto Sênior** via skill
|
|
|
27
27
|
|
|
28
28
|
1. Escrever `plan.md` + `context.md`.
|
|
29
29
|
2. **Invocar `plan-to-tasks`** apontando para o `plan.md` recém-criado — gera os `T-NN*.md` em `tasks/`.
|
|
30
|
-
3.
|
|
31
|
-
4.
|
|
32
|
-
5.
|
|
30
|
+
3. **Invocar `ui-guardrails <plan-dir>`** — bloqueia se faltar estado/responsivo/a11y/tokens em qualquer task de UI. Skip permitido se `descartavel: true` no frontmatter (passa a warning).
|
|
31
|
+
4. Atualizar `progress.txt` (skill `progress-tracker set`).
|
|
32
|
+
5. **Rodar `node <repo>/.gos/scripts/integrations/check-plan.js <plan-dir>`** — gate determinístico.
|
|
33
|
+
6. (Opcional, default ligado) Comprimir secoes prosa do plan.md via `gos-caveman full` — preserva codigo/tabelas/frontmatter, comprime ## Contexto e ## Notas.
|
|
34
|
+
7. Exit 0 → devolver "plano criado" com resumo. Exit != 0 → regerar tasks 1x e re-rodar; se persistir, ABORTAR e devolver a saída do check-plan ao usuário.
|
|
35
|
+
|
|
36
|
+
### Flags de token-control
|
|
37
|
+
- `--no-compress` — desliga gos-caveman (default ligado).
|
|
38
|
+
- `--no-guardrails` — pula ui-guardrails (apenas para descartaveis).
|
|
39
|
+
- `--compress-context` — comprime docs/stack.md + ADRs antes de injetar (via gos-compress, requer setup).
|
|
33
40
|
|
|
34
41
|
Plano sem tasks (tasks/ vazio ou ausente) é falha — não é "plano parcial". Skill que devolve "plano criado" sem ter rodado o check-plan está em estado inválido.
|
|
35
42
|
|
|
@@ -16,6 +16,34 @@ metadata:
|
|
|
16
16
|
|
|
17
17
|
You are operating as a **Tasks Writer** for the G-OS project, following the G-OS Agent-Driven Agile methodology.
|
|
18
18
|
|
|
19
|
+
## UI Guardrails embarcados (CRITICO para tasks de UI)
|
|
20
|
+
|
|
21
|
+
Toda task com `area: ui-ux` ou `area: frontend` que represente uma tela DEVE nascer com seções obrigatórias para evitar que codegen gere UI incompleta (gargalo conhecido do framework):
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
## Estados visuais
|
|
25
|
+
- [ ] Loading: <skeleton ou spinner declarado>
|
|
26
|
+
- [ ] Empty: <copy + ilustracao + CTA>
|
|
27
|
+
- [ ] Error: <mensagem + recovery>
|
|
28
|
+
- [ ] Success (se aplicavel): <toast/inline>
|
|
29
|
+
|
|
30
|
+
## Responsividade
|
|
31
|
+
- [ ] Mobile (<768px): <comportamento>
|
|
32
|
+
- [ ] Tablet: <comportamento>
|
|
33
|
+
- [ ] Desktop: <default>
|
|
34
|
+
|
|
35
|
+
## A11y minimo
|
|
36
|
+
- [ ] Roles ARIA aplicados
|
|
37
|
+
- [ ] aria-label em icon buttons
|
|
38
|
+
- [ ] Focus order definido (>3 elementos)
|
|
39
|
+
- [ ] Contraste AA verificado
|
|
40
|
+
|
|
41
|
+
## Tokens DS
|
|
42
|
+
- [ ] 0 valores hardcoded fora do scale do DS
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Detalhe: ver `libraries/ui-guardrails-checklist.md`. Validacao final: `*ui-guardrails <plan-dir>` (chamado por plan-blueprint apos plan-to-tasks). Em planos com `descartavel: true`, secoes viram warning.
|
|
46
|
+
|
|
19
47
|
## Input
|
|
20
48
|
$ARGUMENTS
|
|
21
49
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prd-from-intake
|
|
3
|
+
description: >
|
|
4
|
+
Converte intake.md (saida de idea-intake) em PRD lean otimizado para LLM. Foco em problema,
|
|
5
|
+
persona, JTBD, telas-chave, criterios de aceite e metricas. NAO inclui decisoes tecnicas
|
|
6
|
+
(deixadas para adr-tech-decisions). Output: docs/prd/PRD-NNN-<slug>/prd.md.
|
|
7
|
+
argument-hint: "<INTAKE-id> [--descartavel] [--lean|--full]"
|
|
8
|
+
allowedTools: [Read, Glob, Grep, Bash, Write, Edit, AskUserQuestion]
|
|
9
|
+
sourceDocs:
|
|
10
|
+
- templates/prdLeanTemplate.md
|
|
11
|
+
use-when:
|
|
12
|
+
- tem-se um intake.md pronto e precisa do PRD
|
|
13
|
+
- usuario diz "transforma essa ideia em PRD"
|
|
14
|
+
do-not-use-for:
|
|
15
|
+
- ideia ainda nao validada (rode idea-intake primeiro)
|
|
16
|
+
- decisoes tecnicas (use adr-tech-decisions)
|
|
17
|
+
- planejamento de tela (use plan-blueprint)
|
|
18
|
+
metadata:
|
|
19
|
+
category: documentation
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Voce esta executando como **Product Manager Lean** via skill `prd-from-intake`. Le um intake.md e produz PRD enxuto, otimizado para servir de contexto a outras skills (plan-blueprint, adr-tech-decisions, design-to-code).
|
|
23
|
+
|
|
24
|
+
## Contrato
|
|
25
|
+
|
|
26
|
+
1. Input obrigatorio: `INTAKE-id` (ex: INTAKE-007-agendamento-mae).
|
|
27
|
+
2. Resolver path: `docs/intake/<INTAKE-id>/intake.md`. Ausente -> abortar.
|
|
28
|
+
3. Modos:
|
|
29
|
+
- `--lean` (default): PRD em <500 palavras, somente o essencial.
|
|
30
|
+
- `--full`: PRD completo com riscos, dependencias, edge cases.
|
|
31
|
+
4. Se `descartavel: true` no intake -> forca `--lean` automaticamente. Sobrescrever so com flag explicita.
|
|
32
|
+
5. Output unico: `docs/prd/PRD-NNN-<slug>/prd.md`. NNN = ultimo PRD + 1.
|
|
33
|
+
|
|
34
|
+
## Estrutura do PRD lean
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
---
|
|
38
|
+
prd_id: PRD-NNN-<slug>
|
|
39
|
+
intake_ref: INTAKE-NNN-<slug>
|
|
40
|
+
descartavel: <bool>
|
|
41
|
+
status: pronto-para-adr
|
|
42
|
+
created_at: <iso>
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# <Titulo>
|
|
46
|
+
|
|
47
|
+
## TL;DR (1 paragrafo, max 4 linhas)
|
|
48
|
+
<problema + persona + solucao + metrica de sucesso, comprimido>
|
|
49
|
+
|
|
50
|
+
## Quem usa
|
|
51
|
+
<persona em 2 linhas>
|
|
52
|
+
|
|
53
|
+
## Por que existe
|
|
54
|
+
<problema em 2 linhas, citando 1 historia real do intake>
|
|
55
|
+
|
|
56
|
+
## O que faz (3-7 bullets)
|
|
57
|
+
- <feature 1>
|
|
58
|
+
- <feature 2>
|
|
59
|
+
|
|
60
|
+
## Telas-chave
|
|
61
|
+
| # | Tela | Proposito | Inputs | Outputs |
|
|
62
|
+
|---|------|-----------|--------|---------|
|
|
63
|
+
| 1 | <nome> | <verbo + objeto> | <dado entrada> | <dado saida> |
|
|
64
|
+
|
|
65
|
+
## Criterios de aceite (do nao-tecnico)
|
|
66
|
+
- [ ] Usuario consegue <acao primaria> em menos de <X> passos
|
|
67
|
+
- [ ] <criterio mensurivel>
|
|
68
|
+
|
|
69
|
+
## Metrica de sucesso
|
|
70
|
+
<copia da metrica humana do intake + 1 metrica quantitativa derivada>
|
|
71
|
+
|
|
72
|
+
## NAO faz parte (escopo negativo)
|
|
73
|
+
- <bullet>
|
|
74
|
+
|
|
75
|
+
## Proximo passo
|
|
76
|
+
- Rodar `*adr-tech-decisions PRD-NNN-<slug>` para definir arquitetura.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Compressao automatica
|
|
80
|
+
|
|
81
|
+
Se contagem de tokens do intake.md > 2000:
|
|
82
|
+
1. Tentar usar `gos-compress` (skill wrapper sandeco) com rate=0.5 sobre intake.md antes de ler.
|
|
83
|
+
2. Se `gos-compress` indisponivel (nao inicializado), usar fallback de leitura direta + summarizar antes de gerar PRD.
|
|
84
|
+
|
|
85
|
+
## Regras criticas
|
|
86
|
+
|
|
87
|
+
- **Zero tecnologia**: nao mencionar framework, banco, deploy. Sao decisoes do ADR.
|
|
88
|
+
- **Compressao agressiva no lean**: se passou de 500 palavras, comprime ate caber.
|
|
89
|
+
- **Anti-template**: nao copiar bullets do intake literal — sintetizar. PRD e nova obra, nao paraphrase.
|
|
90
|
+
- **Marcar descartavel**: o flag se propaga ate o ADR, plan-blueprint e codegen — define se vale a pena ter testes E2E, CI/CD, rate limit, etc.
|
|
91
|
+
|
|
92
|
+
## Input
|
|
93
|
+
|
|
94
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prototype-orchestrator
|
|
3
|
+
description: >
|
|
4
|
+
Orquestra pipeline ideia-para-prototipo end-to-end: idea-intake -> prd-from-intake ->
|
|
5
|
+
adr-tech-decisions -> stitch/figma generate-design -> design-critique -> handoff para
|
|
6
|
+
design-to-code. Pensado para usuarios nao-tecnicos com MVP descartavel. Decision gates
|
|
7
|
+
entre fases para abortar cedo.
|
|
8
|
+
argument-hint: "<frase da ideia ou 'continuar'> [--skip-figma] [--full-stack]"
|
|
9
|
+
allowedTools: [Read, Glob, Grep, Bash, Write, Edit, AskUserQuestion]
|
|
10
|
+
sourceDocs:
|
|
11
|
+
- skills/idea-intake/SKILL.md
|
|
12
|
+
- skills/prd-from-intake/SKILL.md
|
|
13
|
+
- skills/adr-tech-decisions/SKILL.md
|
|
14
|
+
- skills/figma-implement-design/SKILL.md
|
|
15
|
+
- skills/design-to-code/SKILL.md
|
|
16
|
+
- skills/figma-print-diff/SKILL.md
|
|
17
|
+
use-when:
|
|
18
|
+
- usuario nao-tecnico chega com uma ideia e quer prototipo visivel
|
|
19
|
+
- ja existe intake mas usuario quer levar ate Figma+codigo
|
|
20
|
+
- preciso iterar de "ideia" ate "tela rodando" sem perder contexto entre fases
|
|
21
|
+
do-not-use-for:
|
|
22
|
+
- tarefas tecnicas pontuais (use plan-blueprint direto)
|
|
23
|
+
- quando ja existe stack.md + PRD (entre direto via plan-blueprint)
|
|
24
|
+
metadata:
|
|
25
|
+
category: orchestration
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
Voce esta executando como **Orquestrador Ideia-Prototipo** via skill `prototype-orchestrator`. Coordena 5 skills em sequencia com decision gates entre cada uma. Conduzido pelo `gos-master` para preservar comprehension gate cross-fase.
|
|
29
|
+
|
|
30
|
+
## Pipeline
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
[ideia bruta]
|
|
34
|
+
|
|
|
35
|
+
v
|
|
36
|
+
1. idea-intake -> intake.md (gate: usuario valida resumo)
|
|
37
|
+
|
|
|
38
|
+
v
|
|
39
|
+
2. prd-from-intake -> prd.md (gate: usuario aprova TL;DR)
|
|
40
|
+
|
|
|
41
|
+
v
|
|
42
|
+
3. adr-tech-decisions -> ADR + stack.md (gate: usuario confirma decisoes tecnicas)
|
|
43
|
+
|
|
|
44
|
+
v
|
|
45
|
+
4. (opcional) Stitch/Figma generate-design -> frames Figma (gate: usuario aprova mockups)
|
|
46
|
+
|
|
|
47
|
+
v
|
|
48
|
+
5. plan-blueprint por tela -> plan + tasks (gate: validate-plan)
|
|
49
|
+
|
|
|
50
|
+
v
|
|
51
|
+
6. design-to-code + figma-implement-design -> codigo
|
|
52
|
+
|
|
|
53
|
+
v
|
|
54
|
+
7. figma-print-diff -> ajustes ate aprovacao visual
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Estado da orquestracao
|
|
58
|
+
|
|
59
|
+
Persistido em `.gos-local/prototype-session.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"session_id": "proto-2026-05-09T14-22-03",
|
|
64
|
+
"slug": "<derivado da ideia>",
|
|
65
|
+
"current_phase": 3,
|
|
66
|
+
"phases": {
|
|
67
|
+
"1_intake": { "status": "done", "ref": "INTAKE-007-agendamento-mae" },
|
|
68
|
+
"2_prd": { "status": "done", "ref": "PRD-007-agendamento-mae" },
|
|
69
|
+
"3_adr": { "status": "in-progress", "ref": null },
|
|
70
|
+
"4_figma": { "status": "pending", "ref": null },
|
|
71
|
+
"5_plans": { "status": "pending", "refs": [] },
|
|
72
|
+
"6_codegen": { "status": "pending" },
|
|
73
|
+
"7_visual_qa": { "status": "pending" }
|
|
74
|
+
},
|
|
75
|
+
"started_at": "<iso>",
|
|
76
|
+
"updated_at": "<iso>"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Decision gates entre fases
|
|
81
|
+
|
|
82
|
+
Cada gate usa `AskUserQuestion` com 3 opcoes:
|
|
83
|
+
1. **Aprovar e seguir** -> avanca para proxima fase.
|
|
84
|
+
2. **Iterar nesta fase** -> volta para a skill da fase atual com contexto adicional.
|
|
85
|
+
3. **Abortar** -> grava sessao como `aborted` e devolve resumo.
|
|
86
|
+
|
|
87
|
+
## Pre-flight
|
|
88
|
+
|
|
89
|
+
1. Se `$ARGUMENTS == "continuar"`: ler `prototype-session.json`, retomar da fase atual.
|
|
90
|
+
2. Senao: criar nova sessao + chamar fase 1 (idea-intake) com a frase da ideia.
|
|
91
|
+
3. Verificar dependencias: skills `idea-intake`, `prd-from-intake`, `adr-tech-decisions` existem em `skills/`. Falta -> abortar.
|
|
92
|
+
4. `--skip-figma` pula fase 4 (caso usuario queira ir direto para codigo).
|
|
93
|
+
5. `--full-stack` forca perfil B/C no ADR (mesmo que descartavel).
|
|
94
|
+
|
|
95
|
+
## Execucao
|
|
96
|
+
|
|
97
|
+
Para cada fase pendente:
|
|
98
|
+
1. Imprimir cabecalho `[fase N/7] <nome>`.
|
|
99
|
+
2. Invocar skill correspondente via `gos-master` (com comprehension gate).
|
|
100
|
+
3. Persistir `ref` no session.json apos sucesso.
|
|
101
|
+
4. Aplicar decision gate.
|
|
102
|
+
5. Avancar.
|
|
103
|
+
|
|
104
|
+
## Compressao de contexto entre fases
|
|
105
|
+
|
|
106
|
+
Para evitar inflacao de tokens (problema central do framework):
|
|
107
|
+
- A cada fase, comprimir output da anterior via `gos-compress` rate=0.4 antes de passar para a proxima.
|
|
108
|
+
- Manter snapshot integral em disco (`docs/intake/...`, `docs/prd/...`, etc.) — apenas o contexto in-memory e comprimido.
|
|
109
|
+
- Se `gos-compress` indisponivel: usar resumo manual de 200 palavras + path do arquivo original.
|
|
110
|
+
|
|
111
|
+
## Regras criticas
|
|
112
|
+
|
|
113
|
+
- **Sempre perguntar (regra do dono)**: cada gate e obrigatorio. Nunca avancar fase sem confirmacao.
|
|
114
|
+
- **Descartavel-first**: se intake marcou descartavel, pular Storybook, E2E, design system robusto.
|
|
115
|
+
- **Anti-loop**: limite de 3 iteracoes por fase. Se exceder, sugerir abortar.
|
|
116
|
+
- **Output rastreavel**: ao final, gerar `docs/prototypes/PROTO-NNN-<slug>/index.md` com links para todos os artefatos.
|
|
117
|
+
|
|
118
|
+
## Input
|
|
119
|
+
|
|
120
|
+
$ARGUMENTS
|
|
@@ -25,6 +25,17 @@
|
|
|
25
25
|
{ "slug": "progress-tracker", "path": "skills/progress-tracker/SKILL.md" },
|
|
26
26
|
{ "slug": "execute-plan", "path": "skills/execute-plan/SKILL.md" },
|
|
27
27
|
{ "slug": "validate-plan", "path": "skills/validate-plan/SKILL.md" },
|
|
28
|
-
{ "slug": "audit-screenshots", "path": "skills/audit-screenshots/SKILL.md" }
|
|
28
|
+
{ "slug": "audit-screenshots", "path": "skills/audit-screenshots/SKILL.md" },
|
|
29
|
+
{ "slug": "idea-intake", "path": "skills/idea-intake/SKILL.md" },
|
|
30
|
+
{ "slug": "prd-from-intake", "path": "skills/prd-from-intake/SKILL.md" },
|
|
31
|
+
{ "slug": "adr-tech-decisions", "path": "skills/adr-tech-decisions/SKILL.md" },
|
|
32
|
+
{ "slug": "prototype-orchestrator", "path": "skills/prototype-orchestrator/SKILL.md" },
|
|
33
|
+
{ "slug": "gos-caveman", "path": "skills/gos-caveman/SKILL.md" },
|
|
34
|
+
{ "slug": "gos-compress", "path": "skills/gos-compress/SKILL.md" },
|
|
35
|
+
{ "slug": "figma-print-diff", "path": "skills/figma-print-diff/SKILL.md" },
|
|
36
|
+
{ "slug": "ui-guardrails", "path": "skills/ui-guardrails/SKILL.md" },
|
|
37
|
+
{ "slug": "cloudflare-pages-setup", "path": "skills/cloudflare-pages-setup/SKILL.md" },
|
|
38
|
+
{ "slug": "typeform-form-pattern", "path": "skills/typeform-form-pattern/SKILL.md" },
|
|
39
|
+
{ "slug": "timer-component-pattern", "path": "skills/timer-component-pattern/SKILL.md" }
|
|
29
40
|
]
|
|
30
41
|
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: timer-component-pattern
|
|
3
|
+
description: >
|
|
4
|
+
Gera componente Timer (countdown) React + TS com state machine, persistencia,
|
|
5
|
+
atalhos de teclado, edicao inline, tema dark/light, controles via Lucide React.
|
|
6
|
+
Baseado em code-kata-timer adaptado para React.
|
|
7
|
+
argument-hint: "<descricao do uso ou 'spec' para ver anatomia>"
|
|
8
|
+
allowedTools: [Read, Glob, Grep, Bash, Write, Edit, AskUserQuestion]
|
|
9
|
+
sourceDocs:
|
|
10
|
+
- libraries/timer-pattern-spec.md
|
|
11
|
+
- libraries/lucide-icons-policy.md
|
|
12
|
+
- libraries/ui-guardrails-checklist.md
|
|
13
|
+
use-when:
|
|
14
|
+
- usuario pede pomodoro, code kata timer, countdown, contador regressivo
|
|
15
|
+
- precisa de timer com play/pause/reset/edit
|
|
16
|
+
- quer atalhos de teclado (Space, R, E)
|
|
17
|
+
do-not-use-for:
|
|
18
|
+
- cronometro (countup) — variar via `mode: 'countup'` flag
|
|
19
|
+
- timer de polling (use TanStack Query refetchInterval)
|
|
20
|
+
- calendar/scheduler (use componente diferente)
|
|
21
|
+
metadata:
|
|
22
|
+
category: ui-pattern
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Voce esta executando como **Timer Pattern Generator** via skill `timer-component-pattern`. Gera componente React baseado em `libraries/timer-pattern-spec.md`.
|
|
26
|
+
|
|
27
|
+
## Pre-flight
|
|
28
|
+
|
|
29
|
+
1. AskUserQuestion:
|
|
30
|
+
- "Tempo default em segundos? (ex: 30 para code kata, 1500 para pomodoro 25min)"
|
|
31
|
+
- "Som ao terminar? (Web Audio beep / arquivo / nenhum)"
|
|
32
|
+
- "Tema dark/light togglavel? (sim / so dark / so light)"
|
|
33
|
+
- "Persistir entre sessoes? (localStorage / nao)"
|
|
34
|
+
- "Atalhos teclado? (sim default / nao)"
|
|
35
|
+
- "Editar tempo inline? (sim / nao — botao edit aparece se sim)"
|
|
36
|
+
2. Validar stack: `lucide-react`, shadcn `Button`. Senao -> instruir instalacao.
|
|
37
|
+
|
|
38
|
+
## Arquivos gerados
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/components/timer/
|
|
42
|
+
Timer.tsx # componente principal
|
|
43
|
+
hooks/
|
|
44
|
+
useTimer.ts # hook com state machine
|
|
45
|
+
useTimerKeyboard.ts # atalhos
|
|
46
|
+
utils/
|
|
47
|
+
formatTime.ts # MM:SS
|
|
48
|
+
beep.ts # Web Audio (opcional)
|
|
49
|
+
types.ts # TimerStatus, TimerSettings
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Componente principal
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { useEffect } from 'react';
|
|
56
|
+
import { Play, Pause, RotateCcw, Pencil, Activity } from 'lucide-react';
|
|
57
|
+
import { Button } from '@/components/ui/button';
|
|
58
|
+
import { useTimer } from './hooks/useTimer';
|
|
59
|
+
import { useTimerKeyboard } from './hooks/useTimerKeyboard';
|
|
60
|
+
import { TimerStatus, isRunning } from './types';
|
|
61
|
+
import { formatTime } from './utils/formatTime';
|
|
62
|
+
|
|
63
|
+
interface TimerProps {
|
|
64
|
+
defaultSeconds?: number;
|
|
65
|
+
onComplete?: (duration: number) => void;
|
|
66
|
+
enableEdit?: boolean;
|
|
67
|
+
enableKeyboard?: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function Timer({
|
|
71
|
+
defaultSeconds = 30,
|
|
72
|
+
onComplete,
|
|
73
|
+
enableEdit = true,
|
|
74
|
+
enableKeyboard = true,
|
|
75
|
+
}: TimerProps) {
|
|
76
|
+
const timer = useTimer(defaultSeconds);
|
|
77
|
+
|
|
78
|
+
useTimerKeyboard({
|
|
79
|
+
enabled: enableKeyboard,
|
|
80
|
+
status: timer.status,
|
|
81
|
+
actions: timer,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
function onDone(e: Event) {
|
|
86
|
+
const evt = e as CustomEvent<{ duration: number }>;
|
|
87
|
+
onComplete?.(evt.detail.duration);
|
|
88
|
+
}
|
|
89
|
+
window.addEventListener('timer:done', onDone);
|
|
90
|
+
return () => window.removeEventListener('timer:done', onDone);
|
|
91
|
+
}, [onComplete]);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div className="flex flex-col items-center justify-center gap-8 py-12">
|
|
95
|
+
{/* Indicator */}
|
|
96
|
+
{isRunning(timer.status) && (
|
|
97
|
+
<Activity className="h-6 w-6 text-primary animate-pulse" aria-label="Em execucao" />
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{/* Display */}
|
|
101
|
+
{timer.status === TimerStatus.EDITING ? (
|
|
102
|
+
<input
|
|
103
|
+
type="number"
|
|
104
|
+
autoFocus
|
|
105
|
+
defaultValue={timer.seconds}
|
|
106
|
+
className="text-7xl md:text-9xl font-mono font-bold tabular-nums bg-transparent w-72 text-center outline-none border-b-2 border-primary"
|
|
107
|
+
onBlur={(e) => {
|
|
108
|
+
const v = Number(e.currentTarget.value);
|
|
109
|
+
if (v > 0) timer.setSeconds(v);
|
|
110
|
+
timer.setStatus(TimerStatus.STOPPED);
|
|
111
|
+
}}
|
|
112
|
+
onKeyDown={(e) => {
|
|
113
|
+
if (e.key === 'Enter') e.currentTarget.blur();
|
|
114
|
+
if (e.key === 'Escape') timer.setStatus(TimerStatus.STOPPED);
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
) : (
|
|
118
|
+
<div
|
|
119
|
+
className="text-7xl md:text-9xl font-mono font-bold tabular-nums"
|
|
120
|
+
aria-live="polite"
|
|
121
|
+
aria-atomic="true"
|
|
122
|
+
>
|
|
123
|
+
{formatTime(timer.seconds)}
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
|
|
127
|
+
{/* Controls */}
|
|
128
|
+
<div className="flex gap-3">
|
|
129
|
+
{timer.status === TimerStatus.RUNNING ? (
|
|
130
|
+
<Button onClick={timer.pause} size="lg" aria-label="Pausar">
|
|
131
|
+
<Pause className="h-5 w-5" />
|
|
132
|
+
</Button>
|
|
133
|
+
) : (
|
|
134
|
+
<Button
|
|
135
|
+
onClick={timer.start}
|
|
136
|
+
size="lg"
|
|
137
|
+
disabled={timer.seconds === 0}
|
|
138
|
+
aria-label="Iniciar"
|
|
139
|
+
>
|
|
140
|
+
<Play className="h-5 w-5" />
|
|
141
|
+
</Button>
|
|
142
|
+
)}
|
|
143
|
+
|
|
144
|
+
<Button
|
|
145
|
+
onClick={() => timer.reset()}
|
|
146
|
+
size="lg"
|
|
147
|
+
variant="outline"
|
|
148
|
+
aria-label="Resetar"
|
|
149
|
+
>
|
|
150
|
+
<RotateCcw className="h-5 w-5" />
|
|
151
|
+
</Button>
|
|
152
|
+
|
|
153
|
+
{enableEdit && (
|
|
154
|
+
<Button
|
|
155
|
+
onClick={() => timer.setStatus(TimerStatus.EDITING)}
|
|
156
|
+
size="lg"
|
|
157
|
+
variant="outline"
|
|
158
|
+
disabled={isRunning(timer.status)}
|
|
159
|
+
aria-label="Editar tempo"
|
|
160
|
+
>
|
|
161
|
+
<Pencil className="h-5 w-5" />
|
|
162
|
+
</Button>
|
|
163
|
+
)}
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
{/* Hint atalhos */}
|
|
167
|
+
{enableKeyboard && (
|
|
168
|
+
<p className="text-xs text-muted-foreground">
|
|
169
|
+
Espaco play/pause - R reset - E editar
|
|
170
|
+
</p>
|
|
171
|
+
)}
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## State machine (types.ts)
|
|
178
|
+
|
|
179
|
+
Conforme `libraries/timer-pattern-spec.md`:
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
export const TimerStatus = {
|
|
183
|
+
STOPPED: 'STOPPED',
|
|
184
|
+
COUNTDOWN: 'COUNTDOWN',
|
|
185
|
+
RUNNING: 'RUNNING',
|
|
186
|
+
PAUSED: 'PAUSED',
|
|
187
|
+
EDITING: 'EDITING',
|
|
188
|
+
} as const;
|
|
189
|
+
|
|
190
|
+
export type TimerStatusType = typeof TimerStatus[keyof typeof TimerStatus];
|
|
191
|
+
|
|
192
|
+
export const isRunning = (s: TimerStatusType) =>
|
|
193
|
+
s === TimerStatus.RUNNING || s === TimerStatus.COUNTDOWN;
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Hook useTimer (com persistencia opcional)
|
|
197
|
+
|
|
198
|
+
Detalhe completo em `libraries/timer-pattern-spec.md`. Pontos criticos:
|
|
199
|
+
- `setInterval` com cleanup em `useEffect` return + ao parar.
|
|
200
|
+
- Ao restaurar `localStorage`: SEMPRE forcar status STOPPED (evita timer fantasma).
|
|
201
|
+
- Dispatch `CustomEvent('timer:done')` ao zerar.
|
|
202
|
+
|
|
203
|
+
## Estados visuais
|
|
204
|
+
|
|
205
|
+
- **Loading**: NA.
|
|
206
|
+
- **Empty**: tempo `00:00` -> Play disabled, mensagem "Tempo zerado, edite para comecar".
|
|
207
|
+
- **Error**: NA em runtime.
|
|
208
|
+
- **Running**: `Activity` icon pulsando + `animate-pulse` no display opcional.
|
|
209
|
+
- **Done**: tela ou toast com `CheckCircle2` quando atinge 0.
|
|
210
|
+
|
|
211
|
+
## Som ao terminar (utils/beep.ts)
|
|
212
|
+
|
|
213
|
+
Web Audio API (sem assets):
|
|
214
|
+
```ts
|
|
215
|
+
export function beep(frequency = 800, duration = 200) {
|
|
216
|
+
const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();
|
|
217
|
+
const osc = ctx.createOscillator();
|
|
218
|
+
osc.connect(ctx.destination);
|
|
219
|
+
osc.frequency.value = frequency;
|
|
220
|
+
osc.start();
|
|
221
|
+
setTimeout(() => { osc.stop(); ctx.close(); }, duration);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Disparado em `useEffect` quando `seconds === 0 && previousSeconds !== 0`.
|
|
226
|
+
|
|
227
|
+
## Modos disponiveis
|
|
228
|
+
|
|
229
|
+
Flags do componente:
|
|
230
|
+
- `mode="countdown"` (default) — diminui ate 0.
|
|
231
|
+
- `mode="countup"` — sobe a partir de 0 (cronometro).
|
|
232
|
+
- `mode="pomodoro"` — alterna 25min foco / 5min pausa.
|
|
233
|
+
|
|
234
|
+
Cada modo so muda a logica do hook, UI e controles ficam iguais.
|
|
235
|
+
|
|
236
|
+
## Anti-patterns embutidos (warning ao usuario)
|
|
237
|
+
|
|
238
|
+
- "Sem cleanup de setInterval" -> recusar — gera memory leak.
|
|
239
|
+
- "Restaurar status RUNNING do localStorage" -> recusar — timer fantasma.
|
|
240
|
+
- "Emoji nos botoes" -> recusar — usar Lucide.
|
|
241
|
+
- "Sem `tabular-nums`" -> warning — digitos pulam visualmente.
|
|
242
|
+
|
|
243
|
+
## Input
|
|
244
|
+
|
|
245
|
+
$ARGUMENTS
|