spec-first-copilot 0.4.0 → 0.5.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +156 -148
  2. package/bin/cli.js +52 -52
  3. package/lib/init.js +89 -89
  4. package/package.json +11 -4
  5. package/templates/.ai/memory/napkin.md +68 -68
  6. package/templates/.github/agents/backend-coder.md +215 -215
  7. package/templates/.github/agents/db-coder.md +165 -165
  8. package/templates/.github/agents/doc-writer.md +48 -51
  9. package/templates/.github/agents/frontend-coder.md +222 -222
  10. package/templates/.github/agents/infra-coder.md +341 -341
  11. package/templates/.github/agents/reviewer.md +99 -99
  12. package/templates/.github/agents/security-reviewer.md +153 -153
  13. package/templates/.github/copilot-instructions.md +194 -175
  14. package/templates/.github/instructions/docs.instructions.md +123 -123
  15. package/templates/.github/instructions/sensitive-files.instructions.md +32 -32
  16. package/templates/{docs/Desenvolvimento → .github}/rules.md +229 -229
  17. package/templates/.github/skills/sf-design/SKILL.md +180 -181
  18. package/templates/.github/skills/sf-dev/SKILL.md +349 -349
  19. package/templates/.github/skills/sf-discovery/SKILL.md +405 -405
  20. package/templates/.github/skills/sf-extract/SKILL.md +284 -284
  21. package/templates/.github/skills/sf-feature/SKILL.md +130 -130
  22. package/templates/.github/skills/sf-merge-delta/SKILL.md +145 -142
  23. package/templates/.github/skills/sf-plan/SKILL.md +178 -178
  24. package/templates/.github/skills/sf-session-finish/SKILL.md +120 -120
  25. package/templates/.github/skills/sf-setup-projeto/SKILL.md +123 -123
  26. package/templates/{docs/_templates/estrutura/API.template.md → .github/templates/estrutura/apiContracts.template.md} +151 -144
  27. package/templates/.github/templates/estrutura/architecture.template.md +158 -0
  28. package/templates/{docs/_templates/estrutura/Seguranca.template.md → .github/templates/estrutura/conventions.template.md} +202 -138
  29. package/templates/{docs/_templates/estrutura/ADRs.template.md → .github/templates/estrutura/decisions.template.md} +99 -91
  30. package/templates/.github/templates/estrutura/domain.template.md +148 -0
  31. package/templates/{docs/_templates → .github/templates}/feature/PRD.template.md +256 -256
  32. package/templates/{docs/_templates → .github/templates}/feature/Progresso.template.md +136 -136
  33. package/templates/{docs/_templates → .github/templates}/feature/TRD.template.md +204 -200
  34. package/templates/{docs/_templates → .github/templates}/feature/backlog-extraido.template.md +154 -154
  35. package/templates/{docs/_templates → .github/templates}/feature/context.template.md +42 -42
  36. package/templates/{docs/_templates → .github/templates}/feature/extract-log.template.md +38 -38
  37. package/templates/{docs/_templates → .github/templates}/feature/projetos.template.yaml +73 -73
  38. package/templates/{docs/_templates → .github/templates}/feature/sdd.template.md +372 -372
  39. package/templates/{docs/_templates → .github/templates}/feature/tasks.template.md +115 -115
  40. package/templates/{docs/_templates → .github/templates}/global/progresso_global.template.md +57 -57
  41. package/templates/docs/_templates/estrutura/Arquitetura.template.md +0 -82
  42. package/templates/docs/_templates/estrutura/Infraestrutura.template.md +0 -104
  43. package/templates/docs/_templates/estrutura/Modelo_Dados.template.md +0 -99
  44. package/templates/docs/_templates/estrutura/Stack.template.md +0 -78
  45. package/templates/docs/_templates/estrutura/Visao.template.md +0 -82
  46. /package/templates/docs/{Desenvolvimento/.gitkeep → .gitkeep} +0 -0
  47. /package/templates/{docs/Estrutura → workspace/Input}/.gitkeep +0 -0
  48. /package/templates/{docs/PM → workspace/Input/setup_projeto}/.gitkeep +0 -0
  49. /package/templates/{docs/PM/setup_projeto → workspace/Output}/.gitkeep +0 -0
package/README.md CHANGED
@@ -1,148 +1,156 @@
1
- # spec-first-copilot
2
-
3
- Kit completo para desenvolvimento **spec-first** com [GitHub Copilot](https://github.com/features/copilot). A IA segue um pipeline disciplinado — da especificacao ao codigo — com checkpoints humanos e rastreabilidade ponta a ponta.
4
-
5
- ## O que e spec-first?
6
-
7
- Em vez de pedir pra IA "cria um CRUD de usuarios", voce fornece insumos brutos (docs, SQLs, rascunhos) e a IA:
8
-
9
- 1. **Extrai** requisitos estruturados (PRD/TRD)
10
- 2. **Espera sua aprovacao** (checkpoint humano)
11
- 3. **Gera design tecnico** (SDD) — fonte unica de verdade
12
- 4. **Planeja tasks** com dependencias e fases
13
- 5. **Implementa** com agentes especializados por area + security review
14
- 6. **Atualiza docs** automaticamente (delta specs)
15
-
16
- Resultado: codigo previsivel, seguro e rastreavel.
17
-
18
- ## Pre-requisitos
19
-
20
- - **Node.js** 18+
21
- - **Git** instalado
22
- - **GitHub Copilot** com acesso a Copilot Chat
23
-
24
- ### Windows (PowerShell)
25
-
26
- Se encontrar erro de script nao assinado ao rodar o CLI, execute:
27
-
28
- ```powershell
29
- Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
30
- ```
31
-
32
- ## Instalacao
33
-
34
- ```bash
35
- npm i -g spec-first-copilot
36
- ```
37
-
38
- ## Uso
39
-
40
- ```bash
41
- spec-first-copilot init --name=MeuProjeto
42
- ```
43
-
44
- Isso cria a pasta `MeuProjeto/` com toda a estrutura pronta:
45
-
46
- ```
47
- MeuProjeto/
48
- ├── .ai/memory/napkin.md <- Memoria persistente do projeto
49
- ├── .github/
50
- │ ├── copilot-instructions.md <- Regras globais pro agente
51
- │ ├── instructions/ <- Regras por contexto
52
- │ ├── skills/ <- 9 skills do workflow
53
- ├── sf-setup-projeto/ <- Bootstrap do projeto
54
- │ │ ├── sf-feature/ <- Pipeline de feature
55
- │ │ ├── sf-discovery/ <- Analise profunda de insumos
56
- │ │ ├── sf-extract/ <- PM -> PRD/TRD
57
- ├── sf-design/ <- PRD/TRD -> SDD
58
- │ │ ├── sf-plan/ <- SDD -> tasks
59
- │ │ ├── sf-dev/ <- Executa tasks
60
- │ │ ├── sf-merge-delta/ <- Atualiza docs globais
61
- │ │ └── sf-session-finish/ <- Encerra sessao
62
- └── agents/ <- 7 agentes especializados
63
- ├── backend-coder.md <- .NET 8 / C#
64
- ├── frontend-coder.md <- React
65
- ├── db-coder.md <- PostgreSQL
66
- ├── infra-coder.md <- Docker
67
- ├── doc-writer.md <- Documentacao
68
- │ ├── reviewer.md <- Code review
69
- └── security-reviewer.md <- Auditoria de seguranca
70
- ├── docs/
71
- ├── PM/ <- Jogue seus insumos aqui
72
- │ └── setup_projeto/ <- Insumos do bootstrap
73
- ├── _templates/ <- 18 templates do workflow
74
- ├── Estrutura/ <- Docs globais (gerados)
75
- │ └── Desenvolvimento/ <- Docs por feature (gerados)
76
- └── rules.md <- Regras de desenvolvimento
77
- └── .gitignore
78
- ```
79
-
80
- ## Como comecar
81
-
82
- 1. Crie o projeto:
83
- ```bash
84
- spec-first-copilot init --name=MeuProjeto
85
- cd MeuProjeto
86
- ```
87
-
88
- 2. Jogue seus insumos em `docs/PM/setup_projeto/` — qualquer formato:
89
- - `.md`, `.txt` (descricoes, requisitos, decisoes)
90
- - `.sql` (modelagem de banco)
91
- - `.csv`, `.xml`, `.html` (dados, configs)
92
- - `.png`, `.jpg`, `.pdf` (telas, diagramas)
93
-
94
- 3. Abra o VS Code com Copilot Chat e rode:
95
- ```
96
- /sf-setup-projeto
97
- ```
98
-
99
- 4. O pipeline comeca. A IA vai:
100
- - Extrair um TRD dos seus insumos
101
- - Parar e pedir sua aprovacao
102
- - Depois voce roda `/sf-design`, `/sf-plan`, `/sf-dev` na sequencia
103
-
104
- ## Pipeline completo
105
-
106
- ```
107
- docs/PM/ (seus arquivos)
108
- |
109
- v
110
- /sf-setup-projeto --> /sf-extract --> TRD (voce revisa e aprova)
111
- |
112
- v
113
- /sf-design --> SDD + docs/Estrutura/
114
- |
115
- v
116
- /sf-plan --> tasks + Progresso.md
117
- |
118
- v
119
- /sf-dev --> codigo nos repos
120
- |
121
- v
122
- (merge-delta automatico)
123
- ```
124
-
125
- Para features (apos o setup):
126
-
127
- ```
128
- /sf-feature nome --> /sf-extract --> PRD --> /sf-design --> /sf-plan --> /sf-dev (inclui merge-delta)
129
- ```
130
-
131
- ## Opcoes do CLI
132
-
133
- ```
134
- spec-first-copilot init --name=<nome> [--target=<caminho>]
135
- ```
136
-
137
- | Opcao | Descricao |
138
- |-------|-----------|
139
- | `--name` | Nome do projeto (obrigatorio) |
140
- | `--target` | Diretorio destino (default: `./<nome>`) |
141
-
142
- ## Links
143
-
144
- - [Repositorio](https://github.com/gustavomaritan-labs/spec-first-workflow)
145
-
146
- ## Licenca
147
-
148
- MIT
1
+ # spec-first-copilot
2
+
3
+ Kit completo para desenvolvimento **spec-first** com [GitHub Copilot](https://github.com/features/copilot). A IA segue um pipeline disciplinado — da especificacao ao codigo — com checkpoints humanos e rastreabilidade ponta a ponta.
4
+
5
+ ## O que e spec-first?
6
+
7
+ Em vez de pedir pra IA "cria um CRUD de usuarios", voce fornece insumos brutos (docs, SQLs, rascunhos) e a IA:
8
+
9
+ 1. **Extrai** requisitos estruturados (PRD/TRD)
10
+ 2. **Espera sua aprovacao** (checkpoint humano)
11
+ 3. **Gera design tecnico** (SDD) — fonte unica de verdade
12
+ 4. **Planeja tasks** com dependencias e fases
13
+ 5. **Implementa** com agentes especializados por area + security review
14
+ 6. **Atualiza docs** automaticamente (delta specs)
15
+
16
+ Resultado: codigo previsivel, seguro e rastreavel.
17
+
18
+ ## Pre-requisitos
19
+
20
+ - **Node.js** 18+
21
+ - **Git** instalado
22
+ - **GitHub Copilot** com acesso a Copilot Chat
23
+
24
+ ### Windows (PowerShell)
25
+
26
+ Se encontrar erro de script nao assinado ao rodar o CLI, execute:
27
+
28
+ ```powershell
29
+ Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
30
+ ```
31
+
32
+ ## Instalacao
33
+
34
+ ```bash
35
+ npm i -g spec-first-copilot
36
+ ```
37
+
38
+ ## Uso
39
+
40
+ ```bash
41
+ spec-first-copilot init --name=MeuProjeto
42
+ ```
43
+
44
+ Isso cria a pasta `MeuProjeto/` com toda a estrutura pronta:
45
+
46
+ ```
47
+ MeuProjeto/
48
+ ├── .ai/memory/napkin.md <- Memoria persistente do projeto
49
+ ├── .github/ <- AI OPERATIONAL CONFIG
50
+ │ ├── copilot-instructions.md <- Regras globais pro agente
51
+ │ ├── rules.md <- Regras de desenvolvimento
52
+ │ ├── instructions/ <- Regras por contexto
53
+ │ ├── templates/ <- 15 templates do workflow
54
+ │ │ ├── feature/ <- PRD, TRD, SDD, tasks, etc.
55
+ │ │ ├── estrutura/ <- 5 templates de estado do sistema
56
+ │ │ └── global/ <- Progresso global
57
+ │ ├── skills/ <- 9 skills do workflow
58
+ │ │ ├── sf-setup-projeto/
59
+ │ │ ├── sf-feature/
60
+ │ │ ├── sf-discovery/
61
+ │ │ ├── sf-extract/
62
+ │ ├── sf-design/
63
+ ├── sf-plan/
64
+ ├── sf-dev/
65
+ ├── sf-merge-delta/
66
+ │ └── sf-session-finish/
67
+ └── agents/ <- 7 agentes especializados
68
+ │ ├── backend-coder.md <- .NET 8 / C#
69
+ ├── frontend-coder.md <- React
70
+ ├── db-coder.md <- PostgreSQL
71
+ ├── infra-coder.md <- Docker
72
+ ├── doc-writer.md <- Documentacao
73
+ ├── reviewer.md <- Code review
74
+ └── security-reviewer.md <- Auditoria de seguranca
75
+ ├── docs/ <- SYSTEM KNOWLEDGE (gerado pelo /sf-design)
76
+ ├── architecture.md <- Containers, stack, ambientes, deploy
77
+ │ ├── domain.md <- Visao de negocio + modelo de dados
78
+ │ ├── conventions.md <- Auth, authz, LGPD, env vars, monitoramento
79
+ │ ├── apiContracts.md <- Rotas, paginacao, erros, catalogo de endpoints
80
+ │ └── decisions.md <- ADRs
81
+ ├── workspace/ <- TEAM CONTENT (futuro wiki)
82
+ │ ├── Input/ <- Jogue seus insumos aqui
83
+ │ └── setup_projeto/ <- Insumos do bootstrap
84
+ └── Output/ <- Docs por feature (gerados)
85
+ └── .gitignore
86
+ ```
87
+
88
+ ## Como comecar
89
+
90
+ 1. Crie o projeto:
91
+ ```bash
92
+ spec-first-copilot init --name=MeuProjeto
93
+ cd MeuProjeto
94
+ ```
95
+
96
+ 2. Jogue seus insumos em `workspace/Input/setup_projeto/` — qualquer formato:
97
+ - `.md`, `.txt` (descricoes, requisitos, decisoes)
98
+ - `.sql` (modelagem de banco)
99
+ - `.csv`, `.xml`, `.html` (dados, configs)
100
+ - `.png`, `.jpg`, `.pdf` (telas, diagramas)
101
+
102
+ 3. Abra o VS Code com Copilot Chat e rode:
103
+ ```
104
+ /sf-setup-projeto
105
+ ```
106
+
107
+ 4. O pipeline comeca. A IA vai:
108
+ - Extrair um TRD dos seus insumos
109
+ - Parar e pedir sua aprovacao
110
+ - Depois voce roda `/sf-design`, `/sf-plan`, `/sf-dev` na sequencia
111
+
112
+ ## Pipeline completo
113
+
114
+ ```
115
+ workspace/Input/ (seus arquivos)
116
+ |
117
+ v
118
+ /sf-setup-projeto --> /sf-extract --> TRD (voce revisa e aprova)
119
+ |
120
+ v
121
+ /sf-design --> SDD + docs/ (5 arquivos)
122
+ |
123
+ v
124
+ /sf-plan --> tasks + Progresso.md
125
+ |
126
+ v
127
+ /sf-dev --> codigo nos repos
128
+ |
129
+ v
130
+ (merge-delta automatico)
131
+ ```
132
+
133
+ Para features (apos o setup):
134
+
135
+ ```
136
+ /sf-feature nome --> /sf-extract --> PRD --> /sf-design --> /sf-plan --> /sf-dev (inclui merge-delta)
137
+ ```
138
+
139
+ ## Opcoes do CLI
140
+
141
+ ```
142
+ spec-first-copilot init --name=<nome> [--target=<caminho>]
143
+ ```
144
+
145
+ | Opcao | Descricao |
146
+ |-------|-----------|
147
+ | `--name` | Nome do projeto (obrigatorio) |
148
+ | `--target` | Diretorio destino (default: `./<nome>`) |
149
+
150
+ ## Links
151
+
152
+ - [Repositorio](https://github.com/gustavomaritan-labs/spec-first-workflow)
153
+
154
+ ## Licenca
155
+
156
+ MIT
package/bin/cli.js CHANGED
@@ -1,52 +1,52 @@
1
- #!/usr/bin/env node
2
-
3
- const path = require('path');
4
- const { init } = require('../lib/init');
5
-
6
- const args = process.argv.slice(2);
7
- const command = args[0];
8
-
9
- function printUsage() {
10
- console.log('Usage: spec-first-copilot init --name=<project-name> [--target=<path>]');
11
- console.log('');
12
- console.log('Creates a new spec-first project configured for GitHub Copilot.');
13
- console.log('');
14
- console.log('Options:');
15
- console.log(' --name=<name> Project name (required)');
16
- console.log(' --target=<path> Target directory (defaults to ./<name>)');
17
- }
18
-
19
- function parseArgs(args) {
20
- const parsed = {};
21
- for (const arg of args) {
22
- const match = arg.match(/^--(\w+)=(.+)$/);
23
- if (match) {
24
- parsed[match[1]] = match[2];
25
- }
26
- }
27
- return parsed;
28
- }
29
-
30
- if (command === 'init') {
31
- const opts = parseArgs(args.slice(1));
32
-
33
- if (!opts.name) {
34
- console.error('Error: --name is required.\n');
35
- printUsage();
36
- process.exit(1);
37
- }
38
-
39
- const templatesDir = path.join(__dirname, '..', 'templates');
40
-
41
- init({
42
- name: opts.name,
43
- templatesDir,
44
- targetDir: opts.target || undefined,
45
- });
46
- } else {
47
- printUsage();
48
- if (command) {
49
- console.error(`\nUnknown command: "${command}"`);
50
- }
51
- process.exit(command ? 1 : 0);
52
- }
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const { init } = require('../lib/init');
5
+
6
+ const args = process.argv.slice(2);
7
+ const command = args[0];
8
+
9
+ function printUsage() {
10
+ console.log('Usage: spec-first-copilot init --name=<project-name> [--target=<path>]');
11
+ console.log('');
12
+ console.log('Creates a new spec-first project configured for GitHub Copilot.');
13
+ console.log('');
14
+ console.log('Options:');
15
+ console.log(' --name=<name> Project name (required)');
16
+ console.log(' --target=<path> Target directory (defaults to ./<name>)');
17
+ }
18
+
19
+ function parseArgs(args) {
20
+ const parsed = {};
21
+ for (const arg of args) {
22
+ const match = arg.match(/^--(\w+)=(.+)$/);
23
+ if (match) {
24
+ parsed[match[1]] = match[2];
25
+ }
26
+ }
27
+ return parsed;
28
+ }
29
+
30
+ if (command === 'init') {
31
+ const opts = parseArgs(args.slice(1));
32
+
33
+ if (!opts.name) {
34
+ console.error('Error: --name is required.\n');
35
+ printUsage();
36
+ process.exit(1);
37
+ }
38
+
39
+ const templatesDir = path.join(__dirname, '..', 'templates');
40
+
41
+ init({
42
+ name: opts.name,
43
+ templatesDir,
44
+ targetDir: opts.target || undefined,
45
+ });
46
+ } else {
47
+ printUsage();
48
+ if (command) {
49
+ console.error(`\nUnknown command: "${command}"`);
50
+ }
51
+ process.exit(command ? 1 : 0);
52
+ }
package/lib/init.js CHANGED
@@ -1,89 +1,89 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { execSync } = require('child_process');
4
-
5
- const PLACEHOLDER = '{{PROJECT_NAME}}';
6
-
7
- function copyDir(src, dest, replacements) {
8
- fs.mkdirSync(dest, { recursive: true });
9
- for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
10
- const srcPath = path.join(src, entry.name);
11
- const destPath = path.join(dest, entry.name);
12
- if (entry.isDirectory()) {
13
- copyDir(srcPath, destPath, replacements);
14
- } else {
15
- copyFile(srcPath, destPath, replacements);
16
- }
17
- }
18
- }
19
-
20
- function copyFile(src, dest, replacements) {
21
- // Skip if file already exists (preserve user's files)
22
- if (fs.existsSync(dest)) return;
23
-
24
- const textExtensions = ['.md', '.yaml', '.yml', '.json', '.js', '.ts', '.gitignore', '.gitkeep', ''];
25
- const ext = path.extname(src).toLowerCase();
26
- const basename = path.basename(src);
27
- const isText = textExtensions.includes(ext) || basename.startsWith('.');
28
-
29
- if (isText) {
30
- let content = fs.readFileSync(src, 'utf-8');
31
- for (const [placeholder, value] of Object.entries(replacements)) {
32
- content = content.split(placeholder).join(value);
33
- }
34
- fs.writeFileSync(dest, content, 'utf-8');
35
- } else {
36
- fs.copyFileSync(src, dest);
37
- }
38
- }
39
-
40
- function init({ name, templatesDir, targetDir }) {
41
- const dest = targetDir || path.resolve(process.cwd(), name);
42
-
43
- const existed = fs.existsSync(dest);
44
- console.log(`\n${existed ? 'Initializing' : 'Creating'} project "${name}" in ${dest}\n`);
45
-
46
- const replacements = { [PLACEHOLDER]: name };
47
- copyDir(templatesDir, dest, replacements);
48
- patchProjectName(dest, name);
49
-
50
- try {
51
- execSync('git init', { cwd: dest, stdio: 'pipe' });
52
- execSync('git add -A', { cwd: dest, stdio: 'pipe' });
53
- execSync(`git commit -m "chore: init project ${name} via spec-first-workflow"`, {
54
- cwd: dest,
55
- stdio: 'pipe',
56
- });
57
- console.log('Git initialized with initial commit.');
58
- } catch {
59
- console.log('Git init skipped (git not available or error).');
60
- }
61
-
62
- console.log(`\nDone! Project "${name}" is ready.`);
63
- console.log('\nNext steps:');
64
- console.log(` 1. cd ${name}`);
65
- console.log(' 2. Add your input files to docs/PM/setup_projeto/');
66
- console.log(' 3. Run /setup-projeto to start the pipeline');
67
- console.log('');
68
- }
69
-
70
- function patchProjectName(dest, name) {
71
- const filesToPatch = [
72
- path.join('.ai', 'memory', 'napkin.md'),
73
- path.join('.github', 'copilot-instructions.md'),
74
- 'CLAUDE.md',
75
- ];
76
-
77
- for (const relPath of filesToPatch) {
78
- const filePath = path.join(dest, relPath);
79
- if (!fs.existsSync(filePath)) continue;
80
-
81
- let content = fs.readFileSync(filePath, 'utf-8');
82
- content = content.replace(/# Napkin Runbook\b/, `# Napkin Runbook — ${name}`);
83
- content = content.replace(/# Copilot Instructions — Projeto\b/, `# Copilot Instructions — ${name}`);
84
- content = content.replace(/# CLAUDE\.md — Projeto\b/, `# CLAUDE.md — ${name}`);
85
- fs.writeFileSync(filePath, content, 'utf-8');
86
- }
87
- }
88
-
89
- module.exports = { init };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execSync } = require('child_process');
4
+
5
+ const PLACEHOLDER = '{{PROJECT_NAME}}';
6
+
7
+ function copyDir(src, dest, replacements) {
8
+ fs.mkdirSync(dest, { recursive: true });
9
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
10
+ const srcPath = path.join(src, entry.name);
11
+ const destPath = path.join(dest, entry.name);
12
+ if (entry.isDirectory()) {
13
+ copyDir(srcPath, destPath, replacements);
14
+ } else {
15
+ copyFile(srcPath, destPath, replacements);
16
+ }
17
+ }
18
+ }
19
+
20
+ function copyFile(src, dest, replacements) {
21
+ // Skip if file already exists (preserve user's files)
22
+ if (fs.existsSync(dest)) return;
23
+
24
+ const textExtensions = ['.md', '.yaml', '.yml', '.json', '.js', '.ts', '.gitignore', '.gitkeep', ''];
25
+ const ext = path.extname(src).toLowerCase();
26
+ const basename = path.basename(src);
27
+ const isText = textExtensions.includes(ext) || basename.startsWith('.');
28
+
29
+ if (isText) {
30
+ let content = fs.readFileSync(src, 'utf-8');
31
+ for (const [placeholder, value] of Object.entries(replacements)) {
32
+ content = content.split(placeholder).join(value);
33
+ }
34
+ fs.writeFileSync(dest, content, 'utf-8');
35
+ } else {
36
+ fs.copyFileSync(src, dest);
37
+ }
38
+ }
39
+
40
+ function init({ name, templatesDir, targetDir }) {
41
+ const dest = targetDir || path.resolve(process.cwd(), name);
42
+
43
+ const existed = fs.existsSync(dest);
44
+ console.log(`\n${existed ? 'Initializing' : 'Creating'} project "${name}" in ${dest}\n`);
45
+
46
+ const replacements = { [PLACEHOLDER]: name };
47
+ copyDir(templatesDir, dest, replacements);
48
+ patchProjectName(dest, name);
49
+
50
+ try {
51
+ execSync('git init', { cwd: dest, stdio: 'pipe' });
52
+ execSync('git add -A', { cwd: dest, stdio: 'pipe' });
53
+ execSync(`git commit -m "chore: init project ${name} via spec-first-workflow"`, {
54
+ cwd: dest,
55
+ stdio: 'pipe',
56
+ });
57
+ console.log('Git initialized with initial commit.');
58
+ } catch {
59
+ console.log('Git init skipped (git not available or error).');
60
+ }
61
+
62
+ console.log(`\nDone! Project "${name}" is ready.`);
63
+ console.log('\nNext steps:');
64
+ console.log(` 1. cd ${name}`);
65
+ console.log(' 2. Add your input files to workspace/Input/setup_projeto/');
66
+ console.log(' 3. Run /sf-setup-projeto to start the pipeline');
67
+ console.log('');
68
+ }
69
+
70
+ function patchProjectName(dest, name) {
71
+ const filesToPatch = [
72
+ path.join('.ai', 'memory', 'napkin.md'),
73
+ path.join('.github', 'copilot-instructions.md'),
74
+ 'CLAUDE.md',
75
+ ];
76
+
77
+ for (const relPath of filesToPatch) {
78
+ const filePath = path.join(dest, relPath);
79
+ if (!fs.existsSync(filePath)) continue;
80
+
81
+ let content = fs.readFileSync(filePath, 'utf-8');
82
+ content = content.replace(/# Napkin Runbook\b/, `# Napkin Runbook — ${name}`);
83
+ content = content.replace(/# Copilot Instructions — Projeto\b/, `# Copilot Instructions — ${name}`);
84
+ content = content.replace(/# CLAUDE\.md — Projeto\b/, `# CLAUDE.md — ${name}`);
85
+ fs.writeFileSync(filePath, content, 'utf-8');
86
+ }
87
+ }
88
+
89
+ module.exports = { init };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "spec-first-copilot",
3
- "version": "0.4.0",
3
+ "version": "0.5.0-beta.0",
4
4
  "description": "Spec-first workflow kit for GitHub Copilot — AI-driven development with specs, not guesswork",
5
5
  "bin": {
6
- "spec-first-copilot": "./bin/cli.js"
6
+ "spec-first-copilot": "bin/cli.js"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
@@ -11,10 +11,17 @@
11
11
  "templates/"
12
12
  ],
13
13
  "author": "gustavomaritan",
14
- "keywords": ["spec-first", "workflow", "ai", "copilot", "github", "scaffolding"],
14
+ "keywords": [
15
+ "spec-first",
16
+ "workflow",
17
+ "ai",
18
+ "copilot",
19
+ "github",
20
+ "scaffolding"
21
+ ],
15
22
  "repository": {
16
23
  "type": "git",
17
- "url": "https://github.com/gustavomaritan-labs/spec-first-workflow",
24
+ "url": "git+https://github.com/gustavomaritan-labs/spec-first-workflow.git",
18
25
  "directory": "packages/spec-first-copilot"
19
26
  },
20
27
  "scripts": {