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.
- package/LICENSE +21 -21
- package/README.md +64 -24
- package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/SKILL.md +2 -2
- package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/references/REFERENCE.md +9 -3
- package/{src/claude → dist/authoring}/.claude/skills/workflow-builder/references/workflow-example.yaml +15 -8
- package/dist/checkpoints/manager.d.ts +5 -0
- package/dist/checkpoints/manager.js +87 -0
- package/dist/checkpoints/manager.js.map +1 -0
- package/{src → dist}/claude/.claude/skills/analyze/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/create-checkpoint/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/create-log/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/fix-analyze/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/git-branch/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/git-commit/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/git-pr/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/sdlc-plan/SKILL.md +1 -1
- package/{src → dist}/claude/.claude/skills/sdlc-review/SKILL.md +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +173 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/authoring-dir.d.ts +2 -0
- package/dist/commands/authoring-dir.js +9 -0
- package/dist/commands/authoring-dir.js.map +1 -0
- package/dist/commands/config-cmd.d.ts +2 -0
- package/dist/commands/config-cmd.js +30 -0
- package/dist/commands/config-cmd.js.map +1 -0
- package/{src/commands/index.ts → dist/commands/index.d.ts} +2 -10
- package/dist/commands/index.js +14 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.js +83 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/release-notes.d.ts +5 -0
- package/dist/commands/release-notes.js +68 -0
- package/dist/commands/release-notes.js.map +1 -0
- package/dist/commands/resume.d.ts +5 -0
- package/dist/commands/resume.js +79 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/run.d.ts +27 -0
- package/dist/commands/run.js +243 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/shortcuts.d.ts +2 -0
- package/dist/commands/shortcuts.js +11 -0
- package/dist/commands/shortcuts.js.map +1 -0
- package/dist/commands/skills-dir.d.ts +2 -0
- package/dist/commands/skills-dir.js +9 -0
- package/dist/commands/skills-dir.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.js +99 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +4 -0
- package/dist/commands/update.js +65 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/version.d.ts +3 -0
- package/dist/commands/version.js +26 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/commands/workflows.d.ts +4 -0
- package/dist/commands/workflows.js +111 -0
- package/dist/commands/workflows.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +110 -0
- package/dist/config.js.map +1 -0
- package/dist/console.d.ts +103 -0
- package/dist/console.js +670 -0
- package/dist/console.js.map +1 -0
- package/dist/executor.d.ts +27 -0
- package/dist/executor.js +236 -0
- package/dist/executor.js.map +1 -0
- package/dist/git/worktree.d.ts +23 -0
- package/dist/git/worktree.js +170 -0
- package/dist/git/worktree.js.map +1 -0
- package/dist/logging/logger.d.ts +27 -0
- package/dist/logging/logger.js +69 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/orchestrator.d.ts +44 -0
- package/dist/orchestrator.js +587 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/parser.d.ts +17 -0
- package/dist/parser.js +184 -0
- package/dist/parser.js.map +1 -0
- package/dist/progress.d.ts +29 -0
- package/dist/progress.js +275 -0
- package/dist/progress.js.map +1 -0
- package/dist/ralph-loop.d.ts +26 -0
- package/dist/ralph-loop.js +194 -0
- package/dist/ralph-loop.js.map +1 -0
- package/dist/renderer.d.ts +15 -0
- package/dist/renderer.js +123 -0
- package/dist/renderer.js.map +1 -0
- package/dist/runner.d.ts +84 -0
- package/dist/runner.js +529 -0
- package/dist/runner.js.map +1 -0
- package/dist/signal-manager.d.ts +16 -0
- package/dist/signal-manager.js +50 -0
- package/dist/signal-manager.js.map +1 -0
- package/dist/steps/base.d.ts +28 -0
- package/dist/steps/base.js +23 -0
- package/dist/steps/base.js.map +1 -0
- package/dist/steps/conditional-step.d.ts +12 -0
- package/dist/steps/conditional-step.js +106 -0
- package/dist/steps/conditional-step.js.map +1 -0
- package/{src/steps/index.ts → dist/steps/index.d.ts} +1 -9
- package/dist/steps/index.js +8 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/parallel-step.d.ts +11 -0
- package/dist/steps/parallel-step.js +166 -0
- package/dist/steps/parallel-step.js.map +1 -0
- package/dist/steps/prompt-step.d.ts +8 -0
- package/dist/steps/prompt-step.js +94 -0
- package/dist/steps/prompt-step.js.map +1 -0
- package/dist/steps/ralph-loop-step.d.ts +8 -0
- package/dist/steps/ralph-loop-step.js +132 -0
- package/dist/steps/ralph-loop-step.js.map +1 -0
- package/dist/steps/serial-step.d.ts +10 -0
- package/dist/steps/serial-step.js +57 -0
- package/dist/steps/serial-step.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +59 -2
- package/.gitattributes +0 -24
- package/.github/workflows/ci.yml +0 -70
- package/.markdownlint-cli2.jsonc +0 -16
- package/.prettierignore +0 -3
- package/.prettierrc +0 -6
- package/.vscode/agentic-forge.code-workspace +0 -26
- package/CHANGELOG.md +0 -100
- package/CLAUDE.md +0 -158
- package/CONTRIBUTING.md +0 -152
- package/biome.json +0 -21
- package/scripts/copy-assets.js +0 -21
- package/src/checkpoints/manager.ts +0 -119
- package/src/cli.ts +0 -182
- package/src/commands/config-cmd.ts +0 -28
- package/src/commands/init.ts +0 -96
- package/src/commands/release-notes.ts +0 -85
- package/src/commands/resume.ts +0 -103
- package/src/commands/run.ts +0 -234
- package/src/commands/shortcuts.ts +0 -11
- package/src/commands/skills-dir.ts +0 -11
- package/src/commands/status.ts +0 -112
- package/src/commands/update.ts +0 -64
- package/src/commands/version.ts +0 -27
- package/src/commands/workflows.ts +0 -129
- package/src/config.ts +0 -129
- package/src/console.ts +0 -790
- package/src/executor.ts +0 -354
- package/src/git/worktree.ts +0 -236
- package/src/logging/logger.ts +0 -95
- package/src/orchestrator.ts +0 -815
- package/src/parser.ts +0 -225
- package/src/progress.ts +0 -306
- package/src/ralph-loop.ts +0 -260
- package/src/renderer.ts +0 -164
- package/src/runner.ts +0 -634
- package/src/signal-manager.ts +0 -55
- package/src/steps/base.ts +0 -71
- package/src/steps/conditional-step.ts +0 -144
- package/src/steps/parallel-step.ts +0 -213
- package/src/steps/prompt-step.ts +0 -121
- package/src/steps/ralph-loop-step.ts +0 -186
- package/src/steps/serial-step.ts +0 -84
- package/src/types.ts +0 -141
- package/tests/config.test.ts +0 -219
- package/tests/console.test.ts +0 -506
- package/tests/executor.test.ts +0 -339
- package/tests/init.test.ts +0 -86
- package/tests/logger.test.ts +0 -110
- package/tests/parser.test.ts +0 -290
- package/tests/progress.test.ts +0 -345
- package/tests/ralph-loop.test.ts +0 -418
- package/tests/renderer.test.ts +0 -350
- package/tests/runner.test.ts +0 -497
- package/tests/setup.test.ts +0 -7
- package/tests/signal-manager.test.ts +0 -26
- package/tests/steps.test.ts +0 -412
- package/tests/worktree.test.ts +0 -411
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -8
- /package/{src → dist}/agents/explorer.md +0 -0
- /package/{src → dist}/agents/reviewer.md +0 -0
- /package/{src → dist}/claude/.claude/skills/analyze/references/bug.md +0 -0
- /package/{src → dist}/claude/.claude/skills/analyze/references/debt.md +0 -0
- /package/{src → dist}/claude/.claude/skills/analyze/references/doc.md +0 -0
- /package/{src → dist}/claude/.claude/skills/analyze/references/security.md +0 -0
- /package/{src → dist}/claude/.claude/skills/analyze/references/style.md +0 -0
- /package/{src → dist}/claude/.claude/skills/orchestrate/SKILL.md +0 -0
- /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/bug.md +0 -0
- /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/chore.md +0 -0
- /package/{src → dist}/claude/.claude/skills/sdlc-plan/references/feature.md +0 -0
- /package/{src → dist}/prompts/agentic-system.md +0 -0
- /package/{src → dist}/templates/analysis/bug.md.j2 +0 -0
- /package/{src → dist}/templates/analysis/debt.md.j2 +0 -0
- /package/{src → dist}/templates/analysis/doc.md.j2 +0 -0
- /package/{src → dist}/templates/analysis/security.md.j2 +0 -0
- /package/{src → dist}/templates/analysis/style.md.j2 +0 -0
- /package/{src → dist}/templates/analysis-summary.md.j2 +0 -0
- /package/{src → dist}/templates/checkpoint.md.j2 +0 -0
- /package/{src → dist}/templates/implementation-report.md.j2 +0 -0
- /package/{src → dist}/templates/memory.md.j2 +0 -0
- /package/{src → dist}/templates/plan-bug.md.j2 +0 -0
- /package/{src → dist}/templates/plan-chore.md.j2 +0 -0
- /package/{src → dist}/templates/plan-feature.md.j2 +0 -0
- /package/{src → dist}/templates/progress.json.j2 +0 -0
- /package/{src → dist}/templates/ralph-report.md.j2 +0 -0
- /package/{src → dist}/workflows/analyze-codebase-merge.yaml +0 -0
- /package/{src → dist}/workflows/analyze-codebase.yaml +0 -0
- /package/{src → dist}/workflows/analyze-single.yaml +0 -0
- /package/{src → dist}/workflows/demo.yaml +0 -0
- /package/{src → dist}/workflows/one-shot.yaml +0 -0
- /package/{src → dist}/workflows/plan-build-review.yaml +0 -0
- /package/{src → dist}/workflows/ralph-loop.yaml +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Base class and types for step executors. */
|
|
2
|
+
export function buildTemplateContext(context) {
|
|
3
|
+
return {
|
|
4
|
+
variables: context.variables,
|
|
5
|
+
outputs: context.outputs,
|
|
6
|
+
workflow_id: context.workflowId,
|
|
7
|
+
...context.variables,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function resolveModel(context, stepModel) {
|
|
11
|
+
if (stepModel) {
|
|
12
|
+
return stepModel;
|
|
13
|
+
}
|
|
14
|
+
if (context.workflowSettings?.model) {
|
|
15
|
+
return context.workflowSettings.model;
|
|
16
|
+
}
|
|
17
|
+
const defaults = context.config.defaults;
|
|
18
|
+
return defaults?.model ?? "sonnet";
|
|
19
|
+
}
|
|
20
|
+
// --- Abstract base ---
|
|
21
|
+
export class StepExecutor {
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/steps/base.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAoB/C,MAAM,UAAU,oBAAoB,CAAC,OAAoB;IACxD,OAAO;QACN,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,UAAU;QAC/B,GAAI,OAAO,CAAC,SAAqC;KACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAoB,EAAE,SAAyB;IAC3E,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC;QACrC,OAAO,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC;IACvC,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAA+C,CAAC;IAChF,OAAQ,QAAQ,EAAE,KAAgB,IAAI,QAAQ,CAAC;AAChD,CAAC;AAWD,wBAAwB;AAExB,MAAM,OAAgB,YAAY;CAQjC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Conditional step executor. */
|
|
2
|
+
import type { ConsoleOutput } from "../console.js";
|
|
3
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
4
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
5
|
+
import { type BranchStepExecutor, type StepContext, StepExecutor, type StepResult } from "./base.js";
|
|
6
|
+
export declare class ConditionalStepExecutor extends StepExecutor {
|
|
7
|
+
private branchExecutor;
|
|
8
|
+
constructor(branchExecutor: BranchStepExecutor);
|
|
9
|
+
execute(step: StepDefinition, progress: WorkflowProgress, context: StepContext, logger: WorkflowLogger, console: ConsoleOutput): Promise<StepResult>;
|
|
10
|
+
evaluateCondition(condition: string, context: Record<string, unknown>): boolean;
|
|
11
|
+
resolveValue(expr: string, context: Record<string, unknown>): unknown;
|
|
12
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Conditional step executor. */
|
|
2
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
3
|
+
import { StepExecutor, buildTemplateContext, } from "./base.js";
|
|
4
|
+
export class ConditionalStepExecutor extends StepExecutor {
|
|
5
|
+
branchExecutor;
|
|
6
|
+
constructor(branchExecutor) {
|
|
7
|
+
super();
|
|
8
|
+
this.branchExecutor = branchExecutor;
|
|
9
|
+
}
|
|
10
|
+
async execute(step, progress, context, logger, console) {
|
|
11
|
+
let condition = step.condition ?? "false";
|
|
12
|
+
logger.info(step.name, `Evaluating condition: ${condition}`);
|
|
13
|
+
const templateContext = buildTemplateContext(context);
|
|
14
|
+
if (context.renderer.hasVariables(condition)) {
|
|
15
|
+
condition = context.renderer.renderString(condition, templateContext);
|
|
16
|
+
}
|
|
17
|
+
const conditionResult = this.evaluateCondition(condition, templateContext);
|
|
18
|
+
logger.info(step.name, `Condition evaluated to: ${conditionResult}`);
|
|
19
|
+
console.info(`Conditional '${step.name}': ${condition} = ${conditionResult}`);
|
|
20
|
+
const stepsToRun = conditionResult ? step.thenSteps : step.elseSteps;
|
|
21
|
+
const branchName = conditionResult ? "then" : "else";
|
|
22
|
+
if (!stepsToRun || stepsToRun.length === 0) {
|
|
23
|
+
const outputSummary = `Condition ${conditionResult}, no '${branchName}' branch to execute`;
|
|
24
|
+
updateStepCompleted(progress, step.name, outputSummary);
|
|
25
|
+
console.stepComplete(step.name, outputSummary);
|
|
26
|
+
return { success: true, outputSummary };
|
|
27
|
+
}
|
|
28
|
+
logger.info(step.name, `Executing '${branchName}' branch with ${stepsToRun.length} steps`);
|
|
29
|
+
for (const subStep of stepsToRun) {
|
|
30
|
+
try {
|
|
31
|
+
const result = await this.branchExecutor(subStep, progress, context, logger, console);
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
logger.warning(step.name, `Conditional '${branchName}' branch stopped due to failure`);
|
|
34
|
+
const errorMsg = `Step '${subStep.name}' failed: ${result.error}`;
|
|
35
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
36
|
+
console.stepFailed(step.name, `Step '${subStep.name}' failed`);
|
|
37
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
38
|
+
return { success: false, error: errorMsg };
|
|
39
|
+
}
|
|
40
|
+
if (progress.status === WORKFLOW_STATUS.FAILED) {
|
|
41
|
+
logger.warning(step.name, `Conditional '${branchName}' branch stopped due to failure`);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
const errStr = e instanceof Error ? e.message : String(e);
|
|
47
|
+
logger.error(subStep.name, `Step failed in conditional branch: ${errStr}`);
|
|
48
|
+
const errorMsg = `Step '${subStep.name}' failed: ${errStr}`;
|
|
49
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
50
|
+
console.stepFailed(step.name, `Step '${subStep.name}' failed`);
|
|
51
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
52
|
+
return { success: false, error: errorMsg };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (progress.status !== WORKFLOW_STATUS.FAILED) {
|
|
56
|
+
const outputSummary = `Executed '${branchName}' branch (${stepsToRun.length} steps)`;
|
|
57
|
+
updateStepCompleted(progress, step.name, outputSummary);
|
|
58
|
+
console.stepComplete(step.name, outputSummary);
|
|
59
|
+
logger.info(step.name, outputSummary);
|
|
60
|
+
return { success: true, outputSummary };
|
|
61
|
+
}
|
|
62
|
+
return { success: false, error: "Conditional execution failed" };
|
|
63
|
+
}
|
|
64
|
+
evaluateCondition(condition, context) {
|
|
65
|
+
const trimmed = condition.trim();
|
|
66
|
+
if (["true", "1", "yes"].includes(trimmed.toLowerCase())) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (["false", "0", "no", "none", ""].includes(trimmed.toLowerCase())) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (trimmed.includes("!=")) {
|
|
73
|
+
const [left, right] = trimmed.split("!=", 2);
|
|
74
|
+
const leftVal = this.resolveValue(left.trim(), context);
|
|
75
|
+
const rightVal = this.resolveValue(right.trim(), context);
|
|
76
|
+
return leftVal !== rightVal;
|
|
77
|
+
}
|
|
78
|
+
if (trimmed.includes("==")) {
|
|
79
|
+
const [left, right] = trimmed.split("==", 2);
|
|
80
|
+
const leftVal = this.resolveValue(left.trim(), context);
|
|
81
|
+
const rightVal = this.resolveValue(right.trim(), context);
|
|
82
|
+
return leftVal === rightVal;
|
|
83
|
+
}
|
|
84
|
+
const value = this.resolveValue(trimmed, context);
|
|
85
|
+
return (Boolean(value) && value !== "none" && value !== "None" && value !== "null" && value !== "");
|
|
86
|
+
}
|
|
87
|
+
resolveValue(expr, context) {
|
|
88
|
+
const trimmed = expr.trim();
|
|
89
|
+
if ((trimmed.startsWith("'") && trimmed.endsWith("'")) ||
|
|
90
|
+
(trimmed.startsWith('"') && trimmed.endsWith('"'))) {
|
|
91
|
+
return trimmed.slice(1, -1);
|
|
92
|
+
}
|
|
93
|
+
if (trimmed.startsWith("variables.")) {
|
|
94
|
+
const varName = trimmed.slice(10);
|
|
95
|
+
const vars = context.variables;
|
|
96
|
+
return vars?.[varName];
|
|
97
|
+
}
|
|
98
|
+
if (trimmed.startsWith("outputs.")) {
|
|
99
|
+
const outputName = trimmed.slice(8);
|
|
100
|
+
const outputs = context.outputs;
|
|
101
|
+
return outputs?.[outputName];
|
|
102
|
+
}
|
|
103
|
+
return context[trimmed] ?? trimmed;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=conditional-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conditional-step.js","sourceRoot":"","sources":["../../src/steps/conditional-step.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
/** Step executors for workflow execution. */
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
StepContext,
|
|
5
|
-
StepResult,
|
|
6
|
-
StepExecutor,
|
|
7
|
-
BranchStepExecutor,
|
|
8
|
-
buildTemplateContext,
|
|
9
|
-
resolveModel,
|
|
10
|
-
} from "./base.js";
|
|
2
|
+
export { StepContext, StepResult, StepExecutor, BranchStepExecutor, buildTemplateContext, resolveModel, } from "./base.js";
|
|
11
3
|
export { PromptStepExecutor } from "./prompt-step.js";
|
|
12
4
|
export { SerialStepExecutor } from "./serial-step.js";
|
|
13
5
|
export { ConditionalStepExecutor } from "./conditional-step.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Step executors for workflow execution. */
|
|
2
|
+
export { StepExecutor, buildTemplateContext, resolveModel, } from "./base.js";
|
|
3
|
+
export { PromptStepExecutor } from "./prompt-step.js";
|
|
4
|
+
export { SerialStepExecutor } from "./serial-step.js";
|
|
5
|
+
export { ConditionalStepExecutor } from "./conditional-step.js";
|
|
6
|
+
export { RalphLoopStepExecutor } from "./ralph-loop-step.js";
|
|
7
|
+
export { ParallelStepExecutor } from "./parallel-step.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/steps/index.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,EAGN,YAAY,EAEZ,oBAAoB,EACpB,YAAY,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Parallel step executor. */
|
|
2
|
+
import type { ConsoleOutput } from "../console.js";
|
|
3
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
4
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
5
|
+
import { type BranchStepExecutor, type StepContext, StepExecutor, type StepResult } from "./base.js";
|
|
6
|
+
export declare class ParallelStepExecutor extends StepExecutor {
|
|
7
|
+
private branchExecutor;
|
|
8
|
+
constructor(branchExecutor: BranchStepExecutor);
|
|
9
|
+
execute(step: StepDefinition, progress: WorkflowProgress, context: StepContext, logger: WorkflowLogger, console: ConsoleOutput): Promise<StepResult>;
|
|
10
|
+
private mergeWorktreeBranches;
|
|
11
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** Parallel step executor. */
|
|
2
|
+
import { createWorktree, removeWorktree, runGit } from "../git/worktree.js";
|
|
3
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
4
|
+
import { StepExecutor, } from "./base.js";
|
|
5
|
+
export class ParallelStepExecutor extends StepExecutor {
|
|
6
|
+
branchExecutor;
|
|
7
|
+
constructor(branchExecutor) {
|
|
8
|
+
super();
|
|
9
|
+
this.branchExecutor = branchExecutor;
|
|
10
|
+
}
|
|
11
|
+
async execute(step, progress, context, logger, console) {
|
|
12
|
+
if (!step.steps || step.steps.length === 0) {
|
|
13
|
+
logger.warning(step.name, "Parallel step has no sub-steps");
|
|
14
|
+
updateStepCompleted(progress, step.name, "No sub-steps to execute");
|
|
15
|
+
console.stepComplete(step.name, "No sub-steps to execute");
|
|
16
|
+
return { success: true, outputSummary: "No sub-steps to execute" };
|
|
17
|
+
}
|
|
18
|
+
const useWorktree = step.git?.worktree ?? false;
|
|
19
|
+
logger.info(step.name, `Starting parallel execution of ${step.steps.length} branches`);
|
|
20
|
+
if (useWorktree) {
|
|
21
|
+
console.info(`Parallel: starting ${step.steps.length} branches (worktree isolation)`);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.info(`Parallel: starting ${step.steps.length} branches`);
|
|
25
|
+
}
|
|
26
|
+
// Register branches for parallel display
|
|
27
|
+
const branchNames = step.steps.map((s) => s.name);
|
|
28
|
+
console.registerParallelBranches(branchNames);
|
|
29
|
+
console.enterParallelMode();
|
|
30
|
+
const branchResults = {};
|
|
31
|
+
const failedBranches = [];
|
|
32
|
+
const worktrees = {};
|
|
33
|
+
const executeBranch = async (branchStep) => {
|
|
34
|
+
const branchContext = {
|
|
35
|
+
...context,
|
|
36
|
+
variables: { ...context.variables },
|
|
37
|
+
};
|
|
38
|
+
let worktree = null;
|
|
39
|
+
try {
|
|
40
|
+
console.setParallelBranch(branchStep.name);
|
|
41
|
+
if (useWorktree) {
|
|
42
|
+
worktree = createWorktree(progress.workflowName, branchStep.name, undefined, context.repoRoot);
|
|
43
|
+
logger.info(branchStep.name, `Created worktree: ${worktree.path}`);
|
|
44
|
+
console.info(` Branch '${branchStep.name}' worktree: ${worktree.branch}`);
|
|
45
|
+
branchContext.cwdOverride = worktree.path;
|
|
46
|
+
}
|
|
47
|
+
const result = await this.branchExecutor(branchStep, progress, branchContext, logger, console);
|
|
48
|
+
return [branchStep.name, result.success, result.outputSummary ?? "", worktree];
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
const errStr = e instanceof Error ? (e.stack ?? e.message) : String(e);
|
|
52
|
+
logger.error(branchStep.name, `Branch failed with exception: ${errStr}`);
|
|
53
|
+
return [branchStep.name, false, String(e), worktree];
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
// Execute branches with concurrency cap from config
|
|
57
|
+
const execution = context.config?.execution;
|
|
58
|
+
const maxWorkers = execution?.maxWorkers ?? 4;
|
|
59
|
+
const settled = [];
|
|
60
|
+
const queue = [...step.steps];
|
|
61
|
+
const runNext = async () => {
|
|
62
|
+
while (queue.length > 0) {
|
|
63
|
+
const branchStep = queue.shift();
|
|
64
|
+
if (!branchStep)
|
|
65
|
+
break;
|
|
66
|
+
try {
|
|
67
|
+
const value = await executeBranch(branchStep);
|
|
68
|
+
settled.push({ status: "fulfilled", value });
|
|
69
|
+
}
|
|
70
|
+
catch (reason) {
|
|
71
|
+
settled.push({ status: "rejected", reason });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const workers = Array.from({ length: Math.min(maxWorkers, queue.length) }, () => runNext());
|
|
76
|
+
await Promise.all(workers);
|
|
77
|
+
const results = settled;
|
|
78
|
+
for (const result of results) {
|
|
79
|
+
if (result.status === "fulfilled") {
|
|
80
|
+
const [name, success, output, worktree] = result.value;
|
|
81
|
+
branchResults[name] = { success, output };
|
|
82
|
+
if (worktree) {
|
|
83
|
+
worktrees[name] = worktree;
|
|
84
|
+
}
|
|
85
|
+
if (success) {
|
|
86
|
+
console.info(` Branch '${name}' completed`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.error(` Branch '${name}' failed: ${output}`);
|
|
90
|
+
failedBranches.push(name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// Promise rejected — should be rare since executeBranch catches errors
|
|
95
|
+
const reason = String(result.reason);
|
|
96
|
+
// We can't easily get the branch name from a rejected promise
|
|
97
|
+
// but this case is already handled by the try/catch inside executeBranch
|
|
98
|
+
logger.error(step.name, `Branch promise rejected: ${reason}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Exit parallel mode
|
|
102
|
+
console.exitParallelMode();
|
|
103
|
+
// Handle merge modes
|
|
104
|
+
if (step.mergeMode === "merge" && Object.keys(worktrees).length > 0) {
|
|
105
|
+
const mergeFailures = this.mergeWorktreeBranches(step, worktrees, failedBranches, context, logger, console);
|
|
106
|
+
failedBranches.push(...mergeFailures);
|
|
107
|
+
}
|
|
108
|
+
if (step.mergeMode === "independent" && Object.keys(worktrees).length > 0) {
|
|
109
|
+
for (const [name, worktree] of Object.entries(worktrees)) {
|
|
110
|
+
removeWorktree(worktree, context.repoRoot, false);
|
|
111
|
+
logger.info(name, `Worktree removed, branch preserved: ${worktree.branch}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Handle completion based on merge strategy
|
|
115
|
+
if (step.mergeStrategy === "wait-all") {
|
|
116
|
+
if (failedBranches.length > 0 && step.mergeMode !== "independent") {
|
|
117
|
+
const errorMsg = `Parallel branches failed: ${failedBranches.join(", ")}`;
|
|
118
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
119
|
+
console.stepFailed(step.name, errorMsg);
|
|
120
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
121
|
+
return { success: false, error: errorMsg };
|
|
122
|
+
}
|
|
123
|
+
const completed = step.steps.length - failedBranches.length;
|
|
124
|
+
let outputSummary = `Completed ${completed}/${step.steps.length} branches`;
|
|
125
|
+
if (failedBranches.length > 0) {
|
|
126
|
+
outputSummary += ` (failed: ${failedBranches.join(", ")})`;
|
|
127
|
+
}
|
|
128
|
+
updateStepCompleted(progress, step.name, outputSummary);
|
|
129
|
+
console.stepComplete(step.name, outputSummary);
|
|
130
|
+
logger.info(step.name, outputSummary);
|
|
131
|
+
return { success: true, outputSummary };
|
|
132
|
+
}
|
|
133
|
+
const outputSummary = "Parallel execution completed";
|
|
134
|
+
updateStepCompleted(progress, step.name, outputSummary);
|
|
135
|
+
console.stepComplete(step.name, outputSummary);
|
|
136
|
+
logger.info(step.name, outputSummary);
|
|
137
|
+
return { success: true, outputSummary };
|
|
138
|
+
}
|
|
139
|
+
mergeWorktreeBranches(step, worktrees, failedBranches, context, logger, console) {
|
|
140
|
+
console.info("Merging parallel branches...");
|
|
141
|
+
const mergeFailures = [];
|
|
142
|
+
for (const [name, worktree] of Object.entries(worktrees)) {
|
|
143
|
+
if (failedBranches.includes(name)) {
|
|
144
|
+
removeWorktree(worktree, context.repoRoot, true);
|
|
145
|
+
logger.info(name, "Failed branch worktree removed");
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
runGit(["checkout", worktree.baseBranch], context.repoRoot);
|
|
150
|
+
runGit(["merge", "--no-ff", "-m", `Merge parallel branch: ${name}`, worktree.branch], context.repoRoot);
|
|
151
|
+
logger.info(name, `Merged branch ${worktree.branch} into ${worktree.baseBranch}`);
|
|
152
|
+
console.info(` Merged '${name}'`);
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
const errStr = e instanceof Error ? e.message : String(e);
|
|
156
|
+
logger.error(name, `Merge failed: ${errStr}`);
|
|
157
|
+
console.error(` Merge failed for '${name}': ${errStr}`);
|
|
158
|
+
mergeFailures.push(name);
|
|
159
|
+
}
|
|
160
|
+
removeWorktree(worktree, context.repoRoot, true);
|
|
161
|
+
logger.info(name, "Worktree and branch cleaned up");
|
|
162
|
+
}
|
|
163
|
+
return mergeFailures;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=parallel-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel-step.js","sourceRoot":"","sources":["../../src/steps/parallel-step.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Prompt step executor. */
|
|
2
|
+
import type { ConsoleOutput } from "../console.js";
|
|
3
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
4
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
5
|
+
import { type StepContext, StepExecutor, type StepResult } from "./base.js";
|
|
6
|
+
export declare class PromptStepExecutor extends StepExecutor {
|
|
7
|
+
execute(step: StepDefinition, progress: WorkflowProgress, context: StepContext, logger: WorkflowLogger, console: ConsoleOutput): Promise<StepResult>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Prompt step executor. */
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { extractJson, extractSummary } from "../console.js";
|
|
6
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
7
|
+
import { runClaude } from "../runner.js";
|
|
8
|
+
import { StepExecutor, buildTemplateContext, resolveModel, } from "./base.js";
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
export class PromptStepExecutor extends StepExecutor {
|
|
11
|
+
async execute(step, progress, context, logger, console) {
|
|
12
|
+
let prompt = step.prompt ?? "";
|
|
13
|
+
const templateContext = buildTemplateContext(context);
|
|
14
|
+
if (context.renderer.hasVariables(prompt)) {
|
|
15
|
+
prompt = context.renderer.renderString(prompt, templateContext);
|
|
16
|
+
}
|
|
17
|
+
const cwd = context.cwdOverride ?? context.repoRoot;
|
|
18
|
+
// Load agent file if specified (fallback to bundled agents)
|
|
19
|
+
if (step.agent) {
|
|
20
|
+
let agentPath = path.join(context.repoRoot, step.agent);
|
|
21
|
+
if (!existsSync(agentPath)) {
|
|
22
|
+
agentPath = path.join(__dirname, "..", "agents", path.basename(step.agent));
|
|
23
|
+
}
|
|
24
|
+
if (existsSync(agentPath)) {
|
|
25
|
+
const agentContent = readFileSync(agentPath, "utf-8");
|
|
26
|
+
prompt = `${agentContent}\n\n${prompt}`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const timeout = (step.stepTimeoutMinutes ?? 60) * 60;
|
|
30
|
+
const defaults = context.config.defaults;
|
|
31
|
+
const maxRetry = step.stepMaxRetry ?? defaults?.maxRetry ?? 3;
|
|
32
|
+
const bypassPermissions = context.workflowSettings?.bypassPermissions ?? false;
|
|
33
|
+
const allowedTools = context.workflowSettings?.requiredTools?.length
|
|
34
|
+
? context.workflowSettings.requiredTools
|
|
35
|
+
: null;
|
|
36
|
+
// Always enable streaming when console is provided
|
|
37
|
+
const printOutput = true;
|
|
38
|
+
for (let attempt = 0; attempt <= maxRetry; attempt++) {
|
|
39
|
+
const result = await runClaude({
|
|
40
|
+
prompt,
|
|
41
|
+
cwd,
|
|
42
|
+
model: resolveModel(context, step.model),
|
|
43
|
+
timeout,
|
|
44
|
+
printOutput,
|
|
45
|
+
skipPermissions: bypassPermissions,
|
|
46
|
+
allowedTools,
|
|
47
|
+
console,
|
|
48
|
+
workflowId: context.workflowId,
|
|
49
|
+
});
|
|
50
|
+
if (result.success) {
|
|
51
|
+
// Use session output context if available, fall back to extracted summary
|
|
52
|
+
const sessionOut = result.sessionOutput;
|
|
53
|
+
let outputSummary;
|
|
54
|
+
if (sessionOut.isSuccess && sessionOut.context) {
|
|
55
|
+
outputSummary = sessionOut.context;
|
|
56
|
+
if (sessionOut.sessionId) {
|
|
57
|
+
logger.info(step.name, `Session ID: ${sessionOut.sessionId}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
outputSummary = result.stdout ? extractSummary(result.stdout) : "";
|
|
62
|
+
}
|
|
63
|
+
// Try to extract structured JSON from skill output
|
|
64
|
+
const stepOutput = result.stdout ? extractJson(result.stdout) : null;
|
|
65
|
+
const outputValue = stepOutput ?? result.stdout;
|
|
66
|
+
updateStepCompleted(progress, step.name, outputSummary, outputValue);
|
|
67
|
+
console.stepComplete(step.name, outputSummary);
|
|
68
|
+
logger.info(step.name, "Step completed successfully");
|
|
69
|
+
return { success: true, outputSummary, fullOutput: result.stdout };
|
|
70
|
+
}
|
|
71
|
+
if (attempt < maxRetry) {
|
|
72
|
+
const errorSummary = result.stderr ? extractSummary(result.stderr) : "Unknown error";
|
|
73
|
+
console.stepRetry(step.name, attempt + 1, maxRetry + 1, errorSummary);
|
|
74
|
+
logger.warning(step.name, `Attempt ${attempt + 1} failed, retrying...`, {
|
|
75
|
+
error: result.stderr,
|
|
76
|
+
});
|
|
77
|
+
if (progress.currentStep) {
|
|
78
|
+
progress.currentStep.retryCount = attempt + 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const errorMsg = result.stderr || "Step failed";
|
|
83
|
+
const errorSummary = errorMsg ? extractSummary(errorMsg) : "Unknown error";
|
|
84
|
+
console.stepFailed(step.name, errorSummary);
|
|
85
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
86
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
87
|
+
logger.error(step.name, `Step failed after ${maxRetry + 1} attempts`);
|
|
88
|
+
return { success: false, error: errorMsg };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { success: false, error: "Unexpected exit from retry loop" };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=prompt-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-step.js","sourceRoot":"","sources":["../../src/steps/prompt-step.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Ralph loop step executor. */
|
|
2
|
+
import type { ConsoleOutput } from "../console.js";
|
|
3
|
+
import type { WorkflowLogger } from "../logging/logger.js";
|
|
4
|
+
import type { StepDefinition, WorkflowProgress } from "../types.js";
|
|
5
|
+
import { type StepContext, StepExecutor, type StepResult } from "./base.js";
|
|
6
|
+
export declare class RalphLoopStepExecutor extends StepExecutor {
|
|
7
|
+
execute(step: StepDefinition, progress: WorkflowProgress, context: StepContext, logger: WorkflowLogger, console: ConsoleOutput): Promise<StepResult>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** Ralph loop step executor. */
|
|
2
|
+
import { extractSummary } from "../console.js";
|
|
3
|
+
import { WORKFLOW_STATUS, updateStepCompleted, updateStepFailed } from "../progress.js";
|
|
4
|
+
import { buildRalphSystemMessage, createRalphState, deactivateRalphState, detectCompletionPromise, loadRalphState, updateRalphIteration, } from "../ralph-loop.js";
|
|
5
|
+
import { runClaude } from "../runner.js";
|
|
6
|
+
import { StepExecutor, buildTemplateContext, resolveModel, } from "./base.js";
|
|
7
|
+
export class RalphLoopStepExecutor extends StepExecutor {
|
|
8
|
+
async execute(step, progress, context, logger, console) {
|
|
9
|
+
const promptTemplate = step.prompt ?? "";
|
|
10
|
+
const templateContext = buildTemplateContext(context);
|
|
11
|
+
let completionPromise = step.completionPromise ?? "COMPLETE";
|
|
12
|
+
if (context.renderer.hasVariables(completionPromise)) {
|
|
13
|
+
completionPromise = context.renderer.renderString(completionPromise, templateContext);
|
|
14
|
+
}
|
|
15
|
+
// Handle max_iterations which may be a template string or integer
|
|
16
|
+
const maxIterationsRaw = step.maxIterations;
|
|
17
|
+
let maxIterations;
|
|
18
|
+
if (typeof maxIterationsRaw === "string" && context.renderer.hasVariables(maxIterationsRaw)) {
|
|
19
|
+
maxIterations = Number.parseInt(context.renderer.renderString(maxIterationsRaw, templateContext), 10);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
maxIterations = maxIterationsRaw ? Number.parseInt(String(maxIterationsRaw), 10) : 5;
|
|
23
|
+
}
|
|
24
|
+
const timeout = (step.stepTimeoutMinutes ?? 30) * 60;
|
|
25
|
+
const bypassPermissions = context.workflowSettings?.bypassPermissions ?? false;
|
|
26
|
+
const allowedTools = context.workflowSettings?.requiredTools?.length
|
|
27
|
+
? context.workflowSettings.requiredTools
|
|
28
|
+
: null;
|
|
29
|
+
// Always enable streaming when console is provided
|
|
30
|
+
const printOutput = true;
|
|
31
|
+
logger.info(step.name, `Starting Ralph loop (max ${maxIterations} iterations)`);
|
|
32
|
+
console.info(`Ralph loop starting (max ${maxIterations} iterations)`);
|
|
33
|
+
const allOutputs = [];
|
|
34
|
+
// Check for existing ralph state to resume from
|
|
35
|
+
const existingState = loadRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
36
|
+
let startIteration;
|
|
37
|
+
if (existingState?.active) {
|
|
38
|
+
startIteration = existingState.iteration;
|
|
39
|
+
logger.info(step.name, `Resuming Ralph loop from iteration ${startIteration}`);
|
|
40
|
+
console.info(`Resuming Ralph loop from iteration ${startIteration}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
startIteration = 1;
|
|
44
|
+
}
|
|
45
|
+
for (let iteration = startIteration; iteration <= maxIterations; iteration++) {
|
|
46
|
+
logger.info(step.name, `Ralph loop iteration ${iteration}/${maxIterations}`);
|
|
47
|
+
// Render prompt with iteration context
|
|
48
|
+
const iterationContext = {
|
|
49
|
+
...templateContext,
|
|
50
|
+
iteration,
|
|
51
|
+
max_iterations: maxIterations,
|
|
52
|
+
};
|
|
53
|
+
let prompt;
|
|
54
|
+
if (context.renderer.hasVariables(promptTemplate)) {
|
|
55
|
+
prompt = context.renderer.renderString(promptTemplate, iterationContext);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
prompt = promptTemplate;
|
|
59
|
+
}
|
|
60
|
+
// Create ralph state on first iteration
|
|
61
|
+
if (iteration === startIteration && !existingState?.active) {
|
|
62
|
+
createRalphState(progress.workflowId, step.name, prompt, maxIterations, completionPromise, context.repoRoot);
|
|
63
|
+
}
|
|
64
|
+
const systemMessage = buildRalphSystemMessage(iteration, maxIterations, completionPromise);
|
|
65
|
+
const fullPrompt = `${systemMessage}${prompt}`;
|
|
66
|
+
// Display iteration header BEFORE running Claude
|
|
67
|
+
console.ralphIterationStart(step.name, iteration, maxIterations);
|
|
68
|
+
const result = await runClaude({
|
|
69
|
+
prompt: fullPrompt,
|
|
70
|
+
cwd: context.repoRoot,
|
|
71
|
+
model: resolveModel(context, step.model),
|
|
72
|
+
timeout,
|
|
73
|
+
printOutput,
|
|
74
|
+
skipPermissions: bypassPermissions,
|
|
75
|
+
allowedTools,
|
|
76
|
+
console,
|
|
77
|
+
workflowId: context.workflowId,
|
|
78
|
+
});
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
const errorSummary = result.stderr ? extractSummary(result.stderr) : "Unknown error";
|
|
81
|
+
logger.warning(step.name, `Iteration ${iteration} failed: ${result.stderr}`);
|
|
82
|
+
console.ralphIteration(step.name, iteration, maxIterations, `Failed: ${errorSummary}`);
|
|
83
|
+
if (iteration < maxIterations) {
|
|
84
|
+
updateRalphIteration(progress.workflowId, step.name, context.repoRoot);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
88
|
+
const errorMsg = `Ralph loop failed after ${maxIterations} iterations`;
|
|
89
|
+
console.stepFailed(step.name, errorMsg);
|
|
90
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
91
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
92
|
+
return { success: false, error: errorMsg };
|
|
93
|
+
}
|
|
94
|
+
allOutputs.push(result.stdout);
|
|
95
|
+
// Print iteration summary
|
|
96
|
+
const iterationSummary = extractSummary(result.stdout);
|
|
97
|
+
console.ralphIteration(step.name, iteration, maxIterations, iterationSummary);
|
|
98
|
+
const completionResult = detectCompletionPromise(result.stdout, completionPromise);
|
|
99
|
+
// Check for failure signal first
|
|
100
|
+
if (completionResult.isFailed) {
|
|
101
|
+
const errorMsg = `Ralph loop failed: ${completionResult.failureReason}`;
|
|
102
|
+
logger.error(step.name, errorMsg);
|
|
103
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
104
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
105
|
+
console.stepFailed(step.name, errorMsg);
|
|
106
|
+
updateStepFailed(progress, step.name, errorMsg);
|
|
107
|
+
progress.status = WORKFLOW_STATUS.FAILED;
|
|
108
|
+
return { success: false, error: errorMsg, fullOutput: combinedOutput };
|
|
109
|
+
}
|
|
110
|
+
if (completionResult.isComplete && completionResult.promiseMatched) {
|
|
111
|
+
logger.info(step.name, `Ralph loop completed at iteration ${iteration}`);
|
|
112
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
113
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
114
|
+
const outputSummary = `Completed in ${iteration} iterations`;
|
|
115
|
+
updateStepCompleted(progress, step.name, outputSummary, combinedOutput);
|
|
116
|
+
console.ralphComplete(step.name, iteration, maxIterations);
|
|
117
|
+
return { success: true, outputSummary, fullOutput: combinedOutput };
|
|
118
|
+
}
|
|
119
|
+
if (iteration < maxIterations) {
|
|
120
|
+
updateRalphIteration(progress.workflowId, step.name, context.repoRoot);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
logger.warning(step.name, `Ralph loop reached max iterations (${maxIterations}) without completion`);
|
|
124
|
+
deactivateRalphState(progress.workflowId, step.name, context.repoRoot);
|
|
125
|
+
const combinedOutput = allOutputs.join("\n\n---\n\n");
|
|
126
|
+
const outputSummary = `Max iterations (${maxIterations}) reached without completion promise`;
|
|
127
|
+
updateStepCompleted(progress, step.name, outputSummary, combinedOutput);
|
|
128
|
+
console.ralphMaxIterations(step.name, maxIterations);
|
|
129
|
+
return { success: true, outputSummary, fullOutput: combinedOutput };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=ralph-loop-step.js.map
|