@davidorex/pi-workflows 0.2.0 → 0.3.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 (216) hide show
  1. package/CHANGELOG.md +7 -4
  2. package/README.md +12 -2
  3. package/agents/architecture-designer.agent.yaml +58 -0
  4. package/agents/architecture-inferrer.agent.yaml +60 -0
  5. package/agents/gap-identifier.agent.yaml +66 -0
  6. package/agents/handoff-writer.agent.yaml +64 -0
  7. package/agents/plan-creator.agent.yaml +63 -0
  8. package/agents/project-definer.agent.yaml +53 -0
  9. package/agents/project-inferrer.agent.yaml +63 -0
  10. package/agents/requirements-gatherer.agent.yaml +58 -0
  11. package/dist/agent-spec.d.ts +27 -0
  12. package/dist/agent-spec.d.ts.map +1 -0
  13. package/dist/agent-spec.js +112 -0
  14. package/dist/agent-spec.js.map +1 -0
  15. package/dist/checkpoint.d.ts +50 -0
  16. package/dist/checkpoint.d.ts.map +1 -0
  17. package/dist/checkpoint.js +109 -0
  18. package/dist/checkpoint.js.map +1 -0
  19. package/dist/completion.d.ts +18 -0
  20. package/dist/completion.d.ts.map +1 -0
  21. package/dist/completion.js +58 -0
  22. package/dist/completion.js.map +1 -0
  23. package/dist/dag.d.ts +56 -0
  24. package/dist/dag.d.ts.map +1 -0
  25. package/dist/dag.js +178 -0
  26. package/dist/dag.js.map +1 -0
  27. package/dist/dispatch.d.ts +35 -0
  28. package/dist/dispatch.d.ts.map +1 -0
  29. package/dist/dispatch.js +311 -0
  30. package/dist/dispatch.js.map +1 -0
  31. package/dist/expression.d.ts +64 -0
  32. package/dist/expression.d.ts.map +1 -0
  33. package/dist/expression.js +294 -0
  34. package/dist/expression.js.map +1 -0
  35. package/dist/format.d.ts +19 -0
  36. package/dist/format.d.ts.map +1 -0
  37. package/dist/format.js +42 -0
  38. package/dist/format.js.map +1 -0
  39. package/dist/index.d.ts +8 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +724 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/output.d.ts +12 -0
  44. package/dist/output.d.ts.map +1 -0
  45. package/dist/output.js +59 -0
  46. package/dist/output.js.map +1 -0
  47. package/dist/state.d.ts +66 -0
  48. package/dist/state.d.ts.map +1 -0
  49. package/dist/state.js +227 -0
  50. package/dist/state.js.map +1 -0
  51. package/dist/step-agent.d.ts +35 -0
  52. package/dist/step-agent.d.ts.map +1 -0
  53. package/dist/step-agent.js +171 -0
  54. package/dist/step-agent.js.map +1 -0
  55. package/dist/step-command.d.ts +21 -0
  56. package/dist/step-command.d.ts.map +1 -0
  57. package/dist/step-command.js +150 -0
  58. package/dist/step-command.js.map +1 -0
  59. package/dist/step-foreach.d.ts +33 -0
  60. package/dist/step-foreach.d.ts.map +1 -0
  61. package/dist/step-foreach.js +112 -0
  62. package/dist/step-foreach.js.map +1 -0
  63. package/dist/step-gate.d.ts +18 -0
  64. package/dist/step-gate.d.ts.map +1 -0
  65. package/dist/step-gate.js +137 -0
  66. package/dist/step-gate.js.map +1 -0
  67. package/dist/step-loop.d.ts +32 -0
  68. package/dist/step-loop.d.ts.map +1 -0
  69. package/dist/step-loop.js +278 -0
  70. package/dist/step-loop.js.map +1 -0
  71. package/dist/step-monitor.d.ts +56 -0
  72. package/dist/step-monitor.d.ts.map +1 -0
  73. package/dist/step-monitor.js +317 -0
  74. package/dist/step-monitor.js.map +1 -0
  75. package/dist/step-parallel.d.ts +43 -0
  76. package/dist/step-parallel.d.ts.map +1 -0
  77. package/dist/step-parallel.js +122 -0
  78. package/dist/step-parallel.js.map +1 -0
  79. package/{src/step-pause.ts → dist/step-pause.d.ts} +3 -13
  80. package/dist/step-pause.d.ts.map +1 -0
  81. package/dist/step-pause.js +22 -0
  82. package/dist/step-pause.js.map +1 -0
  83. package/dist/step-shared.d.ts +63 -0
  84. package/dist/step-shared.d.ts.map +1 -0
  85. package/dist/step-shared.js +136 -0
  86. package/dist/step-shared.js.map +1 -0
  87. package/dist/step-transform.d.ts +11 -0
  88. package/dist/step-transform.d.ts.map +1 -0
  89. package/dist/step-transform.js +41 -0
  90. package/dist/step-transform.js.map +1 -0
  91. package/dist/template.d.ts +51 -0
  92. package/dist/template.d.ts.map +1 -0
  93. package/{src/template.ts → dist/template.js} +32 -38
  94. package/dist/template.js.map +1 -0
  95. package/dist/test-helpers.d.ts +17 -0
  96. package/dist/test-helpers.d.ts.map +1 -0
  97. package/dist/test-helpers.js +46 -0
  98. package/dist/test-helpers.js.map +1 -0
  99. package/dist/tui.d.ts +47 -0
  100. package/dist/tui.d.ts.map +1 -0
  101. package/dist/tui.js +143 -0
  102. package/dist/tui.js.map +1 -0
  103. package/dist/types.d.ts +165 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +3 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/workflow-discovery.d.ts +23 -0
  108. package/dist/workflow-discovery.d.ts.map +1 -0
  109. package/dist/workflow-discovery.js +103 -0
  110. package/dist/workflow-discovery.js.map +1 -0
  111. package/dist/workflow-executor.d.ts +50 -0
  112. package/dist/workflow-executor.d.ts.map +1 -0
  113. package/dist/workflow-executor.js +738 -0
  114. package/dist/workflow-executor.js.map +1 -0
  115. package/dist/workflow-sdk.d.ts +44 -0
  116. package/dist/workflow-sdk.d.ts.map +1 -0
  117. package/dist/workflow-sdk.js +457 -0
  118. package/dist/workflow-sdk.js.map +1 -0
  119. package/dist/workflow-spec.d.ts +33 -0
  120. package/dist/workflow-spec.d.ts.map +1 -0
  121. package/dist/workflow-spec.js +476 -0
  122. package/dist/workflow-spec.js.map +1 -0
  123. package/dist/workflows-dir.d.ts +3 -0
  124. package/dist/workflows-dir.d.ts.map +1 -0
  125. package/{src/workflows-dir.ts → dist/workflows-dir.js} +1 -0
  126. package/dist/workflows-dir.js.map +1 -0
  127. package/package.json +53 -38
  128. package/schemas/decomposition-specs.schema.json +48 -48
  129. package/schemas/execution-results.schema.json +48 -48
  130. package/schemas/investigation-findings.schema.json +43 -43
  131. package/schemas/pattern-analysis.schema.json +41 -41
  132. package/schemas/phase.schema.json +48 -0
  133. package/schemas/plan-breakdown.schema.json +20 -20
  134. package/schemas/quality-analysis.schema.json +33 -33
  135. package/schemas/research-findings.schema.json +42 -42
  136. package/schemas/structure-analysis.schema.json +40 -40
  137. package/schemas/synthesis.schema.json +31 -31
  138. package/schemas/verifier-output.schema.json +94 -94
  139. package/skill-narrative.md +107 -0
  140. package/skills/pi-workflows/SKILL.md +185 -0
  141. package/skills/pi-workflows/references/bundled-resources.md +87 -0
  142. package/templates/architecture-designer/task.md +117 -0
  143. package/templates/architecture-inferrer/task.md +61 -0
  144. package/templates/gap-identifier/task.md +103 -0
  145. package/templates/handoff-writer/task.md +91 -0
  146. package/templates/plan-creator/task.md +143 -0
  147. package/templates/project-definer/task.md +67 -0
  148. package/templates/project-inferrer/task.md +56 -0
  149. package/templates/requirements-gatherer/task.md +90 -0
  150. package/workflows/analyze-existing-project.workflow.yaml +94 -0
  151. package/workflows/create-handoff.workflow.yaml +66 -0
  152. package/workflows/create-phase.workflow.yaml +1 -1
  153. package/workflows/do-gap.workflow.yaml +4 -4
  154. package/workflows/fix-audit.workflow.yaml +1 -1
  155. package/workflows/gap-to-phase.workflow.yaml +1 -1
  156. package/workflows/init-new-project.workflow.yaml +81 -0
  157. package/workflows/plan-from-requirements.workflow.yaml +59 -0
  158. package/workflows/self-implement.workflow.yaml +3 -3
  159. package/workflows/typed-analysis.workflow.yaml +4 -4
  160. package/src/agent-spec.test.ts +0 -289
  161. package/src/agent-spec.ts +0 -122
  162. package/src/block-validation.test.ts +0 -350
  163. package/src/checkpoint.test.ts +0 -237
  164. package/src/checkpoint.ts +0 -140
  165. package/src/completion.test.ts +0 -143
  166. package/src/completion.ts +0 -68
  167. package/src/dag.test.ts +0 -350
  168. package/src/dag.ts +0 -219
  169. package/src/dispatch.test.ts +0 -475
  170. package/src/dispatch.ts +0 -353
  171. package/src/expression.test.ts +0 -353
  172. package/src/expression.ts +0 -332
  173. package/src/format.test.ts +0 -80
  174. package/src/format.ts +0 -41
  175. package/src/graduated-failure.test.ts +0 -556
  176. package/src/index.test.ts +0 -114
  177. package/src/index.ts +0 -516
  178. package/src/loop.test.ts +0 -551
  179. package/src/output.test.ts +0 -213
  180. package/src/output.ts +0 -70
  181. package/src/parallel-integration.test.ts +0 -175
  182. package/src/resume.test.ts +0 -192
  183. package/src/state.test.ts +0 -192
  184. package/src/state.ts +0 -254
  185. package/src/step-agent.test.ts +0 -327
  186. package/src/step-agent.ts +0 -178
  187. package/src/step-command.test.ts +0 -330
  188. package/src/step-command.ts +0 -132
  189. package/src/step-foreach.test.ts +0 -647
  190. package/src/step-foreach.ts +0 -148
  191. package/src/step-gate.test.ts +0 -185
  192. package/src/step-gate.ts +0 -116
  193. package/src/step-loop.test.ts +0 -626
  194. package/src/step-loop.ts +0 -323
  195. package/src/step-parallel.test.ts +0 -475
  196. package/src/step-parallel.ts +0 -168
  197. package/src/step-pause.test.ts +0 -30
  198. package/src/step-shared.test.ts +0 -355
  199. package/src/step-shared.ts +0 -157
  200. package/src/step-transform.test.ts +0 -155
  201. package/src/step-transform.ts +0 -47
  202. package/src/template-integration.test.ts +0 -72
  203. package/src/template.test.ts +0 -162
  204. package/src/test-helpers.ts +0 -51
  205. package/src/tui.test.ts +0 -355
  206. package/src/tui.ts +0 -182
  207. package/src/types.ts +0 -195
  208. package/src/verifier-schema.test.ts +0 -226
  209. package/src/workflow-discovery.test.ts +0 -105
  210. package/src/workflow-discovery.ts +0 -114
  211. package/src/workflow-executor.test.ts +0 -1532
  212. package/src/workflow-executor.ts +0 -810
  213. package/src/workflow-sdk.test.ts +0 -238
  214. package/src/workflow-sdk.ts +0 -262
  215. package/src/workflow-spec.test.ts +0 -576
  216. package/src/workflow-spec.ts +0 -471
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Agent step executor — dispatches an LLM subprocess and validates output.
3
+ */
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { validateFromFile } from "@davidorex/pi-project/src/schema-validator.js";
7
+ import { dispatch } from "./dispatch.js";
8
+ import { resolveExpressions } from "./expression.js";
9
+ import { persistStepOutput } from "./output.js";
10
+ import { buildPrompt, compileAgentSpec, resolveSchemaPath, zeroUsage } from "./step-shared.js";
11
+ /**
12
+ * Execute an agent step: resolve input, render templates, dispatch subprocess,
13
+ * validate output, persist result.
14
+ *
15
+ * Returns the StepResult.
16
+ */
17
+ export async function executeAgentStep(stepName, stepSpec, state, options) {
18
+ const { ctx, signal, loadAgent, runDir, specFilePath, templateEnv } = options;
19
+ const agentName = stepSpec.agent;
20
+ const scope = { input: state.input, steps: state.steps };
21
+ // Expose forEach bindings (as name + forEach metadata) if present on the state
22
+ const stateAny = state;
23
+ if (stateAny.forEach !== undefined) {
24
+ scope.forEach = stateAny.forEach;
25
+ }
26
+ for (const key of Object.keys(stateAny)) {
27
+ if (key !== "input" &&
28
+ key !== "steps" &&
29
+ key !== "status" &&
30
+ key !== "loop" &&
31
+ key !== "workflowName" &&
32
+ key !== "specVersion" &&
33
+ key !== "startedAt" &&
34
+ key !== "updatedAt" &&
35
+ key !== "forEach") {
36
+ scope[key] = stateAny[key];
37
+ }
38
+ }
39
+ // Resolve input expressions
40
+ let resolvedInput;
41
+ try {
42
+ resolvedInput = resolveExpressions(stepSpec.input ?? {}, scope);
43
+ }
44
+ catch (err) {
45
+ return {
46
+ step: stepName,
47
+ agent: agentName,
48
+ status: "failed",
49
+ usage: zeroUsage(),
50
+ durationMs: 0,
51
+ error: err instanceof Error ? err.message : String(err),
52
+ };
53
+ }
54
+ // Load and optionally render agent template
55
+ let agentSpec;
56
+ try {
57
+ agentSpec = loadAgent(agentName);
58
+ }
59
+ catch (err) {
60
+ return {
61
+ step: stepName,
62
+ agent: agentName,
63
+ status: "failed",
64
+ usage: zeroUsage(),
65
+ durationMs: 0,
66
+ error: err instanceof Error ? err.message : String(err),
67
+ };
68
+ }
69
+ // Inject output schema into template context if available
70
+ if (stepSpec.output?.schema && typeof resolvedInput === "object" && resolvedInput !== null) {
71
+ const schemaPath = resolveSchemaPath(stepSpec.output.schema, options.specFilePath, options.ctx.cwd);
72
+ try {
73
+ const schemaContent = fs.readFileSync(schemaPath, "utf8");
74
+ resolvedInput.output_schema = schemaContent;
75
+ }
76
+ catch {
77
+ /* schema file not found — template can still render without it */
78
+ }
79
+ }
80
+ agentSpec = compileAgentSpec(agentSpec, resolvedInput, templateEnv);
81
+ let prompt = buildPrompt(stepSpec, agentSpec, resolvedInput, runDir, stepName, ctx.cwd);
82
+ // Inject context from prior steps (narrative text inlining)
83
+ if (stepSpec.context && stepSpec.context.length > 0) {
84
+ const contextParts = [];
85
+ for (const ctxStepName of stepSpec.context) {
86
+ const ctxResult = state.steps[ctxStepName];
87
+ if (!ctxResult?.textOutput)
88
+ continue;
89
+ contextParts.push(`### ${ctxStepName}\n`);
90
+ contextParts.push(ctxResult.textOutput);
91
+ contextParts.push("");
92
+ }
93
+ if (contextParts.length > 0) {
94
+ prompt = `## Context from Prior Steps\n\n${contextParts.join("\n")}\n---\n\n${prompt}`;
95
+ }
96
+ }
97
+ // Inject retry context if this is a retry attempt
98
+ if (options.retryContext) {
99
+ const rc = options.retryContext;
100
+ const retryParts = [];
101
+ retryParts.push(`## Retry Context (attempt ${rc.attempt})\n`);
102
+ retryParts.push("Your previous attempt failed. The filesystem has been rolled back to its pre-attempt state.\n");
103
+ retryParts.push("### Prior Errors");
104
+ for (let i = 0; i < rc.priorErrors.length; i++) {
105
+ retryParts.push(`${i + 1}. ${rc.priorErrors[i]}`);
106
+ }
107
+ retryParts.push("");
108
+ if (rc.steeringMessage) {
109
+ retryParts.push("### Steering");
110
+ retryParts.push(rc.steeringMessage);
111
+ retryParts.push("");
112
+ }
113
+ retryParts.push("---\n");
114
+ prompt = retryParts.join("\n") + prompt;
115
+ }
116
+ const dispatchFn = options.dispatchFn ?? dispatch;
117
+ const result = await dispatchFn(stepSpec, agentSpec, prompt, {
118
+ cwd: ctx.cwd,
119
+ sessionLogDir: path.join(runDir, "sessions"),
120
+ stepName,
121
+ signal,
122
+ timeoutMs: stepSpec.timeout ? stepSpec.timeout.seconds * 1000 : undefined,
123
+ onEvent: (event) => {
124
+ if (event.type === "tool_execution_start" && event.toolName && options.onStepActivity) {
125
+ options.onStepActivity({
126
+ tool: event.toolName,
127
+ preview: event.toolArgs || "",
128
+ timestamp: Date.now(),
129
+ });
130
+ }
131
+ },
132
+ modelConfig: options.modelConfig,
133
+ });
134
+ // Resolve output path from spec (may contain ${{ }} expressions)
135
+ const resolvedOutputPath = stepSpec.output?.path
136
+ ? String(resolveExpressions(stepSpec.output.path, scope))
137
+ : undefined;
138
+ // Validate output against schema (if defined)
139
+ if (stepSpec.output?.schema && result.status === "completed") {
140
+ const schemaPath = resolveSchemaPath(stepSpec.output.schema, specFilePath, ctx.cwd);
141
+ try {
142
+ const outputFilePath = path.join(runDir, "outputs", `${stepName}.json`);
143
+ if (fs.existsSync(outputFilePath)) {
144
+ const rawOutput = JSON.parse(fs.readFileSync(outputFilePath, "utf-8"));
145
+ validateFromFile(schemaPath, rawOutput, `step output for '${stepName}'`);
146
+ result.output = rawOutput;
147
+ }
148
+ else {
149
+ try {
150
+ const parsed = JSON.parse(result.textOutput || "");
151
+ validateFromFile(schemaPath, parsed, `step output for '${stepName}'`);
152
+ result.output = parsed;
153
+ result.outputPath = persistStepOutput(runDir, stepName, parsed, undefined, resolvedOutputPath);
154
+ }
155
+ catch {
156
+ result.status = "failed";
157
+ result.error = `Step '${stepName}' has output schema but no valid JSON output was produced`;
158
+ }
159
+ }
160
+ }
161
+ catch (err) {
162
+ result.status = "failed";
163
+ result.error = err instanceof Error ? err.message : String(err);
164
+ }
165
+ }
166
+ else {
167
+ result.outputPath = persistStepOutput(runDir, stepName, result.output, result.textOutput, resolvedOutputPath);
168
+ }
169
+ return result;
170
+ }
171
+ //# sourceMappingURL=step-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-agent.js","sourceRoot":"","sources":["../src/step-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Command step executor — runs a shell command and captures output as data.
3
+ *
4
+ * Unlike gate (which judges pass/fail), command captures stdout as structured
5
+ * or text output for downstream steps. Non-zero exit codes produce a failed result.
6
+ */
7
+ import type { StepResult } from "./types.js";
8
+ /**
9
+ * Execute a command step: runs a shell command, captures stdout as output.
10
+ *
11
+ * The command string is expected to already have ${{ }} expressions resolved
12
+ * before being passed here.
13
+ */
14
+ export declare function executeCommand(command: string, stepName: string, options: {
15
+ cwd: string;
16
+ signal?: AbortSignal;
17
+ timeoutMs?: number;
18
+ runDir?: string;
19
+ outputPath?: string;
20
+ }, outputFormat?: "json" | "text"): Promise<StepResult>;
21
+ //# sourceMappingURL=step-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-command.d.ts","sourceRoot":"","sources":["../src/step-command.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,wBAAsB,cAAc,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EACxG,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAC5B,OAAO,CAAC,UAAU,CAAC,CAiIrB"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Command step executor — runs a shell command and captures output as data.
3
+ *
4
+ * Unlike gate (which judges pass/fail), command captures stdout as structured
5
+ * or text output for downstream steps. Non-zero exit codes produce a failed result.
6
+ */
7
+ import { persistStepOutput } from "./output.js";
8
+ import { SIGKILL_GRACE_MS, zeroUsage } from "./step-shared.js";
9
+ /**
10
+ * Execute a command step: runs a shell command, captures stdout as output.
11
+ *
12
+ * The command string is expected to already have ${{ }} expressions resolved
13
+ * before being passed here.
14
+ */
15
+ export async function executeCommand(command, stepName, options, outputFormat) {
16
+ const startTime = Date.now();
17
+ try {
18
+ const { spawn } = await import("node:child_process");
19
+ const { stdout, stderr } = await new Promise((resolve, reject) => {
20
+ const proc = spawn("sh", ["-c", command], {
21
+ cwd: options.cwd,
22
+ stdio: ["ignore", "pipe", "pipe"],
23
+ detached: true,
24
+ });
25
+ let stdout = "";
26
+ let stderr = "";
27
+ let settled = false;
28
+ proc.stdout.on("data", (d) => {
29
+ stdout += d.toString();
30
+ });
31
+ proc.stderr.on("data", (d) => {
32
+ stderr += d.toString();
33
+ });
34
+ const killProc = () => {
35
+ if (!proc.pid)
36
+ return;
37
+ try {
38
+ process.kill(-proc.pid, "SIGTERM");
39
+ }
40
+ catch {
41
+ /* already dead */
42
+ }
43
+ setTimeout(() => {
44
+ if (!proc.pid)
45
+ return;
46
+ try {
47
+ process.kill(-proc.pid, "SIGKILL");
48
+ }
49
+ catch {
50
+ /* already dead */
51
+ }
52
+ }, SIGKILL_GRACE_MS);
53
+ };
54
+ const onAbort = () => {
55
+ killProc();
56
+ };
57
+ if (options.signal) {
58
+ if (options.signal.aborted) {
59
+ killProc();
60
+ }
61
+ else {
62
+ options.signal.addEventListener("abort", onAbort, { once: true });
63
+ }
64
+ }
65
+ let timeoutId;
66
+ if (options.timeoutMs) {
67
+ timeoutId = setTimeout(() => {
68
+ killProc();
69
+ }, options.timeoutMs);
70
+ }
71
+ proc.on("close", (code) => {
72
+ if (settled)
73
+ return;
74
+ settled = true;
75
+ if (timeoutId)
76
+ clearTimeout(timeoutId);
77
+ if (options.signal)
78
+ options.signal.removeEventListener("abort", onAbort);
79
+ if (code === 0) {
80
+ resolve({ stdout, stderr });
81
+ }
82
+ else {
83
+ const err = new Error(`Process exited with code ${code}`);
84
+ err.status = code;
85
+ err.stdout = stdout;
86
+ err.stderr = stderr;
87
+ reject(err);
88
+ }
89
+ });
90
+ proc.on("error", (err) => {
91
+ if (settled)
92
+ return;
93
+ settled = true;
94
+ if (timeoutId)
95
+ clearTimeout(timeoutId);
96
+ if (options.signal)
97
+ options.signal.removeEventListener("abort", onAbort);
98
+ reject(err);
99
+ });
100
+ });
101
+ // Exit 0: parse output
102
+ let output;
103
+ let textOutput;
104
+ if (outputFormat === "json") {
105
+ try {
106
+ output = JSON.parse(stdout);
107
+ }
108
+ catch {
109
+ output = { text: stdout.trim() };
110
+ }
111
+ textOutput = stdout.trim();
112
+ }
113
+ else {
114
+ textOutput = stdout.trim();
115
+ output = { text: textOutput };
116
+ }
117
+ const result = {
118
+ step: stepName,
119
+ agent: "command",
120
+ status: "completed",
121
+ output,
122
+ textOutput,
123
+ usage: zeroUsage(),
124
+ durationMs: Date.now() - startTime,
125
+ };
126
+ if (options.runDir) {
127
+ result.outputPath = persistStepOutput(options.runDir, stepName, output, textOutput, options.outputPath);
128
+ }
129
+ return result;
130
+ }
131
+ catch (err) {
132
+ const execErr = err;
133
+ const exitCode = execErr.status ?? 1;
134
+ const stderr = execErr.stderr?.trim() ?? "";
135
+ const stdout = execErr.stdout?.trim() ?? "";
136
+ const result = {
137
+ step: stepName,
138
+ agent: "command",
139
+ status: "failed",
140
+ usage: zeroUsage(),
141
+ durationMs: Date.now() - startTime,
142
+ error: `Command failed (exit ${exitCode}): ${stderr || stdout || execErr.message || "unknown error"}`,
143
+ };
144
+ if (options.runDir) {
145
+ persistStepOutput(options.runDir, stepName, { error: result.error, exitCode }, undefined, options.outputPath);
146
+ }
147
+ return result;
148
+ }
149
+ }
150
+ //# sourceMappingURL=step-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-command.js","sourceRoot":"","sources":["../src/step-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * ForEach step executor — iterates over an array, executing the step body
3
+ * once per element with the element bound to a named variable in scope.
4
+ */
5
+ import type { ExecutionState, StepResult, StepSpec } from "./types.js";
6
+ /** Options for forEach execution, matching the StepExecOptions pattern. */
7
+ interface ForEachOptions {
8
+ ctx: any;
9
+ pi: any;
10
+ signal?: AbortSignal;
11
+ loadAgent: (name: string) => any;
12
+ runDir: string;
13
+ spec: any;
14
+ widgetState: any;
15
+ templateEnv?: any;
16
+ dispatchFn?: any;
17
+ }
18
+ /**
19
+ * Execute a forEach step: iterates over an array and executes the step body
20
+ * for each element.
21
+ *
22
+ * @param stepName - the name of the forEach step
23
+ * @param stepSpec - the full step spec (including forEach, as, and the body type)
24
+ * @param state - current execution state
25
+ * @param forEachExpr - the forEach expression string (without ${{ }} delimiters)
26
+ * @param asName - the variable name to bind each element (default: "item")
27
+ * @param executeSingleStep - the step executor function to delegate to
28
+ * @param options - step execution options
29
+ * @returns combined StepResult with array output
30
+ */
31
+ export declare function executeForEach(stepName: string, stepSpec: StepSpec, state: ExecutionState, forEachExpr: string, asName: string, executeSingleStep: (name: string, spec: StepSpec, state: ExecutionState, opts: ForEachOptions) => Promise<boolean>, options: ForEachOptions): Promise<StepResult>;
32
+ export {};
33
+ //# sourceMappingURL=step-foreach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-foreach.d.ts","sourceRoot":"","sources":["../src/step-foreach.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAmB,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExF,2EAA2E;AAC3E,UAAU,cAAc;IACvB,GAAG,EAAE,GAAG,CAAC;IACT,EAAE,EAAE,GAAG,CAAC;IACR,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,GAAG,CAAC;IACV,WAAW,EAAE,GAAG,CAAC;IACjB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,UAAU,CAAC,EAAE,GAAG,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,cAAc,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,EAClH,OAAO,EAAE,cAAc,GACrB,OAAO,CAAC,UAAU,CAAC,CAsGrB"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * ForEach step executor — iterates over an array, executing the step body
3
+ * once per element with the element bound to a named variable in scope.
4
+ */
5
+ import { resolveExpression, resolveExpressions } from "./expression.js";
6
+ import { persistStepOutput } from "./output.js";
7
+ import { addUsage, zeroUsage } from "./step-shared.js";
8
+ /**
9
+ * Execute a forEach step: iterates over an array and executes the step body
10
+ * for each element.
11
+ *
12
+ * @param stepName - the name of the forEach step
13
+ * @param stepSpec - the full step spec (including forEach, as, and the body type)
14
+ * @param state - current execution state
15
+ * @param forEachExpr - the forEach expression string (without ${{ }} delimiters)
16
+ * @param asName - the variable name to bind each element (default: "item")
17
+ * @param executeSingleStep - the step executor function to delegate to
18
+ * @param options - step execution options
19
+ * @returns combined StepResult with array output
20
+ */
21
+ export async function executeForEach(stepName, stepSpec, state, forEachExpr, asName, executeSingleStep, options) {
22
+ const startTime = Date.now();
23
+ const scope = { input: state.input, steps: state.steps };
24
+ // Resolve the forEach expression to get the array
25
+ const rawExpr = forEachExpr.replace(/^\$\{\{\s*/, "").replace(/\s*\}\}$/, "");
26
+ let array;
27
+ try {
28
+ array = resolveExpression(rawExpr, scope);
29
+ }
30
+ catch (err) {
31
+ return {
32
+ step: stepName,
33
+ agent: "forEach",
34
+ status: "failed",
35
+ usage: zeroUsage(),
36
+ durationMs: Date.now() - startTime,
37
+ error: `forEach expression failed: ${err instanceof Error ? err.message : String(err)}`,
38
+ };
39
+ }
40
+ if (!Array.isArray(array)) {
41
+ return {
42
+ step: stepName,
43
+ agent: "forEach",
44
+ status: "failed",
45
+ usage: zeroUsage(),
46
+ durationMs: Date.now() - startTime,
47
+ error: `forEach expression must resolve to an array, got ${typeof array}`,
48
+ };
49
+ }
50
+ // Empty array → completed with empty output
51
+ if (array.length === 0) {
52
+ return {
53
+ step: stepName,
54
+ agent: "forEach",
55
+ status: "completed",
56
+ output: [],
57
+ textOutput: "[]",
58
+ usage: zeroUsage(),
59
+ durationMs: Date.now() - startTime,
60
+ };
61
+ }
62
+ // Create the step body (strip forEach/as fields)
63
+ const bodySpec = { ...stepSpec };
64
+ delete bodySpec.forEach;
65
+ delete bodySpec.as;
66
+ const outputs = [];
67
+ const totalUsage = zeroUsage();
68
+ let failed = false;
69
+ for (let i = 0; i < array.length; i++) {
70
+ const element = array[i];
71
+ const iterStepName = `${stepName}[${i}]`;
72
+ // Create a scoped copy of state for this iteration
73
+ // The as binding and forEach metadata are added to a proxy state
74
+ // that exposes them in the expression scope
75
+ const iterState = {
76
+ ...state,
77
+ steps: { ...state.steps },
78
+ // Store forEach bindings that the executor can pick up
79
+ [asName]: element,
80
+ forEach: { index: i, length: array.length },
81
+ };
82
+ const cont = await executeSingleStep(iterStepName, bodySpec, iterState, options);
83
+ // Copy iteration results back to main state
84
+ const iterResult = iterState.steps[iterStepName];
85
+ if (iterResult) {
86
+ state.steps[iterStepName] = iterResult;
87
+ outputs.push(iterResult.output);
88
+ addUsage(totalUsage, iterResult.usage);
89
+ }
90
+ if (!cont || (iterResult && iterResult.status === "failed")) {
91
+ failed = true;
92
+ break;
93
+ }
94
+ }
95
+ const result = {
96
+ step: stepName,
97
+ agent: "forEach",
98
+ status: failed ? "failed" : "completed",
99
+ output: outputs,
100
+ textOutput: JSON.stringify(outputs, null, 2),
101
+ usage: totalUsage,
102
+ durationMs: Date.now() - startTime,
103
+ error: failed ? `forEach iteration failed` : undefined,
104
+ };
105
+ // Persist the collected output
106
+ if (options.runDir) {
107
+ const outputPath = stepSpec.output?.path ? String(resolveExpressions(stepSpec.output.path, scope)) : undefined;
108
+ result.outputPath = persistStepOutput(options.runDir, stepName, outputs, undefined, outputPath);
109
+ }
110
+ return result;
111
+ }
112
+ //# sourceMappingURL=step-foreach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-foreach.js","sourceRoot":"","sources":["../src/step-foreach.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Gate step executor — runs a shell command and passes/fails based on exit code.
3
+ */
4
+ import type { GateSpec, StepResult } from "./types.js";
5
+ /**
6
+ * Execute a gate step: runs a shell command, passes/fails based on exit code.
7
+ *
8
+ * The gate's check command is expected to already have ${{ }} expressions resolved
9
+ * before being passed here.
10
+ */
11
+ export declare function executeGate(gate: GateSpec, stepName: string, options: {
12
+ cwd: string;
13
+ signal?: AbortSignal;
14
+ timeoutMs?: number;
15
+ runDir?: string;
16
+ outputPath?: string;
17
+ }): Promise<StepResult>;
18
+ //# sourceMappingURL=step-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-gate.d.ts","sourceRoot":"","sources":["../src/step-gate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG,OAAO,CAAC,UAAU,CAAC,CAqHrB"}