forge-dev-framework 1.1.0 → 1.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.
- package/.claude/commands/forge/README.md +156 -189
- package/.claude/commands/forge/add-phase.md +4 -3
- package/.claude/commands/forge/complete-milestone.md +1 -1
- package/.claude/commands/forge/convert.md +31 -0
- package/.claude/commands/forge/debug.md +12 -154
- package/.claude/commands/forge/discuss.md +60 -107
- package/.claude/commands/forge/execute.md +67 -142
- package/.claude/commands/forge/generate.md +8 -107
- package/.claude/commands/forge/help.md +9 -114
- package/.claude/commands/forge/init.md +10 -74
- package/.claude/commands/forge/insert-phase.md +4 -3
- package/.claude/commands/forge/new-milestone.md +1 -1
- package/.claude/commands/forge/new-project.md +12 -91
- package/.claude/commands/forge/pause-work.md +2 -2
- package/.claude/commands/forge/plan.md +114 -129
- package/.claude/commands/forge/quick.md +17 -106
- package/.claude/commands/forge/remove-phase.md +3 -2
- package/.claude/commands/forge/resume.md +22 -0
- package/.claude/commands/forge/team-add.md +24 -0
- package/.claude/commands/forge/team-create.md +22 -0
- package/.claude/commands/forge/team-remove.md +24 -0
- package/.claude/commands/forge/team-start.md +22 -0
- package/.claude/commands/forge/team-view.md +18 -0
- package/.claude/commands/forge/verify.md +68 -147
- package/.claude/hooks/forge-context-cleanup.cjs +79 -0
- package/.claude/hooks/forge-event-guard.cjs +36 -0
- package/.claude/hooks/forge-size-guard.cjs +55 -0
- package/.claude/rules/api-patterns.md +13 -98
- package/.claude/rules/context-efficiency.md +10 -0
- package/.claude/rules/security-baseline.md +18 -204
- package/.claude/rules/testing-standards.md +16 -177
- package/.claude/rules/ui-conventions.md +17 -142
- package/bin/forge.js +5 -3
- package/dist/bin/forge.js +5 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +15 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/convert.d.ts +6 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +132 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +3 -2
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/index.d.ts +4 -4
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +4 -4
- package/dist/commands/index.js.map +1 -1
- package/dist/generators/gsd-converter.d.ts +100 -0
- package/dist/generators/gsd-converter.d.ts.map +1 -0
- package/dist/generators/gsd-converter.js +335 -0
- package/dist/generators/gsd-converter.js.map +1 -0
- package/dist/templates/.claude/rules/api-patterns.md.template +212 -0
- package/dist/templates/.claude/rules/security-baseline.md.template +322 -0
- package/dist/templates/.claude/rules/testing-standards.md.template +280 -0
- package/dist/templates/.claude/rules/ui-conventions.md.template +264 -0
- package/dist/templates/.planning/forge.config.json.template +75 -0
- package/dist/templates/CLAUDE.md.template +161 -0
- package/dist/templates/PLAN.md.template +177 -0
- package/dist/templates/PROJECT.md.template +156 -0
- package/dist/templates/REQUIREMENTS.md.template +221 -0
- package/dist/templates/ROADMAP.md.template +130 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +5 -5
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -5
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/template-client.d.ts.map +1 -1
- package/dist/utils/template-client.js +3 -2
- package/dist/utils/template-client.js.map +1 -1
- package/package.json +6 -4
- package/.claude/commands/forge/resume-work.md +0 -122
- package/dist/git/__tests__/worktree.test.d.ts +0 -5
- package/dist/git/__tests__/worktree.test.d.ts.map +0 -1
- package/dist/git/__tests__/worktree.test.js +0 -121
- package/dist/git/__tests__/worktree.test.js.map +0 -1
- package/dist/git/codeowners.d.ts +0 -101
- package/dist/git/codeowners.d.ts.map +0 -1
- package/dist/git/codeowners.js +0 -216
- package/dist/git/codeowners.js.map +0 -1
- package/dist/git/commit.d.ts +0 -135
- package/dist/git/commit.d.ts.map +0 -1
- package/dist/git/commit.js +0 -223
- package/dist/git/commit.js.map +0 -1
- package/dist/git/hooks/commit-msg.d.ts +0 -8
- package/dist/git/hooks/commit-msg.d.ts.map +0 -1
- package/dist/git/hooks/commit-msg.js +0 -34
- package/dist/git/hooks/commit-msg.js.map +0 -1
- package/dist/git/hooks/pre-commit.d.ts +0 -8
- package/dist/git/hooks/pre-commit.d.ts.map +0 -1
- package/dist/git/hooks/pre-commit.js +0 -34
- package/dist/git/hooks/pre-commit.js.map +0 -1
- package/dist/git/pre-commit-hooks.d.ts +0 -117
- package/dist/git/pre-commit-hooks.d.ts.map +0 -1
- package/dist/git/pre-commit-hooks.js +0 -270
- package/dist/git/pre-commit-hooks.js.map +0 -1
- package/dist/git/wipe-protocol.d.ts +0 -281
- package/dist/git/wipe-protocol.d.ts.map +0 -1
- package/dist/git/wipe-protocol.js +0 -237
- package/dist/git/wipe-protocol.js.map +0 -1
- package/dist/git/worktree.d.ts +0 -69
- package/dist/git/worktree.d.ts.map +0 -1
- package/dist/git/worktree.js +0 -202
- package/dist/git/worktree.js.map +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ForgeCommand } from './base.js';
|
|
2
|
+
import { convertGSDToForge, detectGSDProject } from '../generators/gsd-converter.js';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export class ConvertCommand extends ForgeCommand {
|
|
6
|
+
register() {
|
|
7
|
+
this.program
|
|
8
|
+
.command('convert')
|
|
9
|
+
.description('Convert GSD project to FORGE format')
|
|
10
|
+
.option('-d, --dry-run', 'Preview changes without modifying files')
|
|
11
|
+
.option('-v, --verbose', 'Show detailed conversion output')
|
|
12
|
+
.option('-f, --force', 'Force conversion even if FORGE files exist')
|
|
13
|
+
.action((options) => this.execute(options));
|
|
14
|
+
}
|
|
15
|
+
async execute(options) {
|
|
16
|
+
const projectPath = process.cwd();
|
|
17
|
+
this.logger.header('FORGE — GSD to FORGE Converter');
|
|
18
|
+
// Detect GSD project
|
|
19
|
+
this.logger.info('Detecting GSD project...');
|
|
20
|
+
const gsdInfo = await detectGSDProject(projectPath);
|
|
21
|
+
if (!gsdInfo.hasProjectMd && !gsdInfo.hasPlanningDir) {
|
|
22
|
+
this.logger.error('Not a GSD project');
|
|
23
|
+
this.logger.info('Expected: PROJECT.md or .planning/ directory');
|
|
24
|
+
this.logger.info('Use "forge init" to initialize a new FORGE project.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Show detected project info
|
|
28
|
+
this.logger.success('Found GSD project');
|
|
29
|
+
console.log();
|
|
30
|
+
console.log(chalk.cyan(' Project Information:'));
|
|
31
|
+
console.log(` Name: ${gsdInfo.name || path.basename(projectPath)}`);
|
|
32
|
+
console.log(` PROJECT.md: ${gsdInfo.hasProjectMd ? chalk.green('✓') : chalk.red('✗')}`);
|
|
33
|
+
console.log(` ROADMAP.md: ${gsdInfo.hasRoadmapMd ? chalk.green('✓') : chalk.red('✗')}`);
|
|
34
|
+
console.log(` .planning/: ${gsdInfo.hasPlanningDir ? chalk.green('✓') : chalk.red('✗')}`);
|
|
35
|
+
if (gsdInfo.phases.length > 0) {
|
|
36
|
+
console.log(` Phases: ${gsdInfo.phases.length} found`);
|
|
37
|
+
}
|
|
38
|
+
console.log();
|
|
39
|
+
// Check for existing FORGE files
|
|
40
|
+
const hasClaudeMd = gsdInfo.hasProjectMd; // Will be overwritten
|
|
41
|
+
const hasStateDir = true; // Will create it
|
|
42
|
+
if (!options.force && hasClaudeMd) {
|
|
43
|
+
// Check if it's already a FORGE project
|
|
44
|
+
const { readFile } = await import('fs/promises');
|
|
45
|
+
try {
|
|
46
|
+
const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
|
|
47
|
+
const content = await readFile(claudeMdPath, 'utf-8');
|
|
48
|
+
if (content.includes('FORGE')) {
|
|
49
|
+
this.logger.warning('This appears to already be a FORGE project');
|
|
50
|
+
this.logger.info('Use --force to overwrite existing FORGE files.');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// CLAUDE.md doesn't exist yet
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Dry run mode
|
|
59
|
+
if (options.dryRun) {
|
|
60
|
+
this.logger.info('Dry run mode — no files will be modified');
|
|
61
|
+
console.log();
|
|
62
|
+
const result = await convertGSDToForge(projectPath, {
|
|
63
|
+
dryRun: true,
|
|
64
|
+
verbose: options.verbose,
|
|
65
|
+
});
|
|
66
|
+
if (result.success) {
|
|
67
|
+
this.logger.success(result.message);
|
|
68
|
+
if (result.warnings.length > 0) {
|
|
69
|
+
console.log();
|
|
70
|
+
this.logger.warning('Warnings:');
|
|
71
|
+
result.warnings.forEach((w) => console.log(chalk.yellow(` ⚠ ${w}`)));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.logger.error(result.message);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Confirm conversion
|
|
80
|
+
if (process.stdout.isTTY) {
|
|
81
|
+
const inquirer = await import('inquirer');
|
|
82
|
+
const { confirm } = await inquirer.default.prompt([
|
|
83
|
+
{
|
|
84
|
+
type: 'confirm',
|
|
85
|
+
name: 'confirm',
|
|
86
|
+
message: 'Convert this GSD project to FORGE?',
|
|
87
|
+
default: true,
|
|
88
|
+
},
|
|
89
|
+
]);
|
|
90
|
+
if (!confirm) {
|
|
91
|
+
this.logger.info('Conversion cancelled.');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Perform conversion
|
|
96
|
+
this.logger.info('Converting GSD project to FORGE...');
|
|
97
|
+
console.log();
|
|
98
|
+
const result = await convertGSDToForge(projectPath, {
|
|
99
|
+
dryRun: false,
|
|
100
|
+
verbose: options.verbose,
|
|
101
|
+
});
|
|
102
|
+
if (result.success) {
|
|
103
|
+
this.logger.success(result.message);
|
|
104
|
+
console.log();
|
|
105
|
+
if (result.filesCreated.length > 0) {
|
|
106
|
+
console.log(chalk.cyan('Files created:'));
|
|
107
|
+
result.filesCreated.forEach((file) => {
|
|
108
|
+
const relPath = path.relative(projectPath, file);
|
|
109
|
+
console.log(chalk.green(` ✓ ${relPath}`));
|
|
110
|
+
});
|
|
111
|
+
console.log();
|
|
112
|
+
}
|
|
113
|
+
if (result.warnings.length > 0) {
|
|
114
|
+
this.logger.warning('Warnings:');
|
|
115
|
+
result.warnings.forEach((w) => console.log(chalk.yellow(` ⚠ ${w}`)));
|
|
116
|
+
console.log();
|
|
117
|
+
}
|
|
118
|
+
// Next steps
|
|
119
|
+
console.log(chalk.cyan('Next steps:'));
|
|
120
|
+
console.log(` ${chalk.dim('1.')} Review the generated CLAUDE.md`);
|
|
121
|
+
console.log(` ${chalk.dim('2.')} Run ${chalk.cyan('/forge:status')} to verify the conversion`);
|
|
122
|
+
console.log(` ${chalk.dim('3.')} Run ${chalk.cyan('/forge:plan <phase-number>')} to create detailed task plans`);
|
|
123
|
+
console.log(` ${chalk.dim('Tip:')} Use ${chalk.cyan('/clear')} to start from a fresh context`);
|
|
124
|
+
console.log();
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.logger.error(result.message);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/commands/convert.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAMzC;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,QAAQ,IAAI,IAAI;IASV,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAMzC;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,QAAQ,IAAI,IAAI;IASV,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA6F5D;;OAEG;YACW,WAAW;IA4CzB;;OAEG;IACH,OAAO,CAAC,QAAQ;CAajB"}
|
|
@@ -61,8 +61,9 @@ export class GenerateCommand extends ForgeCommand {
|
|
|
61
61
|
logger.info('Available artifacts: claude, project, requirements, roadmap, plan, config, rules');
|
|
62
62
|
process.exit(1);
|
|
63
63
|
}
|
|
64
|
-
// Check if template exists
|
|
65
|
-
const
|
|
64
|
+
// Check if template exists — look in package install dir first, then project
|
|
65
|
+
const packageTemplatesDir = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', 'templates');
|
|
66
|
+
const templatePath = path.join(packageTemplatesDir, target.template);
|
|
66
67
|
const fs = await import('fs/promises');
|
|
67
68
|
try {
|
|
68
69
|
await fs.access(templatePath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC/C,QAAQ;QACN,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,qBAAqB,CAAC;aAC9B,WAAW,CAAC,oCAAoC,CAAC;aACjD,QAAQ,CAAC,YAAY,EAAE,oFAAoF,CAAC;aAC5G,MAAM,CAAC,aAAa,EAAE,yCAAyC,CAAC;aAChE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,OAAY;QAC1C,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAElC,uCAAuC;YACvC,MAAM,WAAW,GAAmF;gBAClG,MAAM,EAAE;oBACN,QAAQ,EAAE,oBAAoB;oBAC9B,MAAM,EAAE,WAAW;oBACnB,cAAc,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,WAAW,CAAC;iBACvD;gBACD,OAAO,EAAE;oBACP,QAAQ,EAAE,qBAAqB;oBAC/B,MAAM,EAAE,YAAY;oBACpB,cAAc,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,WAAW,CAAC;iBACvD;gBACD,YAAY,EAAE;oBACZ,QAAQ,EAAE,0BAA0B;oBACpC,MAAM,EAAE,iBAAiB;oBACzB,cAAc,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC;iBAC9D;gBACD,OAAO,EAAE;oBACP,QAAQ,EAAE,qBAAqB;oBAC/B,MAAM,EAAE,YAAY;oBACpB,cAAc,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,QAAQ,CAAC;iBACxD;gBACD,IAAI,EAAE;oBACJ,QAAQ,EAAE,kBAAkB;oBAC5B,MAAM,EAAE,SAAS;oBACjB,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,CAAC;iBAC7C;gBACD,MAAM,EAAE;oBACN,QAAQ,EAAE,4BAA4B;oBACtC,MAAM,EAAE,6BAA6B;oBACrC,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC;iBAC/D;gBACD,KAAK,EAAE;oBACL,QAAQ,EAAE,6BAA6B;oBACvC,MAAM,EAAE,gBAAgB;oBACxB,cAAc,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;iBACtC;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAC,kFAAkF,CAAC,CAAC;gBAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FORGE Command Exports
|
|
3
3
|
*/
|
|
4
|
-
export * from './base';
|
|
5
|
-
export * from './help';
|
|
6
|
-
export * from './status';
|
|
7
|
-
export * from './config';
|
|
4
|
+
export * from './base.js';
|
|
5
|
+
export * from './help.js';
|
|
6
|
+
export * from './status.js';
|
|
7
|
+
export * from './config.js';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
package/dist/commands/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* FORGE Command Exports
|
|
3
3
|
*/
|
|
4
|
-
export * from './base';
|
|
5
|
-
export * from './help';
|
|
6
|
-
export * from './status';
|
|
7
|
-
export * from './config';
|
|
4
|
+
export * from './base.js';
|
|
5
|
+
export * from './help.js';
|
|
6
|
+
export * from './status.js';
|
|
7
|
+
export * from './config.js';
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD to FORGE Project Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts existing GSD projects to FORGE format by:
|
|
5
|
+
* 1. Reading GSD artifacts (PROJECT.md, ROADMAP.md, phase plans)
|
|
6
|
+
* 2. Creating FORGE equivalents (CLAUDE.md, STATE.json)
|
|
7
|
+
* 3. Preserving roadmap and phase structure
|
|
8
|
+
*
|
|
9
|
+
* @private - Not published to NPM
|
|
10
|
+
*/
|
|
11
|
+
interface LocalTask {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
ownerRole: string;
|
|
15
|
+
status: 'pending' | 'in_progress' | 'completed' | 'blocked';
|
|
16
|
+
deps: string[];
|
|
17
|
+
allowedPaths: string[];
|
|
18
|
+
acceptance: string[];
|
|
19
|
+
verify: string[];
|
|
20
|
+
commit: string | null;
|
|
21
|
+
requests: string[];
|
|
22
|
+
priority: number;
|
|
23
|
+
blockedBy: string[];
|
|
24
|
+
blocks: string[];
|
|
25
|
+
assignedTo: string | null;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
startedAt: string | null;
|
|
28
|
+
completedAt: string | null;
|
|
29
|
+
}
|
|
30
|
+
interface LocalProjectState {
|
|
31
|
+
name: string;
|
|
32
|
+
status: string;
|
|
33
|
+
currentMilestone: string;
|
|
34
|
+
currentPhase: number;
|
|
35
|
+
updatedAt: string;
|
|
36
|
+
}
|
|
37
|
+
interface LocalForgeState {
|
|
38
|
+
project: LocalProjectState;
|
|
39
|
+
tasks: LocalTask[];
|
|
40
|
+
contracts: Array<{
|
|
41
|
+
id: string;
|
|
42
|
+
path: string;
|
|
43
|
+
version: string;
|
|
44
|
+
publishedBy: string;
|
|
45
|
+
consumers: string[];
|
|
46
|
+
publishedAt?: string;
|
|
47
|
+
status?: string;
|
|
48
|
+
}>;
|
|
49
|
+
eventsPointer: string;
|
|
50
|
+
}
|
|
51
|
+
export interface GSDProjectInfo {
|
|
52
|
+
name: string;
|
|
53
|
+
hasProjectMd: boolean;
|
|
54
|
+
hasRoadmapMd: boolean;
|
|
55
|
+
hasPlanningDir: boolean;
|
|
56
|
+
phases: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface ConversionResult {
|
|
59
|
+
success: boolean;
|
|
60
|
+
message: string;
|
|
61
|
+
filesCreated: string[];
|
|
62
|
+
warnings: string[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Detect if current directory is a GSD project
|
|
66
|
+
*/
|
|
67
|
+
export declare function detectGSDProject(projectPath: string): Promise<GSDProjectInfo>;
|
|
68
|
+
/**
|
|
69
|
+
* Extract project metadata from PROJECT.md
|
|
70
|
+
*/
|
|
71
|
+
export declare function extractProjectMetadata(projectPath: string): Promise<{
|
|
72
|
+
name: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
techStack?: string[];
|
|
75
|
+
team?: string[];
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
* Generate CLAUDE.md from PROJECT.md content
|
|
79
|
+
*/
|
|
80
|
+
export declare function generateClaudeMd(projectPath: string): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Extract tasks from GSD phase plans and convert to FORGE tasks
|
|
83
|
+
*/
|
|
84
|
+
export declare function extractTasksFromPhases(projectPath: string): Promise<{
|
|
85
|
+
currentMilestone: string;
|
|
86
|
+
tasks: LocalTask[];
|
|
87
|
+
}>;
|
|
88
|
+
/**
|
|
89
|
+
* Create initial STATE.json for FORGE project
|
|
90
|
+
*/
|
|
91
|
+
export declare function createForgeState(projectName: string, tasks: LocalTask[]): Promise<LocalForgeState>;
|
|
92
|
+
/**
|
|
93
|
+
* Main conversion function
|
|
94
|
+
*/
|
|
95
|
+
export declare function convertGSDToForge(projectPath: string, options?: {
|
|
96
|
+
dryRun?: boolean;
|
|
97
|
+
verbose?: boolean;
|
|
98
|
+
}): Promise<ConversionResult>;
|
|
99
|
+
export {};
|
|
100
|
+
//# sourceMappingURL=gsd-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gsd-converter.d.ts","sourceRoot":"","sources":["../../src/generators/gsd-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSD to FORGE Project Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts existing GSD projects to FORGE format by:
|
|
5
|
+
* 1. Reading GSD artifacts (PROJECT.md, ROADMAP.md, phase plans)
|
|
6
|
+
* 2. Creating FORGE equivalents (CLAUDE.md, STATE.json)
|
|
7
|
+
* 3. Preserving roadmap and phase structure
|
|
8
|
+
*
|
|
9
|
+
* @private - Not published to NPM
|
|
10
|
+
*/
|
|
11
|
+
import { readFile, writeFile, mkdir, access, readdir } from 'fs/promises';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
|
+
import { existsSync } from 'fs';
|
|
14
|
+
/**
|
|
15
|
+
* Detect if current directory is a GSD project
|
|
16
|
+
*/
|
|
17
|
+
export async function detectGSDProject(projectPath) {
|
|
18
|
+
const projectMdPath = join(projectPath, 'PROJECT.md');
|
|
19
|
+
const roadmapMdPath = join(projectPath, 'ROADMAP.md');
|
|
20
|
+
const planningDir = join(projectPath, '.planning');
|
|
21
|
+
const info = {
|
|
22
|
+
name: '',
|
|
23
|
+
hasProjectMd: false,
|
|
24
|
+
hasRoadmapMd: false,
|
|
25
|
+
hasPlanningDir: false,
|
|
26
|
+
phases: [],
|
|
27
|
+
};
|
|
28
|
+
// Check for PROJECT.md
|
|
29
|
+
try {
|
|
30
|
+
await access(projectMdPath);
|
|
31
|
+
info.hasProjectMd = true;
|
|
32
|
+
const content = await readFile(projectMdPath, 'utf-8');
|
|
33
|
+
// Extract project name from first line or title
|
|
34
|
+
const nameMatch = content.match(/^#\s+(.+)$/m) || content.match(/^# Project: (.+)$/m);
|
|
35
|
+
if (nameMatch) {
|
|
36
|
+
info.name = nameMatch[1].trim();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// PROJECT.md doesn't exist
|
|
41
|
+
}
|
|
42
|
+
// Check for ROADMAP.md
|
|
43
|
+
try {
|
|
44
|
+
await access(roadmapMdPath);
|
|
45
|
+
info.hasRoadmapMd = true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ROADMAP.md doesn't exist
|
|
49
|
+
}
|
|
50
|
+
// Check for .planning directory and phases
|
|
51
|
+
try {
|
|
52
|
+
await access(planningDir);
|
|
53
|
+
info.hasPlanningDir = true;
|
|
54
|
+
// List phases
|
|
55
|
+
const phasesDir = join(planningDir, 'phases');
|
|
56
|
+
try {
|
|
57
|
+
await access(phasesDir);
|
|
58
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
59
|
+
info.phases = entries
|
|
60
|
+
.filter((e) => e.name.endsWith('.md') || e.isDirectory())
|
|
61
|
+
.map((e) => e.name)
|
|
62
|
+
.sort();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// phases directory doesn't exist
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// .planning directory doesn't exist
|
|
70
|
+
}
|
|
71
|
+
return info;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract project metadata from PROJECT.md
|
|
75
|
+
*/
|
|
76
|
+
export async function extractProjectMetadata(projectPath) {
|
|
77
|
+
const projectMdPath = join(projectPath, 'PROJECT.md');
|
|
78
|
+
const metadata = {
|
|
79
|
+
name: '',
|
|
80
|
+
description: '',
|
|
81
|
+
techStack: [],
|
|
82
|
+
team: [],
|
|
83
|
+
};
|
|
84
|
+
try {
|
|
85
|
+
const content = await readFile(projectMdPath, 'utf-8');
|
|
86
|
+
// Extract name from title
|
|
87
|
+
const nameMatch = content.match(/^#\s+(.+)$/m);
|
|
88
|
+
if (nameMatch) {
|
|
89
|
+
metadata.name = nameMatch[1].trim();
|
|
90
|
+
}
|
|
91
|
+
// Extract description (usually after title)
|
|
92
|
+
const descMatch = content.match(/^#\s+.+\n+(.+)$/m);
|
|
93
|
+
if (descMatch) {
|
|
94
|
+
metadata.description = descMatch[1].trim();
|
|
95
|
+
}
|
|
96
|
+
// Extract tech stack (looks for "Tech Stack" or similar section)
|
|
97
|
+
const techStackMatch = content.match(/##?\s*(?:Tech Stack|Technology Stack|Stack)\n+([\s\S]+?)(?=\n##|\n*$)/i);
|
|
98
|
+
if (techStackMatch) {
|
|
99
|
+
const techLines = techStackMatch[1]
|
|
100
|
+
.split('\n')
|
|
101
|
+
.map((line) => line.replace(/^[\s\-\*]+/, '').trim())
|
|
102
|
+
.filter((line) => line.length > 0);
|
|
103
|
+
metadata.techStack = techLines;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// PROJECT.md doesn't exist or couldn't be read
|
|
108
|
+
}
|
|
109
|
+
return metadata;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Generate CLAUDE.md from PROJECT.md content
|
|
113
|
+
*/
|
|
114
|
+
export async function generateClaudeMd(projectPath) {
|
|
115
|
+
const projectMdPath = join(projectPath, 'PROJECT.md');
|
|
116
|
+
let projectMdContent = '';
|
|
117
|
+
try {
|
|
118
|
+
projectMdContent = await readFile(projectMdPath, 'utf-8');
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// PROJECT.md doesn't exist, use template
|
|
122
|
+
}
|
|
123
|
+
const metadata = await extractProjectMetadata(projectPath);
|
|
124
|
+
// Build CLAUDE.md content
|
|
125
|
+
let claudeMd = `# ${metadata.name || 'FORGE Project'}\n\n`;
|
|
126
|
+
claudeMd += `> **Converted from GSD.** This project was migrated from GSD to FORGE.\n`;
|
|
127
|
+
claudeMd += `> Conversion date: ${new Date().toISOString()}\n\n`;
|
|
128
|
+
// Add tech stack if available
|
|
129
|
+
if (metadata.techStack && metadata.techStack.length > 0) {
|
|
130
|
+
claudeMd += `## Tech Stack\n\n`;
|
|
131
|
+
metadata.techStack.forEach((tech) => {
|
|
132
|
+
claudeMd += `- ${tech}\n`;
|
|
133
|
+
});
|
|
134
|
+
claudeMd += `\n`;
|
|
135
|
+
}
|
|
136
|
+
// Add FORGE-specific sections
|
|
137
|
+
claudeMd += `## Core Architecture\n\n`;
|
|
138
|
+
claudeMd += `### Event-Sourced State\n\n`;
|
|
139
|
+
claudeMd += `FORGE uses an **append-only event log** with **single-writer state derivation**:\n\n`;
|
|
140
|
+
claudeMd += `1. All agents write events to \`state/events/\`\n`;
|
|
141
|
+
claudeMd += `2. State Steward (ARCHITECT) merges events → canonical \`STATE.json\`\n`;
|
|
142
|
+
claudeMd += `3. Events are **never modified**, only appended\n`;
|
|
143
|
+
claudeMd += `4. State is **deterministically replayable** from event log\n\n`;
|
|
144
|
+
claudeMd += `### Command System\n\n`;
|
|
145
|
+
claudeMd += `FORGE provides slash commands for Claude Code:\n\n`;
|
|
146
|
+
claudeMd += `\`\`\`\n`;
|
|
147
|
+
claudeMd += `/forge:new-project # Initialize new FORGE project\n`;
|
|
148
|
+
claudeMd += `/forge:init # Initialize FORGE in current directory\n`;
|
|
149
|
+
claudeMd += `/forge:status # Show project progress\n`;
|
|
150
|
+
claudeMd += `/forge:config # View/edit configuration\n`;
|
|
151
|
+
claudeMd += `/forge:discuss # Capture phase context\n`;
|
|
152
|
+
claudeMd += `/forge:plan # Generate task breakdown\n`;
|
|
153
|
+
claudeMd += `/forge:verify # Verify plan against requirements\n`;
|
|
154
|
+
claudeMd += `/forge:execute # Execute phase with agent teams\n`;
|
|
155
|
+
claudeMd += `/forge:generate # Generate artifact from template\n`;
|
|
156
|
+
claudeMd += `/forge:help # Show command reference\n`;
|
|
157
|
+
claudeMd += `\`\`\`\n\n`;
|
|
158
|
+
claudeMd += `### The Wipe Protocol\n\n`;
|
|
159
|
+
claudeMd += `Agent context is **ephemeral**, git is **persistent**:\n\n`;
|
|
160
|
+
claudeMd += `1. **Hydrate** — Agent reads CLAUDE.md + STATE.json + task + contracts\n`;
|
|
161
|
+
claudeMd += `2. **Execute** — Agent writes code, runs tests\n`;
|
|
162
|
+
claudeMd += `3. **Commit** — Atomic git commit (one task = one commit)\n`;
|
|
163
|
+
claudeMd += `4. **Terminate** — Session ends, context wiped\n`;
|
|
164
|
+
claudeMd += `5. **Reincarnate** — Next task starts with fresh context\n\n`;
|
|
165
|
+
claudeMd += `## Hard Rules\n\n`;
|
|
166
|
+
claudeMd += `### 5-6 Task Limit\n\n`;
|
|
167
|
+
claudeMd += `Each teammate gets **maximum 6 atomic tasks per phase**.\n\n`;
|
|
168
|
+
claudeMd += `### Atomic Commits\n\n`;
|
|
169
|
+
claudeMd += `**Every task = one git commit.** No exceptions.\n\n`;
|
|
170
|
+
claudeMd += `Commit format: \`type(scope): description\`\n\n`;
|
|
171
|
+
// Include original PROJECT.md content as appendix
|
|
172
|
+
if (projectMdContent) {
|
|
173
|
+
claudeMd += `\n---\n\n## Original GSD Content\n\n`;
|
|
174
|
+
claudeMd += `The following content was preserved from the original GSD PROJECT.md:\n\n`;
|
|
175
|
+
claudeMd += projectMdContent;
|
|
176
|
+
}
|
|
177
|
+
return claudeMd;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Extract tasks from GSD phase plans and convert to FORGE tasks
|
|
181
|
+
*/
|
|
182
|
+
export async function extractTasksFromPhases(projectPath) {
|
|
183
|
+
const phasesDir = join(projectPath, '.planning', 'phases');
|
|
184
|
+
const tasks = [];
|
|
185
|
+
let currentMilestone = 'v1.0-M1';
|
|
186
|
+
let taskId = 1;
|
|
187
|
+
try {
|
|
188
|
+
await access(phasesDir);
|
|
189
|
+
const entries = await readdir(phasesDir, { withFileTypes: true });
|
|
190
|
+
for (const entry of entries.filter((e) => e.isFile())) {
|
|
191
|
+
const phasePath = join(phasesDir, entry.name);
|
|
192
|
+
const phaseContent = await readFile(phasePath, 'utf-8');
|
|
193
|
+
// Extract tasks from phase plan
|
|
194
|
+
// GSD phase plans typically have tasks as list items or under "Tasks" section
|
|
195
|
+
const taskMatches = phaseContent.matchAll(/^[\s]*(?:[-*+]|\d+\.)\s+\[?\[?(?:task|Task)?\]?\]?\s*(.+?)(?:\s+\[([^\]]+)\])?$/gm);
|
|
196
|
+
for (const match of taskMatches) {
|
|
197
|
+
const taskTitle = match[1]?.trim() || '';
|
|
198
|
+
const taskOwner = match[2]?.trim() || 'unassigned';
|
|
199
|
+
if (taskTitle.length > 0 && !taskTitle.toLowerCase().includes('optional')) {
|
|
200
|
+
tasks.push({
|
|
201
|
+
id: `task-${String(taskId).padStart(3, '0')}`,
|
|
202
|
+
title: taskTitle,
|
|
203
|
+
ownerRole: taskOwner,
|
|
204
|
+
status: 'pending',
|
|
205
|
+
deps: [],
|
|
206
|
+
allowedPaths: [],
|
|
207
|
+
acceptance: [],
|
|
208
|
+
verify: [],
|
|
209
|
+
commit: null,
|
|
210
|
+
requests: [],
|
|
211
|
+
priority: 5,
|
|
212
|
+
blockedBy: [],
|
|
213
|
+
blocks: [],
|
|
214
|
+
assignedTo: null,
|
|
215
|
+
createdAt: new Date().toISOString(),
|
|
216
|
+
startedAt: null,
|
|
217
|
+
completedAt: null,
|
|
218
|
+
});
|
|
219
|
+
taskId++;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// No phases directory or couldn't read
|
|
226
|
+
}
|
|
227
|
+
return { currentMilestone, tasks };
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create initial STATE.json for FORGE project
|
|
231
|
+
*/
|
|
232
|
+
export async function createForgeState(projectName, tasks) {
|
|
233
|
+
const projectState = {
|
|
234
|
+
name: projectName,
|
|
235
|
+
status: 'in_progress',
|
|
236
|
+
currentMilestone: 'v1.0-M1',
|
|
237
|
+
currentPhase: 1,
|
|
238
|
+
updatedAt: new Date().toISOString(),
|
|
239
|
+
};
|
|
240
|
+
return {
|
|
241
|
+
project: projectState,
|
|
242
|
+
tasks,
|
|
243
|
+
contracts: [],
|
|
244
|
+
eventsPointer: 'state/events/',
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Main conversion function
|
|
249
|
+
*/
|
|
250
|
+
export async function convertGSDToForge(projectPath, options = {}) {
|
|
251
|
+
const result = {
|
|
252
|
+
success: false,
|
|
253
|
+
message: '',
|
|
254
|
+
filesCreated: [],
|
|
255
|
+
warnings: [],
|
|
256
|
+
};
|
|
257
|
+
const log = (msg) => {
|
|
258
|
+
if (options.verbose) {
|
|
259
|
+
console.log(`[convert] ${msg}`);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
// Detect GSD project
|
|
263
|
+
log('Detecting GSD project...');
|
|
264
|
+
const gsdInfo = await detectGSDProject(projectPath);
|
|
265
|
+
if (!gsdInfo.hasProjectMd && !gsdInfo.hasPlanningDir) {
|
|
266
|
+
result.message = 'Not a GSD project: No PROJECT.md or .planning/ directory found.';
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
log(`Found GSD project: ${gsdInfo.name || projectPath}`);
|
|
270
|
+
log(` - PROJECT.md: ${gsdInfo.hasProjectMd}`);
|
|
271
|
+
log(` - ROADMAP.md: ${gsdInfo.hasRoadmapMd}`);
|
|
272
|
+
log(` - Phases: ${gsdInfo.phases.length}`);
|
|
273
|
+
if (options.dryRun) {
|
|
274
|
+
result.success = true;
|
|
275
|
+
result.message = 'Dry run completed. No files modified.';
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
// Create FORGE directory structure
|
|
279
|
+
const stateDir = join(projectPath, 'state');
|
|
280
|
+
const eventsDir = join(stateDir, 'events');
|
|
281
|
+
const contractsDir = join(projectPath, 'contracts');
|
|
282
|
+
const claudeRulesDir = join(projectPath, '.claude', 'rules');
|
|
283
|
+
for (const dir of [stateDir, eventsDir, contractsDir, claudeRulesDir]) {
|
|
284
|
+
if (!existsSync(dir)) {
|
|
285
|
+
await mkdir(dir, { recursive: true });
|
|
286
|
+
result.filesCreated.push(dir);
|
|
287
|
+
log(`Created directory: ${dir}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// Generate CLAUDE.md
|
|
291
|
+
log('Generating CLAUDE.md...');
|
|
292
|
+
const claudeMd = await generateClaudeMd(projectPath);
|
|
293
|
+
const claudeMdPath = join(projectPath, 'CLAUDE.md');
|
|
294
|
+
await writeFile(claudeMdPath, claudeMd, 'utf-8');
|
|
295
|
+
result.filesCreated.push(claudeMdPath);
|
|
296
|
+
log(`Created: ${claudeMdPath}`);
|
|
297
|
+
// Extract tasks and create STATE.json
|
|
298
|
+
log('Extracting tasks from phase plans...');
|
|
299
|
+
const { currentMilestone, tasks } = await extractTasksFromPhases(projectPath);
|
|
300
|
+
const projectName = gsdInfo.name || 'Forge Project';
|
|
301
|
+
log(`Extracted ${tasks.length} tasks from ${gsdInfo.phases.length} phase plans`);
|
|
302
|
+
const forgeState = await createForgeState(projectName, tasks);
|
|
303
|
+
const stateJsonPath = join(stateDir, 'STATE.json');
|
|
304
|
+
await writeFile(stateJsonPath, JSON.stringify(forgeState, null, 2), 'utf-8');
|
|
305
|
+
result.filesCreated.push(stateJsonPath);
|
|
306
|
+
log(`Created: ${stateJsonPath}`);
|
|
307
|
+
// Create forge.config.json
|
|
308
|
+
log('Creating forge.config.json...');
|
|
309
|
+
const config = {
|
|
310
|
+
mode: 'interactive',
|
|
311
|
+
depth: 'standard',
|
|
312
|
+
maxTeammates: 5,
|
|
313
|
+
taskLimit: 6,
|
|
314
|
+
conventionalCommits: true,
|
|
315
|
+
worktreeIsolation: true,
|
|
316
|
+
convertedFrom: 'GSD',
|
|
317
|
+
convertedAt: new Date().toISOString(),
|
|
318
|
+
};
|
|
319
|
+
const configPath = join(projectPath, '.planning', 'forge.config.json');
|
|
320
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
321
|
+
await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
322
|
+
result.filesCreated.push(configPath);
|
|
323
|
+
log(`Created: ${configPath}`);
|
|
324
|
+
// Warnings
|
|
325
|
+
if (!gsdInfo.hasRoadmapMd) {
|
|
326
|
+
result.warnings.push('No ROADMAP.md found. You may need to create one manually.');
|
|
327
|
+
}
|
|
328
|
+
if (tasks.length === 0) {
|
|
329
|
+
result.warnings.push('No tasks found in phase plans. You may need to run `forge plan <phase>` to create tasks.');
|
|
330
|
+
}
|
|
331
|
+
result.success = true;
|
|
332
|
+
result.message = `Successfully converted GSD project to FORGE. Created ${result.filesCreated.length} files.`;
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=gsd-converter.js.map
|