@samahlstrom/forge-cli 0.1.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 (100) hide show
  1. package/README.md +175 -0
  2. package/bin/forge.js +2 -0
  3. package/dist/addons/index.d.ts +25 -0
  4. package/dist/addons/index.js +139 -0
  5. package/dist/addons/index.js.map +1 -0
  6. package/dist/commands/add.d.ts +1 -0
  7. package/dist/commands/add.js +61 -0
  8. package/dist/commands/add.js.map +1 -0
  9. package/dist/commands/doctor.d.ts +1 -0
  10. package/dist/commands/doctor.js +177 -0
  11. package/dist/commands/doctor.js.map +1 -0
  12. package/dist/commands/ingest.d.ts +24 -0
  13. package/dist/commands/ingest.js +316 -0
  14. package/dist/commands/ingest.js.map +1 -0
  15. package/dist/commands/init.d.ts +8 -0
  16. package/dist/commands/init.js +557 -0
  17. package/dist/commands/init.js.map +1 -0
  18. package/dist/commands/remove.d.ts +1 -0
  19. package/dist/commands/remove.js +42 -0
  20. package/dist/commands/remove.js.map +1 -0
  21. package/dist/commands/status.d.ts +1 -0
  22. package/dist/commands/status.js +48 -0
  23. package/dist/commands/status.js.map +1 -0
  24. package/dist/commands/upgrade.d.ts +5 -0
  25. package/dist/commands/upgrade.js +190 -0
  26. package/dist/commands/upgrade.js.map +1 -0
  27. package/dist/detect/features.d.ts +10 -0
  28. package/dist/detect/features.js +33 -0
  29. package/dist/detect/features.js.map +1 -0
  30. package/dist/detect/go.d.ts +3 -0
  31. package/dist/detect/go.js +38 -0
  32. package/dist/detect/go.js.map +1 -0
  33. package/dist/detect/index.d.ts +25 -0
  34. package/dist/detect/index.js +32 -0
  35. package/dist/detect/index.js.map +1 -0
  36. package/dist/detect/node.d.ts +3 -0
  37. package/dist/detect/node.js +99 -0
  38. package/dist/detect/node.js.map +1 -0
  39. package/dist/detect/python.d.ts +3 -0
  40. package/dist/detect/python.js +86 -0
  41. package/dist/detect/python.js.map +1 -0
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +51 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/render/engine.d.ts +8 -0
  46. package/dist/render/engine.js +71 -0
  47. package/dist/render/engine.js.map +1 -0
  48. package/dist/render/merge.d.ts +5 -0
  49. package/dist/render/merge.js +33 -0
  50. package/dist/render/merge.js.map +1 -0
  51. package/dist/utils/fs.d.ts +8 -0
  52. package/dist/utils/fs.js +42 -0
  53. package/dist/utils/fs.js.map +1 -0
  54. package/dist/utils/git.d.ts +3 -0
  55. package/dist/utils/git.js +31 -0
  56. package/dist/utils/git.js.map +1 -0
  57. package/dist/utils/hash.d.ts +8 -0
  58. package/dist/utils/hash.js +22 -0
  59. package/dist/utils/hash.js.map +1 -0
  60. package/dist/utils/yaml.d.ts +3 -0
  61. package/dist/utils/yaml.js +12 -0
  62. package/dist/utils/yaml.js.map +1 -0
  63. package/package.json +53 -0
  64. package/templates/addons/beads-dolt-backend/files/dolt-setup.sh +267 -0
  65. package/templates/addons/beads-dolt-backend/manifest.yaml +13 -0
  66. package/templates/addons/browser-testing/files/browser-smoke.sh +196 -0
  67. package/templates/addons/browser-testing/files/visual-qa.md +103 -0
  68. package/templates/addons/browser-testing/manifest.yaml +20 -0
  69. package/templates/addons/compliance-hipaa/files/hipaa-checks.sh +184 -0
  70. package/templates/addons/compliance-hipaa/files/hipaa-context.md +91 -0
  71. package/templates/addons/compliance-hipaa/manifest.yaml +15 -0
  72. package/templates/addons/compliance-soc2/files/soc2-checks.sh +232 -0
  73. package/templates/addons/compliance-soc2/files/soc2-context.md +147 -0
  74. package/templates/addons/compliance-soc2/manifest.yaml +15 -0
  75. package/templates/core/CLAUDE.md.hbs +70 -0
  76. package/templates/core/agents/architect.md.hbs +68 -0
  77. package/templates/core/agents/backend.md.hbs +27 -0
  78. package/templates/core/agents/frontend.md.hbs +25 -0
  79. package/templates/core/agents/quality.md.hbs +40 -0
  80. package/templates/core/agents/security.md.hbs +53 -0
  81. package/templates/core/context/project.md.hbs +60 -0
  82. package/templates/core/forge.yaml.hbs +69 -0
  83. package/templates/core/hooks/post-edit.sh.hbs +8 -0
  84. package/templates/core/hooks/pre-edit.sh.hbs +41 -0
  85. package/templates/core/hooks/session-start.sh.hbs +34 -0
  86. package/templates/core/pipeline/classify.sh.hbs +159 -0
  87. package/templates/core/pipeline/decompose.md.hbs +100 -0
  88. package/templates/core/pipeline/deliver.sh.hbs +171 -0
  89. package/templates/core/pipeline/execute.md.hbs +138 -0
  90. package/templates/core/pipeline/intake.sh.hbs +152 -0
  91. package/templates/core/pipeline/orchestrator.sh.hbs +361 -0
  92. package/templates/core/pipeline/verify.sh.hbs +160 -0
  93. package/templates/core/settings.json.hbs +55 -0
  94. package/templates/core/skill-creator.md.hbs +151 -0
  95. package/templates/core/skill-deliver.md.hbs +46 -0
  96. package/templates/core/skill-ingest.md.hbs +245 -0
  97. package/templates/presets/go/stack.md.hbs +133 -0
  98. package/templates/presets/python-fastapi/stack.md.hbs +101 -0
  99. package/templates/presets/react-next-ts/stack.md.hbs +77 -0
  100. package/templates/presets/sveltekit-ts/stack.md.hbs +116 -0
@@ -0,0 +1,557 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { join, resolve, extname, basename } from 'node:path';
4
+ import { detect } from '../detect/index.js';
5
+ import { render } from '../render/engine.js';
6
+ import { exists, readText, writeText, ensureDir } from '../utils/fs.js';
7
+ import { hashContent, writeHashes } from '../utils/hash.js';
8
+ import { resolveTemplatePath } from '../utils/fs.js';
9
+ import { analyzeSpecForInit } from './ingest.js';
10
+ import { copyFile } from 'node:fs/promises';
11
+ const AVAILABLE_PRESETS = ['sveltekit-ts', 'react-next-ts', 'python-fastapi', 'go'];
12
+ // Maps user-friendly language + framework choices to presets and default commands
13
+ const LANGUAGE_OPTIONS = [
14
+ { value: 'typescript', label: 'TypeScript' },
15
+ { value: 'javascript', label: 'JavaScript' },
16
+ { value: 'python', label: 'Python' },
17
+ { value: 'go', label: 'Go' },
18
+ ];
19
+ const FRAMEWORK_OPTIONS = {
20
+ typescript: [
21
+ { value: 'next', label: 'Next.js', preset: 'react-next-ts' },
22
+ { value: 'sveltekit', label: 'SvelteKit', preset: 'sveltekit-ts' },
23
+ { value: 'other', label: 'Other / None', preset: 'react-next-ts' },
24
+ ],
25
+ javascript: [
26
+ { value: 'next', label: 'Next.js', preset: 'react-next-ts' },
27
+ { value: 'sveltekit', label: 'SvelteKit', preset: 'sveltekit-ts' },
28
+ { value: 'other', label: 'Other / None', preset: 'react-next-ts' },
29
+ ],
30
+ python: [
31
+ { value: 'fastapi', label: 'FastAPI', preset: 'python-fastapi' },
32
+ { value: 'django', label: 'Django', preset: 'python-fastapi' },
33
+ { value: 'flask', label: 'Flask', preset: 'python-fastapi' },
34
+ { value: 'other', label: 'Other / None', preset: 'python-fastapi' },
35
+ ],
36
+ go: [
37
+ { value: 'gin', label: 'Gin', preset: 'go' },
38
+ { value: 'chi', label: 'Chi', preset: 'go' },
39
+ { value: 'fiber', label: 'Fiber', preset: 'go' },
40
+ { value: 'other', label: 'Other / None', preset: 'go' },
41
+ ],
42
+ };
43
+ const DEFAULT_COMMANDS = {
44
+ typescript: { typecheck: 'npx tsc --noEmit', lint: 'npm run lint', test: 'npx vitest run', format: 'npx prettier --write .', dev: 'npm run dev' },
45
+ javascript: { typecheck: 'echo "no typecheck"', lint: 'npm run lint', test: 'npx vitest run', format: 'npx prettier --write .', dev: 'npm run dev' },
46
+ python: { typecheck: 'mypy .', lint: 'ruff check .', test: 'pytest', format: 'ruff format .', dev: 'uvicorn app.main:app --reload' },
47
+ go: { typecheck: 'go vet ./...', lint: 'golangci-lint run', test: 'go test ./...', format: 'gofmt -w .', dev: 'go run .' },
48
+ };
49
+ export async function init(options) {
50
+ const cwd = process.cwd();
51
+ p.intro(chalk.bold('forge v0.1.0') + chalk.dim(' — Agent Harness for Claude Code'));
52
+ // Check for existing harness
53
+ if (!options.force && (await exists(join(cwd, 'forge.yaml')))) {
54
+ const shouldOverwrite = await p.confirm({
55
+ message: 'A forge.yaml already exists. Overwrite?',
56
+ initialValue: false,
57
+ });
58
+ if (p.isCancel(shouldOverwrite) || !shouldOverwrite) {
59
+ p.cancel('Init cancelled. Use --force to overwrite.');
60
+ process.exit(0);
61
+ }
62
+ }
63
+ // Phase 1: Detect
64
+ const spinner = p.spinner();
65
+ spinner.start('Scanning project...');
66
+ const detected = await detect(cwd);
67
+ spinner.stop('Scan complete');
68
+ displayDetected(detected, cwd);
69
+ // Phase 2: Spec analysis (if --spec provided)
70
+ let specAnalysis = null;
71
+ let specId = null;
72
+ if (options.spec) {
73
+ const specPath = resolve(options.spec);
74
+ if (!(await exists(specPath))) {
75
+ p.cancel(`Spec file not found: ${specPath}`);
76
+ process.exit(1);
77
+ }
78
+ spinner.start('Analyzing spec with Claude Code...');
79
+ try {
80
+ specAnalysis = await analyzeSpecForInit(specPath);
81
+ spinner.stop('Spec analysis complete');
82
+ }
83
+ catch (err) {
84
+ spinner.stop('Spec analysis failed');
85
+ p.log.warn(chalk.yellow(`Could not analyze spec: ${err}`));
86
+ p.log.warn(chalk.dim('Falling back to manual onboarding.'));
87
+ }
88
+ if (specAnalysis) {
89
+ const extractedLines = [
90
+ `Project: ${chalk.cyan(specAnalysis.project_name)}`,
91
+ `Description: ${chalk.cyan(specAnalysis.description)}`,
92
+ `Type: ${chalk.cyan(specAnalysis.project_type)}`,
93
+ `Language: ${chalk.cyan(specAnalysis.language)}`,
94
+ ];
95
+ if (specAnalysis.framework)
96
+ extractedLines.push(`Framework: ${chalk.cyan(specAnalysis.framework)}`);
97
+ if (specAnalysis.modules.length > 0)
98
+ extractedLines.push(`Modules: ${chalk.cyan(specAnalysis.modules.join(', '))}`);
99
+ extractedLines.push(`Architecture: ${chalk.cyan(specAnalysis.architecture)}`);
100
+ if (specAnalysis.sensitive_areas)
101
+ extractedLines.push(`Sensitive: ${chalk.cyan(specAnalysis.sensitive_areas)}`);
102
+ if (specAnalysis.constraints.length > 0)
103
+ extractedLines.push(`Constraints: ${chalk.cyan(specAnalysis.constraints.slice(0, 3).join('; '))}`);
104
+ p.note(extractedLines.join('\n'), 'Extracted from spec');
105
+ const confirmed = await p.confirm({ message: 'Does this look right?', initialValue: true });
106
+ if (p.isCancel(confirmed)) {
107
+ p.cancel('Cancelled.');
108
+ process.exit(0);
109
+ }
110
+ if (!confirmed) {
111
+ const corrections = await p.text({
112
+ message: 'What needs to change?',
113
+ placeholder: 'e.g. Use SvelteKit instead of Next.js',
114
+ });
115
+ if (p.isCancel(corrections)) {
116
+ p.cancel('Cancelled.');
117
+ process.exit(0);
118
+ }
119
+ if (corrections) {
120
+ spinner.start('Re-analyzing with corrections...');
121
+ try {
122
+ specAnalysis = await analyzeSpecForInit(specPath);
123
+ spinner.stop('Updated');
124
+ }
125
+ catch {
126
+ spinner.stop('Re-analysis failed, using original');
127
+ }
128
+ }
129
+ }
130
+ }
131
+ // Copy spec into .forge/specs/
132
+ const randomHex = (n) => Array.from(crypto.getRandomValues(new Uint8Array(n)), b => b.toString(16).padStart(2, '0')).join('');
133
+ specId = `spec-${randomHex(4)}`;
134
+ const specDir = join(cwd, '.forge', 'specs', specId);
135
+ await ensureDir(specDir);
136
+ await copyFile(specPath, join(specDir, `source${extname(specPath)}`));
137
+ if (specAnalysis) {
138
+ await writeText(join(specDir, 'analysis.json'), JSON.stringify(specAnalysis, null, 2));
139
+ }
140
+ await writeText(join(specDir, 'meta.json'), JSON.stringify({
141
+ spec_id: specId,
142
+ source: { file: basename(specPath), format: extname(specPath).replace('.', '') },
143
+ status: 'pending-analysis',
144
+ ingested_at: new Date().toISOString(),
145
+ }, null, 2));
146
+ }
147
+ // Phase 3: Confirm + ask questions (pre-filled from spec if available)
148
+ const answers = await askQuestions(detected, options, specAnalysis);
149
+ // Phase 4: Generate
150
+ spinner.start('Generating harness...');
151
+ const files = await generateHarness(cwd, detected, answers);
152
+ spinner.stop(`${files.length} files created`);
153
+ // Phase 5: Display results
154
+ displayResults(files, answers, specId);
155
+ p.log.warn(chalk.yellow('If you ran this inside Claude Code, restart the session so it picks up the new settings, skills, and hooks.'));
156
+ if (specId) {
157
+ p.outro(chalk.green('Harness ready!') + chalk.dim(` Run /ingest ${specId} in Claude Code to start.`));
158
+ }
159
+ else {
160
+ p.outro(chalk.green('Harness ready!') + chalk.dim(' Run /deliver in Claude Code to start.'));
161
+ }
162
+ }
163
+ function displayDetected(detected, cwd) {
164
+ const lines = [];
165
+ if (detected.language !== 'unknown') {
166
+ lines.push(`Language: ${chalk.cyan(detected.language)}`);
167
+ }
168
+ if (detected.framework) {
169
+ lines.push(`Framework: ${chalk.cyan(detected.framework)}`);
170
+ }
171
+ if (detected.testRunner) {
172
+ lines.push(`Testing: ${chalk.cyan(detected.testRunner.name)}`);
173
+ }
174
+ if (detected.linter) {
175
+ lines.push(`Linting: ${chalk.cyan(detected.linter.name)}`);
176
+ }
177
+ if (detected.typeChecker) {
178
+ lines.push(`Type check: ${chalk.cyan(detected.typeChecker.name)}`);
179
+ }
180
+ if (detected.features.git) {
181
+ lines.push(`VCS: ${chalk.cyan('Git')}`);
182
+ }
183
+ if (lines.length > 0) {
184
+ p.note(lines.join('\n'), 'Detected');
185
+ }
186
+ else {
187
+ p.log.warn('Could not auto-detect project stack. You will need to select a preset manually.');
188
+ }
189
+ }
190
+ async function askQuestions(detected, options, specAnalysis) {
191
+ const projectName = specAnalysis?.project_name ?? process.cwd().split('/').pop() ?? 'my-app';
192
+ const nothingDetected = detected.language === 'unknown';
193
+ // --- Stack selection ---
194
+ let preset = options.preset ?? null;
195
+ let chosenLanguage = detected.language !== 'unknown' ? detected.language : 'typescript';
196
+ let commands = { typecheck: '', lint: '', test: '', format: '', dev: '' };
197
+ // If spec analysis provided language/framework, use those
198
+ if (specAnalysis && !preset) {
199
+ chosenLanguage = specAnalysis.language || 'typescript';
200
+ // Map spec framework to preset
201
+ const frameworkMap = {
202
+ next: 'react-next-ts', sveltekit: 'sveltekit-ts',
203
+ fastapi: 'python-fastapi', django: 'python-fastapi', flask: 'python-fastapi',
204
+ gin: 'go', chi: 'go', fiber: 'go',
205
+ };
206
+ if (specAnalysis.framework && frameworkMap[specAnalysis.framework]) {
207
+ preset = frameworkMap[specAnalysis.framework];
208
+ }
209
+ else {
210
+ // Fall back to language default
211
+ const langPresets = {
212
+ typescript: 'react-next-ts', javascript: 'react-next-ts',
213
+ python: 'python-fastapi', go: 'go',
214
+ };
215
+ preset = langPresets[chosenLanguage] ?? 'react-next-ts';
216
+ }
217
+ }
218
+ else if (!preset && !options.yes) {
219
+ if (nothingDetected) {
220
+ // Empty repo — ask what they want to build
221
+ p.log.step('No existing code detected — let\'s set up your stack.');
222
+ const langAnswer = await p.select({
223
+ message: 'What language will you use?',
224
+ options: LANGUAGE_OPTIONS.map((o) => ({ value: o.value, label: o.label })),
225
+ });
226
+ if (p.isCancel(langAnswer)) {
227
+ p.cancel('Init cancelled.');
228
+ process.exit(0);
229
+ }
230
+ chosenLanguage = langAnswer;
231
+ const frameworks = FRAMEWORK_OPTIONS[chosenLanguage] ?? [];
232
+ if (frameworks.length > 0) {
233
+ const fwAnswer = await p.select({
234
+ message: 'What framework?',
235
+ options: frameworks.map((o) => ({ value: o.value, label: o.label })),
236
+ });
237
+ if (p.isCancel(fwAnswer)) {
238
+ p.cancel('Init cancelled.');
239
+ process.exit(0);
240
+ }
241
+ const chosen = frameworks.find((f) => f.value === fwAnswer);
242
+ preset = chosen?.preset ?? frameworks[0].preset;
243
+ }
244
+ }
245
+ else {
246
+ // Existing code detected — confirm or let them change
247
+ if (detected.preset) {
248
+ const confirmPreset = await p.confirm({
249
+ message: `Detected ${chalk.cyan(detected.preset)} — use this preset?`,
250
+ initialValue: true,
251
+ });
252
+ if (p.isCancel(confirmPreset)) {
253
+ p.cancel('Init cancelled.');
254
+ process.exit(0);
255
+ }
256
+ if (confirmPreset) {
257
+ preset = detected.preset;
258
+ }
259
+ }
260
+ if (!preset) {
261
+ const presetOptions = AVAILABLE_PRESETS.map((pr) => ({
262
+ value: pr,
263
+ label: pr + (pr === detected.preset ? chalk.dim(' (detected)') : ''),
264
+ }));
265
+ if (detected.preset) {
266
+ const idx = presetOptions.findIndex((o) => o.value === detected.preset);
267
+ if (idx > 0) {
268
+ const [match] = presetOptions.splice(idx, 1);
269
+ presetOptions.unshift(match);
270
+ }
271
+ }
272
+ const selected = await p.select({ message: 'Select preset:', options: presetOptions });
273
+ if (p.isCancel(selected)) {
274
+ p.cancel('Init cancelled.');
275
+ process.exit(0);
276
+ }
277
+ preset = selected;
278
+ }
279
+ }
280
+ }
281
+ // Fallback for --yes or if still null
282
+ if (!preset) {
283
+ preset = detected.preset ?? 'react-next-ts';
284
+ }
285
+ // --- Commands ---
286
+ // Use detected commands if available, otherwise fall back to language defaults
287
+ const langDefaults = DEFAULT_COMMANDS[chosenLanguage] ?? DEFAULT_COMMANDS.typescript;
288
+ commands = {
289
+ typecheck: detected.typeChecker?.command ?? langDefaults.typecheck,
290
+ lint: detected.linter?.command ?? langDefaults.lint,
291
+ test: detected.testRunner?.command ?? langDefaults.test,
292
+ format: detected.formatter?.command ?? langDefaults.format,
293
+ dev: langDefaults.dev,
294
+ };
295
+ if (!options.yes) {
296
+ p.note([
297
+ `Typecheck: ${chalk.cyan(commands.typecheck)}`,
298
+ `Lint: ${chalk.cyan(commands.lint)}`,
299
+ `Test: ${chalk.cyan(commands.test)}`,
300
+ commands.format ? `Format: ${chalk.cyan(commands.format)}` : null,
301
+ ]
302
+ .filter(Boolean)
303
+ .join('\n'), 'Verification commands (edit in forge.yaml later)');
304
+ }
305
+ // --- Auto-PR ---
306
+ const autoPr = options.yes
307
+ ? true
308
+ : await p.confirm({
309
+ message: 'Auto-create PRs on delivery?',
310
+ initialValue: true,
311
+ });
312
+ if (p.isCancel(autoPr)) {
313
+ p.cancel('Init cancelled.');
314
+ process.exit(0);
315
+ }
316
+ // --- Onboarding ---
317
+ // If spec analysis is available, use it to pre-fill; otherwise ask interactively
318
+ let projectDescription = specAnalysis?.description ?? '';
319
+ let projectType = specAnalysis?.project_type ?? 'web-app';
320
+ let keyModules = specAnalysis?.modules ?? [];
321
+ let architectureStyle = specAnalysis?.architecture ?? 'monolith';
322
+ let sensitivePaths = specAnalysis?.sensitive_areas ?? '';
323
+ let domainRules = specAnalysis?.domain_rules ?? '';
324
+ if (!options.yes && !specAnalysis) {
325
+ // No spec — ask everything interactively
326
+ p.log.step('Tell us about your project so agents understand what they\'re working on.');
327
+ const descAnswer = await p.text({
328
+ message: 'What are you building?',
329
+ placeholder: 'e.g. A SaaS platform for restaurant inventory management',
330
+ validate: (val) => {
331
+ if (!val.trim())
332
+ return 'A short description helps agents write better code.';
333
+ },
334
+ });
335
+ if (p.isCancel(descAnswer)) {
336
+ p.cancel('Init cancelled.');
337
+ process.exit(0);
338
+ }
339
+ projectDescription = descAnswer;
340
+ const typeAnswer = await p.select({
341
+ message: 'What kind of project is this?',
342
+ options: [
343
+ { value: 'web-app', label: 'Web application — frontend + backend' },
344
+ { value: 'api', label: 'API / Backend service — no frontend' },
345
+ { value: 'cli', label: 'CLI tool — command-line interface' },
346
+ { value: 'library', label: 'Library / Package — consumed by other projects' },
347
+ { value: 'automation', label: 'Automation / Scripts — GitHub Actions, bots, pipelines' },
348
+ { value: 'fullstack', label: 'Full-stack monorepo — multiple apps in one repo' },
349
+ ],
350
+ });
351
+ if (p.isCancel(typeAnswer)) {
352
+ p.cancel('Init cancelled.');
353
+ process.exit(0);
354
+ }
355
+ projectType = typeAnswer;
356
+ const modulesAnswer = await p.text({
357
+ message: 'What are the main features or modules?',
358
+ placeholder: 'e.g. auth, dashboard, inventory, notifications',
359
+ });
360
+ if (p.isCancel(modulesAnswer)) {
361
+ p.cancel('Init cancelled.');
362
+ process.exit(0);
363
+ }
364
+ keyModules = modulesAnswer.split(',').map((s) => s.trim()).filter(Boolean);
365
+ const archAnswer = await p.select({
366
+ message: 'How is the app structured?',
367
+ options: [
368
+ { value: 'monolith', label: 'Monolith — single deployable unit' },
369
+ { value: 'client-server', label: 'Client + Server — separate frontend and backend' },
370
+ { value: 'microservices', label: 'Microservices — multiple independent services' },
371
+ { value: 'static-site', label: 'Static site — pre-rendered or JAMstack' },
372
+ { value: 'library', label: 'Library / Package — consumed by other projects' },
373
+ ],
374
+ });
375
+ if (p.isCancel(archAnswer)) {
376
+ p.cancel('Init cancelled.');
377
+ process.exit(0);
378
+ }
379
+ architectureStyle = archAnswer;
380
+ const sensitiveAnswer = await p.text({
381
+ message: 'Any sensitive areas? (leave blank to skip)',
382
+ placeholder: 'e.g. src/auth/ handles tokens, src/payments/ has Stripe integration',
383
+ });
384
+ if (p.isCancel(sensitiveAnswer)) {
385
+ p.cancel('Init cancelled.');
386
+ process.exit(0);
387
+ }
388
+ sensitivePaths = sensitiveAnswer || '';
389
+ const domainAnswer = await p.text({
390
+ message: 'Any domain-specific rules agents should know? (leave blank to skip)',
391
+ placeholder: 'e.g. All prices stored in cents. Users always belong to exactly one org.',
392
+ });
393
+ if (p.isCancel(domainAnswer)) {
394
+ p.cancel('Init cancelled.');
395
+ process.exit(0);
396
+ }
397
+ domainRules = domainAnswer || '';
398
+ }
399
+ return {
400
+ preset,
401
+ commands,
402
+ autoPr: autoPr,
403
+ projectName,
404
+ projectDescription,
405
+ projectType,
406
+ keyModules,
407
+ architectureStyle,
408
+ sensitivePaths,
409
+ domainRules,
410
+ };
411
+ }
412
+ async function generateHarness(cwd, detected, answers) {
413
+ const ctx = buildTemplateContext(detected, answers);
414
+ const files = [];
415
+ const hashes = { version: '0.1.0', files: {} };
416
+ // Determine which agents to generate based on project type
417
+ const projectType = answers.projectType;
418
+ const needsFrontend = ['web-app', 'fullstack'].includes(projectType);
419
+ const needsBackend = ['web-app', 'api', 'fullstack', 'microservices'].includes(projectType);
420
+ // Define all files to generate: [templatePath, outputPath]
421
+ const fileMap = [
422
+ ['core/forge.yaml.hbs', 'forge.yaml'],
423
+ ['core/CLAUDE.md.hbs', 'CLAUDE.md'],
424
+ ['core/settings.json.hbs', '.claude/settings.json'],
425
+ ['core/skill-deliver.md.hbs', '.claude/skills/deliver/SKILL.md'],
426
+ ['core/skill-creator.md.hbs', '.claude/skills/skill-creator/SKILL.md'],
427
+ ['core/skill-ingest.md.hbs', '.claude/skills/ingest/SKILL.md'],
428
+ ['core/pipeline/orchestrator.sh.hbs', '.forge/pipeline/orchestrator.sh'],
429
+ ['core/pipeline/intake.sh.hbs', '.forge/pipeline/intake.sh'],
430
+ ['core/pipeline/classify.sh.hbs', '.forge/pipeline/classify.sh'],
431
+ ['core/pipeline/decompose.md.hbs', '.forge/pipeline/decompose.md'],
432
+ ['core/pipeline/execute.md.hbs', '.forge/pipeline/execute.md'],
433
+ ['core/pipeline/verify.sh.hbs', '.forge/pipeline/verify.sh'],
434
+ ['core/pipeline/deliver.sh.hbs', '.forge/pipeline/deliver.sh'],
435
+ ['core/agents/architect.md.hbs', '.forge/agents/architect.md'],
436
+ ['core/agents/quality.md.hbs', '.forge/agents/quality.md'],
437
+ ['core/agents/security.md.hbs', '.forge/agents/security.md'],
438
+ ['core/context/project.md.hbs', '.forge/context/project.md'],
439
+ ['core/hooks/pre-edit.sh.hbs', '.forge/hooks/pre-edit.sh'],
440
+ ['core/hooks/post-edit.sh.hbs', '.forge/hooks/post-edit.sh'],
441
+ ['core/hooks/session-start.sh.hbs', '.forge/hooks/session-start.sh'],
442
+ ];
443
+ // Add agents based on project type
444
+ if (needsFrontend) {
445
+ fileMap.push(['core/agents/frontend.md.hbs', '.forge/agents/frontend.md']);
446
+ }
447
+ if (needsBackend) {
448
+ fileMap.push(['core/agents/backend.md.hbs', '.forge/agents/backend.md']);
449
+ }
450
+ // Add stack-specific context from preset
451
+ const presetContextPath = `presets/${answers.preset}/stack.md.hbs`;
452
+ fileMap.push([presetContextPath, '.forge/context/stack.md']);
453
+ for (const [templateRel, outputRel] of fileMap) {
454
+ const templatePath = resolveTemplatePath(templateRel);
455
+ let content;
456
+ try {
457
+ const template = await readText(templatePath);
458
+ content = render(template, ctx);
459
+ }
460
+ catch {
461
+ // Template doesn't exist yet — write a placeholder
462
+ content = `# ${outputRel}\n\n> Template not yet created: ${templateRel}\n> This file will be populated in a future phase.\n`;
463
+ }
464
+ const outputPath = join(cwd, outputRel);
465
+ await writeText(outputPath, content);
466
+ files.push({ relativePath: outputRel, content });
467
+ hashes.files[outputRel] = hashContent(content);
468
+ // Make shell scripts executable
469
+ if (outputRel.endsWith('.sh')) {
470
+ const { chmod } = await import('node:fs/promises');
471
+ await chmod(outputPath, 0o755);
472
+ }
473
+ }
474
+ // Create empty directories
475
+ await ensureDir(join(cwd, '.forge', 'addons'));
476
+ await ensureDir(join(cwd, '.forge', 'state'));
477
+ await ensureDir(join(cwd, '.forge', 'pipeline', 'runs'));
478
+ // Write .gitkeep for state
479
+ await writeText(join(cwd, '.forge', 'state', '.gitkeep'), '');
480
+ // Write hash manifest
481
+ await writeHashes(cwd, hashes);
482
+ // Initialize bd (beads) for task tracking
483
+ try {
484
+ const { execaCommand } = await import('execa');
485
+ await execaCommand('bd init --quiet', { cwd, shell: true, timeout: 15000 });
486
+ await execaCommand('bd setup claude', { cwd, shell: true, timeout: 15000 });
487
+ }
488
+ catch {
489
+ // bd not installed — that's OK, user can install later
490
+ }
491
+ return files;
492
+ }
493
+ function buildTemplateContext(detected, answers) {
494
+ const projectType = answers.projectType;
495
+ const needsFrontend = ['web-app', 'fullstack'].includes(projectType);
496
+ const needsBackend = ['web-app', 'api', 'fullstack', 'microservices'].includes(projectType);
497
+ const agents = ['architect', 'quality', 'security'];
498
+ if (needsFrontend)
499
+ agents.push('frontend');
500
+ if (needsBackend)
501
+ agents.push('backend');
502
+ return {
503
+ project: {
504
+ name: answers.projectName,
505
+ preset: answers.preset,
506
+ },
507
+ commands: answers.commands,
508
+ agents,
509
+ has_frontend: needsFrontend,
510
+ has_backend: needsBackend,
511
+ has_format: Boolean(answers.commands.format),
512
+ auto_pr: answers.autoPr,
513
+ detected: {
514
+ language: detected.language,
515
+ framework: detected.framework,
516
+ features: detected.features,
517
+ },
518
+ // Preset-specific context
519
+ preset: answers.preset,
520
+ is_sveltekit: answers.preset === 'sveltekit-ts',
521
+ is_nextjs: answers.preset === 'react-next-ts',
522
+ is_fastapi: answers.preset === 'python-fastapi',
523
+ is_go: answers.preset === 'go',
524
+ // Onboarding context
525
+ onboarding: {
526
+ description: answers.projectDescription,
527
+ projectType: answers.projectType,
528
+ modules: answers.keyModules,
529
+ architecture: answers.architectureStyle,
530
+ sensitivePaths: answers.sensitivePaths,
531
+ domainRules: answers.domainRules,
532
+ },
533
+ has_sensitive: Boolean(answers.sensitivePaths),
534
+ has_domain_rules: Boolean(answers.domainRules),
535
+ has_modules: answers.keyModules.length > 0,
536
+ };
537
+ }
538
+ function displayResults(files, answers, specId) {
539
+ const lines = files.map((f) => ` ${chalk.green('✓')} ${f.relativePath}`);
540
+ p.note(lines.join('\n'), `Generated (${files.length} files)`);
541
+ p.log.step('Next steps:');
542
+ p.log.message(` 1. Review ${chalk.cyan('.forge/context/project.md')} — verify your project context`);
543
+ p.log.message(` 2. ${chalk.dim('git add forge.yaml CLAUDE.md .claude .forge')}`);
544
+ p.log.message(` 3. ${chalk.dim('git commit -m "forge: initialize agent harness"')}`);
545
+ if (specId) {
546
+ p.log.message(` 4. Open Claude Code → ${chalk.cyan(`/ingest ${specId}`)}`);
547
+ }
548
+ else {
549
+ p.log.message(` 4. Open Claude Code → ${chalk.cyan('/deliver "your first task"')}`);
550
+ }
551
+ p.log.message('');
552
+ p.log.message(` ${chalk.dim('Optional:')}`);
553
+ p.log.message(` ${chalk.dim('forge add browser-testing')} — Playwright visual QA`);
554
+ p.log.message(` ${chalk.dim('forge add compliance-hipaa')} — HIPAA security checks`);
555
+ p.log.message(` ${chalk.dim('forge doctor')} — Verify harness health`);
556
+ }
557
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function remove(addon: string): Promise<void>;
@@ -0,0 +1,42 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ import { join } from 'node:path';
4
+ import { exists } from '../utils/fs.js';
5
+ import { isValidAddon, uninstallAddon } from '../addons/index.js';
6
+ export async function remove(addon) {
7
+ const cwd = process.cwd();
8
+ p.intro(chalk.bold(`forge remove ${addon}`));
9
+ if (!isValidAddon(addon)) {
10
+ p.log.error(`Unknown addon: "${addon}"`);
11
+ process.exit(1);
12
+ }
13
+ if (!(await exists(join(cwd, 'forge.yaml')))) {
14
+ p.log.error('No forge.yaml found. Run `forge init` first.');
15
+ process.exit(1);
16
+ }
17
+ // Check if installed
18
+ const { readYaml } = await import('../utils/yaml.js');
19
+ const config = await readYaml(join(cwd, 'forge.yaml'));
20
+ const addons = config.addons ?? [];
21
+ if (!addons.includes(addon)) {
22
+ p.log.warn(`Addon "${addon}" is not installed.`);
23
+ process.exit(0);
24
+ }
25
+ const spinner = p.spinner();
26
+ spinner.start(`Removing ${addon}...`);
27
+ try {
28
+ const removedFiles = await uninstallAddon(addon, cwd);
29
+ for (const file of removedFiles) {
30
+ p.log.success(`Deleted ${file}`);
31
+ }
32
+ p.log.success('Updated forge.yaml');
33
+ spinner.stop(`${addon} removed`);
34
+ }
35
+ catch (err) {
36
+ spinner.stop('Removal failed');
37
+ p.log.error(String(err));
38
+ process.exit(1);
39
+ }
40
+ p.outro(chalk.green('Done!'));
41
+ }
42
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAa;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC,CAAC;IAE7C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,KAAK,GAAG,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,qBAAqB;IACrB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAA0B,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAChF,MAAM,MAAM,GAAI,MAAM,CAAC,MAAmB,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,KAAK,qBAAqB,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC;IAEtC,IAAI,CAAC;QACJ,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEtD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAEpC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC/B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function status(): Promise<void>;