agentic-forge 0.0.0 → 0.7.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 (209) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +31 -21
  3. package/dist/checkpoints/manager.d.ts +5 -0
  4. package/dist/checkpoints/manager.js +87 -0
  5. package/dist/checkpoints/manager.js.map +1 -0
  6. package/{src → dist}/claude/.claude/skills/analyze/SKILL.md +1 -1
  7. package/{src → dist}/claude/.claude/skills/create-checkpoint/SKILL.md +1 -1
  8. package/{src → dist}/claude/.claude/skills/create-log/SKILL.md +1 -1
  9. package/{src → dist}/claude/.claude/skills/fix-analyze/SKILL.md +1 -1
  10. package/{src → dist}/claude/.claude/skills/git-branch/SKILL.md +1 -1
  11. package/{src → dist}/claude/.claude/skills/git-commit/SKILL.md +1 -1
  12. package/{src → dist}/claude/.claude/skills/git-pr/SKILL.md +1 -1
  13. package/{src → dist}/claude/.claude/skills/sdlc-plan/SKILL.md +1 -1
  14. package/{src → dist}/claude/.claude/skills/sdlc-review/SKILL.md +1 -1
  15. package/{src → dist}/claude/.claude/skills/workflow-builder/SKILL.md +1 -1
  16. package/dist/cli.d.ts +3 -0
  17. package/dist/cli.js +155 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/commands/config-cmd.d.ts +2 -0
  20. package/dist/commands/config-cmd.js +30 -0
  21. package/dist/commands/config-cmd.js.map +1 -0
  22. package/{src/commands/index.ts → dist/commands/index.d.ts} +1 -10
  23. package/dist/commands/index.js +13 -0
  24. package/dist/commands/index.js.map +1 -0
  25. package/dist/commands/init.d.ts +6 -0
  26. package/dist/commands/init.js +83 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/release-notes.d.ts +5 -0
  29. package/dist/commands/release-notes.js +68 -0
  30. package/dist/commands/release-notes.js.map +1 -0
  31. package/dist/commands/resume.d.ts +5 -0
  32. package/dist/commands/resume.js +79 -0
  33. package/dist/commands/resume.js.map +1 -0
  34. package/dist/commands/run.d.ts +14 -0
  35. package/dist/commands/run.js +193 -0
  36. package/dist/commands/run.js.map +1 -0
  37. package/dist/commands/shortcuts.d.ts +2 -0
  38. package/dist/commands/shortcuts.js +11 -0
  39. package/dist/commands/shortcuts.js.map +1 -0
  40. package/dist/commands/skills-dir.d.ts +2 -0
  41. package/dist/commands/skills-dir.js +9 -0
  42. package/dist/commands/skills-dir.js.map +1 -0
  43. package/dist/commands/status.d.ts +4 -0
  44. package/dist/commands/status.js +99 -0
  45. package/dist/commands/status.js.map +1 -0
  46. package/dist/commands/update.d.ts +4 -0
  47. package/dist/commands/update.js +65 -0
  48. package/dist/commands/update.js.map +1 -0
  49. package/dist/commands/version.d.ts +3 -0
  50. package/dist/commands/version.js +26 -0
  51. package/dist/commands/version.js.map +1 -0
  52. package/dist/commands/workflows.d.ts +4 -0
  53. package/dist/commands/workflows.js +109 -0
  54. package/dist/commands/workflows.js.map +1 -0
  55. package/dist/config.d.ts +8 -0
  56. package/dist/config.js +110 -0
  57. package/dist/config.js.map +1 -0
  58. package/dist/console.d.ts +103 -0
  59. package/dist/console.js +670 -0
  60. package/dist/console.js.map +1 -0
  61. package/dist/executor.d.ts +27 -0
  62. package/dist/executor.js +236 -0
  63. package/dist/executor.js.map +1 -0
  64. package/dist/git/worktree.d.ts +23 -0
  65. package/dist/git/worktree.js +170 -0
  66. package/dist/git/worktree.js.map +1 -0
  67. package/dist/logging/logger.d.ts +27 -0
  68. package/dist/logging/logger.js +69 -0
  69. package/dist/logging/logger.js.map +1 -0
  70. package/dist/orchestrator.d.ts +44 -0
  71. package/dist/orchestrator.js +587 -0
  72. package/dist/orchestrator.js.map +1 -0
  73. package/dist/parser.d.ts +17 -0
  74. package/dist/parser.js +184 -0
  75. package/dist/parser.js.map +1 -0
  76. package/dist/progress.d.ts +29 -0
  77. package/dist/progress.js +275 -0
  78. package/dist/progress.js.map +1 -0
  79. package/dist/ralph-loop.d.ts +26 -0
  80. package/dist/ralph-loop.js +194 -0
  81. package/dist/ralph-loop.js.map +1 -0
  82. package/dist/renderer.d.ts +15 -0
  83. package/dist/renderer.js +123 -0
  84. package/dist/renderer.js.map +1 -0
  85. package/dist/runner.d.ts +84 -0
  86. package/dist/runner.js +529 -0
  87. package/dist/runner.js.map +1 -0
  88. package/dist/signal-manager.d.ts +16 -0
  89. package/dist/signal-manager.js +50 -0
  90. package/dist/signal-manager.js.map +1 -0
  91. package/dist/steps/base.d.ts +28 -0
  92. package/dist/steps/base.js +23 -0
  93. package/dist/steps/base.js.map +1 -0
  94. package/dist/steps/conditional-step.d.ts +12 -0
  95. package/dist/steps/conditional-step.js +106 -0
  96. package/dist/steps/conditional-step.js.map +1 -0
  97. package/{src/steps/index.ts → dist/steps/index.d.ts} +1 -9
  98. package/dist/steps/index.js +8 -0
  99. package/dist/steps/index.js.map +1 -0
  100. package/dist/steps/parallel-step.d.ts +11 -0
  101. package/dist/steps/parallel-step.js +166 -0
  102. package/dist/steps/parallel-step.js.map +1 -0
  103. package/dist/steps/prompt-step.d.ts +8 -0
  104. package/dist/steps/prompt-step.js +94 -0
  105. package/dist/steps/prompt-step.js.map +1 -0
  106. package/dist/steps/ralph-loop-step.d.ts +8 -0
  107. package/dist/steps/ralph-loop-step.js +132 -0
  108. package/dist/steps/ralph-loop-step.js.map +1 -0
  109. package/dist/steps/serial-step.d.ts +10 -0
  110. package/dist/steps/serial-step.js +57 -0
  111. package/dist/steps/serial-step.js.map +1 -0
  112. package/dist/types.d.ts +118 -0
  113. package/dist/types.js +10 -0
  114. package/dist/types.js.map +1 -0
  115. package/package.json +56 -2
  116. package/.gitattributes +0 -24
  117. package/.github/workflows/ci.yml +0 -70
  118. package/.markdownlint-cli2.jsonc +0 -16
  119. package/.prettierignore +0 -3
  120. package/.prettierrc +0 -6
  121. package/.vscode/agentic-forge.code-workspace +0 -26
  122. package/CHANGELOG.md +0 -100
  123. package/CLAUDE.md +0 -158
  124. package/CONTRIBUTING.md +0 -152
  125. package/biome.json +0 -21
  126. package/scripts/copy-assets.js +0 -21
  127. package/src/checkpoints/manager.ts +0 -119
  128. package/src/cli.ts +0 -182
  129. package/src/commands/config-cmd.ts +0 -28
  130. package/src/commands/init.ts +0 -96
  131. package/src/commands/release-notes.ts +0 -85
  132. package/src/commands/resume.ts +0 -103
  133. package/src/commands/run.ts +0 -234
  134. package/src/commands/shortcuts.ts +0 -11
  135. package/src/commands/skills-dir.ts +0 -11
  136. package/src/commands/status.ts +0 -112
  137. package/src/commands/update.ts +0 -64
  138. package/src/commands/version.ts +0 -27
  139. package/src/commands/workflows.ts +0 -129
  140. package/src/config.ts +0 -129
  141. package/src/console.ts +0 -790
  142. package/src/executor.ts +0 -354
  143. package/src/git/worktree.ts +0 -236
  144. package/src/logging/logger.ts +0 -95
  145. package/src/orchestrator.ts +0 -815
  146. package/src/parser.ts +0 -225
  147. package/src/progress.ts +0 -306
  148. package/src/ralph-loop.ts +0 -260
  149. package/src/renderer.ts +0 -164
  150. package/src/runner.ts +0 -634
  151. package/src/signal-manager.ts +0 -55
  152. package/src/steps/base.ts +0 -71
  153. package/src/steps/conditional-step.ts +0 -144
  154. package/src/steps/parallel-step.ts +0 -213
  155. package/src/steps/prompt-step.ts +0 -121
  156. package/src/steps/ralph-loop-step.ts +0 -186
  157. package/src/steps/serial-step.ts +0 -84
  158. package/src/types.ts +0 -141
  159. package/tests/config.test.ts +0 -219
  160. package/tests/console.test.ts +0 -506
  161. package/tests/executor.test.ts +0 -339
  162. package/tests/init.test.ts +0 -86
  163. package/tests/logger.test.ts +0 -110
  164. package/tests/parser.test.ts +0 -290
  165. package/tests/progress.test.ts +0 -345
  166. package/tests/ralph-loop.test.ts +0 -418
  167. package/tests/renderer.test.ts +0 -350
  168. package/tests/runner.test.ts +0 -497
  169. package/tests/setup.test.ts +0 -7
  170. package/tests/signal-manager.test.ts +0 -26
  171. package/tests/steps.test.ts +0 -412
  172. package/tests/worktree.test.ts +0 -411
  173. package/tsconfig.json +0 -18
  174. package/vitest.config.ts +0 -8
  175. /package/{src → dist}/agents/explorer.md +0 -0
  176. /package/{src → dist}/agents/reviewer.md +0 -0
  177. /package/{src → dist}/claude/.claude/skills/analyze/references/bug.md +0 -0
  178. /package/{src → dist}/claude/.claude/skills/analyze/references/debt.md +0 -0
  179. /package/{src → dist}/claude/.claude/skills/analyze/references/doc.md +0 -0
  180. /package/{src → dist}/claude/.claude/skills/analyze/references/security.md +0 -0
  181. /package/{src → dist}/claude/.claude/skills/analyze/references/style.md +0 -0
  182. /package/{src → dist}/claude/.claude/skills/orchestrate/SKILL.md +0 -0
  183. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/bug.md +0 -0
  184. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/chore.md +0 -0
  185. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/feature.md +0 -0
  186. /package/{src → dist}/claude/.claude/skills/workflow-builder/references/REFERENCE.md +0 -0
  187. /package/{src → dist}/claude/.claude/skills/workflow-builder/references/workflow-example.yaml +0 -0
  188. /package/{src → dist}/prompts/agentic-system.md +0 -0
  189. /package/{src → dist}/templates/analysis/bug.md.j2 +0 -0
  190. /package/{src → dist}/templates/analysis/debt.md.j2 +0 -0
  191. /package/{src → dist}/templates/analysis/doc.md.j2 +0 -0
  192. /package/{src → dist}/templates/analysis/security.md.j2 +0 -0
  193. /package/{src → dist}/templates/analysis/style.md.j2 +0 -0
  194. /package/{src → dist}/templates/analysis-summary.md.j2 +0 -0
  195. /package/{src → dist}/templates/checkpoint.md.j2 +0 -0
  196. /package/{src → dist}/templates/implementation-report.md.j2 +0 -0
  197. /package/{src → dist}/templates/memory.md.j2 +0 -0
  198. /package/{src → dist}/templates/plan-bug.md.j2 +0 -0
  199. /package/{src → dist}/templates/plan-chore.md.j2 +0 -0
  200. /package/{src → dist}/templates/plan-feature.md.j2 +0 -0
  201. /package/{src → dist}/templates/progress.json.j2 +0 -0
  202. /package/{src → dist}/templates/ralph-report.md.j2 +0 -0
  203. /package/{src → dist}/workflows/analyze-codebase-merge.yaml +0 -0
  204. /package/{src → dist}/workflows/analyze-codebase.yaml +0 -0
  205. /package/{src → dist}/workflows/analyze-single.yaml +0 -0
  206. /package/{src → dist}/workflows/demo.yaml +0 -0
  207. /package/{src → dist}/workflows/one-shot.yaml +0 -0
  208. /package/{src → dist}/workflows/plan-build-review.yaml +0 -0
  209. /package/{src → dist}/workflows/ralph-loop.yaml +0 -0
@@ -1,411 +0,0 @@
1
- /** Tests for git worktree module and parallel step executor. */
2
-
3
- import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { Writable } from "node:stream";
7
- import { beforeEach, describe, expect, it, vi } from "vitest";
8
-
9
- import { ConsoleOutput } from "../src/console.js";
10
- import { WorkflowLogger } from "../src/logging/logger.js";
11
- import { createProgress } from "../src/progress.js";
12
- import { TemplateRenderer } from "../src/renderer.js";
13
- import type { BranchStepExecutor, StepContext } from "../src/steps/base.js";
14
- import type { StepDefinition, WorkflowProgress, WorkflowSettings } from "../src/types.js";
15
-
16
- // Mock the worktree module for parallel step tests
17
- const mockCreateWorktree = vi.fn();
18
- const mockRemoveWorktree = vi.fn();
19
- const mockRunGit = vi.fn();
20
-
21
- vi.mock("../src/git/worktree.js", async (importOriginal) => {
22
- const original = await importOriginal<typeof import("../src/git/worktree.js")>();
23
- return {
24
- ...original,
25
- createWorktree: (...args: unknown[]) => mockCreateWorktree(...args),
26
- removeWorktree: (...args: unknown[]) => mockRemoveWorktree(...args),
27
- runGit: (...args: unknown[]) => mockRunGit(...args),
28
- };
29
- });
30
-
31
- // Import ParallelStepExecutor after mock setup
32
- const { ParallelStepExecutor } = await import("../src/steps/parallel-step.js");
33
-
34
- // --- Helpers ---
35
-
36
- function createMockStream(): Writable {
37
- return new Writable({
38
- write(_chunk, _encoding, cb) {
39
- cb();
40
- },
41
- });
42
- }
43
-
44
- function makeStepDef(
45
- overrides: Partial<StepDefinition> & { name: string; type: StepDefinition["type"] },
46
- ): StepDefinition {
47
- return {
48
- steps: [],
49
- mergeStrategy: "wait-all",
50
- mergeMode: "merge",
51
- thenSteps: [],
52
- elseSteps: [],
53
- maxIterations: 5,
54
- pollingInterval: 30,
55
- onTimeout: "fail",
56
- onError: "fail",
57
- checkpoint: false,
58
- ...overrides,
59
- };
60
- }
61
-
62
- function defaultSettings(): WorkflowSettings {
63
- return {
64
- maxRetry: 3,
65
- timeoutMinutes: 60,
66
- trackProgress: true,
67
- autofix: "off",
68
- terminalOutput: "base",
69
- bypassPermissions: false,
70
- strictMode: false,
71
- model: null,
72
- requiredTools: [],
73
- git: {
74
- enabled: false,
75
- worktree: false,
76
- autoCommit: false,
77
- autoPr: false,
78
- branchPrefix: "agentic",
79
- },
80
- };
81
- }
82
-
83
- let tempDir: string;
84
- let mockLogger: WorkflowLogger;
85
-
86
- beforeEach(() => {
87
- vi.clearAllMocks();
88
- tempDir = mkdtempSync(path.join(os.tmpdir(), "worktree-test-"));
89
- const logDir = path.join(tempDir, "agentic", "outputs", "test-workflow-id");
90
- mkdirSync(logDir, { recursive: true });
91
- mockLogger = new WorkflowLogger("test-workflow-id", tempDir);
92
- });
93
-
94
- function createStepContext(overrides?: Partial<StepContext>): StepContext {
95
- return {
96
- repoRoot: tempDir,
97
- config: { defaults: { model: "sonnet", maxRetry: 3, timeoutMinutes: 60 } },
98
- renderer: new TemplateRenderer(),
99
- workflowSettings: defaultSettings(),
100
- workflowId: "test-workflow-id",
101
- variables: { test_var: "test_value" },
102
- outputs: {},
103
- ...overrides,
104
- };
105
- }
106
-
107
- function createWorkflowProgress(): WorkflowProgress {
108
- return createProgress("test-workflow-id", "test-workflow", ["step1", "step2"], {});
109
- }
110
-
111
- // --- Worktree name helper tests ---
112
-
113
- describe("worktree name sanitization", () => {
114
- // Test the sanitization logic indirectly through createWorktree mock behavior
115
- // The actual sanitization is internal, so we test the exported functions
116
-
117
- it("should export createWorktree function", async () => {
118
- const mod = await import("../src/git/worktree.js");
119
- expect(mod.createWorktree).toBeDefined();
120
- });
121
-
122
- it("should export removeWorktree function", async () => {
123
- const mod = await import("../src/git/worktree.js");
124
- expect(mod.removeWorktree).toBeDefined();
125
- });
126
-
127
- it("should export listWorktrees function", async () => {
128
- const mod = await import("../src/git/worktree.js");
129
- expect(mod.listWorktrees).toBeDefined();
130
- });
131
-
132
- it("should export listAgenticWorktrees function", async () => {
133
- const mod = await import("../src/git/worktree.js");
134
- expect(mod.listAgenticWorktrees).toBeDefined();
135
- });
136
-
137
- it("should export pruneOrphaned function", async () => {
138
- const mod = await import("../src/git/worktree.js");
139
- expect(mod.pruneOrphaned).toBeDefined();
140
- });
141
-
142
- it("should export branch operation functions", async () => {
143
- const mod = await import("../src/git/worktree.js");
144
- expect(mod.createBranch).toBeDefined();
145
- expect(mod.checkoutBranch).toBeDefined();
146
- expect(mod.commitChanges).toBeDefined();
147
- expect(mod.pushBranch).toBeDefined();
148
- });
149
- });
150
-
151
- // --- ParallelStepExecutor tests ---
152
-
153
- describe("ParallelStepExecutor", () => {
154
- it("should be instantiable", () => {
155
- const branchExecutor: BranchStepExecutor = vi.fn();
156
- const executor = new ParallelStepExecutor(branchExecutor);
157
- expect(executor).toBeDefined();
158
- });
159
-
160
- it("should handle empty steps", async () => {
161
- const branchExecutor: BranchStepExecutor = vi.fn();
162
- const executor = new ParallelStepExecutor(branchExecutor);
163
-
164
- const step = makeStepDef({
165
- name: "parallel-step",
166
- type: "parallel",
167
- steps: [],
168
- });
169
-
170
- const context = createStepContext();
171
- const progress = createWorkflowProgress();
172
- const consoleOut = new ConsoleOutput(createMockStream());
173
-
174
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
175
-
176
- expect(result.success).toBe(true);
177
- expect(result.outputSummary).toContain("No sub-steps");
178
- expect(branchExecutor).not.toHaveBeenCalled();
179
- });
180
-
181
- it("should execute branches in parallel without worktrees", async () => {
182
- const branchExecutor = vi.fn<BranchStepExecutor>().mockResolvedValue({
183
- success: true,
184
- outputSummary: "Done",
185
- });
186
-
187
- const executor = new ParallelStepExecutor(branchExecutor);
188
- const innerSteps = [
189
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
190
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
191
- ];
192
-
193
- const step = makeStepDef({
194
- name: "parallel-step",
195
- type: "parallel",
196
- steps: innerSteps,
197
- });
198
-
199
- const context = createStepContext();
200
- const progress = createWorkflowProgress();
201
- const consoleOut = new ConsoleOutput(createMockStream());
202
-
203
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
204
-
205
- expect(result.success).toBe(true);
206
- expect(branchExecutor).toHaveBeenCalledTimes(2);
207
- expect(result.outputSummary).toContain("2/2");
208
- expect(mockCreateWorktree).not.toHaveBeenCalled();
209
- });
210
-
211
- it("should execute branches with worktree isolation", async () => {
212
- const branchExecutor = vi.fn<BranchStepExecutor>().mockResolvedValue({
213
- success: true,
214
- outputSummary: "Done",
215
- });
216
-
217
- mockCreateWorktree.mockReturnValue({
218
- path: "/tmp/worktree-a",
219
- branch: "agentic/test-branch-a",
220
- baseBranch: "main",
221
- });
222
-
223
- mockRunGit.mockReturnValue({ stdout: "", stderr: "", returncode: 0 });
224
-
225
- const executor = new ParallelStepExecutor(branchExecutor);
226
- const innerSteps = [
227
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
228
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
229
- ];
230
-
231
- const step = makeStepDef({
232
- name: "parallel-step",
233
- type: "parallel",
234
- steps: innerSteps,
235
- git: { worktree: true, autoPr: false, branchPrefix: "agentic" },
236
- });
237
-
238
- const context = createStepContext();
239
- const progress = createWorkflowProgress();
240
- const consoleOut = new ConsoleOutput(createMockStream());
241
-
242
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
243
-
244
- expect(result.success).toBe(true);
245
- expect(mockCreateWorktree).toHaveBeenCalledTimes(2);
246
- // Merge mode is "merge" by default, so branches get merged and cleaned up
247
- expect(mockRunGit).toHaveBeenCalled();
248
- expect(mockRemoveWorktree).toHaveBeenCalled();
249
- });
250
-
251
- it("should handle branch failures with wait-all strategy", async () => {
252
- const branchExecutor = vi
253
- .fn<BranchStepExecutor>()
254
- .mockResolvedValueOnce({ success: true, outputSummary: "Done" })
255
- .mockResolvedValueOnce({ success: false, error: "Branch B failed" });
256
-
257
- const executor = new ParallelStepExecutor(branchExecutor);
258
- const innerSteps = [
259
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
260
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
261
- ];
262
-
263
- const step = makeStepDef({
264
- name: "parallel-step",
265
- type: "parallel",
266
- steps: innerSteps,
267
- mergeStrategy: "wait-all",
268
- });
269
-
270
- const context = createStepContext();
271
- const progress = createWorkflowProgress();
272
- const consoleOut = new ConsoleOutput(createMockStream());
273
-
274
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
275
-
276
- expect(result.success).toBe(false);
277
- expect(result.error).toContain("branch-b");
278
- });
279
-
280
- it("should tolerate failures in independent merge mode", async () => {
281
- const branchExecutor = vi
282
- .fn<BranchStepExecutor>()
283
- .mockResolvedValueOnce({ success: true, outputSummary: "Done" })
284
- .mockResolvedValueOnce({ success: false, error: "Failed" });
285
-
286
- const executor = new ParallelStepExecutor(branchExecutor);
287
- const innerSteps = [
288
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
289
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
290
- ];
291
-
292
- const step = makeStepDef({
293
- name: "parallel-step",
294
- type: "parallel",
295
- steps: innerSteps,
296
- mergeStrategy: "wait-all",
297
- mergeMode: "independent",
298
- });
299
-
300
- const context = createStepContext();
301
- const progress = createWorkflowProgress();
302
- const consoleOut = new ConsoleOutput(createMockStream());
303
-
304
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
305
-
306
- // Independent mode tolerates failures in wait-all
307
- expect(result.success).toBe(true);
308
- expect(result.outputSummary).toContain("1/2");
309
- expect(result.outputSummary).toContain("failed");
310
- });
311
-
312
- it("should handle branch exceptions gracefully", async () => {
313
- const branchExecutor = vi
314
- .fn<BranchStepExecutor>()
315
- .mockResolvedValueOnce({ success: true, outputSummary: "Done" })
316
- .mockRejectedValueOnce(new Error("Unexpected error"));
317
-
318
- const executor = new ParallelStepExecutor(branchExecutor);
319
- const innerSteps = [
320
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
321
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
322
- ];
323
-
324
- const step = makeStepDef({
325
- name: "parallel-step",
326
- type: "parallel",
327
- steps: innerSteps,
328
- });
329
-
330
- const context = createStepContext();
331
- const progress = createWorkflowProgress();
332
- const consoleOut = new ConsoleOutput(createMockStream());
333
-
334
- const result = await executor.execute(step, progress, context, mockLogger, consoleOut);
335
-
336
- // Exception in branch-b should be caught and handled
337
- expect(result.success).toBe(false);
338
- expect(result.error).toContain("branch-b");
339
- });
340
-
341
- it("should pass cwdOverride to branch context when using worktrees", async () => {
342
- let capturedContext: StepContext | null = null;
343
- const branchExecutor = vi
344
- .fn<BranchStepExecutor>()
345
- .mockImplementation(async (_step, _progress, ctx) => {
346
- capturedContext = ctx;
347
- return { success: true, outputSummary: "Done" };
348
- });
349
-
350
- mockCreateWorktree.mockReturnValue({
351
- path: "/tmp/test-worktree",
352
- branch: "agentic/test-branch",
353
- baseBranch: "main",
354
- });
355
- mockRunGit.mockReturnValue({ stdout: "", stderr: "", returncode: 0 });
356
-
357
- const executor = new ParallelStepExecutor(branchExecutor);
358
- const innerSteps = [makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" })];
359
-
360
- const step = makeStepDef({
361
- name: "parallel-step",
362
- type: "parallel",
363
- steps: innerSteps,
364
- git: { worktree: true, autoPr: false, branchPrefix: "agentic" },
365
- });
366
-
367
- const context = createStepContext();
368
- const progress = createWorkflowProgress();
369
- const consoleOut = new ConsoleOutput(createMockStream());
370
-
371
- await executor.execute(step, progress, context, mockLogger, consoleOut);
372
-
373
- expect(capturedContext).not.toBeNull();
374
- expect((capturedContext as StepContext).cwdOverride).toBe("/tmp/test-worktree");
375
- });
376
-
377
- it("should clone variables for each branch context", async () => {
378
- const capturedContexts: StepContext[] = [];
379
- const branchExecutor = vi
380
- .fn<BranchStepExecutor>()
381
- .mockImplementation(async (_step, _progress, ctx) => {
382
- capturedContexts.push(ctx);
383
- // Mutate variables in this branch
384
- ctx.variables.modified = true;
385
- return { success: true, outputSummary: "Done" };
386
- });
387
-
388
- const executor = new ParallelStepExecutor(branchExecutor);
389
- const innerSteps = [
390
- makeStepDef({ name: "branch-a", type: "prompt", prompt: "Task A" }),
391
- makeStepDef({ name: "branch-b", type: "prompt", prompt: "Task B" }),
392
- ];
393
-
394
- const step = makeStepDef({
395
- name: "parallel-step",
396
- type: "parallel",
397
- steps: innerSteps,
398
- });
399
-
400
- const context = createStepContext();
401
- const progress = createWorkflowProgress();
402
- const consoleOut = new ConsoleOutput(createMockStream());
403
-
404
- await executor.execute(step, progress, context, mockLogger, consoleOut);
405
-
406
- // Original context should not be mutated
407
- expect(context.variables.modified).toBeUndefined();
408
- // Each branch should get its own variables copy
409
- expect(capturedContexts).toHaveLength(2);
410
- });
411
- });
package/tsconfig.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "Node16",
5
- "moduleResolution": "Node16",
6
- "outDir": "dist",
7
- "rootDir": "src",
8
- "strict": true,
9
- "declaration": true,
10
- "sourceMap": true,
11
- "esModuleInterop": true,
12
- "forceConsistentCasingInFileNames": true,
13
- "skipLibCheck": true,
14
- "resolveJsonModule": true
15
- },
16
- "include": ["src/**/*.ts"],
17
- "exclude": ["node_modules", "dist", "tests"]
18
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- dir: "tests",
6
- globals: true,
7
- },
8
- });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes