create-sdd-ai-stack 0.1.17

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.
Files changed (72) hide show
  1. package/AGENTS.md +164 -0
  2. package/APP-STACK.md +31 -0
  3. package/APP.md +46 -0
  4. package/ARCHITECTURE.md +115 -0
  5. package/DESIGN.md +219 -0
  6. package/LICENSE +21 -0
  7. package/NEXT.md +345 -0
  8. package/NODE.md +107 -0
  9. package/REACT.md +92 -0
  10. package/README.md +260 -0
  11. package/SKILLS/check-docs/SKILL.md +24 -0
  12. package/SKILLS/check-docs/check-docs.mjs +56 -0
  13. package/SKILLS/create-feature/SKILL.md +40 -0
  14. package/SKILLS/create-feature/create-feature.mjs +128 -0
  15. package/SKILLS/create-feature.sh +112 -0
  16. package/SKILLS/install-submodule/SKILL.md +42 -0
  17. package/SKILLS/install-submodule/install-submodule.mjs +119 -0
  18. package/bin/create-sdd-ai-stack.mjs +93 -0
  19. package/docs/CHANGELOG.md +209 -0
  20. package/docs/PLANNING.md +68 -0
  21. package/docs/PRODUCT.md +76 -0
  22. package/docs/RELEASE.md +332 -0
  23. package/lib/check-links.mjs +42 -0
  24. package/lib/constants.mjs +60 -0
  25. package/lib/scaffold.mjs +253 -0
  26. package/package.json +80 -0
  27. package/specs/BACKLOG.md +24 -0
  28. package/specs/PLAN.md +57 -0
  29. package/specs/ROADMAP.md +35 -0
  30. package/specs/history/phases/phase-0-bootstrap.md +67 -0
  31. package/specs/tasks/TASK_TEMPLATE.md +46 -0
  32. package/src/cli.mjs +119 -0
  33. package/stacks/README.md +33 -0
  34. package/stacks/ai.md +52 -0
  35. package/stacks/ci.md +59 -0
  36. package/stacks/database.md +56 -0
  37. package/stacks/git.md +51 -0
  38. package/stacks/shadcn.md +52 -0
  39. package/stacks/tailwind.md +65 -0
  40. package/stacks/testing.md +74 -0
  41. package/stacks/typescript.md +58 -0
  42. package/template/next/.env.example +4 -0
  43. package/template/next/README.md +47 -0
  44. package/template/next/biome.json +36 -0
  45. package/template/next/gitignore +32 -0
  46. package/template/next/next.config.ts +12 -0
  47. package/template/next/package.json +47 -0
  48. package/template/next/playwright.config.ts +21 -0
  49. package/template/next/postcss.config.mjs +7 -0
  50. package/template/next/src/app/(app)/app/page.tsx +18 -0
  51. package/template/next/src/app/(app)/error.tsx +30 -0
  52. package/template/next/src/app/(app)/layout.tsx +25 -0
  53. package/template/next/src/app/(marketing)/page.tsx +73 -0
  54. package/template/next/src/app/globals.css +437 -0
  55. package/template/next/src/app/layout.tsx +41 -0
  56. package/template/next/src/app/not-found.tsx +11 -0
  57. package/template/next/src/features/example/actions.ts +43 -0
  58. package/template/next/src/features/example/application/create-example.usecase.ts +26 -0
  59. package/template/next/src/features/example/container.ts +16 -0
  60. package/template/next/src/features/example/domain/IExampleRepository.ts +11 -0
  61. package/template/next/src/features/example/domain/example.schema.ts +18 -0
  62. package/template/next/src/features/example/infrastructure/example.repository.ts +26 -0
  63. package/template/next/src/features/example/ui/create-example-form.tsx +56 -0
  64. package/template/next/src/proxy.ts +23 -0
  65. package/template/next/src/shared/lib/cn.ts +6 -0
  66. package/template/next/src/shared/server/auth.ts +32 -0
  67. package/template/next/src/shared/server/env.ts +14 -0
  68. package/template/next/src/shared/ui/index.ts +3 -0
  69. package/template/next/tests/e2e/routes.spec.ts +34 -0
  70. package/template/next/tests/unit/create-example.test.ts +55 -0
  71. package/template/next/tsconfig.json +37 -0
  72. package/template/next/vitest.config.ts +19 -0
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SDD SKILL: instala o core de regras (SDD/) em um projeto EXISTENTE
4
+ * como git submodule, e cria os atalhos na raiz apontando para ./SDD/AGENTS.md
5
+ *
6
+ * Uso:
7
+ * node SDD/SKILLS/install-submodule/install-submodule.mjs [caminho-do-projeto]
8
+ * node SDD/SKILLS/install-submodule/install-submodule.mjs # usa cwd
9
+ * node SDD/SKILLS/install-submodule/install-submodule.mjs . --copy # copia em vez de submodule
10
+ */
11
+ import fs from "node:fs";
12
+ import path from "node:path";
13
+ import { execFileSync } from "node:child_process";
14
+
15
+ const REPO_URL = "https://github.com/marcelinosandroni/sdd-ai-stack.git";
16
+ const SDD_DIR = "SDD";
17
+
18
+ const RULE_FILES = [
19
+ "AGENTS.md", "APP.md", "APP-STACK.md", "ARCHITECTURE.md",
20
+ "DESIGN.md", "NEXT.md", "NODE.md", "REACT.md",
21
+ ];
22
+ const RULE_DIRS = ["stacks", "specs", "docs", "SKILLS"];
23
+ const SHORTCUTS = [
24
+ "AGENTS.md", "CLAUDE.md", "GEMINI.md", ".cursorrules",
25
+ ".windsurfrules", ".github/copilot-instructions.md", ".clinerules",
26
+ ];
27
+
28
+ const STUB = `# 🤖 AGENTS.md (ponteiro)
29
+
30
+ > A fonte da verdade vive em **[SDD/AGENTS.md](./SDD/AGENTS.md)**.
31
+
32
+ \`\`\`bash
33
+ cat SDD/AGENTS.md # leis + fluxo (LEIA PRIMEIRO)
34
+ cat SDD/specs/PLAN.md # a task AGORA
35
+ cat SDD/NEXT.md # regras da stack
36
+ \`\`\`
37
+
38
+ > **Não edite \`SDD/\`** sem pedir ao humano.
39
+ > Atualize com: \`git submodule update --remote --merge SDD\`
40
+ `;
41
+
42
+ const log = (m) => console.log(m);
43
+ const sh = (cmd, args, cwd) => execFileSync(cmd, args, { cwd, stdio: "inherit" });
44
+ const has = (cmd) => { try { execFileSync(cmd, ["--version"], { stdio: "ignore" }); return true; } catch { return false; } };
45
+
46
+ function copyDir(from, to) {
47
+ fs.mkdirSync(to, { recursive: true });
48
+ for (const e of fs.readdirSync(from, { withFileTypes: true })) {
49
+ if (e.name === ".git" || e.name === "node_modules") continue;
50
+ const s = path.join(from, e.name), d = path.join(to, e.name);
51
+ if (e.isDirectory()) copyDir(s, d);
52
+ else if (e.isFile()) fs.copyFileSync(s, d);
53
+ }
54
+ }
55
+
56
+ function installShortcuts(root) {
57
+ for (const rel of SHORTCUTS) {
58
+ const p = path.join(root, rel);
59
+ if (fs.existsSync(p)) { log(` = ${rel} (já existe, preservado)`); continue; }
60
+ fs.mkdirSync(path.dirname(p), { recursive: true });
61
+ try {
62
+ fs.symlinkSync("SDD/AGENTS.md", p, "file");
63
+ log(` ✓ ${rel} (symlink)`);
64
+ } catch {
65
+ fs.writeFileSync(p, STUB, "utf8");
66
+ log(` ✓ ${rel} (stub)`);
67
+ }
68
+ }
69
+ }
70
+
71
+ function installRulesLocally(root) {
72
+ const here = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1"));
73
+ const source = path.resolve(here, "..", "..");
74
+ const dest = path.join(root, SDD_DIR);
75
+ fs.mkdirSync(dest, { recursive: true });
76
+ for (const f of RULE_FILES) {
77
+ const s = path.join(source, f);
78
+ if (fs.existsSync(s)) { fs.copyFileSync(s, path.join(dest, f)); log(` ✓ SDD/${f}`); }
79
+ }
80
+ for (const d of RULE_DIRS) {
81
+ const s = path.join(source, d);
82
+ if (fs.existsSync(s)) { copyDir(s, path.join(dest, d)); log(` ✓ SDD/${d}/`); }
83
+ }
84
+ return dest;
85
+ }
86
+
87
+ const args = process.argv.slice(2);
88
+ const useCopy = args.includes("--copy");
89
+ const target = path.resolve(process.cwd(), args.find((a) => !a.startsWith("-")) ?? ".");
90
+
91
+ log(`\n🤖 Instalando o core SDD em: ${target}\n`);
92
+
93
+ if (!fs.existsSync(target)) { console.error("✖ Pasta não existe."); process.exit(1); }
94
+
95
+ if (useCopy) {
96
+ log("📋 Modo: cópia local");
97
+ installRulesLocally(target);
98
+ installShortcuts(target);
99
+ } else {
100
+ if (!has("git")) { console.error("✖ git não encontrado. Use --copy."); process.exit(1); }
101
+ if (fs.existsSync(path.join(target, ".git")) === false) {
102
+ log("! Projeto não é um repositório git. Rode 'git init' antes ou use --copy.");
103
+ process.exit(1);
104
+ }
105
+ log(`🔗 Modo: git submodule → ${REPO_URL}`);
106
+ sh("git", ["submodule", "add", REPO_URL, SDD_DIR], target);
107
+ installShortcuts(target);
108
+ }
109
+
110
+ log(`
111
+ ✅ Pronto.
112
+
113
+ Leia agora:
114
+ cat ${SDD_DIR}/AGENTS.md
115
+ cat ${SDD_DIR}/specs/PLAN.md
116
+
117
+ Atualizar regras depois:
118
+ git submodule update --remote --merge ${SDD_DIR}
119
+ `);
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { createInterface } from "node:readline/promises";
5
+ import { parseArgs, HELP } from "../src/cli.mjs";
6
+ import { scaffold } from "../lib/scaffold.mjs";
7
+
8
+ const pkg = JSON.parse(
9
+ fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
10
+ );
11
+
12
+ function ask(question, fallback) {
13
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
14
+ return rl
15
+ .question(`${question} `)
16
+ .then((a) => a.trim() || fallback)
17
+ .finally(() => rl.close());
18
+ }
19
+
20
+ async function main() {
21
+ let opts;
22
+ try {
23
+ opts = parseArgs(process.argv.slice(2));
24
+ } catch (err) {
25
+ console.error(`\n✖ ${err.message}\n`);
26
+ console.error(HELP);
27
+ process.exit(1);
28
+ }
29
+
30
+ if (opts.help) {
31
+ console.log(HELP);
32
+ return;
33
+ }
34
+ if (opts.version) {
35
+ console.log(pkg.version);
36
+ return;
37
+ }
38
+
39
+ console.log("\n🤖 create-sdd-ai-stack — Spec-Driven Development para agentes de IA\n");
40
+
41
+ const name = opts.name ?? (await ask("Nome do projeto:", "meu-app"));
42
+ const target = path.resolve(process.cwd(), name);
43
+ const usingSubmodule = Boolean(opts.submodule);
44
+
45
+ console.log(`
46
+ 📁 projeto: ${name}
47
+ 📦 template: ${opts.template === "none" ? "(nenhum — só regras)" : opts.template}
48
+ 🧠 regras: ${usingSubmodule ? `submodule ${opts.submodule}` : "copiadas para ./SDD"}
49
+ `);
50
+
51
+ if (process.stdin.isTTY) {
52
+ const answer = await ask("Criar agora? [Y/n]", "Y");
53
+ if (!/^y(es)?$/i.test(answer)) {
54
+ console.log("\nCancelado. Nada foi criado.\n");
55
+ return;
56
+ }
57
+ }
58
+
59
+ try {
60
+ const summary = scaffold({
61
+ target,
62
+ template: opts.template,
63
+ install: opts.install,
64
+ git: opts.git,
65
+ submodule: opts.submodule,
66
+ shortcutMode: opts.shortcutMode,
67
+ });
68
+
69
+ console.log(`
70
+ ✅ Projeto criado em: ${summary.target}
71
+
72
+ Próximos passos:
73
+ cd ${name}
74
+ ${opts.install ? "" : " npm install\n"}${opts.git ? "" : " git init && git add -A && git commit -m \"chore: scaffold inicial\"\n"}
75
+ npm run dev
76
+
77
+ ⚠️ LEIA ANTES DE CODAR:
78
+ cat SDD/AGENTS.md # leis do agente
79
+ cat SDD/specs/PLAN.md # a task AGORA
80
+ cat SDD/NEXT.md # regras da stack (Next.js 16)
81
+
82
+ Atualizar as regras depois (se submodule):
83
+ git submodule update --remote --merge SDD
84
+
85
+ Docs: ${pkg.homepage}
86
+ `);
87
+ } catch (err) {
88
+ console.error(`\n✖ Falhou: ${err.message}\n`);
89
+ process.exit(1);
90
+ }
91
+ }
92
+
93
+ main();
@@ -0,0 +1,209 @@
1
+ # CHANGELOG
2
+
3
+ Todas as mudanças relevantes deste template. Formato baseado em
4
+ [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/); versionamento por
5
+ [SemVer](https://semver.org/lang/pt-BR/).
6
+
7
+ ---
8
+
9
+ ## [0.1.17] — 2026-09-29
10
+
11
+ > **Primeira versão publicada.** O projeto segue em `0.x` de propósito: a API de
12
+ > regras e o template ainda vão mudar com base no uso real. `0.y.z` comunica
13
+ > isso sem versionar breaking changes a cada duas semanas.
14
+
15
+ ### 🔒 Publicação no npm
16
+
17
+ - `.github/workflows/release.yml` — publica no push de tag `v*` (automático), com
18
+ `workflow_dispatch` para disparo manual e `dry_run` para validar sem queimar versão
19
+ - Secret do repositório: **`NPM_TOKEN`** (mapeado para `NODE_AUTH_TOKEN` pelo npm)
20
+ - `.npmrc` commitado apenas com `${NODE_AUTH_TOKEN}` — **nenhum token em arquivo**
21
+ - `publishConfig`: `access: public` + `provenance` (pacote assinado via GitHub OIDC)
22
+ - Guards antes do publish: `npm test` · links da doc · tag `vX.Y.Z` == `version` ·
23
+ 10 arquivos essenciais no tarball · `concurrency: release-npm`
24
+ - `exports` no `package.json` (consumo programático: `import { scaffold } from "create-sdd-ai-stack"`)
25
+ - `docs/RELEASE.md` — passo a passo, troubleshooting e a alternativa sem token (Trusted Publishing/OIDC)
26
+ - Scripts: `version:patch|minor|major`, `check:docs`, `check:pack`
27
+ (o `npm publish` manual saiu de propósito: **um caminho só**, o do CI)
28
+
29
+ ### 🐛 `.gitignore` do template não chegava no pacote
30
+
31
+ O npm **nunca** empacota arquivo chamado `.gitignore` (é um dos default-ignore dele).
32
+ O app gerado saía **sem `.gitignore`** — ou seja, `.env.local`, `.next/` e
33
+ `node_modules/` podiam ser commitados por acidente.
34
+
35
+ A negação `!template/**/.gitignore` no campo `files` **não resolve** (npm exclui por
36
+ padrão, antes de aplicar o allowlist). Solução: o template guarda como `gitignore`
37
+ (sem ponto, que o npm empacota normalmente) e `installTemplate` renomeia para
38
+ `.gitignore` ao copiar — fonte única, sem duplicar conteúdo.
39
+
40
+ `restoreGitignore()` lança erro se o arquivo faltar, então o app **nunca** sai sem
41
+ proteção de `.env`.
42
+
43
+ ### 📈 Cobertura de teste
44
+
45
+ - 20 → **27 testes** (symlink resolvendo o conteúdo certo · `.gitignore` no app gerado ·
46
+ provenance fora do `publishConfig` · `--provenance` explícito no CI ·
47
+ `NODE_AUTH_TOKEN` ausente do passo Publica · `_authToken` fora do `.npmrc` do projeto ·
48
+ token injetado via `GITHUB_ENV`)
49
+
50
+ ### 🐛 `.npmrc` do projeto zerava a autenticação (404 na primeira publicação)
51
+
52
+ ```
53
+ npm error code E404
54
+ npm error 404 Not Found - PUT https://registry.npmjs.org/create-sdd-ai-stack - Not found
55
+ ```
56
+
57
+ **Não era o pacote ausente** — o `npm publish` cria o pacote sozinho na primeira vez.
58
+ O 404 no PUT significa que o registry não reconheceu o usuário como autorizado.
59
+
60
+ Causa: o `.npmrc` do projeto declarava
61
+ `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}`. O npm lê os arquivos nesta
62
+ ordem — **projeto > usuário > global** — então esse placeholder **sombreava** o token
63
+ real do `~/.npmrc`. Com a variável vazia, o token efetivo ficava vazio:
64
+
65
+ | Comando | Antes | Depois |
66
+ | --- | --- | --- |
67
+ | `npm whoami` | `401 Unauthorized` | `marcelinosandroni` |
68
+ | `npm publish` (1ª vez) | `404 Not Found` (PUT) | cria o pacote |
69
+
70
+ O mesmo defeito atingia o caminho por token **no CI**, porque o `.npmrc` do repositório
71
+ também é copiado para o runner e tem prioridade sobre o `~/.npmrc` gerado pelo
72
+ `setup-node`.
73
+
74
+ Correções:
75
+ - `.npmrc` do projeto ficou só com `registry=` (o comentário no arquivo explica por quê)
76
+ - CI passou a injetar `NODE_AUTH_TOKEN` via `$GITHUB_ENV` em vez de escrever token em
77
+ arquivo — assim o OIDC continua engatando quando não há secret
78
+ - três testes de regressão, todos verificados reintroduzindo o bug de propósito
79
+
80
+ ### 🐛 `publishConfig.provenance` quebrava o publish local
81
+
82
+ Com 2FA ligado, o bootstrap local do pacote falhou:
83
+
84
+ ```
85
+ npm error code EUSAGE
86
+ npm error Automatic provenance generation not supported for provider: null
87
+ ```
88
+
89
+ A causa era o **nosso** `package.json`: `publishConfig.provenance: true`.
90
+
91
+ O npm lê `publishConfig` **com prioridade sobre flag de CLI e sobre variável de
92
+ ambiente** — então `--provenance=false` e `NPM_CONFIG_PROVENANCE=false` **não resolvem**.
93
+ O `publishConfig` vence os dois, e o provenance passou a ser exigido também no publish
94
+ local, onde não existe provedor OIDC.
95
+
96
+ Correção: `provenance` saiu do `publishConfig` (ficou só `access: public`) e passou a ser
97
+ controlado **por invocação** — o workflow de release passa `--provenance` explicitamente,
98
+ o publish local não passa nada.
99
+
100
+ Três testes de regressão agora travam esse comportamento (o terceiro foi verificado
101
+ reintroduzindo o bug de propósito):
102
+ - `provenance` não pode estar no `publishConfig`
103
+ - o passo `Publica` passa `--provenance`
104
+ - o passo `Publica` não define `NODE_AUTH_TOKEN` (senão o OIDC não engata)
105
+
106
+ ### 🔐 Autenticação: 2FA no npm quebrou o publish por token
107
+
108
+ Com 2FA ligado na conta, `npm publish` por token passa a exigir **OTP do autenticador**,
109
+ que o CI não tem como digitar:
110
+
111
+ ```
112
+ npm error code EOTP
113
+ npm error This operation requires a one-time password from your authenticator.
114
+ ```
115
+
116
+ Três saídas, e o workflow agora suporta as duas principais:
117
+
118
+ - **Bootstrap local + Trusted Publishing (OIDC)** — publica a primeira versão da máquina
119
+ com `--otp`, configura o publisher no npmjs.com, **apaga o token**. Da frente em diante
120
+ o CI publica sem credencial nenhuma. É o caminho recomendado.
121
+ - **Token com "Bypass 2FA"** — funciona hoje, mas o npm avisa que publicação direta com
122
+ token granular **será removida em janeiro de 2027**, e há bug aberto onde o bypass é
123
+ ignorado pelo npm 11.x ([npm/cli#9268](https://github.com/npm/cli/issues/9268)).
124
+ - **Token stage-only** — o CI sobe a versão, um maintainer aprova com 2FA.
125
+
126
+ Mudanças no workflow:
127
+
128
+ - `npm install -g npm@latest` no job de publish — **OIDC exige npm ≥ 11.5.1** e o Node 22
129
+ do runner do GitHub vem com npm 10.x. Sem isso o OIDC nunca engata.
130
+ - `NODE_AUTH_TOKEN` **removido** do passo `Publica`. O npm só usa OIDC quando o auth está
131
+ **ausente**; com a variável no ambiente, ele ignora o OIDC e volta a falhar por token.
132
+ - Step `Autentica` virou condicional: com `NPM_TOKEN` escreve o token; sem ele, **não
133
+ escreve nada** no `.npmrc` e deixa o npm escolher o OIDC sozinho.
134
+
135
+ ### 🎯 Objetivo
136
+ Reestruturar o core de regras para **Next.js 16 como stack padrão** (antes: React/Vite + Node),
137
+ tornar o repositório instalável como **git submodule em `SDD/`**, e transformar em **pacote npm
138
+ CLI** (`npx create-sdd-ai-stack`) com um template Next.js funcional embutido.
139
+
140
+ ### ✨ Adicionado
141
+
142
+ **Regras**
143
+ - `NEXT.md` — 11 seções de regras do Next.js 16 (Server-First, Data Layer, Server Actions,
144
+ Cache Components, Segurança, Route Handlers, Forms, Metadata, Performance, armadilhas)
145
+ - `APP-STACK.md` — ponteiro de stack do app (qual doc de regra ler)
146
+ - `stacks/` — pasta nova com regras por linguagem/ferramenta:
147
+ `typescript.md`, `tailwind.md`, `shadcn.md`, `testing.md`, `database.md`, `ai.md`, `git.md`, `ci.md`
148
+ - `specs/history/phases/phase-0-bootstrap.md` — histórico da fase
149
+
150
+ **Template**
151
+ - `template/next/` — projeto Next.js 16 completo e validado:
152
+ App Router com route groups, `cacheComponents`, React Compiler, Turbopack,
153
+ Tailwind v4 com tokens, Biome, Vitest, Playwright, vertical slice de exemplo,
154
+ `proxy.ts` com hardening de headers, `shared/server` com `server-only`
155
+ - `src/app/globals.css` — design system completo como `@theme` do Tailwind v4
156
+ - Testes: 1 unit (3 casos) + 4 E2E prontos
157
+
158
+ **CLI / npm**
159
+ - `create-sdd-ai-stack` — pacote npm com bin (`bin/create-sdd-ai-stack.mjs`)
160
+ - Opções: `--template`, `--rules-only`, `--submodule [url]`, `--install/--no-install`,
161
+ `--git/--no-git`, `--shortcuts auto|stub|symlink`, `-y`, `--help`, `--version`
162
+ - Atalhos criados na raiz: `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules`,
163
+ `.windsurfrules`, `.github/copilot-instructions.md`, `.clinerules`
164
+ - `npm run release` / `release:minor` / `release:major` (testa → versiona com tag → publica)
165
+
166
+ **SKILLS**
167
+ - `SKILLS/create-feature/` — cria vertical slice com a estrutura padrão
168
+ - `SKILLS/install-submodule/` — instala as regras em projeto existente
169
+
170
+ **Testes da própria lib**
171
+ - `tests/scaffold.test.mjs` — 17 testes cobrindo `parseArgs`, `installRules`,
172
+ `installShortcuts` e `scaffold`
173
+
174
+ ### 🔄 Alterado
175
+
176
+ - `AGENTS.md` — Next-first; documenta que vive em `SDD/` quando instalado
177
+ - `DESIGN.md` — substituído pelo design system **Executive Engineering**
178
+ (tokens, tipografia tripla, grid 12 col/1320px, elevação em tiers, componentes)
179
+ - `ARCHITECTURE.md` — de "monorepo client/server" para Next-first com vertical slices
180
+ - `NODE.md` — de "backend padrão" para **complemento** (worker/cron/fila) com critério de uso
181
+ - `REACT.md` — de "frontend padrão" para **complemento** (Server-First)
182
+ - `APP.md` — ponteiro para `NEXT.md` e `stacks/`
183
+ - `specs/PLAN.md` — regra de "exatamente uma task `[-]`" + checklist de entrega
184
+ - `specs/tasks/TASK_TEMPLATE.md` — DoD com os comandos de gate reais
185
+ - `README.md` — reescrito como documentação do pacote npm
186
+
187
+ ### 🗑️ Removido
188
+
189
+ - `specs/ROADMAP.md` vazio → reescrito
190
+ - `docs/PRODUCT.md` vazio → mantido como stub de template
191
+
192
+ ### 🐛 Correções encontradas pela própria validação
193
+
194
+ 1. `error.tsx` sem `"use client"` — quebrava o build
195
+ 2. `reactCompiler: true` sem `babel-plugin-react-compiler` — quebrava o build
196
+ 3. `biome.json` no schema 1.x — quebrava o lint no Biome 2
197
+ 4. `prepare: "husky || true"` — quebrava `npm install` no Windows
198
+ 5. `proxy.ts` redirecionando `/` — escondia a landing (achado pelo E2E)
199
+ 6. Rota `/` duplicada entre `app/page.tsx` e `(marketing)/page.tsx`
200
+ 7. `installShortcuts` retornava `undefined` no modo stub
201
+ 8. symlink dos atalhos com caminho relativo quebrado (`path.relative` com caminho não-absoluto) — **achado pelo CI no Linux**, mascarado no Windows pelo fallback pra stub
202
+ 9. `cache: npm` no workflow sem lockfile commitado
203
+ 10. rota `/` duplicada entre `app/page.tsx` e `(marketing)/page.tsx` (achado pelo E2E)
204
+ 11. `.gitignore` do template não empacotado pelo npm (achado conferindo o `npm pack`)
205
+
206
+ > O nº 8 é o melhor argumento pra manter o CI que **revalida o template a cada push**:
207
+ > o teste passava 100% na minha máquina e só quebrou no Linux.
208
+
209
+ [0.1.17]: https://github.com/marcelinosandroni/sdd-ai-stack/releases/tag/v0.1.17
@@ -0,0 +1,68 @@
1
+ # PLANNING
2
+
3
+ > Espaço para **planejamento e refinamento** antes de virar task em [`../specs/PLAN.md`](../specs/PLAN.md).
4
+ > Aqui a gente pensa. No PLAN a gente faz.
5
+
6
+ ## 🎯 Como este fluxo funciona
7
+
8
+ ```text
9
+ IDEIA
10
+ ↓
11
+ BACKLOG.md captura cru, sem compromisso
12
+ ↓
13
+ REFINAMENTO aqui em PLANNING.md: problema, escopo, decisões, riscos
14
+ ↓
15
+ PLAN.md vira task, com micro-passos
16
+ ↓
17
+ tasks/TASK-N.M.md vira checklist executável
18
+ ```
19
+
20
+ ## 📄 Template de refinamento
21
+
22
+ Crie `docs/planning/AAAA-MM-DD-<slug>.md` com:
23
+
24
+ ```markdown
25
+ # Refinamento: [Nome]
26
+
27
+ ## 🧠 Problema
28
+ Quem sofre com o quê, hoje. Sem solução — só o problema.
29
+
30
+ ## 🎯 Objetivo
31
+ Uma frase. Como saberemos que deu certo (métrica).
32
+
33
+ ## 🗺️ Escopo
34
+ - [ ] Inclui:
35
+ - [ ] Não inclui: (o mais importante de preencher)
36
+
37
+ ## 🧩 Entidades e invariantes
38
+ [domínio: o que existe e o que nunca pode quebrar]
39
+
40
+ ## 🏗️ Decisões de arquitetura
41
+ | Decisão | Alternativa | Por quê |
42
+ | --- | --- | --- |
43
+ | [ex] Server Action | Route Handler | sem URL pública, sem boilerplate |
44
+
45
+ ## ⚠️ Riscos
46
+ | Risco | Mitigação |
47
+ | --- | --- |
48
+
49
+ ## 🪓 Task breakdown
50
+ 1. TASK-1.1 — …
51
+ 2. TASK-1.2 — …
52
+
53
+ ## ✅ Definition of Done
54
+ - [ ] critérios mensuráveis
55
+ ```
56
+
57
+ ## 🎨 Artefatos visuais
58
+
59
+ Qualquer coisa que vira imagem (wireframe, fluxo, diagrama de arquitetura) vai em
60
+ `docs/planning/assets/` e é referenciada pelo markdown. Sem commit de binário no
61
+ `specs/` — os specs são texto, para o git diff fazer sentido.
62
+
63
+ ## 📌 Regras
64
+
65
+ 1. **Refinamento não vira código.** Se tem `diff` no arquivo, virou task.
66
+ 2. **Escopo negativo é obrigatório.** "O que NÃO vai entrar" evita 50% das retrabalhadas.
67
+ 3. **Toda decisão de arquitetura vira linha no `ARCHITECTURE.md`** quando estabilizar.
68
+ 4. **Se a task virar > 1h, quebramos antes de começar** (regra do `AGENTS.md`).
@@ -0,0 +1,76 @@
1
+ # 📦 PRODUCT
2
+
3
+ > **O que este template entrega, para quem, e o que ele NÃO entrega.**
4
+ > Preencha a seção "Contexto do projeto consumidor" ao usar num projeto real.
5
+
6
+ ---
7
+
8
+ ## 🎯 O problema
9
+
10
+ Agentes de IA (Claude Code, Cursor, Copilot…) falham em projetos sem regra explícita por
11
+ três motivos previsíveis:
12
+
13
+ 1. **Contexto demais** — leem 40 arquivos e não concluem nada.
14
+ 2. **Sem critério de parada** — voltam a inventar arquitetura e não param.
15
+ 3. **Sem memória de processo** — não sabem que estão no meio de uma task.
16
+
17
+ Isto é **Spec-Driven Development aplicado a agentes**: a especificação vira o sistema
18
+ nervoso, e o agente só precisa saber *onde olhar agora*.
19
+
20
+ ## 💡 A solução
21
+
22
+ Um pacote com três partes:
23
+
24
+ | Parte | Problema que resolve |
25
+ | --- | --- |
26
+ | **Roteador de regras** | O agente lê `AGENTS.md` → `PLAN.md` → o doc da stack. Contexto mínimo. |
27
+ | **Template de projeto** | Não precisa inventar estrutura. Já vem com Next.js 16 + design system. |
28
+ | **CLI + submodule** | Instalação em 1 comando, atualizável por git. |
29
+
30
+ ## 👤 Quem é
31
+
32
+ -_times pequenos/médios com IA como pair programmer
33
+ - Devs que perdem contexto no meio de refatorações longas
34
+ - Times que querem padronizar a entrega entre humanos e agentes
35
+
36
+ ## 🧭 Princípios do design
37
+
38
+ | Princípio | Consequência prática |
39
+ | --- | --- |
40
+ | **Roteador em tudo** | Todo doc tem "se você está fazendo X, leia §Y" no topo |
41
+ | **Uma task por vez** | `PLAN.md` permite exatamente uma task `[-]` |
42
+ | **Prova de vida** | Não marca `[x]` sem output verde do terminal colado |
43
+ | **Vertical slices** | Um requisito = uma pasta |
44
+ | **Tokens em um lugar só** | Design muda no `@theme`, nunca no componente |
45
+ | **Doc perto do que edita** | `error.tsx` sem `"use client"` = build quebrado. proximity paga. |
46
+
47
+ ## 🚫 O que NÃO entregamos
48
+
49
+ - Conta de IA, prompts de modelo, gateway de LLM
50
+ - Autenticação pronta (o ponto de extensão é `src/shared/server/auth.ts`)
51
+ - Banco de dados configurado (o slice de exemplo usa repositório em memória)
52
+ - Monorepo com vários pacotes
53
+ - CI/CD pronto (as regras estão em `stacks/ci.md`)
54
+
55
+ > O que não entregamos é **deliberado**: o template que resolve um problema por vez
56
+ > é mais útil que o que resolve tudo mal.
57
+
58
+ ## 🧪 Como sabemos que funciona
59
+
60
+ O template em `template/next/` passa em `typecheck`, `lint`, `test`, `test:e2e` e `build`.
61
+ A própria CLI tem 17 testes. Bugs reais já foram encontrados por essa validação
62
+ (veja [`CHANGELOG.md`](./CHANGELOG.md) § 🐛).
63
+
64
+ ---
65
+
66
+ ## 📝 Contexto do projeto consumidor
67
+
68
+ > Preencha ao instalar este template num projeto real.
69
+
70
+ **Nome:** [SEU APP]
71
+ **O que faz:** [1 linha]
72
+ **Usuário final:** [quem usa]
73
+ **Stack ativa:** Next.js 16 · [outras]
74
+ **Integrações:** [Stripe, OpenAI, …]
75
+ **Regras críticas de negócio:**
76
+ - [ex: usuário free gera no máximo 5 vídeos/dia]