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.
Files changed (107) hide show
  1. package/.claude/commands/forge/README.md +156 -189
  2. package/.claude/commands/forge/add-phase.md +4 -3
  3. package/.claude/commands/forge/complete-milestone.md +1 -1
  4. package/.claude/commands/forge/convert.md +31 -0
  5. package/.claude/commands/forge/debug.md +12 -154
  6. package/.claude/commands/forge/discuss.md +60 -107
  7. package/.claude/commands/forge/execute.md +67 -142
  8. package/.claude/commands/forge/generate.md +8 -107
  9. package/.claude/commands/forge/help.md +9 -114
  10. package/.claude/commands/forge/init.md +10 -74
  11. package/.claude/commands/forge/insert-phase.md +4 -3
  12. package/.claude/commands/forge/new-milestone.md +1 -1
  13. package/.claude/commands/forge/new-project.md +12 -91
  14. package/.claude/commands/forge/pause-work.md +2 -2
  15. package/.claude/commands/forge/plan.md +114 -129
  16. package/.claude/commands/forge/quick.md +17 -106
  17. package/.claude/commands/forge/remove-phase.md +3 -2
  18. package/.claude/commands/forge/resume.md +22 -0
  19. package/.claude/commands/forge/team-add.md +24 -0
  20. package/.claude/commands/forge/team-create.md +22 -0
  21. package/.claude/commands/forge/team-remove.md +24 -0
  22. package/.claude/commands/forge/team-start.md +22 -0
  23. package/.claude/commands/forge/team-view.md +18 -0
  24. package/.claude/commands/forge/verify.md +68 -147
  25. package/.claude/hooks/forge-context-cleanup.cjs +79 -0
  26. package/.claude/hooks/forge-event-guard.cjs +36 -0
  27. package/.claude/hooks/forge-size-guard.cjs +55 -0
  28. package/.claude/rules/api-patterns.md +13 -98
  29. package/.claude/rules/context-efficiency.md +10 -0
  30. package/.claude/rules/security-baseline.md +18 -204
  31. package/.claude/rules/testing-standards.md +16 -177
  32. package/.claude/rules/ui-conventions.md +17 -142
  33. package/bin/forge.js +5 -3
  34. package/dist/bin/forge.js +5 -3
  35. package/dist/cli/index.d.ts.map +1 -1
  36. package/dist/cli/index.js +15 -1
  37. package/dist/cli/index.js.map +1 -1
  38. package/dist/commands/convert.d.ts +6 -0
  39. package/dist/commands/convert.d.ts.map +1 -0
  40. package/dist/commands/convert.js +132 -0
  41. package/dist/commands/convert.js.map +1 -0
  42. package/dist/commands/generate.d.ts.map +1 -1
  43. package/dist/commands/generate.js +3 -2
  44. package/dist/commands/generate.js.map +1 -1
  45. package/dist/commands/index.d.ts +4 -4
  46. package/dist/commands/index.d.ts.map +1 -1
  47. package/dist/commands/index.js +4 -4
  48. package/dist/commands/index.js.map +1 -1
  49. package/dist/generators/gsd-converter.d.ts +100 -0
  50. package/dist/generators/gsd-converter.d.ts.map +1 -0
  51. package/dist/generators/gsd-converter.js +335 -0
  52. package/dist/generators/gsd-converter.js.map +1 -0
  53. package/dist/templates/.claude/rules/api-patterns.md.template +212 -0
  54. package/dist/templates/.claude/rules/security-baseline.md.template +322 -0
  55. package/dist/templates/.claude/rules/testing-standards.md.template +280 -0
  56. package/dist/templates/.claude/rules/ui-conventions.md.template +264 -0
  57. package/dist/templates/.planning/forge.config.json.template +75 -0
  58. package/dist/templates/CLAUDE.md.template +161 -0
  59. package/dist/templates/PLAN.md.template +177 -0
  60. package/dist/templates/PROJECT.md.template +156 -0
  61. package/dist/templates/REQUIREMENTS.md.template +221 -0
  62. package/dist/templates/ROADMAP.md.template +130 -0
  63. package/dist/types/index.d.ts +2 -2
  64. package/dist/types/index.d.ts.map +1 -1
  65. package/dist/types/index.js +2 -2
  66. package/dist/types/index.js.map +1 -1
  67. package/dist/utils/index.d.ts +5 -5
  68. package/dist/utils/index.d.ts.map +1 -1
  69. package/dist/utils/index.js +5 -5
  70. package/dist/utils/index.js.map +1 -1
  71. package/dist/utils/template-client.d.ts.map +1 -1
  72. package/dist/utils/template-client.js +3 -2
  73. package/dist/utils/template-client.js.map +1 -1
  74. package/package.json +6 -4
  75. package/.claude/commands/forge/resume-work.md +0 -122
  76. package/dist/git/__tests__/worktree.test.d.ts +0 -5
  77. package/dist/git/__tests__/worktree.test.d.ts.map +0 -1
  78. package/dist/git/__tests__/worktree.test.js +0 -121
  79. package/dist/git/__tests__/worktree.test.js.map +0 -1
  80. package/dist/git/codeowners.d.ts +0 -101
  81. package/dist/git/codeowners.d.ts.map +0 -1
  82. package/dist/git/codeowners.js +0 -216
  83. package/dist/git/codeowners.js.map +0 -1
  84. package/dist/git/commit.d.ts +0 -135
  85. package/dist/git/commit.d.ts.map +0 -1
  86. package/dist/git/commit.js +0 -223
  87. package/dist/git/commit.js.map +0 -1
  88. package/dist/git/hooks/commit-msg.d.ts +0 -8
  89. package/dist/git/hooks/commit-msg.d.ts.map +0 -1
  90. package/dist/git/hooks/commit-msg.js +0 -34
  91. package/dist/git/hooks/commit-msg.js.map +0 -1
  92. package/dist/git/hooks/pre-commit.d.ts +0 -8
  93. package/dist/git/hooks/pre-commit.d.ts.map +0 -1
  94. package/dist/git/hooks/pre-commit.js +0 -34
  95. package/dist/git/hooks/pre-commit.js.map +0 -1
  96. package/dist/git/pre-commit-hooks.d.ts +0 -117
  97. package/dist/git/pre-commit-hooks.d.ts.map +0 -1
  98. package/dist/git/pre-commit-hooks.js +0 -270
  99. package/dist/git/pre-commit-hooks.js.map +0 -1
  100. package/dist/git/wipe-protocol.d.ts +0 -281
  101. package/dist/git/wipe-protocol.d.ts.map +0 -1
  102. package/dist/git/wipe-protocol.js +0 -237
  103. package/dist/git/wipe-protocol.js.map +0 -1
  104. package/dist/git/worktree.d.ts +0 -69
  105. package/dist/git/worktree.d.ts.map +0 -1
  106. package/dist/git/worktree.js +0 -202
  107. package/dist/git/worktree.js.map +0 -1
@@ -1,202 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/git/worktree.ts"],"names":[],"mappings":"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"}