@cristiancorreau/forge 2.3.0 → 2.4.1
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 +52 -109
- package/dist/cli.js +1 -1
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +27 -7
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +54 -19
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +88 -37
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +29 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/lib/detect.d.ts +13 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +85 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/lock.d.ts +15 -0
- package/dist/lib/lock.d.ts.map +1 -0
- package/dist/lib/lock.js +48 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/wizard.d.ts +3 -2
- package/dist/lib/wizard.d.ts.map +1 -1
- package/dist/lib/wizard.js +211 -142
- package/dist/lib/wizard.js.map +1 -1
- package/dist/ui/box.d.ts +2 -0
- package/dist/ui/box.d.ts.map +1 -0
- package/dist/ui/box.js +15 -0
- package/dist/ui/box.js.map +1 -0
- package/dist/ui/colors.d.ts +15 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +19 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/spinner.d.ts +9 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +46 -0
- package/dist/ui/spinner.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,156 +1,99 @@
|
|
|
1
1
|
# forge
|
|
2
2
|
|
|
3
3
|
[](https://github.com/cristiancorreau/forge/actions/workflows/tests.yml)
|
|
4
|
-
[](https://www.npmjs.com/package/@cristiancorreau/forge)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Configura cualquier proyecto para trabajar con agentes IA en un comando.**
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Wizard interactivo que detecta tu stack, instala agentes especializados, genera guardrails y mantiene un manifest con SHA-256 para auditar cada cambio.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
- **Los agentes olvidan.** Sin memoria y reglas persistentes, cada sesión empieza desde cero. Forge mantiene el contexto entre sesiones.
|
|
16
|
-
- **El contexto se pierde entre archivos.** Un CLAUDE.md plano no sabe qué agente ejecuta qué tarea. Forge separa responsabilidades con agentes especializados por tier.
|
|
17
|
-
- **Cada runtime tiene su formato.** Claude Code, OpenCode, Kiro y Codex CLI esperan archivos distintos. Forge los genera todos desde una sola fuente de verdad.
|
|
18
|
-
- **La calidad baja con el tiempo.** Sin auditoría, los agentes se desactualizan silenciosamente. Forge detecta gaps y ofrece correcciones.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Diferencias con otras herramientas
|
|
23
|
-
|
|
24
|
-
| Herramienta | Qué hace | Alcance | Runtimes | Hooks | Equipos |
|
|
25
|
-
|-------------|----------|---------|----------|-------|---------|
|
|
26
|
-
| **Forge** | Framework completo: agentes, skills, reglas, auditoría | Proyecto + team | Claude Code, OpenCode, Kiro, Codex CLI | Sí (pre-commit) | Sí (tiers) |
|
|
27
|
-
| `cc-sdd` | Plantillas SDD para Claude Code | Proyecto individual | Claude Code | No | No |
|
|
28
|
-
| `Bridle` | Guardrails para prompts | Prompt-level | Agnóstico | No | No |
|
|
29
|
-
| `wshobson/agents` | Colección de agent files | Proyecto individual | Claude Code | No | No |
|
|
30
|
-
| CLAUDE.md manual | Instrucciones en texto plano | Sesión | Claude Code | No | No |
|
|
31
|
-
|
|
32
|
-
**Lo que Forge NO es:** no es un modelo de IA, no es un servicio en la nube, no es una plataforma de deployment, no ejecuta agentes por sí solo. Es una capa de configuración y estructura que vive en tu repositorio.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Quick start (5 minutos)
|
|
37
|
-
|
|
38
|
-
**Requisitos:** Python 3.9+, git, Claude Code (u otro runtime soportado).
|
|
13
|
+
## Quick start
|
|
39
14
|
|
|
40
15
|
```bash
|
|
41
|
-
|
|
42
|
-
git submodule add https://github.com/cristiancorreau/forge .agentic
|
|
43
|
-
pip3 install -r .agentic/requirements.txt
|
|
16
|
+
npx @cristiancorreau/forge init
|
|
44
17
|
```
|
|
45
18
|
|
|
46
|
-
|
|
47
|
-
# 2. Copiar y completar project.yaml
|
|
48
|
-
cp .agentic/templates/project.yaml.tpl project.yaml
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Editar `project.yaml` con los datos del proyecto:
|
|
52
|
-
|
|
53
|
-
```yaml
|
|
54
|
-
project:
|
|
55
|
-
name: "Mi SaaS"
|
|
56
|
-
mode: "standard" # startup | standard | enterprise
|
|
19
|
+
Sin instalación global. Sin Python. Solo Node.js.
|
|
57
20
|
|
|
58
|
-
|
|
59
|
-
backend: "hono"
|
|
60
|
-
frontend: "nextjs"
|
|
21
|
+
---
|
|
61
22
|
|
|
62
|
-
|
|
63
|
-
active: [orchestrator, test-engineer, docs-writer]
|
|
64
|
-
profiles: [hono-drizzle, nextjs-admin]
|
|
23
|
+
## Cómo funciona
|
|
65
24
|
|
|
66
|
-
|
|
67
|
-
active: [new-feature, security-audit, db-migrate]
|
|
68
|
-
```
|
|
25
|
+
El wizard detecta y configura el proyecto en cinco pasos:
|
|
69
26
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
# 4. Abrir Claude Code y ejecutar
|
|
77
|
-
/session-start
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Después del paso 4 verás: agentes instalados en `.claude/agents/`, un `CLAUDE.md` generado con el roster del proyecto, y slash commands disponibles en Claude Code.
|
|
27
|
+
1. **Detecta el stack** — lee `package.json`, lockfiles y `Dockerfile` para identificar framework, lenguaje y dependencias.
|
|
28
|
+
2. **Selecciona agentes** — muestra un selector de flechas con los agentes disponibles para tu stack (TypeScript, Python, Ruby, Go, PHP).
|
|
29
|
+
3. **Instala configuración** — escribe `.claude/agents/`, `CLAUDE.md`, `settings.json` y `architecture.rules` en el repositorio.
|
|
30
|
+
4. **Instala hooks** — genera hooks de guardrail en JavaScript puro; sin dependencias de Python ni binarios externos.
|
|
31
|
+
5. **Crea el manifest** — `forge/.forge/manifest.json` con SHA-256 de cada archivo gestionado para rastrear derivaciones futuras.
|
|
81
32
|
|
|
82
33
|
---
|
|
83
34
|
|
|
84
|
-
##
|
|
85
|
-
|
|
86
|
-
| Capa | Qué hace |
|
|
87
|
-
|------|----------|
|
|
88
|
-
| **Memory** | `project.yaml` como fuente de verdad; wiki de proyecto persistente entre sesiones |
|
|
89
|
-
| **Knowledge** | Agentes especializados (Tier 1/2/3) con scope declarado y reglas no-negociables |
|
|
90
|
-
| **Guardrail** | Compliance by design, hook de pre-commit, auditoría con `forge-audit.py` |
|
|
91
|
-
| **Delegation** | Orquestador que descompone tareas y delega a agentes especializados |
|
|
92
|
-
| **Distribution** | Un solo `project.yaml` genera configs para todos los runtimes soportados |
|
|
35
|
+
## Comandos
|
|
93
36
|
|
|
94
|
-
|
|
37
|
+
| Comando | Qué hace |
|
|
38
|
+
|---------|----------|
|
|
39
|
+
| `forge init` | Wizard completo: detecta stack, instala agentes, hooks y genera configuración |
|
|
40
|
+
| `forge audit` | Verifica el estado del proyecto contra el manifest; detecta archivos modificados o faltantes |
|
|
41
|
+
| `forge generate` | Regenera configuración desde el estado actual del proyecto sin ejecutar el wizard completo |
|
|
42
|
+
| `forge validate` | Valida que los archivos generados cumplan el esquema esperado |
|
|
43
|
+
| `forge doctor` | Health-check del entorno: Node.js, git, runtime de IA activo, permisos |
|
|
95
44
|
|
|
96
45
|
---
|
|
97
46
|
|
|
98
47
|
## Runtimes soportados
|
|
99
48
|
|
|
100
|
-
| Runtime | Soporte |
|
|
101
|
-
|
|
102
|
-
| **Claude Code** | Completo
|
|
103
|
-
| **OpenCode** |
|
|
104
|
-
| **Codex CLI** |
|
|
105
|
-
| **Kiro** |
|
|
106
|
-
| **Todos** | Genera los cuatro | `--tool all` |
|
|
107
|
-
|
|
108
|
-
"Soporte completo" significa integración con hooks, settings.json y slash commands. "Serial" significa generación del archivo de instrucciones sin integración profunda con el runtime.
|
|
49
|
+
| Runtime | Soporte |
|
|
50
|
+
|---------|---------|
|
|
51
|
+
| **Claude Code** | Completo — agentes, `CLAUDE.md`, `settings.json`, hooks |
|
|
52
|
+
| **OpenCode** | `AGENTS.md` generado |
|
|
53
|
+
| **Codex CLI** | `AGENTS.md` enriquecido para contexto de proyecto |
|
|
54
|
+
| **Kiro** | Steering files |
|
|
109
55
|
|
|
110
56
|
---
|
|
111
57
|
|
|
112
|
-
##
|
|
113
|
-
|
|
114
|
-
15 perfiles listos para usar, declarados en `agents.profiles` del `project.yaml`:
|
|
58
|
+
## Stacks soportados
|
|
115
59
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
60
|
+
| Lenguaje | Frameworks |
|
|
61
|
+
|----------|------------|
|
|
62
|
+
| TypeScript | Hono, Next.js, NestJS, Astro |
|
|
63
|
+
| Python | FastAPI, Django |
|
|
64
|
+
| Ruby | Rails |
|
|
65
|
+
| Go | Gin |
|
|
66
|
+
| PHP | Laravel |
|
|
119
67
|
|
|
120
|
-
Cada
|
|
121
|
-
|
|
122
|
-
Para stacks no cubiertos:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
python3 .agentic/scripts/forge-scaffold-profile.py --name <stack> --engineer <agente>
|
|
126
|
-
```
|
|
68
|
+
Cada stack instala agentes especializados con reglas de arquitectura, convenciones de código y patrones específicos del framework.
|
|
127
69
|
|
|
128
70
|
---
|
|
129
71
|
|
|
130
|
-
##
|
|
72
|
+
## Sin Python requerido
|
|
131
73
|
|
|
132
|
-
|
|
74
|
+
Toda la CLI corre en Node.js. Los hooks de guardrail son JavaScript puro.
|
|
133
75
|
|
|
134
|
-
|
|
76
|
+
No hay `pip install`, no hay `requirements.txt`, no hay dependencias de sistema fuera de Node.js 18+.
|
|
135
77
|
|
|
136
|
-
|
|
137
|
-
python3 .agentic/scripts/forge-scaffold-profile.py --name <stack> --engineer <agente>
|
|
138
|
-
```
|
|
78
|
+
---
|
|
139
79
|
|
|
140
|
-
|
|
80
|
+
## Comparativa
|
|
141
81
|
|
|
142
|
-
|
|
82
|
+
| Herramienta | Agentes especializados | Hooks de guardrail | Manifest con SHA-256 | Multi-runtime |
|
|
83
|
+
|-------------|------------------------|-------------------|----------------------|---------------|
|
|
84
|
+
| **forge** | Sí | Sí | Sí | Claude Code, OpenCode, Codex, Kiro |
|
|
85
|
+
| `cc-sdd` | No — plantillas SDD | No | No | Claude Code |
|
|
86
|
+
| `autoskills` | No — skills genéricos | No | No | Claude Code |
|
|
143
87
|
|
|
144
|
-
|
|
88
|
+
---
|
|
145
89
|
|
|
146
|
-
|
|
90
|
+
## Documentación
|
|
147
91
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```
|
|
92
|
+
- [Guía completa](docs/guide.md)
|
|
93
|
+
- [Runtimes](docs/runtimes/)
|
|
151
94
|
|
|
152
95
|
---
|
|
153
96
|
|
|
154
97
|
## Licencia
|
|
155
98
|
|
|
156
|
-
Apache 2.0 — [Cristian Correa](https://github.com/cristiancorreau), 2026.
|
|
99
|
+
Apache 2.0 — Copyright [Cristian Correa](https://github.com/cristiancorreau), 2026.
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { audit } from './commands/audit.js';
|
|
|
4
4
|
import { generate } from './commands/generate.js';
|
|
5
5
|
import { validate } from './commands/validate.js';
|
|
6
6
|
import { doctor } from './commands/doctor.js';
|
|
7
|
-
const VERSION = '2.
|
|
7
|
+
const VERSION = '2.4.1';
|
|
8
8
|
const HELP = `forge v${VERSION} — Agentic development framework
|
|
9
9
|
|
|
10
10
|
Usage: forge <command> [options]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAmEA,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyI3D"}
|
package/dist/commands/audit.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { findProjectYaml, loadProjectYaml } from '../lib/yaml.js';
|
|
4
|
+
import { bold, dim, green, red, yellow, cyan, gray, icons } from '../ui/colors.js';
|
|
5
|
+
import { box } from '../ui/box.js';
|
|
6
|
+
import { loadManifest, checkOutdated } from '../lib/lock.js';
|
|
4
7
|
const HELP = `Usage: forge audit [options]
|
|
5
8
|
|
|
6
9
|
Audit a project against the forge standard. Checks installed agents,
|
|
@@ -140,6 +143,20 @@ export async function audit(args) {
|
|
|
140
143
|
if (!hasClaudeDir && !hasAgentsMd && !hasKiro) {
|
|
141
144
|
issues.push({ level: 'warn', check: 'runtime', message: 'No se detectó ningún runtime — ejecutar forge init' });
|
|
142
145
|
}
|
|
146
|
+
// Manifest check
|
|
147
|
+
const manifest = loadManifest(root);
|
|
148
|
+
if (manifest) {
|
|
149
|
+
const outdated = checkOutdated(root, manifest);
|
|
150
|
+
if (outdated.length === 0) {
|
|
151
|
+
issues.push({ level: 'ok', check: 'manifest', message: `forge v${manifest.forgeVersion} — todos los archivos al día` });
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
issues.push({ level: 'warn', check: 'manifest', message: `${outdated.length} archivo(s) modificados desde forge init` });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
issues.push({ level: 'info', check: 'manifest', message: 'Sin .forge/manifest.json — ejecutar forge init para generarlo' });
|
|
159
|
+
}
|
|
143
160
|
// Summary
|
|
144
161
|
const errors = issues.filter(i => i.level === 'error').length;
|
|
145
162
|
const warnings = issues.filter(i => i.level === 'warn').length;
|
|
@@ -151,15 +168,18 @@ export async function audit(args) {
|
|
|
151
168
|
}, null, 2));
|
|
152
169
|
}
|
|
153
170
|
else {
|
|
154
|
-
console.log('forge audit\n');
|
|
171
|
+
console.log(cyan(bold('forge audit')) + '\n');
|
|
155
172
|
for (const issue of issues) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
console.log(` [${icon}] ${issue.check.padEnd(20)} ${issue.message}`);
|
|
173
|
+
const levelIcon = icons[issue.level] ?? gray('·');
|
|
174
|
+
console.log(` [${levelIcon}] ${bold(issue.check.padEnd(20))} ${dim(issue.message)}`);
|
|
159
175
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
176
|
+
const summaryLine = `Resumen: ${green(String(ok) + ' OK')} · ${yellow(String(warnings) + ' warn')} · ${red(String(errors) + ' ✗')}`;
|
|
177
|
+
const boxTitle = errors === 0 && warnings === 0
|
|
178
|
+
? green('Todo en orden')
|
|
179
|
+
: errors > 0
|
|
180
|
+
? red('Se encontraron errores')
|
|
181
|
+
: yellow('Advertencias encontradas');
|
|
182
|
+
console.log('\n' + box(boxTitle, [summaryLine]));
|
|
163
183
|
}
|
|
164
184
|
return errors > 0 ? 1 : 0;
|
|
165
185
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAOA,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqG7D"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -2,67 +2,102 @@ import { existsSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { resolveForgeRoot } from '../lib/paths.js';
|
|
4
4
|
import { findProjectYaml } from '../lib/yaml.js';
|
|
5
|
+
import { bold, dim, green, red, cyan, icons } from '../ui/colors.js';
|
|
6
|
+
import { box } from '../ui/box.js';
|
|
5
7
|
export async function doctor(_args) {
|
|
6
8
|
let ok = true;
|
|
7
|
-
|
|
9
|
+
const lines = [];
|
|
10
|
+
console.log(cyan(bold('forge doctor')) + dim(' — environment check') + '\n');
|
|
8
11
|
// Node.js version
|
|
9
12
|
const nodeVersion = process.versions.node;
|
|
10
13
|
const [major] = nodeVersion.split('.').map(Number);
|
|
11
14
|
if (major >= 18) {
|
|
12
|
-
|
|
15
|
+
const line = `${icons.ok} Node.js ${nodeVersion}`;
|
|
16
|
+
console.log(' ' + line);
|
|
17
|
+
lines.push(line);
|
|
13
18
|
}
|
|
14
19
|
else {
|
|
15
|
-
|
|
20
|
+
const line = `${icons.error} Node.js ${nodeVersion} — se requiere >= 18`;
|
|
21
|
+
console.log(' ' + line);
|
|
22
|
+
lines.push(line);
|
|
16
23
|
ok = false;
|
|
17
24
|
}
|
|
18
25
|
// forge root
|
|
19
26
|
try {
|
|
20
27
|
const root = resolveForgeRoot();
|
|
21
|
-
|
|
28
|
+
const rootLine = `${icons.ok} forge root encontrado`;
|
|
29
|
+
console.log(' ' + rootLine);
|
|
30
|
+
lines.push(rootLine);
|
|
22
31
|
// Core assets
|
|
23
32
|
const coreOk = existsSync(join(root, 'core', 'agents'))
|
|
24
33
|
&& existsSync(join(root, 'core', 'schemas'))
|
|
25
34
|
&& existsSync(join(root, 'scripts'));
|
|
26
35
|
if (coreOk) {
|
|
27
|
-
|
|
36
|
+
const assetsLine = `${icons.ok} forge assets: completos`;
|
|
37
|
+
console.log(' ' + assetsLine);
|
|
38
|
+
lines.push(assetsLine);
|
|
28
39
|
}
|
|
29
40
|
else {
|
|
30
|
-
|
|
41
|
+
const assetsLine = `${icons.error} forge assets: incompletos — reinstalar con npx @cristiancorreau/forge`;
|
|
42
|
+
console.log(' ' + assetsLine);
|
|
43
|
+
lines.push(assetsLine);
|
|
31
44
|
ok = false;
|
|
32
45
|
}
|
|
33
46
|
}
|
|
34
47
|
catch (e) {
|
|
35
48
|
const msg = e instanceof Error ? e.message : String(e);
|
|
36
|
-
|
|
49
|
+
const line = `${icons.error} forge root: ${msg}`;
|
|
50
|
+
console.log(' ' + line);
|
|
51
|
+
lines.push(line);
|
|
37
52
|
ok = false;
|
|
38
53
|
}
|
|
39
54
|
// project.yaml
|
|
40
55
|
const projectYaml = findProjectYaml(process.cwd());
|
|
41
56
|
if (projectYaml) {
|
|
42
|
-
|
|
57
|
+
const line = `${icons.ok} project.yaml: ${projectYaml}`;
|
|
58
|
+
console.log(' ' + line);
|
|
59
|
+
lines.push(line);
|
|
43
60
|
}
|
|
44
61
|
else {
|
|
45
|
-
|
|
62
|
+
const line = `${icons.skip} project.yaml: no encontrado (ejecutar forge init)`;
|
|
63
|
+
console.log(' ' + line);
|
|
64
|
+
lines.push(line);
|
|
46
65
|
}
|
|
47
66
|
// .claude / AGENTS.md / .kiro
|
|
48
67
|
const cwd = process.cwd();
|
|
49
68
|
const hasClaude = existsSync(join(cwd, '.claude'));
|
|
50
69
|
const hasAgents = existsSync(join(cwd, 'AGENTS.md'));
|
|
51
70
|
const hasKiro = existsSync(join(cwd, '.kiro'));
|
|
52
|
-
if (hasClaude)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
console.log('
|
|
71
|
+
if (hasClaude) {
|
|
72
|
+
const line = `${icons.ok} runtime: Claude Code (.claude/)`;
|
|
73
|
+
console.log(' ' + line);
|
|
74
|
+
lines.push(line);
|
|
75
|
+
}
|
|
76
|
+
if (hasAgents && !hasClaude) {
|
|
77
|
+
const line = `${icons.ok} runtime: OpenCode / Codex (AGENTS.md)`;
|
|
78
|
+
console.log(' ' + line);
|
|
79
|
+
lines.push(line);
|
|
80
|
+
}
|
|
81
|
+
if (hasKiro) {
|
|
82
|
+
const line = `${icons.ok} runtime: Kiro (.kiro/)`;
|
|
83
|
+
console.log(' ' + line);
|
|
84
|
+
lines.push(line);
|
|
85
|
+
}
|
|
86
|
+
if (!hasClaude && !hasAgents && !hasKiro) {
|
|
87
|
+
const line = `${icons.skip} runtime: no detectado (ejecutar forge init)`;
|
|
88
|
+
console.log(' ' + line);
|
|
89
|
+
lines.push(line);
|
|
90
|
+
}
|
|
60
91
|
console.log('');
|
|
61
92
|
if (ok) {
|
|
62
|
-
|
|
93
|
+
const summaryLine = green('All checks passed.');
|
|
94
|
+
console.log(box('forge doctor', [...lines, '', summaryLine]));
|
|
63
95
|
}
|
|
64
96
|
else {
|
|
65
|
-
|
|
97
|
+
const failed = lines.filter(l => l.includes('✗'));
|
|
98
|
+
const summaryLine = red('Algunos checks fallaron. Ver detalles arriba.');
|
|
99
|
+
console.log(box('forge doctor', [...lines, '', summaryLine]));
|
|
100
|
+
void failed;
|
|
66
101
|
}
|
|
67
102
|
return ok ? 0 : 1;
|
|
68
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAqDA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0I9D"}
|
|
@@ -5,6 +5,8 @@ import { generateClaudeMd } from '../lib/generators/claude-code.js';
|
|
|
5
5
|
import { generateAgentsMd } from '../lib/generators/opencode.js';
|
|
6
6
|
import { generateCodexAgentsMd } from '../lib/generators/codex.js';
|
|
7
7
|
import { generateKiroProduct, generateKiroStructure, generateKiroAgents, generateKiroCommands, generateKiroBranchGuardHook } from '../lib/generators/kiro.js';
|
|
8
|
+
import { bold, dim, green, red, yellow, cyan, gray } from '../ui/colors.js';
|
|
9
|
+
import { createSpinner } from '../ui/spinner.js';
|
|
8
10
|
const HELP = `Usage: forge generate [options]
|
|
9
11
|
|
|
10
12
|
Generate runtime configuration files from project.yaml.
|
|
@@ -70,9 +72,9 @@ export async function generate(args) {
|
|
|
70
72
|
}
|
|
71
73
|
const root = join(yamlPath, '..');
|
|
72
74
|
const projectName = config.project.name ?? 'Proyecto';
|
|
73
|
-
console.log(
|
|
75
|
+
console.log(cyan(bold('forge generate')) + dim(' — ' + projectName) + '\n');
|
|
74
76
|
if (dryRun)
|
|
75
|
-
console.log(' Modo: DRY-RUN (no escribe archivos)\n');
|
|
77
|
+
console.log(dim(' Modo: DRY-RUN (no escribe archivos)') + '\n');
|
|
76
78
|
let runtimesToRun;
|
|
77
79
|
if (runtimeArg === 'all') {
|
|
78
80
|
runtimesToRun = ['claude-code', 'opencode', 'codex', 'kiro'];
|
|
@@ -88,49 +90,98 @@ export async function generate(args) {
|
|
|
88
90
|
return 0;
|
|
89
91
|
}
|
|
90
92
|
}
|
|
93
|
+
// Build spinner items: one entry per runtime (kiro gets a summary entry)
|
|
94
|
+
const spinnerItems = runtimesToRun.map(rt => ({
|
|
95
|
+
runtime: rt,
|
|
96
|
+
file: rt === 'kiro' ? '.kiro/steering/' : rt === 'claude-code' ? 'CLAUDE.md' : 'AGENTS.md',
|
|
97
|
+
}));
|
|
98
|
+
const spinner = createSpinner(spinnerItems);
|
|
99
|
+
spinner.start();
|
|
91
100
|
const results = [];
|
|
92
101
|
for (const runtime of runtimesToRun) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
spinner.update(runtime, 'running');
|
|
103
|
+
try {
|
|
104
|
+
if (runtime === 'claude-code') {
|
|
105
|
+
mkdirSync(join(root, '.claude'), { recursive: true });
|
|
106
|
+
const claudeMdPath = join(root, 'CLAUDE.md');
|
|
107
|
+
const status = writeFile(claudeMdPath, generateClaudeMd(config), dryRun, force);
|
|
108
|
+
results.push({ runtime, file: 'CLAUDE.md', status });
|
|
109
|
+
spinner.update(runtime, status.startsWith('SKIP') ? 'skip' : 'done', 'CLAUDE.md');
|
|
110
|
+
}
|
|
111
|
+
else if (runtime === 'opencode') {
|
|
112
|
+
mkdirSync(join(root, '.opencode'), { recursive: true });
|
|
113
|
+
const status = writeFile(join(root, 'AGENTS.md'), generateAgentsMd(config), dryRun, force);
|
|
114
|
+
results.push({ runtime, file: 'AGENTS.md', status });
|
|
115
|
+
spinner.update(runtime, status.startsWith('SKIP') ? 'skip' : 'done', 'AGENTS.md');
|
|
116
|
+
}
|
|
117
|
+
else if (runtime === 'codex') {
|
|
118
|
+
const status = writeFile(join(root, 'AGENTS.md'), generateCodexAgentsMd(config), dryRun, force);
|
|
119
|
+
results.push({ runtime, file: 'AGENTS.md', status });
|
|
120
|
+
spinner.update(runtime, status.startsWith('SKIP') ? 'skip' : 'done', 'AGENTS.md');
|
|
121
|
+
}
|
|
122
|
+
else if (runtime === 'kiro') {
|
|
123
|
+
const kiroDir = join(root, '.kiro', 'steering');
|
|
124
|
+
const kiroHooks = join(root, '.kiro', 'hooks');
|
|
125
|
+
mkdirSync(kiroDir, { recursive: true });
|
|
126
|
+
mkdirSync(kiroHooks, { recursive: true });
|
|
127
|
+
const files = [
|
|
128
|
+
[join(kiroDir, 'product.md'), generateKiroProduct(config)],
|
|
129
|
+
[join(kiroDir, 'structure.md'), generateKiroStructure(config)],
|
|
130
|
+
[join(kiroDir, 'agents.md'), generateKiroAgents(config)],
|
|
131
|
+
[join(kiroDir, 'commands.md'), generateKiroCommands()],
|
|
132
|
+
[join(kiroHooks, 'pre-edit-branch-guard.json'), generateKiroBranchGuardHook()],
|
|
133
|
+
];
|
|
134
|
+
let kiroOk = 0;
|
|
135
|
+
let kiroSkip = 0;
|
|
136
|
+
for (const [path, content] of files) {
|
|
137
|
+
const status = writeFile(path, content, dryRun, force);
|
|
138
|
+
results.push({ runtime, file: path.replace(root + '/', ''), status });
|
|
139
|
+
if (status.startsWith('SKIP'))
|
|
140
|
+
kiroSkip++;
|
|
141
|
+
else
|
|
142
|
+
kiroOk++;
|
|
143
|
+
}
|
|
144
|
+
const kiroSummary = `.kiro/steering/ (${files.length} archivos)`;
|
|
145
|
+
spinner.update(runtime, kiroSkip === files.length ? 'skip' : 'done', kiroSummary);
|
|
146
|
+
}
|
|
98
147
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
148
|
+
catch (e) {
|
|
149
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
150
|
+
results.push({ runtime, file: '—', status: `ERROR: ${msg}` });
|
|
151
|
+
spinner.update(runtime, 'error');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
spinner.stop();
|
|
155
|
+
console.log('');
|
|
156
|
+
// Print final results table with colors
|
|
157
|
+
for (const r of results) {
|
|
158
|
+
const rt = r.runtime.padEnd(12);
|
|
159
|
+
let statusStr;
|
|
160
|
+
if (r.status === 'OK' || r.status === 'DRY-RUN') {
|
|
161
|
+
statusStr = green(r.status);
|
|
103
162
|
}
|
|
104
|
-
else if (
|
|
105
|
-
|
|
106
|
-
results.push({ runtime, file: 'AGENTS.md', status });
|
|
163
|
+
else if (r.status.startsWith('SKIP')) {
|
|
164
|
+
statusStr = yellow(dim(r.status));
|
|
107
165
|
}
|
|
108
|
-
else
|
|
109
|
-
|
|
110
|
-
const kiroHooks = join(root, '.kiro', 'hooks');
|
|
111
|
-
mkdirSync(kiroDir, { recursive: true });
|
|
112
|
-
mkdirSync(kiroHooks, { recursive: true });
|
|
113
|
-
const files = [
|
|
114
|
-
[join(kiroDir, 'product.md'), generateKiroProduct(config)],
|
|
115
|
-
[join(kiroDir, 'structure.md'), generateKiroStructure(config)],
|
|
116
|
-
[join(kiroDir, 'agents.md'), generateKiroAgents(config)],
|
|
117
|
-
[join(kiroDir, 'commands.md'), generateKiroCommands()],
|
|
118
|
-
[join(kiroHooks, 'pre-edit-branch-guard.json'), generateKiroBranchGuardHook()],
|
|
119
|
-
];
|
|
120
|
-
for (const [path, content] of files) {
|
|
121
|
-
const status = writeFile(path, content, dryRun, force);
|
|
122
|
-
results.push({ runtime, file: path.replace(root + '/', ''), status });
|
|
123
|
-
}
|
|
166
|
+
else {
|
|
167
|
+
statusStr = red(r.status);
|
|
124
168
|
}
|
|
169
|
+
console.log(` ${rt} ${gray(r.file)} ${statusStr}`);
|
|
125
170
|
}
|
|
126
|
-
console.log('
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
console.log(
|
|
171
|
+
console.log('');
|
|
172
|
+
const hasErrors = results.some(r => r.status.startsWith('ERROR'));
|
|
173
|
+
const hasSkips = results.some(r => r.status.startsWith('SKIP'));
|
|
174
|
+
const okCount = results.filter(r => r.status === 'OK' || r.status === 'DRY-RUN').length;
|
|
175
|
+
if (hasErrors) {
|
|
176
|
+
console.log(red(' Algunos archivos fallaron. Ver detalles arriba.'));
|
|
177
|
+
}
|
|
178
|
+
else if (hasSkips && okCount === 0) {
|
|
179
|
+
console.log(yellow(' Archivos existentes sin cambios. Usa --force para sobreescribir.'));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.log(green(` ${okCount} archivo(s) generado(s) correctamente.`));
|
|
132
183
|
}
|
|
133
184
|
console.log('');
|
|
134
|
-
return 0;
|
|
185
|
+
return hasErrors ? 1 : 0;
|
|
135
186
|
}
|
|
136
187
|
//# sourceMappingURL=generate.js.map
|