forge-dev-framework 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/.claude/rules/api-patterns.md +98 -0
  2. package/.claude/rules/security-baseline.md +204 -0
  3. package/.claude/rules/testing-standards.md +177 -0
  4. package/.claude/rules/ui-conventions.md +142 -0
  5. package/README.md +261 -0
  6. package/bin/forge.js +14 -0
  7. package/dist/bin/forge.js +14 -0
  8. package/dist/cli/index.d.ts +22 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +116 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/commands/base.d.ts +31 -0
  13. package/dist/commands/base.d.ts.map +1 -0
  14. package/dist/commands/base.js +31 -0
  15. package/dist/commands/base.js.map +1 -0
  16. package/dist/commands/config.d.ts +14 -0
  17. package/dist/commands/config.d.ts.map +1 -0
  18. package/dist/commands/config.js +175 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/generate.d.ts +17 -0
  21. package/dist/commands/generate.d.ts.map +1 -0
  22. package/dist/commands/generate.js +159 -0
  23. package/dist/commands/generate.js.map +1 -0
  24. package/dist/commands/help.d.ts +11 -0
  25. package/dist/commands/help.d.ts.map +1 -0
  26. package/dist/commands/help.js +65 -0
  27. package/dist/commands/help.js.map +1 -0
  28. package/dist/commands/index.d.ts +8 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +8 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/init.d.ts +10 -0
  33. package/dist/commands/init.d.ts.map +1 -0
  34. package/dist/commands/init.js +22 -0
  35. package/dist/commands/init.js.map +1 -0
  36. package/dist/commands/status.d.ts +13 -0
  37. package/dist/commands/status.d.ts.map +1 -0
  38. package/dist/commands/status.js +101 -0
  39. package/dist/commands/status.js.map +1 -0
  40. package/dist/commands/stubs.d.ts +14 -0
  41. package/dist/commands/stubs.d.ts.map +1 -0
  42. package/dist/commands/stubs.js +30 -0
  43. package/dist/commands/stubs.js.map +1 -0
  44. package/dist/generators/index.d.ts +11 -0
  45. package/dist/generators/index.d.ts.map +1 -0
  46. package/dist/generators/index.js +10 -0
  47. package/dist/generators/index.js.map +1 -0
  48. package/dist/generators/required-fields.d.ts +74 -0
  49. package/dist/generators/required-fields.d.ts.map +1 -0
  50. package/dist/generators/required-fields.js +179 -0
  51. package/dist/generators/required-fields.js.map +1 -0
  52. package/dist/generators/template-engine.d.ts +65 -0
  53. package/dist/generators/template-engine.d.ts.map +1 -0
  54. package/dist/generators/template-engine.js +209 -0
  55. package/dist/generators/template-engine.js.map +1 -0
  56. package/dist/generators/token-validator.d.ts +51 -0
  57. package/dist/generators/token-validator.d.ts.map +1 -0
  58. package/dist/generators/token-validator.js +141 -0
  59. package/dist/generators/token-validator.js.map +1 -0
  60. package/dist/generators/types.d.ts +433 -0
  61. package/dist/generators/types.d.ts.map +1 -0
  62. package/dist/generators/types.js +5 -0
  63. package/dist/generators/types.js.map +1 -0
  64. package/dist/generators/xml-task-generator.d.ts +67 -0
  65. package/dist/generators/xml-task-generator.d.ts.map +1 -0
  66. package/dist/generators/xml-task-generator.js +297 -0
  67. package/dist/generators/xml-task-generator.js.map +1 -0
  68. package/dist/git/__tests__/worktree.test.d.ts +5 -0
  69. package/dist/git/__tests__/worktree.test.d.ts.map +1 -0
  70. package/dist/git/__tests__/worktree.test.js +121 -0
  71. package/dist/git/__tests__/worktree.test.js.map +1 -0
  72. package/dist/git/codeowners.d.ts +101 -0
  73. package/dist/git/codeowners.d.ts.map +1 -0
  74. package/dist/git/codeowners.js +216 -0
  75. package/dist/git/codeowners.js.map +1 -0
  76. package/dist/git/commit.d.ts +135 -0
  77. package/dist/git/commit.d.ts.map +1 -0
  78. package/dist/git/commit.js +223 -0
  79. package/dist/git/commit.js.map +1 -0
  80. package/dist/git/hooks/commit-msg.d.ts +8 -0
  81. package/dist/git/hooks/commit-msg.d.ts.map +1 -0
  82. package/dist/git/hooks/commit-msg.js +34 -0
  83. package/dist/git/hooks/commit-msg.js.map +1 -0
  84. package/dist/git/hooks/pre-commit.d.ts +8 -0
  85. package/dist/git/hooks/pre-commit.d.ts.map +1 -0
  86. package/dist/git/hooks/pre-commit.js +34 -0
  87. package/dist/git/hooks/pre-commit.js.map +1 -0
  88. package/dist/git/pre-commit-hooks.d.ts +117 -0
  89. package/dist/git/pre-commit-hooks.d.ts.map +1 -0
  90. package/dist/git/pre-commit-hooks.js +270 -0
  91. package/dist/git/pre-commit-hooks.js.map +1 -0
  92. package/dist/git/wipe-protocol.d.ts +281 -0
  93. package/dist/git/wipe-protocol.d.ts.map +1 -0
  94. package/dist/git/wipe-protocol.js +237 -0
  95. package/dist/git/wipe-protocol.js.map +1 -0
  96. package/dist/git/worktree.d.ts +69 -0
  97. package/dist/git/worktree.d.ts.map +1 -0
  98. package/dist/git/worktree.js +202 -0
  99. package/dist/git/worktree.js.map +1 -0
  100. package/dist/scripts/install.d.ts +8 -0
  101. package/dist/scripts/install.d.ts.map +1 -0
  102. package/dist/scripts/install.js +161 -0
  103. package/dist/scripts/install.js.map +1 -0
  104. package/dist/types/config.d.ts +30 -0
  105. package/dist/types/config.d.ts.map +1 -0
  106. package/dist/types/config.js +23 -0
  107. package/dist/types/config.js.map +1 -0
  108. package/dist/types/index.d.ts +6 -0
  109. package/dist/types/index.d.ts.map +1 -0
  110. package/dist/types/index.js +6 -0
  111. package/dist/types/index.js.map +1 -0
  112. package/dist/types/state.d.ts +56 -0
  113. package/dist/types/state.d.ts.map +1 -0
  114. package/dist/types/state.js +6 -0
  115. package/dist/types/state.js.map +1 -0
  116. package/dist/utils/config.d.ts +15 -0
  117. package/dist/utils/config.d.ts.map +1 -0
  118. package/dist/utils/config.js +80 -0
  119. package/dist/utils/config.js.map +1 -0
  120. package/dist/utils/errors.d.ts +25 -0
  121. package/dist/utils/errors.d.ts.map +1 -0
  122. package/dist/utils/errors.js +48 -0
  123. package/dist/utils/errors.js.map +1 -0
  124. package/dist/utils/index.d.ts +11 -0
  125. package/dist/utils/index.d.ts.map +1 -0
  126. package/dist/utils/index.js +9 -0
  127. package/dist/utils/index.js.map +1 -0
  128. package/dist/utils/logger.d.ts +34 -0
  129. package/dist/utils/logger.d.ts.map +1 -0
  130. package/dist/utils/logger.js +73 -0
  131. package/dist/utils/logger.js.map +1 -0
  132. package/dist/utils/state-api.d.ts +128 -0
  133. package/dist/utils/state-api.d.ts.map +1 -0
  134. package/dist/utils/state-api.js +170 -0
  135. package/dist/utils/state-api.js.map +1 -0
  136. package/dist/utils/template-client.d.ts +73 -0
  137. package/dist/utils/template-client.d.ts.map +1 -0
  138. package/dist/utils/template-client.js +151 -0
  139. package/dist/utils/template-client.js.map +1 -0
  140. package/package.json +72 -0
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Git Worktree Management for FORGE
3
+ *
4
+ * Implements isolated worktree strategy for parallel agent execution.
5
+ * Each task gets its own worktree to prevent merge conflicts during development.
6
+ *
7
+ * Commands (from FORGE spec):
8
+ * - git worktree add .worktrees/{taskId} -b forge/{taskId}
9
+ * - git worktree remove .worktrees/{taskId}
10
+ */
11
+ import { execa } from "execa";
12
+ export class WorktreeError extends Error {
13
+ code;
14
+ constructor(message, code) {
15
+ super(message);
16
+ this.code = code;
17
+ this.name = "WorktreeError";
18
+ }
19
+ }
20
+ /**
21
+ * Create a new git worktree for a task.
22
+ *
23
+ * Creates a branch `forge/{taskId}` and checks it out into `.worktrees/{taskId}`.
24
+ * This gives each agent an isolated filesystem to work in.
25
+ *
26
+ * @param options - Task identification and branch configuration
27
+ * @returns Path to the new worktree
28
+ * @throws WorktreeError if worktree creation fails
29
+ */
30
+ export async function createWorktree(options) {
31
+ const { taskId, branchName = `forge/${taskId}`, baseBranch = "main" } = options;
32
+ const worktreePath = `.worktrees/${taskId}`;
33
+ try {
34
+ // Create the .worktrees directory if it doesn't exist
35
+ await execa("mkdir", ["-p", ".worktrees"]);
36
+ // Create the worktree with a new branch
37
+ await execa("git", ["worktree", "add", "-b", branchName, worktreePath, baseBranch]);
38
+ return worktreePath;
39
+ }
40
+ catch (error) {
41
+ if (error instanceof Error) {
42
+ throw new WorktreeError(`Failed to create worktree for task ${taskId}: ${error.message}`, error.code);
43
+ }
44
+ throw new WorktreeError(`Failed to create worktree for task ${taskId}`);
45
+ }
46
+ }
47
+ /**
48
+ * Get information about a worktree.
49
+ *
50
+ * @param taskId - Task ID to look up
51
+ * @returns Worktree information or null if not found
52
+ */
53
+ export async function getWorktree(taskId) {
54
+ try {
55
+ const { stdout } = await execa("git", ["worktree", "list", "--porcelain"]);
56
+ const lines = stdout.split("\n");
57
+ let currentPath = null;
58
+ let currentBranch = null;
59
+ let currentCommit = null;
60
+ for (const line of lines) {
61
+ if (line.startsWith("worktree ")) {
62
+ // Check if this is our target worktree
63
+ const path = line.slice("worktree ".length);
64
+ if (path.endsWith(`.worktrees/${taskId}`) || path.endsWith(`.worktrees/${taskId}/`)) {
65
+ currentPath = path;
66
+ }
67
+ }
68
+ else if (currentPath && line.startsWith("branch ")) {
69
+ currentBranch = line.slice("branch ".length).replace("refs/heads/", "");
70
+ }
71
+ else if (currentPath && line.startsWith("commit ")) {
72
+ currentCommit = line.slice("commit ".length);
73
+ }
74
+ else if (line === "") {
75
+ // End of a worktree block
76
+ if (currentPath && currentBranch && currentCommit) {
77
+ return {
78
+ taskId,
79
+ branchName: currentBranch,
80
+ path: currentPath,
81
+ commit: currentCommit,
82
+ };
83
+ }
84
+ // Reset
85
+ currentPath = null;
86
+ currentBranch = null;
87
+ currentCommit = null;
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ catch (error) {
93
+ throw new WorktreeError(`Failed to get worktree info for task ${taskId}`);
94
+ }
95
+ }
96
+ /**
97
+ * Merge a worktree's branch back into the base branch.
98
+ *
99
+ * Should only be called after CI passes. The worktree is removed after merge.
100
+ *
101
+ * @param taskId - Task ID whose branch to merge
102
+ * @param targetBranch - Branch to merge into (default: main)
103
+ * @throws WorktreeError if merge fails or has conflicts
104
+ */
105
+ export async function mergeWorktree(taskId, targetBranch = "main") {
106
+ const worktree = await getWorktree(taskId);
107
+ if (!worktree) {
108
+ throw new WorktreeError(`Worktree for task ${taskId} not found`);
109
+ }
110
+ try {
111
+ // Checkout the target branch in the main repository
112
+ await execa("git", ["checkout", targetBranch]);
113
+ // Merge the worktree branch
114
+ const branchName = worktree.branchName;
115
+ await execa("git", ["merge", "--no-ff", branchName, "-m", `Merge ${branchName} into ${targetBranch}`]);
116
+ // Clean up the worktree after successful merge
117
+ await cleanupWorktree(taskId);
118
+ }
119
+ catch (error) {
120
+ if (error instanceof Error) {
121
+ throw new WorktreeError(`Failed to merge worktree for task ${taskId}: ${error.message}`, error.code);
122
+ }
123
+ throw new WorktreeError(`Failed to merge worktree for task ${taskId}`);
124
+ }
125
+ }
126
+ /**
127
+ * Remove a worktree.
128
+ *
129
+ * Safely removes the worktree after cleaning up any uncommitted changes.
130
+ *
131
+ * @param taskId - Task ID whose worktree to remove
132
+ * @throws WorktreeError if removal fails
133
+ */
134
+ export async function cleanupWorktree(taskId) {
135
+ const worktree = await getWorktree(taskId);
136
+ if (!worktree) {
137
+ // Already cleaned up, nothing to do
138
+ return;
139
+ }
140
+ try {
141
+ // Remove the worktree
142
+ await execa("git", ["worktree", "remove", worktree.path]);
143
+ }
144
+ catch (error) {
145
+ if (error instanceof Error) {
146
+ throw new WorktreeError(`Failed to cleanup worktree for task ${taskId}: ${error.message}`, error.code);
147
+ }
148
+ throw new WorktreeError(`Failed to cleanup worktree for task ${taskId}`);
149
+ }
150
+ }
151
+ /**
152
+ * List all FORGE worktrees.
153
+ *
154
+ * @returns Array of worktree information for all active tasks
155
+ */
156
+ export async function listWorktrees() {
157
+ try {
158
+ const { stdout } = await execa("git", ["worktree", "list", "--porcelain"]);
159
+ const lines = stdout.split("\n");
160
+ const worktrees = [];
161
+ let currentPath = null;
162
+ let currentBranch = null;
163
+ let currentCommit = null;
164
+ for (const line of lines) {
165
+ if (line.startsWith("worktree ")) {
166
+ const path = line.slice("worktree ".length);
167
+ // Only include FORGE worktrees
168
+ if (path.includes(".worktrees/")) {
169
+ currentPath = path;
170
+ }
171
+ }
172
+ else if (currentPath && line.startsWith("branch ")) {
173
+ currentBranch = line.slice("branch ".length).replace("refs/heads/", "");
174
+ }
175
+ else if (currentPath && line.startsWith("commit ")) {
176
+ currentCommit = line.slice("commit ".length);
177
+ }
178
+ else if (line === "") {
179
+ // End of a worktree block
180
+ if (currentPath && currentBranch && currentCommit) {
181
+ // Extract taskId from path
182
+ const taskId = currentPath.match(/\.worktrees\/([^/]+)/)?.[1] || "unknown";
183
+ worktrees.push({
184
+ taskId,
185
+ branchName: currentBranch,
186
+ path: currentPath,
187
+ commit: currentCommit,
188
+ });
189
+ }
190
+ // Reset
191
+ currentPath = null;
192
+ currentBranch = null;
193
+ currentCommit = null;
194
+ }
195
+ }
196
+ return worktrees;
197
+ }
198
+ catch (error) {
199
+ throw new WorktreeError("Failed to list worktrees");
200
+ }
201
+ }
202
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/git/worktree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * FORGE Installation Script
4
+ * Copies command definitions to global or project .claude folder
5
+ * Run automatically via npm postinstall or manually with: node dist/scripts/install.js
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/scripts/install.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * FORGE Installation Script
4
+ * Copies command definitions to global or project .claude folder
5
+ * Run automatically via npm postinstall or manually with: node dist/scripts/install.js
6
+ */
7
+ import fs from 'fs/promises';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname } from 'path';
11
+ import { existsSync } from 'fs';
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ /**
15
+ * Detect if current directory is a FORGE project
16
+ */
17
+ async function isForgeProject(cwd) {
18
+ const claudeMdPath = path.join(cwd, 'CLAUDE.md');
19
+ const stateDirPath = path.join(cwd, 'state');
20
+ try {
21
+ const [claudeExists, stateExists] = await Promise.all([
22
+ fs.access(claudeMdPath).then(() => true).catch(() => false),
23
+ fs.access(stateDirPath).then(() => true).catch(() => false),
24
+ ]);
25
+ return claudeExists && stateExists;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ /**
32
+ * Copy command files from source to target
33
+ */
34
+ async function copyCommands(sourceDir, targetDir, verbose = false) {
35
+ const log = (msg) => {
36
+ if (verbose)
37
+ console.log(` ${msg}`);
38
+ };
39
+ // Remove existing directory if it exists
40
+ try {
41
+ await fs.rm(targetDir, { recursive: true, force: true });
42
+ log('Removed existing directory');
43
+ }
44
+ catch {
45
+ // Directory doesn't exist, that's fine
46
+ }
47
+ // Create target directory
48
+ await fs.mkdir(targetDir, { recursive: true });
49
+ log(`Created directory: ${targetDir}`);
50
+ // Copy all files
51
+ const files = await fs.readdir(sourceDir);
52
+ let copiedCount = 0;
53
+ for (const file of files) {
54
+ if (file.endsWith('.md')) {
55
+ const sourcePath = path.join(sourceDir, file);
56
+ const targetPath = path.join(targetDir, file);
57
+ await fs.copyFile(sourcePath, targetPath);
58
+ copiedCount++;
59
+ log(`Copied: ${file}`);
60
+ }
61
+ }
62
+ return copiedCount;
63
+ }
64
+ /**
65
+ * Main installation function
66
+ */
67
+ async function install(options = {}) {
68
+ const { verbose = false, mode = 'auto' } = options;
69
+ // Determine paths
70
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
71
+ const cwd = process.cwd();
72
+ const globalCommandsDir = path.join(homeDir, '.claude', 'commands', 'forge');
73
+ const projectCommandsDir = path.join(cwd, '.claude', 'commands', 'forge');
74
+ // Determine installation mode
75
+ let installMode = mode;
76
+ let targetDir;
77
+ if (mode === 'auto') {
78
+ // Auto-detect: check if we're in a FORGE project
79
+ const inForgeProject = await isForgeProject(cwd);
80
+ if (inForgeProject) {
81
+ installMode = 'project';
82
+ targetDir = projectCommandsDir;
83
+ console.log('ℹ FORGE project detected - installing to project .claude folder');
84
+ }
85
+ else {
86
+ installMode = 'global';
87
+ targetDir = globalCommandsDir;
88
+ console.log('ℹ No FORGE project detected - installing to global .claude folder');
89
+ }
90
+ }
91
+ else if (mode === 'global') {
92
+ targetDir = globalCommandsDir;
93
+ }
94
+ else {
95
+ targetDir = projectCommandsDir;
96
+ }
97
+ // Get package directory (where npm installed the package)
98
+ const packageDir = path.join(__dirname, '..');
99
+ // Try different source paths (for both installed and dev modes)
100
+ const possibleSources = [
101
+ path.join(packageDir, '..', '.claude', 'commands', 'forge'), // Installed
102
+ path.join(cwd, '.claude', 'commands', 'forge'), // Dev
103
+ path.join(process.cwd(), '.claude', 'commands', 'forge'), // Alternative
104
+ ];
105
+ let sourceCommandsDir = null;
106
+ for (const sourcePath of possibleSources) {
107
+ if (existsSync(sourcePath)) {
108
+ sourceCommandsDir = sourcePath;
109
+ break;
110
+ }
111
+ }
112
+ if (!sourceCommandsDir) {
113
+ console.error('✗ Commands directory not found');
114
+ console.log('ℹ If developing, run: npm run build');
115
+ process.exit(1);
116
+ }
117
+ const log = (msg) => {
118
+ if (verbose)
119
+ console.log(` ${msg}`);
120
+ };
121
+ const success = (msg) => console.log(`✓ ${msg}`);
122
+ const error = (msg) => console.error(`✗ ${msg}`);
123
+ try {
124
+ log(`Mode: ${installMode}`);
125
+ log(`Source: ${sourceCommandsDir}`);
126
+ log(`Target: ${targetDir}`);
127
+ const copiedCount = await copyCommands(sourceCommandsDir, targetDir, verbose);
128
+ success(`FORGE commands installed (${installMode} mode)`);
129
+ console.log(` ${copiedCount} command files copied`);
130
+ if (installMode === 'global') {
131
+ console.log('');
132
+ console.log('Available commands:');
133
+ console.log(' /forge:new-project Initialize a new FORGE project');
134
+ console.log(' /forge:init Initialize FORGE in current directory');
135
+ console.log(' /forge:status Show project progress');
136
+ console.log(' /forge:discuss Capture phase context');
137
+ console.log(' /forge:plan Generate task breakdown');
138
+ console.log(' /forge:execute Execute phase with agent teams');
139
+ console.log(' /forge:help Show all commands');
140
+ }
141
+ else {
142
+ console.log('');
143
+ console.log('ℹ Project-level installation complete');
144
+ console.log('ℹ Commands available in this project only');
145
+ }
146
+ console.log('');
147
+ console.log('Documentation: https://github.com/Alzarak/forge');
148
+ }
149
+ catch (err) {
150
+ error(`Installation failed: ${err}`);
151
+ process.exit(1);
152
+ }
153
+ }
154
+ // Parse CLI arguments
155
+ const args = process.argv.slice(2);
156
+ const verbose = args.includes('--verbose') || args.includes('-v');
157
+ const modeArg = args.find(arg => arg.startsWith('--mode='));
158
+ const mode = modeArg ? modeArg.split('=')[1] : 'auto';
159
+ // Run installation
160
+ await install({ verbose, mode });
161
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/scripts/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * FORGE Configuration Types
3
+ * Based on .planning/forge.config.json schema
4
+ */
5
+ export type ForgeMode = 'yolo' | 'interactive';
6
+ export type ForgeDepth = 'quick' | 'standard' | 'comprehensive';
7
+ export type GitStrategy = 'none' | 'worktree' | 'branch';
8
+ export type AgentProfile = 'quality' | 'balanced' | 'budget';
9
+ export interface WorkflowConfig {
10
+ research: boolean;
11
+ planCheck: boolean;
12
+ tribunal: boolean;
13
+ contractFirst: boolean;
14
+ }
15
+ export interface GitConfig {
16
+ strategy: GitStrategy;
17
+ branchTemplate: string;
18
+ squashOnShip: boolean;
19
+ }
20
+ export interface ForgeConfig {
21
+ mode: ForgeMode;
22
+ depth: ForgeDepth;
23
+ maxTeammates: number;
24
+ taskLimit: number;
25
+ agentProfile: AgentProfile;
26
+ workflow: WorkflowConfig;
27
+ git: GitConfig;
28
+ }
29
+ export declare const DEFAULT_CONFIG: ForgeConfig;
30
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;AAC/C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,CAAC;AAChE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;AACzD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAE1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAGlB,YAAY,EAAE,YAAY,CAAC;IAG3B,QAAQ,EAAE,cAAc,CAAC;IAGzB,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,eAAO,MAAM,cAAc,EAAE,WAiB5B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * FORGE Configuration Types
3
+ * Based on .planning/forge.config.json schema
4
+ */
5
+ export const DEFAULT_CONFIG = {
6
+ mode: 'interactive',
7
+ depth: 'standard',
8
+ maxTeammates: 4,
9
+ taskLimit: 6,
10
+ agentProfile: 'balanced',
11
+ workflow: {
12
+ research: true,
13
+ planCheck: true,
14
+ tribunal: true,
15
+ contractFirst: true,
16
+ },
17
+ git: {
18
+ strategy: 'worktree',
19
+ branchTemplate: 'forge/{taskId}-{slug}',
20
+ squashOnShip: true,
21
+ },
22
+ };
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqCH,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,UAAU;IACjB,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,UAAU;IACxB,QAAQ,EAAE;QACR,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;KACpB;IACD,GAAG,EAAE;QACH,QAAQ,EAAE,UAAU;QACpB,cAAc,EAAE,uBAAuB;QACvC,YAAY,EAAE,IAAI;KACnB;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * FORGE Type Exports
3
+ */
4
+ export * from './config';
5
+ export * from './state';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * FORGE Type Exports
3
+ */
4
+ export * from './config';
5
+ export * from './state';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * FORGE State Types
3
+ * Based on state/STATE.json schema
4
+ */
5
+ export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'blocked';
6
+ export type EventType = 'TASK_STARTED' | 'TASK_COMPLETED' | 'TASK_BLOCKED' | 'REQUEST_CONTRACT' | 'CONTRACT_PUBLISHED' | 'REVIEW_FINDING' | 'REVIEW_RESOLVED';
7
+ export interface Task {
8
+ id: string;
9
+ title: string;
10
+ ownerRole: string;
11
+ status: TaskStatus;
12
+ deps: string[];
13
+ allowedPaths: string[];
14
+ acceptance: string[];
15
+ verify: string[];
16
+ commit: string | null;
17
+ requests: string[];
18
+ priority: number;
19
+ }
20
+ export interface Contract {
21
+ id: string;
22
+ path: string;
23
+ version: string;
24
+ publishedBy: string;
25
+ consumers: string[];
26
+ }
27
+ export interface ProjectState {
28
+ name: string;
29
+ status: string;
30
+ currentMilestone: string;
31
+ currentPhase: number;
32
+ }
33
+ export interface EventPayload {
34
+ [key: string]: any;
35
+ commitHash?: string;
36
+ filesChanged?: string[];
37
+ testsRun?: number;
38
+ testsPassed?: number;
39
+ reason?: string;
40
+ findings?: any[];
41
+ }
42
+ export interface StateEvent {
43
+ eventId: string;
44
+ timestamp: string;
45
+ taskId: string;
46
+ actor: string;
47
+ type: EventType;
48
+ payload: EventPayload;
49
+ }
50
+ export interface ForgeState {
51
+ project: ProjectState;
52
+ tasks: Task[];
53
+ contracts: Contract[];
54
+ eventsPointer: string;
55
+ }
56
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/types/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;AAC7E,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,kBAAkB,GAClB,oBAAoB,GACpB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * FORGE State Types
3
+ * Based on state/STATE.json schema
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/types/state.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,15 @@
1
+ import { ForgeConfig } from '../types/index.js';
2
+ /**
3
+ * Load FORGE configuration from .planning/forge.config.json
4
+ * Falls back to defaults if config doesn't exist
5
+ */
6
+ export declare function loadConfig(projectRoot?: string): ForgeConfig;
7
+ /**
8
+ * Save FORGE configuration to .planning/forge.config.json
9
+ */
10
+ export declare function saveConfig(config: ForgeConfig, projectRoot?: string): void;
11
+ /**
12
+ * Validate configuration values
13
+ */
14
+ export declare function validateConfig(config: Partial<ForgeConfig>): string[];
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,UAAU,CAAC,WAAW,GAAE,MAAsB,GAAG,WAAW,CA8B3E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAczF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,EAAE,CA4BrE"}
@@ -0,0 +1,80 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { DEFAULT_CONFIG } from '../types/index.js';
4
+ const CONFIG_PATH = '.planning/forge.config.json';
5
+ /**
6
+ * Load FORGE configuration from .planning/forge.config.json
7
+ * Falls back to defaults if config doesn't exist
8
+ */
9
+ export function loadConfig(projectRoot = process.cwd()) {
10
+ const configPath = path.join(projectRoot, CONFIG_PATH);
11
+ if (!fs.existsSync(configPath)) {
12
+ return DEFAULT_CONFIG;
13
+ }
14
+ try {
15
+ const configContent = fs.readFileSync(configPath, 'utf-8');
16
+ const config = JSON.parse(configContent);
17
+ // Merge with defaults to ensure all fields exist
18
+ return {
19
+ mode: config.mode ?? DEFAULT_CONFIG.mode,
20
+ depth: config.depth ?? DEFAULT_CONFIG.depth,
21
+ maxTeammates: config.maxTeammates ?? DEFAULT_CONFIG.maxTeammates,
22
+ taskLimit: config.taskLimit ?? DEFAULT_CONFIG.taskLimit,
23
+ agentProfile: config.agentProfile ?? DEFAULT_CONFIG.agentProfile,
24
+ workflow: {
25
+ ...DEFAULT_CONFIG.workflow,
26
+ ...config.workflow,
27
+ },
28
+ git: {
29
+ ...DEFAULT_CONFIG.git,
30
+ ...config.git,
31
+ },
32
+ };
33
+ }
34
+ catch (error) {
35
+ throw new Error(`Failed to load config from ${configPath}: ${error}`);
36
+ }
37
+ }
38
+ /**
39
+ * Save FORGE configuration to .planning/forge.config.json
40
+ */
41
+ export function saveConfig(config, projectRoot = process.cwd()) {
42
+ const configDir = path.join(projectRoot, '.planning');
43
+ const configPath = path.join(configDir, 'forge.config.json');
44
+ // Ensure .planning directory exists
45
+ if (!fs.existsSync(configDir)) {
46
+ fs.mkdirSync(configDir, { recursive: true });
47
+ }
48
+ try {
49
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
50
+ }
51
+ catch (error) {
52
+ throw new Error(`Failed to save config to ${configPath}: ${error}`);
53
+ }
54
+ }
55
+ /**
56
+ * Validate configuration values
57
+ */
58
+ export function validateConfig(config) {
59
+ const errors = [];
60
+ if (config.mode && !['yolo', 'interactive'].includes(config.mode)) {
61
+ errors.push(`Invalid mode: ${config.mode}. Must be 'yolo' or 'interactive'.`);
62
+ }
63
+ if (config.depth && !['quick', 'standard', 'comprehensive'].includes(config.depth)) {
64
+ errors.push(`Invalid depth: ${config.depth}. Must be 'quick', 'standard', or 'comprehensive'.`);
65
+ }
66
+ if (config.maxTeammates !== undefined && (config.maxTeammates < 2 || config.maxTeammates > 6)) {
67
+ errors.push(`maxTeammates must be between 2 and 6. Got: ${config.maxTeammates}`);
68
+ }
69
+ if (config.taskLimit !== undefined && (config.taskLimit < 3 || config.taskLimit > 8)) {
70
+ errors.push(`taskLimit must be between 3 and 8. Got: ${config.taskLimit}`);
71
+ }
72
+ if (config.agentProfile && !['quality', 'balanced', 'budget'].includes(config.agentProfile)) {
73
+ errors.push(`Invalid agentProfile: ${config.agentProfile}. Must be 'quality', 'balanced', or 'budget'.`);
74
+ }
75
+ if (config.git?.strategy && !['none', 'worktree', 'branch'].includes(config.git.strategy)) {
76
+ errors.push(`Invalid git.strategy: ${config.git.strategy}. Must be 'none', 'worktree', or 'branch'.`);
77
+ }
78
+ return errors;
79
+ }
80
+ //# sourceMappingURL=config.js.map