@cristiancorreau/forge 2.1.0 → 2.2.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 (41) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/commands/audit.d.ts.map +1 -1
  3. package/dist/commands/audit.js +154 -9
  4. package/dist/commands/audit.js.map +1 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +39 -28
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/generate.d.ts.map +1 -1
  9. package/dist/commands/generate.js +114 -5
  10. package/dist/commands/generate.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +274 -9
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/validate.d.ts.map +1 -1
  15. package/dist/commands/validate.js +92 -6
  16. package/dist/commands/validate.js.map +1 -1
  17. package/dist/lib/generators/claude-code.d.ts +3 -0
  18. package/dist/lib/generators/claude-code.d.ts.map +1 -0
  19. package/dist/lib/generators/claude-code.js +134 -0
  20. package/dist/lib/generators/claude-code.js.map +1 -0
  21. package/dist/lib/generators/codex.d.ts +3 -0
  22. package/dist/lib/generators/codex.d.ts.map +1 -0
  23. package/dist/lib/generators/codex.js +69 -0
  24. package/dist/lib/generators/codex.js.map +1 -0
  25. package/dist/lib/generators/kiro.d.ts +7 -0
  26. package/dist/lib/generators/kiro.d.ts.map +1 -0
  27. package/dist/lib/generators/kiro.js +134 -0
  28. package/dist/lib/generators/kiro.js.map +1 -0
  29. package/dist/lib/generators/opencode.d.ts +3 -0
  30. package/dist/lib/generators/opencode.d.ts.map +1 -0
  31. package/dist/lib/generators/opencode.js +96 -0
  32. package/dist/lib/generators/opencode.js.map +1 -0
  33. package/dist/lib/wizard.d.ts +17 -0
  34. package/dist/lib/wizard.d.ts.map +1 -0
  35. package/dist/lib/wizard.js +162 -0
  36. package/dist/lib/wizard.js.map +1 -0
  37. package/dist/lib/yaml.d.ts +96 -0
  38. package/dist/lib/yaml.d.ts.map +1 -0
  39. package/dist/lib/yaml.js +26 -0
  40. package/dist/lib/yaml.js.map +1 -0
  41. package/package.json +7 -1
@@ -1,22 +1,287 @@
1
- import { resolveScript } from '../lib/paths.js';
2
- import { runPython } from '../lib/python.js';
1
+ import { existsSync, mkdirSync, writeFileSync, copyFileSync, readdirSync, statSync } from 'fs';
2
+ import { join, basename } from 'path';
3
+ import { loadProjectYaml } from '../lib/yaml.js';
4
+ import { runWizard } from '../lib/wizard.js';
5
+ import { resolveForgeRoot } from '../lib/paths.js';
6
+ import { generateClaudeMd } from '../lib/generators/claude-code.js';
7
+ import { generateAgentsMd } from '../lib/generators/opencode.js';
8
+ import { generateCodexAgentsMd } from '../lib/generators/codex.js';
9
+ import { generateKiroProduct, generateKiroStructure, generateKiroAgents, generateKiroCommands, generateKiroBranchGuardHook } from '../lib/generators/kiro.js';
3
10
  const HELP = `Usage: forge init [options]
4
11
 
5
- Initialize forge in a project. Creates project.yaml via interactive wizard
6
- and generates agent files for the selected runtime.
12
+ Initialize forge in a project. Launches an interactive wizard to configure
13
+ project.yaml, then installs agents, hooks, and runtime configuration.
7
14
 
8
15
  Options:
9
- --runtime <name> Target runtime: claude-code, opencode, codex, kiro
10
- --dry-run Show what would be created without writing files
11
- --force Skip confirmation prompts
16
+ --runtime <name> Skip wizard for runtime selection: claude-code, opencode, codex, kiro
17
+ --force Overwrite existing files without prompting
12
18
  -h, --help Show this help
13
19
  `;
20
+ // ---------------------------------------------------------------------------
21
+ // Helpers
22
+ // ---------------------------------------------------------------------------
23
+ function write(path, content, force) {
24
+ if (existsSync(path) && !force) {
25
+ console.log(` skip ${basename(path)} (ya existe)`);
26
+ return;
27
+ }
28
+ writeFileSync(path, content, 'utf-8');
29
+ console.log(` write ${basename(path)}`);
30
+ }
31
+ function copyFile(src, dest, force) {
32
+ if (existsSync(dest) && !force) {
33
+ console.log(` skip ${basename(dest)} (ya existe)`);
34
+ return;
35
+ }
36
+ copyFileSync(src, dest);
37
+ console.log(` copy ${basename(dest)}`);
38
+ }
39
+ function copyDir(src, dest, force) {
40
+ if (!existsSync(dest))
41
+ mkdirSync(dest, { recursive: true });
42
+ for (const entry of readdirSync(src)) {
43
+ const srcPath = join(src, entry);
44
+ const destPath = join(dest, entry);
45
+ if (statSync(srcPath).isDirectory())
46
+ copyDir(srcPath, destPath, force);
47
+ else
48
+ copyFile(srcPath, destPath, force);
49
+ }
50
+ }
51
+ function buildProjectYaml(result) {
52
+ if (!result)
53
+ return '';
54
+ const stack = [];
55
+ if (result.backend)
56
+ stack.push(` backend: ${result.backend}`);
57
+ if (result.frontend)
58
+ stack.push(` frontend: ${result.frontend}`);
59
+ if (result.database)
60
+ stack.push(` database: ${result.database}`);
61
+ if (result.orm)
62
+ stack.push(` orm: ${result.orm}`);
63
+ if (result.packageManager)
64
+ stack.push(` package_manager: ${result.packageManager}`);
65
+ if (result.testing && result.testing.length > 0) {
66
+ stack.push(` testing:\n${result.testing.map(t => ` - ${t}`).join('\n')}`);
67
+ }
68
+ const profiles = result.profiles && result.profiles.length > 0
69
+ ? ` profiles:\n${result.profiles.map(p => ` - ${p}`).join('\n')}`
70
+ : '';
71
+ const coreAgents = defaultAgentsForMode(result.mode);
72
+ return `project:
73
+ name: "${result.name}"
74
+ slug: "${result.slug}"
75
+ description: "${result.description}"
76
+ language: ${result.language}
77
+ mode: ${result.mode}
78
+ status: active
79
+
80
+ stack:
81
+ ${stack.join('\n') || ' # Agregar stack aquí'}
82
+
83
+ agents:
84
+ active:
85
+ ${coreAgents.map(a => ` - ${a}`).join('\n')}
86
+ compliance: []
87
+ ${profiles}
88
+
89
+ runtimes:
90
+ active:
91
+ - ${result.runtime}
92
+
93
+ # Agregar cuando tengas deploy configurado:
94
+ # deploy:
95
+ # provider: vercel
96
+ # production_url: https://tu-proyecto.vercel.app
97
+ `;
98
+ }
99
+ function defaultAgentsForMode(mode) {
100
+ if (mode === 'startup')
101
+ return ['orchestrator', 'backend-engineer', 'frontend-engineer'];
102
+ if (mode === 'enterprise')
103
+ return ['orchestrator', 'backend-engineer', 'frontend-engineer', 'test-engineer', 'docs-writer', 'compliance-reviewer', 'security-auditor'];
104
+ return ['orchestrator', 'backend-engineer', 'frontend-engineer', 'test-engineer', 'docs-writer'];
105
+ }
106
+ function installCoreAgents(forgeRoot, destDir, activeAgents, profiles, force) {
107
+ mkdirSync(destDir, { recursive: true });
108
+ // Tier 2: profile agents first
109
+ for (const profile of profiles) {
110
+ const profileAgentsDir = join(forgeRoot, 'profiles', profile, 'agents');
111
+ if (existsSync(profileAgentsDir)) {
112
+ copyDir(profileAgentsDir, destDir, force);
113
+ }
114
+ }
115
+ // Tier 1: core agents (only if not already installed)
116
+ const coreAgentsDir = join(forgeRoot, 'core', 'agents');
117
+ if (existsSync(coreAgentsDir)) {
118
+ for (const agent of activeAgents) {
119
+ const src = join(coreAgentsDir, `${agent}.md`);
120
+ const dest = join(destDir, `${agent}.md`);
121
+ if (existsSync(src) && (!existsSync(dest) || force)) {
122
+ copyFile(src, dest, force);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ function installHooks(forgeRoot, destDir, mode, force) {
128
+ mkdirSync(destDir, { recursive: true });
129
+ const hooksDir = join(forgeRoot, 'core', 'hooks');
130
+ if (!existsSync(hooksDir))
131
+ return;
132
+ const universal = ['pre-edit-check.py', 'post-turn-check.sh', 'session-start.sh'];
133
+ const standard = ['pre-bash-check.py'];
134
+ for (const hook of universal) {
135
+ const src = join(hooksDir, hook);
136
+ if (existsSync(src))
137
+ copyFile(src, join(destDir, hook), force);
138
+ }
139
+ if (mode === 'standard' || mode === 'enterprise') {
140
+ for (const hook of standard) {
141
+ const src = join(hooksDir, hook);
142
+ if (existsSync(src))
143
+ copyFile(src, join(destDir, hook), force);
144
+ }
145
+ }
146
+ }
147
+ function generateSettingsJson(language, mode) {
148
+ const allowList = [];
149
+ if (language === 'typescript') {
150
+ allowList.push('Bash(pnpm *)', 'Bash(npm *)', 'Bash(node *)', 'Bash(npx *)');
151
+ }
152
+ else if (language === 'python') {
153
+ allowList.push('Bash(python3 *)', 'Bash(pip3 *)', 'Bash(pytest *)', 'Bash(ruff *)');
154
+ }
155
+ else if (language === 'ruby') {
156
+ allowList.push('Bash(bundle *)', 'Bash(rails *)', 'Bash(rake *)');
157
+ }
158
+ else if (language === 'go') {
159
+ allowList.push('Bash(go *)');
160
+ }
161
+ else if (language === 'php') {
162
+ allowList.push('Bash(composer *)', 'Bash(php *)');
163
+ }
164
+ allowList.push('Bash(git *)');
165
+ const hooks = {
166
+ PreToolUse: [{ matcher: 'Bash', hooks: [{ type: 'command', command: 'python3 .claude/hooks/pre-edit-check.py' }] }],
167
+ Stop: [{ hooks: [{ type: 'command', command: 'bash .claude/hooks/post-turn-check.sh' }] }],
168
+ };
169
+ if (mode === 'standard' || mode === 'enterprise') {
170
+ hooks.PreToolUse.push({
171
+ matcher: 'Bash',
172
+ hooks: [{ type: 'command', command: 'python3 .claude/hooks/pre-bash-check.py' }],
173
+ });
174
+ }
175
+ return JSON.stringify({ permissions: { allow: allowList }, hooks }, null, 2);
176
+ }
177
+ function installCommands(forgeRoot, destDir, force) {
178
+ mkdirSync(destDir, { recursive: true });
179
+ const commandsDir = join(forgeRoot, 'adapters', 'claude-code', 'commands');
180
+ if (!existsSync(commandsDir))
181
+ return;
182
+ copyDir(commandsDir, destDir, force);
183
+ }
184
+ function installKiro(forgeRoot, projectRoot, config, force) {
185
+ const kiroDir = join(projectRoot, '.kiro', 'steering');
186
+ const hooksDir = join(projectRoot, '.kiro', 'hooks');
187
+ mkdirSync(kiroDir, { recursive: true });
188
+ mkdirSync(hooksDir, { recursive: true });
189
+ write(join(kiroDir, 'product.md'), generateKiroProduct(config), force);
190
+ write(join(kiroDir, 'structure.md'), generateKiroStructure(config), force);
191
+ write(join(kiroDir, 'agents.md'), generateKiroAgents(config), force);
192
+ write(join(kiroDir, 'commands.md'), generateKiroCommands(), force);
193
+ write(join(hooksDir, 'pre-edit-branch-guard.json'), generateKiroBranchGuardHook(), force);
194
+ }
195
+ // ---------------------------------------------------------------------------
196
+ // Main
197
+ // ---------------------------------------------------------------------------
14
198
  export async function init(args) {
15
199
  if (args.includes('-h') || args.includes('--help')) {
16
200
  process.stdout.write(HELP);
17
201
  return 0;
18
202
  }
19
- const script = resolveScript('forge-init.py');
20
- return runPython(script, args);
203
+ const force = args.includes('--force');
204
+ const runtimeIdx = args.indexOf('--runtime');
205
+ const runtimeOverride = runtimeIdx !== -1 ? (args[runtimeIdx + 1] ?? null) : null;
206
+ const projectYamlPath = join(process.cwd(), 'project.yaml');
207
+ let config;
208
+ if (!existsSync(projectYamlPath)) {
209
+ // Run interactive wizard
210
+ const result = await runWizard();
211
+ if (!result) {
212
+ console.log('\nCancelado.');
213
+ return 1;
214
+ }
215
+ const yamlContent = buildProjectYaml(result);
216
+ writeFileSync(projectYamlPath, yamlContent, 'utf-8');
217
+ console.log(`\n write project.yaml`);
218
+ // Build config from wizard result
219
+ config = {
220
+ project: { name: result.name, slug: result.slug, description: result.description, language: result.language, mode: result.mode, status: 'active' },
221
+ stack: { backend: result.backend, frontend: result.frontend, database: result.database, orm: result.orm, package_manager: result.packageManager, testing: result.testing },
222
+ agents: { active: defaultAgentsForMode(result.mode), compliance: [], profiles: result.profiles },
223
+ runtimes: { active: [runtimeOverride ?? result.runtime] },
224
+ };
225
+ }
226
+ else {
227
+ console.log('project.yaml encontrado — usando configuración existente.\n');
228
+ config = loadProjectYaml(projectYamlPath);
229
+ }
230
+ const forgeRoot = resolveForgeRoot();
231
+ const projectRoot = process.cwd();
232
+ const runtime = runtimeOverride ?? config.runtimes?.active?.[0] ?? 'claude-code';
233
+ const mode = config.project.mode ?? 'standard';
234
+ const language = config.project.language ?? 'typescript';
235
+ const activeAgents = config.agents?.active ?? [];
236
+ const complianceAgents = config.agents?.compliance ?? [];
237
+ const profiles = config.agents?.profiles ?? [];
238
+ const allAgents = [...activeAgents, ...complianceAgents];
239
+ console.log(`\nInstalando forge para runtime: ${runtime}\n`);
240
+ if (runtime === 'claude-code') {
241
+ const claudeDir = join(projectRoot, '.claude');
242
+ mkdirSync(claudeDir, { recursive: true });
243
+ console.log('Agentes:');
244
+ installCoreAgents(forgeRoot, join(claudeDir, 'agents'), allAgents, profiles, force);
245
+ console.log('\nHooks:');
246
+ installHooks(forgeRoot, join(claudeDir, 'hooks'), mode, force);
247
+ console.log('\nSlash commands:');
248
+ installCommands(forgeRoot, join(claudeDir, 'commands'), force);
249
+ console.log('\nArchivos de configuración:');
250
+ write(join(projectRoot, 'CLAUDE.md'), generateClaudeMd(config), force);
251
+ write(join(claudeDir, 'settings.json'), generateSettingsJson(language, mode), force);
252
+ // Docs structure
253
+ mkdirSync(join(projectRoot, 'docs', 'specs'), { recursive: true });
254
+ mkdirSync(join(projectRoot, 'docs', 'daily-notes'), { recursive: true });
255
+ const specTemplateSrc = join(forgeRoot, 'core', 'templates', 'spec-template.md');
256
+ if (existsSync(specTemplateSrc)) {
257
+ copyFile(specTemplateSrc, join(projectRoot, 'docs', 'specs', '_template.md'), false);
258
+ }
259
+ }
260
+ else if (runtime === 'opencode') {
261
+ mkdirSync(join(projectRoot, '.opencode'), { recursive: true });
262
+ write(join(projectRoot, 'AGENTS.md'), generateAgentsMd(config), force);
263
+ }
264
+ else if (runtime === 'codex') {
265
+ write(join(projectRoot, 'AGENTS.md'), generateCodexAgentsMd(config), force);
266
+ }
267
+ else if (runtime === 'kiro') {
268
+ installKiro(forgeRoot, projectRoot, config, force);
269
+ }
270
+ console.log(`\nForge instalado para ${runtime}.\n`);
271
+ console.log('Próximos pasos:');
272
+ if (runtime === 'claude-code') {
273
+ console.log(' 1. Revisar CLAUDE.md y ajustar si es necesario');
274
+ console.log(' 2. Abrir el proyecto en Claude Code');
275
+ console.log(' 3. Usar /plan para crear tu primera spec');
276
+ }
277
+ else if (runtime === 'opencode') {
278
+ console.log(' 1. Revisar AGENTS.md');
279
+ console.log(' 2. Abrir el proyecto en OpenCode');
280
+ }
281
+ else if (runtime === 'kiro') {
282
+ console.log(' 1. Revisar .kiro/steering/');
283
+ console.log(' 2. Abrir el proyecto en Kiro IDE');
284
+ }
285
+ return 0;
21
286
  }
22
287
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc;IACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAaA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAO9D"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAyCA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmE9D"}
@@ -1,20 +1,106 @@
1
- import { resolveScript } from '../lib/paths.js';
2
- import { runPython } from '../lib/python.js';
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { createRequire } from 'module';
4
+ const require = createRequire(import.meta.url);
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ const Ajv = require('ajv');
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ const addFormats = require('ajv-formats');
9
+ import { findProjectYaml, loadProjectYaml } from '../lib/yaml.js';
10
+ import { resolveForgeRoot } from '../lib/paths.js';
3
11
  const HELP = `Usage: forge validate [options]
4
12
 
5
13
  Validate project.yaml in the current directory against the forge v2 schema.
6
- Exits with code 1 if validation fails (suitable for CI pre-checks).
14
+ Exits with code 1 if validation fails (CI-safe).
7
15
 
8
16
  Options:
9
- --json Output errors as JSON
17
+ --json Output results as JSON
10
18
  -h, --help Show this help
11
19
  `;
20
+ function loadSchema(forgeRoot) {
21
+ const schemaPath = join(forgeRoot, 'core', 'schemas', 'project.schema.json');
22
+ if (!existsSync(schemaPath))
23
+ return null;
24
+ try {
25
+ return JSON.parse(readFileSync(schemaPath, 'utf-8'));
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ function businessWarnings(data) {
32
+ const warnings = [];
33
+ if (!data.deploy)
34
+ warnings.push("Sección 'deploy' ausente — considera agregar deploy.provider y deploy.smoke_tests (v2)");
35
+ if (!data.rules)
36
+ warnings.push("Sección 'rules' ausente — considera agregar guardrails del proyecto (v2)");
37
+ if (!data.github)
38
+ warnings.push("Sección 'github' ausente — considera integrar con GitHub Projects (v2)");
39
+ return warnings;
40
+ }
12
41
  export async function validate(args) {
13
42
  if (args.includes('-h') || args.includes('--help')) {
14
43
  process.stdout.write(HELP);
15
44
  return 0;
16
45
  }
17
- const script = resolveScript('forge-validate-project-yaml.py');
18
- return runPython(script, args);
46
+ const jsonMode = args.includes('--json');
47
+ const projectYamlPath = findProjectYaml(process.cwd());
48
+ if (!projectYamlPath) {
49
+ const result = { valid: false, errors: ['No se encontró project.yaml'], warnings: [] };
50
+ jsonMode ? console.log(JSON.stringify(result, null, 2)) : console.error('ERROR: No se encontró project.yaml');
51
+ return 1;
52
+ }
53
+ let data;
54
+ try {
55
+ data = loadProjectYaml(projectYamlPath);
56
+ }
57
+ catch (e) {
58
+ const msg = e instanceof Error ? e.message : String(e);
59
+ const result = { valid: false, errors: [msg], warnings: [] };
60
+ jsonMode ? console.log(JSON.stringify(result, null, 2)) : console.error(`ERROR: ${msg}`);
61
+ return 1;
62
+ }
63
+ let errors = [];
64
+ try {
65
+ const forgeRoot = resolveForgeRoot();
66
+ const schema = loadSchema(forgeRoot);
67
+ if (schema) {
68
+ const ajv = new Ajv({ allErrors: true, strict: false });
69
+ addFormats(ajv);
70
+ const validate = ajv.compile(schema);
71
+ const valid = validate(data);
72
+ if (!valid && validate.errors) {
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ errors = validate.errors.map((e) => {
75
+ const path = e.instancePath || 'raíz';
76
+ return `${path}: ${e.message}`;
77
+ });
78
+ }
79
+ }
80
+ }
81
+ catch {
82
+ // schema not available — skip schema validation
83
+ }
84
+ const warnings = businessWarnings(data);
85
+ const valid = errors.length === 0;
86
+ const result = { valid, errors, warnings };
87
+ if (jsonMode) {
88
+ console.log(JSON.stringify(result, null, 2));
89
+ }
90
+ else {
91
+ console.log(`Validando: ${projectYamlPath}\n`);
92
+ if (valid) {
93
+ console.log('OK — project.yaml es válido');
94
+ }
95
+ else {
96
+ console.log(`INVALIDO — ${errors.length} error(s) encontrado(s):`);
97
+ errors.forEach(e => console.log(` [ERROR] ${e}`));
98
+ }
99
+ if (warnings.length > 0) {
100
+ console.log(`\n${warnings.length} advertencia(s):`);
101
+ warnings.forEach(w => console.log(` [WARN] ${w}`));
102
+ }
103
+ }
104
+ return valid ? 0 : 1;
19
105
  }
20
106
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,IAAI,GAAG;;;;;;;;CAQZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC/D,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectYaml } from '../yaml.js';
2
+ export declare function generateClaudeMd(config: ProjectYaml): string;
3
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../../src/lib/generators/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAsE9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA2E5D"}
@@ -0,0 +1,134 @@
1
+ const AGENT_TRIGGER = {
2
+ 'orchestrator': ['tareas multi-agente, análisis de >3 archivos, descomposición de features completas', null],
3
+ 'backend-engineer': ['endpoints, middleware, validaciones, lógica de negocio', 'api'],
4
+ 'api-engineer': ['endpoints REST, middleware, validaciones, migraciones de BD', 'api'],
5
+ 'frontend-engineer': ['componentes UI, páginas, estilos, integración con API', 'frontend'],
6
+ 'admin-engineer': ['UI de gestión interna, dashboards de admin', 'admin'],
7
+ 'mobile-engineer': ['pantallas móviles, navegación, stores de estado', 'mobile'],
8
+ 'fullstack-engineer': ['features full-stack end-to-end que abarcan backend y frontend', null],
9
+ 'test-engineer': ['tests unitarios, integración, E2E — nunca código de producción', 'tests'],
10
+ 'docs-writer': ['specs, ADRs, READMEs, documentación — nunca código de producción', 'specs'],
11
+ 'compliance-reviewer': ['revisión de PRs con PII, consentimientos, logs de auditoría', null],
12
+ 'security-auditor': ['auditoría de vulnerabilidades, revisión de dependencias, pentest', null],
13
+ 'migration-specialist': ['migraciones de versión de framework (ej: L6→L13)', 'migrations'],
14
+ 'wp-engineer': ['temas WordPress, FSE, Gutenberg, child themes', 'frontend'],
15
+ 'divi-engineer': ['layouts Divi 5, módulos custom, Divi Builder', 'frontend'],
16
+ 'elementor-engineer': ['templates Elementor Pro, widgets custom', 'frontend'],
17
+ 'scanner-engineer': ['scraping, crawling, extracción estructurada de datos', 'scanner'],
18
+ };
19
+ function buildAgentScopeTable(agents, paths) {
20
+ const active = agents?.active ?? [];
21
+ const compliance = agents?.compliance ?? [];
22
+ const all = [...active, ...compliance];
23
+ if (all.length === 0)
24
+ return '';
25
+ const rows = all.map(agent => {
26
+ const [trigger, pathKey] = AGENT_TRIGGER[agent] ?? ['implementación', null];
27
+ const scope = pathKey && paths ? paths[pathKey] : undefined;
28
+ const scopeStr = scope ? `\`${scope}\`` : '`/`';
29
+ return `| \`${agent}\` | ${scopeStr} | ${trigger} |`;
30
+ });
31
+ return ('## Agentes y su scope\n\n' +
32
+ '| Agente | Scope | Cuándo usarlo |\n' +
33
+ '|--------|-------|---------------|\n' +
34
+ rows.join('\n') + '\n\n' +
35
+ '> Invocar el agente del scope correcto, no el orchestrator, para tareas acotadas.\n\n');
36
+ }
37
+ function renderPhases(config) {
38
+ const sprint = config.sprint ?? {};
39
+ const current = sprint.current ?? 1;
40
+ const phases = sprint.phases ?? [];
41
+ if (phases.length === 0) {
42
+ return `- **Sprint actual:** Sprint ${current}\n- **Completadas:** —\n- **En curso:** —\n- **Pendientes:** —`;
43
+ }
44
+ const lines = [`- **Sprint actual:** Sprint ${current}`];
45
+ for (const phase of phases) {
46
+ const specs = phase.specs ?? [];
47
+ const specList = specs.length > 0 ? specs.join(', ') : '—';
48
+ lines.push(`- **Fase ${phase.id} — ${phase.name}** (${phase.status ?? 'pendiente'}): ${specList}`);
49
+ }
50
+ return lines.join('\n');
51
+ }
52
+ function devCommands(language) {
53
+ switch (language) {
54
+ case 'typescript': return { dev: 'pnpm dev', test: 'pnpm test', lint: 'pnpm lint', build: 'pnpm build' };
55
+ case 'python': return { dev: 'uvicorn main:app --reload', test: 'pytest', lint: 'ruff check .', build: '# no aplica' };
56
+ case 'ruby': return { dev: 'rails server', test: 'bundle exec rspec', lint: 'rubocop', build: '# no aplica' };
57
+ case 'go': return { dev: 'go run ./cmd/...', test: 'go test ./...', lint: 'golangci-lint run', build: 'go build ./...' };
58
+ case 'php': return { dev: 'php artisan serve', test: './vendor/bin/pest', lint: 'vendor/bin/phpstan analyse', build: 'composer install --no-dev' };
59
+ default: return { dev: '# ver documentación', test: '# ver documentación', lint: '# ver documentación', build: '# ver documentación' };
60
+ }
61
+ }
62
+ export function generateClaudeMd(config) {
63
+ const proj = config.project;
64
+ const stack = config.stack ?? {};
65
+ const agents = config.agents ?? {};
66
+ const compliance = config.compliance ?? {};
67
+ const paths = config.paths;
68
+ const name = proj.name ?? 'Mi Proyecto';
69
+ const description = proj.description ?? '';
70
+ const language = proj.language ?? 'typescript';
71
+ const { dev, test, lint, build } = devCommands(language);
72
+ const specsPath = paths?.specs ?? 'docs/specs';
73
+ const progressPath = paths?.progress ?? 'docs/progress.html';
74
+ const agentScopeSection = buildAgentScopeTable(agents, paths);
75
+ const complianceSection = compliance.frameworks && compliance.frameworks.length > 0
76
+ ? `\n## Compliance activo\n\nEste proyecto opera bajo:\n${compliance.frameworks.map(f => `- **${f.toUpperCase()}**`).join('\n')}\n\nReglas no-negociables:\n- Sin datos personales en logs de stdout\n- Consentimiento explícito antes de cualquier tracker no esencial\n- Logs de auditoría append-only (sin UPDATE/DELETE)\n`
77
+ : '';
78
+ return `# CLAUDE.md — ${name}
79
+
80
+ > Generado por forge. Actualizar project.yaml para cambiar la configuración.
81
+
82
+ ## Misión del proyecto
83
+
84
+ ${description}
85
+
86
+ ## Stack
87
+
88
+ - **Lenguaje**: ${language}
89
+ - **Backend**: ${stack.backend ?? 'N/A'}
90
+ - **Frontend**: ${stack.frontend ?? 'N/A'}
91
+ - **Base de datos**: ${stack.database ?? 'N/A'}
92
+ - **Testing**: ${(stack.testing ?? []).join(', ')}
93
+
94
+ ${agentScopeSection}## Estructura
95
+
96
+ \`\`\`
97
+ ${proj.slug ?? 'proyecto'}/
98
+ ├── CLAUDE.md ← Estás acá
99
+ ├── project.yaml ← Config de forge (fuente de verdad)
100
+ ├── ${specsPath}/ ← Specs de features (requeridas antes de implementar)
101
+ └── ${progressPath} ← Dashboard de progreso
102
+ \`\`\`
103
+
104
+ ## Cómo trabajar (SDD)
105
+
106
+ 1. **Identificá la spec.** Si no está en \`${specsPath}/\`, pará y pedí que se cree.
107
+ 2. **Leé la spec correspondiente.**
108
+ 3. **Proponé opciones** para decisiones no cubiertas por la spec.
109
+ 4. **Esperá aprobación** antes de generar código.
110
+ 5. **Tests** junto con la implementación, no al final.
111
+ 6. **Antes de cerrar**: \`${test}\`, \`${lint}\`.
112
+ ${complianceSection}
113
+ ## Phases activas y estado
114
+
115
+ ${renderPhases(config)}
116
+
117
+ ## Comandos frecuentes
118
+
119
+ \`\`\`bash
120
+ ${dev} # Desarrollo
121
+ ${test} # Tests
122
+ ${lint} # Lint
123
+ ${build} # Build
124
+ \`\`\`
125
+
126
+ ## Qué NO hacer
127
+
128
+ - No implementar sin spec en \`${specsPath}/\`
129
+ - No hardcodear tokens, passwords o secrets
130
+ - No commits con \`console.log\` o \`print\` de depuración
131
+ - No hacer force push a main/master
132
+ `;
133
+ }
134
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/lib/generators/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ProjectYaml } from '../yaml.js';
2
+ export declare function generateCodexAgentsMd(config: ProjectYaml): string;
3
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../../src/lib/generators/codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAsEjE"}