spec-first-copilot 0.1.0 → 0.3.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.
- package/README.md +148 -0
- package/bin/cli.js +1 -1
- package/lib/init.js +89 -0
- package/package.json +2 -4
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
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-pausar/ <- 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
|
+
/sf-merge-delta --> docs atualizados
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Para features (apos o setup):
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
/sf-feature nome --> /sf-extract --> PRD --> /sf-design --> /sf-plan --> /sf-dev --> /sf-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
|
package/bin/cli.js
CHANGED
package/lib/init.js
ADDED
|
@@ -0,0 +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 };
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spec-first-copilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Spec-first workflow kit for GitHub Copilot — AI-driven development with specs, not guesswork",
|
|
5
5
|
"bin": {
|
|
6
6
|
"spec-first-copilot": "./bin/cli.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"bin/",
|
|
10
|
+
"lib/",
|
|
10
11
|
"templates/"
|
|
11
12
|
],
|
|
12
13
|
"author": "gustavomaritan",
|
|
@@ -15,9 +16,6 @@
|
|
|
15
16
|
"type": "git",
|
|
16
17
|
"url": "https://github.com/gustavomaritan-labs/spec-first-workflow"
|
|
17
18
|
},
|
|
18
|
-
"dependencies": {
|
|
19
|
-
"spec-first-core": "0.1.0"
|
|
20
|
-
},
|
|
21
19
|
"scripts": {
|
|
22
20
|
"test": "echo \"No tests yet\""
|
|
23
21
|
},
|