agentic-forge 0.0.0 → 0.7.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 (212) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +64 -24
  3. package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/SKILL.md +2 -2
  4. package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/references/REFERENCE.md +9 -3
  5. package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/references/workflow-example.yaml +15 -8
  6. package/dist/checkpoints/manager.d.ts +5 -0
  7. package/dist/checkpoints/manager.js +87 -0
  8. package/dist/checkpoints/manager.js.map +1 -0
  9. package/{src → dist}/claude/.claude/skills/analyze/SKILL.md +1 -1
  10. package/{src → dist}/claude/.claude/skills/create-checkpoint/SKILL.md +1 -1
  11. package/{src → dist}/claude/.claude/skills/create-log/SKILL.md +1 -1
  12. package/{src → dist}/claude/.claude/skills/fix-analyze/SKILL.md +1 -1
  13. package/{src → dist}/claude/.claude/skills/git-branch/SKILL.md +1 -1
  14. package/{src → dist}/claude/.claude/skills/git-commit/SKILL.md +1 -1
  15. package/{src → dist}/claude/.claude/skills/git-pr/SKILL.md +1 -1
  16. package/{src → dist}/claude/.claude/skills/sdlc-plan/SKILL.md +1 -1
  17. package/{src → dist}/claude/.claude/skills/sdlc-review/SKILL.md +1 -1
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.js +173 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/commands/authoring-dir.d.ts +2 -0
  22. package/dist/commands/authoring-dir.js +9 -0
  23. package/dist/commands/authoring-dir.js.map +1 -0
  24. package/dist/commands/config-cmd.d.ts +2 -0
  25. package/dist/commands/config-cmd.js +30 -0
  26. package/dist/commands/config-cmd.js.map +1 -0
  27. package/{src/commands/index.ts → dist/commands/index.d.ts} +2 -10
  28. package/dist/commands/index.js +14 -0
  29. package/dist/commands/index.js.map +1 -0
  30. package/dist/commands/init.d.ts +6 -0
  31. package/dist/commands/init.js +83 -0
  32. package/dist/commands/init.js.map +1 -0
  33. package/dist/commands/release-notes.d.ts +5 -0
  34. package/dist/commands/release-notes.js +68 -0
  35. package/dist/commands/release-notes.js.map +1 -0
  36. package/dist/commands/resume.d.ts +5 -0
  37. package/dist/commands/resume.js +79 -0
  38. package/dist/commands/resume.js.map +1 -0
  39. package/dist/commands/run.d.ts +27 -0
  40. package/dist/commands/run.js +243 -0
  41. package/dist/commands/run.js.map +1 -0
  42. package/dist/commands/shortcuts.d.ts +2 -0
  43. package/dist/commands/shortcuts.js +11 -0
  44. package/dist/commands/shortcuts.js.map +1 -0
  45. package/dist/commands/skills-dir.d.ts +2 -0
  46. package/dist/commands/skills-dir.js +9 -0
  47. package/dist/commands/skills-dir.js.map +1 -0
  48. package/dist/commands/status.d.ts +4 -0
  49. package/dist/commands/status.js +99 -0
  50. package/dist/commands/status.js.map +1 -0
  51. package/dist/commands/update.d.ts +4 -0
  52. package/dist/commands/update.js +65 -0
  53. package/dist/commands/update.js.map +1 -0
  54. package/dist/commands/version.d.ts +3 -0
  55. package/dist/commands/version.js +26 -0
  56. package/dist/commands/version.js.map +1 -0
  57. package/dist/commands/workflows.d.ts +4 -0
  58. package/dist/commands/workflows.js +111 -0
  59. package/dist/commands/workflows.js.map +1 -0
  60. package/dist/config.d.ts +8 -0
  61. package/dist/config.js +110 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/console.d.ts +103 -0
  64. package/dist/console.js +670 -0
  65. package/dist/console.js.map +1 -0
  66. package/dist/executor.d.ts +27 -0
  67. package/dist/executor.js +236 -0
  68. package/dist/executor.js.map +1 -0
  69. package/dist/git/worktree.d.ts +23 -0
  70. package/dist/git/worktree.js +170 -0
  71. package/dist/git/worktree.js.map +1 -0
  72. package/dist/logging/logger.d.ts +27 -0
  73. package/dist/logging/logger.js +69 -0
  74. package/dist/logging/logger.js.map +1 -0
  75. package/dist/orchestrator.d.ts +44 -0
  76. package/dist/orchestrator.js +587 -0
  77. package/dist/orchestrator.js.map +1 -0
  78. package/dist/parser.d.ts +17 -0
  79. package/dist/parser.js +184 -0
  80. package/dist/parser.js.map +1 -0
  81. package/dist/progress.d.ts +29 -0
  82. package/dist/progress.js +275 -0
  83. package/dist/progress.js.map +1 -0
  84. package/dist/ralph-loop.d.ts +26 -0
  85. package/dist/ralph-loop.js +194 -0
  86. package/dist/ralph-loop.js.map +1 -0
  87. package/dist/renderer.d.ts +15 -0
  88. package/dist/renderer.js +123 -0
  89. package/dist/renderer.js.map +1 -0
  90. package/dist/runner.d.ts +84 -0
  91. package/dist/runner.js +529 -0
  92. package/dist/runner.js.map +1 -0
  93. package/dist/signal-manager.d.ts +16 -0
  94. package/dist/signal-manager.js +50 -0
  95. package/dist/signal-manager.js.map +1 -0
  96. package/dist/steps/base.d.ts +28 -0
  97. package/dist/steps/base.js +23 -0
  98. package/dist/steps/base.js.map +1 -0
  99. package/dist/steps/conditional-step.d.ts +12 -0
  100. package/dist/steps/conditional-step.js +106 -0
  101. package/dist/steps/conditional-step.js.map +1 -0
  102. package/{src/steps/index.ts → dist/steps/index.d.ts} +1 -9
  103. package/dist/steps/index.js +8 -0
  104. package/dist/steps/index.js.map +1 -0
  105. package/dist/steps/parallel-step.d.ts +11 -0
  106. package/dist/steps/parallel-step.js +166 -0
  107. package/dist/steps/parallel-step.js.map +1 -0
  108. package/dist/steps/prompt-step.d.ts +8 -0
  109. package/dist/steps/prompt-step.js +94 -0
  110. package/dist/steps/prompt-step.js.map +1 -0
  111. package/dist/steps/ralph-loop-step.d.ts +8 -0
  112. package/dist/steps/ralph-loop-step.js +132 -0
  113. package/dist/steps/ralph-loop-step.js.map +1 -0
  114. package/dist/steps/serial-step.d.ts +10 -0
  115. package/dist/steps/serial-step.js +57 -0
  116. package/dist/steps/serial-step.js.map +1 -0
  117. package/dist/types.d.ts +118 -0
  118. package/dist/types.js +10 -0
  119. package/dist/types.js.map +1 -0
  120. package/package.json +59 -2
  121. package/.gitattributes +0 -24
  122. package/.github/workflows/ci.yml +0 -70
  123. package/.markdownlint-cli2.jsonc +0 -16
  124. package/.prettierignore +0 -3
  125. package/.prettierrc +0 -6
  126. package/.vscode/agentic-forge.code-workspace +0 -26
  127. package/CHANGELOG.md +0 -100
  128. package/CLAUDE.md +0 -158
  129. package/CONTRIBUTING.md +0 -152
  130. package/biome.json +0 -21
  131. package/scripts/copy-assets.js +0 -21
  132. package/src/checkpoints/manager.ts +0 -119
  133. package/src/cli.ts +0 -182
  134. package/src/commands/config-cmd.ts +0 -28
  135. package/src/commands/init.ts +0 -96
  136. package/src/commands/release-notes.ts +0 -85
  137. package/src/commands/resume.ts +0 -103
  138. package/src/commands/run.ts +0 -234
  139. package/src/commands/shortcuts.ts +0 -11
  140. package/src/commands/skills-dir.ts +0 -11
  141. package/src/commands/status.ts +0 -112
  142. package/src/commands/update.ts +0 -64
  143. package/src/commands/version.ts +0 -27
  144. package/src/commands/workflows.ts +0 -129
  145. package/src/config.ts +0 -129
  146. package/src/console.ts +0 -790
  147. package/src/executor.ts +0 -354
  148. package/src/git/worktree.ts +0 -236
  149. package/src/logging/logger.ts +0 -95
  150. package/src/orchestrator.ts +0 -815
  151. package/src/parser.ts +0 -225
  152. package/src/progress.ts +0 -306
  153. package/src/ralph-loop.ts +0 -260
  154. package/src/renderer.ts +0 -164
  155. package/src/runner.ts +0 -634
  156. package/src/signal-manager.ts +0 -55
  157. package/src/steps/base.ts +0 -71
  158. package/src/steps/conditional-step.ts +0 -144
  159. package/src/steps/parallel-step.ts +0 -213
  160. package/src/steps/prompt-step.ts +0 -121
  161. package/src/steps/ralph-loop-step.ts +0 -186
  162. package/src/steps/serial-step.ts +0 -84
  163. package/src/types.ts +0 -141
  164. package/tests/config.test.ts +0 -219
  165. package/tests/console.test.ts +0 -506
  166. package/tests/executor.test.ts +0 -339
  167. package/tests/init.test.ts +0 -86
  168. package/tests/logger.test.ts +0 -110
  169. package/tests/parser.test.ts +0 -290
  170. package/tests/progress.test.ts +0 -345
  171. package/tests/ralph-loop.test.ts +0 -418
  172. package/tests/renderer.test.ts +0 -350
  173. package/tests/runner.test.ts +0 -497
  174. package/tests/setup.test.ts +0 -7
  175. package/tests/signal-manager.test.ts +0 -26
  176. package/tests/steps.test.ts +0 -412
  177. package/tests/worktree.test.ts +0 -411
  178. package/tsconfig.json +0 -18
  179. package/vitest.config.ts +0 -8
  180. /package/{src → dist}/agents/explorer.md +0 -0
  181. /package/{src → dist}/agents/reviewer.md +0 -0
  182. /package/{src → dist}/claude/.claude/skills/analyze/references/bug.md +0 -0
  183. /package/{src → dist}/claude/.claude/skills/analyze/references/debt.md +0 -0
  184. /package/{src → dist}/claude/.claude/skills/analyze/references/doc.md +0 -0
  185. /package/{src → dist}/claude/.claude/skills/analyze/references/security.md +0 -0
  186. /package/{src → dist}/claude/.claude/skills/analyze/references/style.md +0 -0
  187. /package/{src → dist}/claude/.claude/skills/orchestrate/SKILL.md +0 -0
  188. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/bug.md +0 -0
  189. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/chore.md +0 -0
  190. /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/feature.md +0 -0
  191. /package/{src → dist}/prompts/agentic-system.md +0 -0
  192. /package/{src → dist}/templates/analysis/bug.md.j2 +0 -0
  193. /package/{src → dist}/templates/analysis/debt.md.j2 +0 -0
  194. /package/{src → dist}/templates/analysis/doc.md.j2 +0 -0
  195. /package/{src → dist}/templates/analysis/security.md.j2 +0 -0
  196. /package/{src → dist}/templates/analysis/style.md.j2 +0 -0
  197. /package/{src → dist}/templates/analysis-summary.md.j2 +0 -0
  198. /package/{src → dist}/templates/checkpoint.md.j2 +0 -0
  199. /package/{src → dist}/templates/implementation-report.md.j2 +0 -0
  200. /package/{src → dist}/templates/memory.md.j2 +0 -0
  201. /package/{src → dist}/templates/plan-bug.md.j2 +0 -0
  202. /package/{src → dist}/templates/plan-chore.md.j2 +0 -0
  203. /package/{src → dist}/templates/plan-feature.md.j2 +0 -0
  204. /package/{src → dist}/templates/progress.json.j2 +0 -0
  205. /package/{src → dist}/templates/ralph-report.md.j2 +0 -0
  206. /package/{src → dist}/workflows/analyze-codebase-merge.yaml +0 -0
  207. /package/{src → dist}/workflows/analyze-codebase.yaml +0 -0
  208. /package/{src → dist}/workflows/analyze-single.yaml +0 -0
  209. /package/{src → dist}/workflows/demo.yaml +0 -0
  210. /package/{src → dist}/workflows/one-shot.yaml +0 -0
  211. /package/{src → dist}/workflows/plan-build-review.yaml +0 -0
  212. /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