patchwork-os 0.2.0-alpha.21 → 0.2.0-alpha.22

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 (169) hide show
  1. package/README.md +26 -12
  2. package/deploy/bootstrap-vps.sh +184 -0
  3. package/dist/approvalHttp.js +6 -1
  4. package/dist/approvalHttp.js.map +1 -1
  5. package/dist/automation.d.ts +20 -0
  6. package/dist/automation.js +35 -0
  7. package/dist/automation.js.map +1 -1
  8. package/dist/bridge.js +22 -4
  9. package/dist/bridge.js.map +1 -1
  10. package/dist/bridgeToken.js +57 -19
  11. package/dist/bridgeToken.js.map +1 -1
  12. package/dist/commands/recipe.d.ts +256 -0
  13. package/dist/commands/recipe.js +1313 -0
  14. package/dist/commands/recipe.js.map +1 -0
  15. package/dist/config.d.ts +8 -0
  16. package/dist/config.js +9 -0
  17. package/dist/config.js.map +1 -1
  18. package/dist/connectors/baseConnector.d.ts +117 -0
  19. package/dist/connectors/baseConnector.js +213 -0
  20. package/dist/connectors/baseConnector.js.map +1 -0
  21. package/dist/connectors/confluence.d.ts +111 -0
  22. package/dist/connectors/confluence.js +406 -0
  23. package/dist/connectors/confluence.js.map +1 -0
  24. package/dist/connectors/fixtureLibrary.d.ts +21 -0
  25. package/dist/connectors/fixtureLibrary.js +70 -0
  26. package/dist/connectors/fixtureLibrary.js.map +1 -0
  27. package/dist/connectors/fixtureRecorder.d.ts +1 -0
  28. package/dist/connectors/fixtureRecorder.js +35 -0
  29. package/dist/connectors/fixtureRecorder.js.map +1 -0
  30. package/dist/connectors/github.js +2 -11
  31. package/dist/connectors/github.js.map +1 -1
  32. package/dist/connectors/gmail.js +23 -7
  33. package/dist/connectors/gmail.js.map +1 -1
  34. package/dist/connectors/googleCalendar.js +23 -7
  35. package/dist/connectors/googleCalendar.js.map +1 -1
  36. package/dist/connectors/jira.d.ts +98 -0
  37. package/dist/connectors/jira.js +379 -0
  38. package/dist/connectors/jira.js.map +1 -0
  39. package/dist/connectors/linear.js +2 -11
  40. package/dist/connectors/linear.js.map +1 -1
  41. package/dist/connectors/mcpOAuth.d.ts +1 -0
  42. package/dist/connectors/mcpOAuth.js +30 -4
  43. package/dist/connectors/mcpOAuth.js.map +1 -1
  44. package/dist/connectors/mockConnector.d.ts +28 -0
  45. package/dist/connectors/mockConnector.js +81 -0
  46. package/dist/connectors/mockConnector.js.map +1 -0
  47. package/dist/connectors/notion.d.ts +143 -0
  48. package/dist/connectors/notion.js +424 -0
  49. package/dist/connectors/notion.js.map +1 -0
  50. package/dist/connectors/sentry.js +2 -11
  51. package/dist/connectors/sentry.js.map +1 -1
  52. package/dist/connectors/slack.js +50 -15
  53. package/dist/connectors/slack.js.map +1 -1
  54. package/dist/connectors/tokenStorage.d.ts +35 -0
  55. package/dist/connectors/tokenStorage.js +394 -0
  56. package/dist/connectors/tokenStorage.js.map +1 -0
  57. package/dist/connectors/zendesk.d.ts +104 -0
  58. package/dist/connectors/zendesk.js +424 -0
  59. package/dist/connectors/zendesk.js.map +1 -0
  60. package/dist/featureFlags.d.ts +73 -0
  61. package/dist/featureFlags.js +203 -0
  62. package/dist/featureFlags.js.map +1 -0
  63. package/dist/fp/automationInterpreter.js +1 -0
  64. package/dist/fp/automationInterpreter.js.map +1 -1
  65. package/dist/fp/automationProgram.d.ts +1 -1
  66. package/dist/fp/automationProgram.js.map +1 -1
  67. package/dist/fp/policyParser.js +17 -0
  68. package/dist/fp/policyParser.js.map +1 -1
  69. package/dist/index.js +508 -36
  70. package/dist/index.js.map +1 -1
  71. package/dist/oauth.d.ts +4 -1
  72. package/dist/oauth.js +50 -14
  73. package/dist/oauth.js.map +1 -1
  74. package/dist/recipes/chainedRunner.d.ts +104 -0
  75. package/dist/recipes/chainedRunner.js +359 -0
  76. package/dist/recipes/chainedRunner.js.map +1 -0
  77. package/dist/recipes/dependencyGraph.d.ts +39 -0
  78. package/dist/recipes/dependencyGraph.js +199 -0
  79. package/dist/recipes/dependencyGraph.js.map +1 -0
  80. package/dist/recipes/legacyRecipeCompat.d.ts +1 -0
  81. package/dist/recipes/legacyRecipeCompat.js +97 -0
  82. package/dist/recipes/legacyRecipeCompat.js.map +1 -0
  83. package/dist/recipes/nestedRecipeStep.d.ts +58 -0
  84. package/dist/recipes/nestedRecipeStep.js +95 -0
  85. package/dist/recipes/nestedRecipeStep.js.map +1 -0
  86. package/dist/recipes/outputRegistry.d.ts +28 -0
  87. package/dist/recipes/outputRegistry.js +52 -0
  88. package/dist/recipes/outputRegistry.js.map +1 -0
  89. package/dist/recipes/schemaGenerator.d.ts +28 -0
  90. package/dist/recipes/schemaGenerator.js +484 -0
  91. package/dist/recipes/schemaGenerator.js.map +1 -0
  92. package/dist/recipes/templateEngine.d.ts +62 -0
  93. package/dist/recipes/templateEngine.js +182 -0
  94. package/dist/recipes/templateEngine.js.map +1 -0
  95. package/dist/recipes/toolRegistry.d.ts +181 -0
  96. package/dist/recipes/toolRegistry.js +300 -0
  97. package/dist/recipes/toolRegistry.js.map +1 -0
  98. package/dist/recipes/tools/calendar.d.ts +6 -0
  99. package/dist/recipes/tools/calendar.js +61 -0
  100. package/dist/recipes/tools/calendar.js.map +1 -0
  101. package/dist/recipes/tools/confluence.d.ts +6 -0
  102. package/dist/recipes/tools/confluence.js +254 -0
  103. package/dist/recipes/tools/confluence.js.map +1 -0
  104. package/dist/recipes/tools/diagnostics.d.ts +6 -0
  105. package/dist/recipes/tools/diagnostics.js +36 -0
  106. package/dist/recipes/tools/diagnostics.js.map +1 -0
  107. package/dist/recipes/tools/file.d.ts +6 -0
  108. package/dist/recipes/tools/file.js +170 -0
  109. package/dist/recipes/tools/file.js.map +1 -0
  110. package/dist/recipes/tools/git.d.ts +6 -0
  111. package/dist/recipes/tools/git.js +63 -0
  112. package/dist/recipes/tools/git.js.map +1 -0
  113. package/dist/recipes/tools/github.d.ts +6 -0
  114. package/dist/recipes/tools/github.js +91 -0
  115. package/dist/recipes/tools/github.js.map +1 -0
  116. package/dist/recipes/tools/gmail.d.ts +6 -0
  117. package/dist/recipes/tools/gmail.js +210 -0
  118. package/dist/recipes/tools/gmail.js.map +1 -0
  119. package/dist/recipes/tools/index.d.ts +18 -0
  120. package/dist/recipes/tools/index.js +21 -0
  121. package/dist/recipes/tools/index.js.map +1 -0
  122. package/dist/recipes/tools/linear.d.ts +6 -0
  123. package/dist/recipes/tools/linear.js +83 -0
  124. package/dist/recipes/tools/linear.js.map +1 -0
  125. package/dist/recipes/tools/notion.d.ts +6 -0
  126. package/dist/recipes/tools/notion.js +278 -0
  127. package/dist/recipes/tools/notion.js.map +1 -0
  128. package/dist/recipes/tools/slack.d.ts +6 -0
  129. package/dist/recipes/tools/slack.js +72 -0
  130. package/dist/recipes/tools/slack.js.map +1 -0
  131. package/dist/recipes/tools/zendesk.d.ts +6 -0
  132. package/dist/recipes/tools/zendesk.js +245 -0
  133. package/dist/recipes/tools/zendesk.js.map +1 -0
  134. package/dist/recipes/yamlRunner.d.ts +71 -7
  135. package/dist/recipes/yamlRunner.js +406 -439
  136. package/dist/recipes/yamlRunner.js.map +1 -1
  137. package/dist/riskTier.js +1 -0
  138. package/dist/riskTier.js.map +1 -1
  139. package/dist/runLog.d.ts +18 -0
  140. package/dist/runLog.js +5 -0
  141. package/dist/runLog.js.map +1 -1
  142. package/dist/server.d.ts +4 -0
  143. package/dist/server.js +224 -0
  144. package/dist/server.js.map +1 -1
  145. package/dist/streamableHttp.js +2 -0
  146. package/dist/streamableHttp.js.map +1 -1
  147. package/dist/tools/github/actions.js +4 -2
  148. package/dist/tools/github/actions.js.map +1 -1
  149. package/dist/tools/github/composite.d.ts +339 -0
  150. package/dist/tools/github/composite.js +343 -0
  151. package/dist/tools/github/composite.js.map +1 -0
  152. package/dist/tools/github/index.d.ts +1 -0
  153. package/dist/tools/github/index.js +1 -0
  154. package/dist/tools/github/index.js.map +1 -1
  155. package/dist/tools/github/issues.js +8 -4
  156. package/dist/tools/github/issues.js.map +1 -1
  157. package/dist/tools/github/pr.js +14 -7
  158. package/dist/tools/github/pr.js.map +1 -1
  159. package/dist/tools/index.js +10 -1
  160. package/dist/tools/index.js.map +1 -1
  161. package/dist/tools/searchTools.js +1 -1
  162. package/dist/tools/searchTools.js.map +1 -1
  163. package/dist/transport.d.ts +7 -1
  164. package/dist/transport.js +85 -11
  165. package/dist/transport.js.map +1 -1
  166. package/package.json +1 -1
  167. package/templates/automation-policies/recipe-authoring.json +25 -0
  168. package/templates/automation-policy.example.json +6 -0
  169. package/templates/recipes/lint-on-save.yaml +1 -2
@@ -0,0 +1,104 @@
1
+ /**
2
+ * ChainedRecipeRunner — executes recipes with:
3
+ * - Parallel step execution (respecting dependencies)
4
+ * - Template-based variable resolution
5
+ * - Nested recipe calls
6
+ * - Conditional step execution (when)
7
+ * - Dry-run mode
8
+ */
9
+ import type { NestedRecipeConfig } from "./nestedRecipeStep.js";
10
+ import type { OutputRegistry } from "./outputRegistry.js";
11
+ import type { TemplateContext, TemplateError } from "./templateEngine.js";
12
+ export interface ChainedStep {
13
+ id: string;
14
+ tool?: string;
15
+ agent?: {
16
+ prompt: string;
17
+ model?: string;
18
+ driver?: string;
19
+ };
20
+ recipe?: NestedRecipeConfig["recipe"];
21
+ vars?: Record<string, string>;
22
+ awaits?: string[];
23
+ when?: string;
24
+ output?: string;
25
+ risk?: "low" | "medium" | "high";
26
+ optional?: boolean;
27
+ transform?: string;
28
+ [key: string]: unknown;
29
+ }
30
+ export interface ChainedRecipe {
31
+ name: string;
32
+ description?: string;
33
+ steps: ChainedStep[];
34
+ maxConcurrency?: number;
35
+ maxDepth?: number;
36
+ /** Plugin specs (npm package name or local path) to load before running steps. */
37
+ servers?: string[];
38
+ }
39
+ export interface RunOptions {
40
+ env: Record<string, string | undefined>;
41
+ maxConcurrency: number;
42
+ maxDepth: number;
43
+ dryRun: boolean;
44
+ onStepStart?: (stepId: string) => void;
45
+ onStepComplete?: (stepId: string, error?: Error) => void;
46
+ }
47
+ export interface StepExecutionContext {
48
+ registry: OutputRegistry;
49
+ step: ChainedStep;
50
+ options: RunOptions;
51
+ recipe: ChainedRecipe;
52
+ depth: number;
53
+ }
54
+ export type ToolExecutor = (tool: string, params: Record<string, unknown>) => Promise<unknown>;
55
+ export type AgentExecutor = (prompt: string, model?: string, driver?: string) => Promise<string>;
56
+ export interface ExecutionDeps {
57
+ executeTool: ToolExecutor;
58
+ executeAgent: AgentExecutor;
59
+ loadNestedRecipe: (name: string) => Promise<ChainedRecipe | null>;
60
+ }
61
+ /** Build template context from registry and env */
62
+ export declare function buildTemplateContext(registry: OutputRegistry, env: Record<string, string | undefined>): TemplateContext;
63
+ /** Resolve all template strings in a step */
64
+ export declare function resolveStepTemplates(step: ChainedStep, context: TemplateContext): {
65
+ resolved: Record<string, unknown>;
66
+ conditionResult: boolean;
67
+ errors: TemplateError[];
68
+ };
69
+ /** Execute a single step */
70
+ export declare function executeChainedStep(ctx: StepExecutionContext, deps: ExecutionDeps): Promise<{
71
+ success: boolean;
72
+ skipped?: boolean;
73
+ data?: unknown;
74
+ error?: string;
75
+ }>;
76
+ export interface ChainedRunResult {
77
+ success: boolean;
78
+ stepResults: Map<string, {
79
+ success: boolean;
80
+ error?: Error;
81
+ }>;
82
+ summary: {
83
+ total: number;
84
+ succeeded: number;
85
+ failed: number;
86
+ skipped: number;
87
+ };
88
+ errorMessage?: string;
89
+ }
90
+ /** Main entry point: run a chained recipe */
91
+ export declare function runChainedRecipe(recipe: ChainedRecipe, options: RunOptions, deps: ExecutionDeps, existingRegistry?: OutputRegistry, depth?: number): Promise<ChainedRunResult>;
92
+ /** Generate execution plan for dry-run mode */
93
+ export declare function generateExecutionPlan(recipe: ChainedRecipe): {
94
+ steps: Array<{
95
+ id: string;
96
+ type: "tool" | "agent" | "recipe";
97
+ dependencies: string[];
98
+ condition?: string;
99
+ risk: "low" | "medium" | "high";
100
+ optional?: boolean;
101
+ }>;
102
+ parallelGroups: string[][];
103
+ maxDepth: number;
104
+ };
@@ -0,0 +1,359 @@
1
+ /**
2
+ * ChainedRecipeRunner — executes recipes with:
3
+ * - Parallel step execution (respecting dependencies)
4
+ * - Template-based variable resolution
5
+ * - Nested recipe calls
6
+ * - Conditional step execution (when)
7
+ * - Dry-run mode
8
+ */
9
+ import { buildDependencyGraph, executeWithDependencies, } from "./dependencyGraph.js";
10
+ import { mockNestedRecipe, resolveNestedVars, validateNestedRecipe, } from "./nestedRecipeStep.js";
11
+ import { createOutputRegistry } from "./outputRegistry.js";
12
+ import { compileTemplate } from "./templateEngine.js";
13
+ /** Build template context from registry and env */
14
+ export function buildTemplateContext(registry, env) {
15
+ return registry.toTemplateContext(env);
16
+ }
17
+ /** Resolve all template strings in a step */
18
+ export function resolveStepTemplates(step, context) {
19
+ const resolved = {};
20
+ const errors = [];
21
+ // W3: keys that are recipe metadata, not tool params
22
+ const STEP_META_KEYS = new Set([
23
+ "id",
24
+ "tool",
25
+ "agent",
26
+ "recipe",
27
+ "awaits",
28
+ "when",
29
+ "output",
30
+ "risk",
31
+ "optional",
32
+ "vars",
33
+ "transform",
34
+ ]);
35
+ // Resolve tool params
36
+ for (const [key, value] of Object.entries(step)) {
37
+ if (STEP_META_KEYS.has(key)) {
38
+ continue;
39
+ }
40
+ if (typeof value === "string" && value.includes("{{")) {
41
+ const compiled = compileTemplate(value);
42
+ const result = compiled.evaluate(context);
43
+ if ("error" in result) {
44
+ errors.push(result.error);
45
+ resolved[key] = value;
46
+ }
47
+ else {
48
+ // Try to parse JSON for structured data
49
+ try {
50
+ resolved[key] = JSON.parse(result.value);
51
+ }
52
+ catch {
53
+ resolved[key] = result.value;
54
+ }
55
+ }
56
+ }
57
+ else {
58
+ resolved[key] = value;
59
+ }
60
+ }
61
+ // Resolve agent prompt if present
62
+ if (step.agent && typeof step.agent.prompt === "string") {
63
+ const compiled = compileTemplate(step.agent.prompt);
64
+ const result = compiled.evaluate(context);
65
+ if ("error" in result) {
66
+ errors.push(result.error);
67
+ }
68
+ else {
69
+ resolved.agentPrompt = result.value;
70
+ }
71
+ }
72
+ // Evaluate when condition
73
+ let conditionResult = true;
74
+ if (step.when) {
75
+ const compiled = compileTemplate(step.when);
76
+ const result = compiled.evaluate(context);
77
+ if ("error" in result) {
78
+ errors.push(result.error);
79
+ conditionResult = false;
80
+ }
81
+ else {
82
+ // Simple truthiness check (empty string, "0", "false" are falsy)
83
+ const val = result.value.trim().toLowerCase();
84
+ conditionResult =
85
+ !!val &&
86
+ val !== "0" &&
87
+ val !== "false" &&
88
+ val !== "null" &&
89
+ val !== "undefined";
90
+ }
91
+ }
92
+ return { resolved, conditionResult, errors };
93
+ }
94
+ /** Execute a single step */
95
+ export async function executeChainedStep(ctx, deps) {
96
+ const { registry, step, options, depth } = ctx;
97
+ const { dryRun } = options;
98
+ // Build template context
99
+ const templateContext = buildTemplateContext(registry, options.env);
100
+ // Resolve templates
101
+ const { resolved, conditionResult, errors } = resolveStepTemplates(step, templateContext);
102
+ if (errors.length > 0) {
103
+ return {
104
+ success: false,
105
+ error: `Template errors: ${errors.map((e) => e.message).join(", ")}`,
106
+ };
107
+ }
108
+ // Check when condition
109
+ if (!conditionResult) {
110
+ return {
111
+ success: true,
112
+ skipped: true,
113
+ data: { skipped: true, reason: "when condition falsy" },
114
+ };
115
+ }
116
+ // Dry run: just report what would happen
117
+ if (dryRun) {
118
+ return {
119
+ success: true,
120
+ data: {
121
+ dryRun: true,
122
+ stepType: step.recipe ? "recipe" : step.agent ? "agent" : "tool",
123
+ wouldExecute: (step.tool ?? step.agent) ? "prompt" : step.recipe,
124
+ resolvedParams: Object.keys(resolved).length > 0 ? resolved : undefined,
125
+ },
126
+ };
127
+ }
128
+ /** Flat `{{ key }}` renderer for transform strings — mirrors yamlRunner.render */
129
+ function applyTransform(template, rawResult, ctx) {
130
+ const resultStr = typeof rawResult === "string" ? rawResult : JSON.stringify(rawResult);
131
+ const flatCtx = { $result: resultStr };
132
+ // Expose env keys as flat vars too
133
+ for (const [k, v] of Object.entries(ctx.env)) {
134
+ if (v !== undefined)
135
+ flatCtx[k] = v;
136
+ }
137
+ try {
138
+ return template.replace(/\{\{\s*([^}]+?)\s*\}\}/g, (_, expr) => {
139
+ const key = expr.trim();
140
+ return Object.hasOwn(flatCtx, key) ? (flatCtx[key] ?? "") : "";
141
+ });
142
+ }
143
+ catch {
144
+ return rawResult;
145
+ }
146
+ }
147
+ // Execute based on step type
148
+ try {
149
+ if (step.recipe) {
150
+ // Nested recipe call
151
+ const nestedConfig = {
152
+ recipe: step.recipe,
153
+ vars: step.vars ?? {},
154
+ output: step.output ?? step.id,
155
+ risk: step.risk,
156
+ id: step.id,
157
+ };
158
+ const nestedContext = {
159
+ parentRegistry: registry,
160
+ parentEnv: options.env,
161
+ recipeMaxDepth: options.maxDepth,
162
+ currentDepth: depth,
163
+ dryRun,
164
+ };
165
+ if (dryRun) {
166
+ const result = await mockNestedRecipe(nestedConfig, nestedContext);
167
+ return {
168
+ success: result.success,
169
+ data: result.data,
170
+ error: result.error,
171
+ };
172
+ }
173
+ // Load and execute nested recipe
174
+ const nestedRecipe = await deps.loadNestedRecipe(step.recipe);
175
+ if (!nestedRecipe) {
176
+ return {
177
+ success: false,
178
+ error: `Nested recipe "${step.recipe}" not found`,
179
+ };
180
+ }
181
+ const validation = validateNestedRecipe(nestedConfig, nestedContext);
182
+ if (!validation.valid) {
183
+ return { success: false, error: validation.error };
184
+ }
185
+ // Resolve vars for child
186
+ const { resolved: resolvedVars, errors: varErrors } = resolveNestedVars(step.vars ?? {}, templateContext);
187
+ if (varErrors.length > 0) {
188
+ return {
189
+ success: false,
190
+ error: `Variable template errors: ${varErrors.map((e) => e.message).join(", ")}`,
191
+ };
192
+ }
193
+ // Execute child recipe with isolated registry
194
+ const childRegistry = createOutputRegistry();
195
+ const childOptions = {
196
+ ...options,
197
+ maxDepth: options.maxDepth,
198
+ env: { ...options.env, ...resolvedVars }, // Merge resolved vars into env
199
+ };
200
+ const childResult = await runChainedRecipe(nestedRecipe, childOptions, deps, childRegistry, depth + 1);
201
+ return {
202
+ success: !childResult.errorMessage,
203
+ data: {
204
+ recipe: step.recipe,
205
+ childSummary: childRegistry.summary(),
206
+ childOutputs: Object.fromEntries(childRegistry.keys().map((k) => [k, childRegistry.get(k)?.data])),
207
+ },
208
+ };
209
+ }
210
+ else if (step.agent) {
211
+ // Agent step
212
+ const prompt = resolved.agentPrompt ?? step.agent.prompt;
213
+ let result = await deps.executeAgent(prompt, step.agent.model, step.agent.driver);
214
+ if (step.transform) {
215
+ try {
216
+ result = applyTransform(step.transform, result, templateContext);
217
+ }
218
+ catch (err) {
219
+ console.warn(`transform failed for step ${step.id}: ${err}`);
220
+ }
221
+ }
222
+ return { success: true, data: result };
223
+ }
224
+ else if (step.tool) {
225
+ // Tool step
226
+ let result = await deps.executeTool(step.tool, resolved);
227
+ if (step.transform) {
228
+ try {
229
+ result = applyTransform(step.transform, result, templateContext);
230
+ }
231
+ catch (err) {
232
+ console.warn(`transform failed for step ${step.id}: ${err}`);
233
+ }
234
+ }
235
+ return { success: true, data: result };
236
+ }
237
+ else {
238
+ return { success: false, error: "Step has no tool, agent, or recipe" };
239
+ }
240
+ }
241
+ catch (error) {
242
+ const msg = error instanceof Error ? error.message : String(error);
243
+ return { success: false, error: msg };
244
+ }
245
+ }
246
+ /** Main entry point: run a chained recipe */
247
+ export async function runChainedRecipe(recipe, options, deps, existingRegistry, depth = 0) {
248
+ // Load plugin servers declared in the recipe before executing any steps.
249
+ // Only done at the top-level call (depth 0) to avoid redundant loads in nested recipes.
250
+ if (depth === 0 && recipe.servers?.length) {
251
+ try {
252
+ const { loadRecipeServers } = await import("./yamlRunner.js");
253
+ await loadRecipeServers(recipe.servers);
254
+ }
255
+ catch {
256
+ // Non-fatal — if yamlRunner import fails, proceed without plugins
257
+ }
258
+ }
259
+ const registry = existingRegistry ?? createOutputRegistry();
260
+ // Build dependency graph
261
+ const depGraph = buildDependencyGraph(recipe.steps.map((s, i) => ({ id: s.id ?? `step_${i}`, awaits: s.awaits })));
262
+ if (depGraph.hasCycles) {
263
+ return {
264
+ success: false,
265
+ stepResults: new Map(),
266
+ summary: { total: 0, succeeded: 0, failed: 0, skipped: 0 },
267
+ errorMessage: "Recipe has circular dependencies",
268
+ };
269
+ }
270
+ // Create step lookup
271
+ const stepMap = new Map();
272
+ for (let i = 0; i < recipe.steps.length; i++) {
273
+ const step = recipe.steps[i];
274
+ if (!step)
275
+ continue;
276
+ const stepId = step.id ?? `step_${i}`;
277
+ stepMap.set(stepId, { ...step, id: stepId });
278
+ }
279
+ // Execute with dependency tracking
280
+ const execOptions = {
281
+ maxConcurrency: options.maxConcurrency,
282
+ onStepStart: options.onStepStart,
283
+ onStepComplete: options.onStepComplete,
284
+ };
285
+ const stepExecutor = async (stepId) => {
286
+ const step = stepMap.get(stepId);
287
+ if (!step)
288
+ throw new Error(`Step ${stepId} not found`);
289
+ const ctx = {
290
+ registry,
291
+ step,
292
+ options,
293
+ recipe,
294
+ depth,
295
+ };
296
+ const result = await executeChainedStep(ctx, deps);
297
+ const isOptional = step.optional === true;
298
+ const effectiveSuccess = result.success || isOptional;
299
+ // Store output in registry with accurate status
300
+ registry.set(stepId, {
301
+ status: result.skipped
302
+ ? "skipped"
303
+ : result.success
304
+ ? "success"
305
+ : isOptional
306
+ ? "success"
307
+ : "error",
308
+ data: result.data,
309
+ });
310
+ // Optional steps must not propagate failure to the executor
311
+ if (!effectiveSuccess) {
312
+ throw new Error(result.error ?? `Step ${stepId} failed`);
313
+ }
314
+ };
315
+ const stepResults = await executeWithDependencies(depGraph, stepExecutor, execOptions);
316
+ // Calculate overall success
317
+ let failed = 0;
318
+ for (const [_, result] of stepResults) {
319
+ if (!result.success)
320
+ failed++;
321
+ }
322
+ return {
323
+ success: failed === 0,
324
+ stepResults,
325
+ summary: registry.summary(),
326
+ errorMessage: failed > 0 ? `${failed} step(s) failed` : undefined,
327
+ };
328
+ }
329
+ /** Generate execution plan for dry-run mode */
330
+ export function generateExecutionPlan(recipe) {
331
+ const depGraph = buildDependencyGraph(recipe.steps.map((s, i) => ({ id: s.id ?? `step_${i}`, awaits: s.awaits })));
332
+ // Group by topological levels (parallelizable)
333
+ const levels = [];
334
+ const completed = new Set();
335
+ while (completed.size < depGraph.topologicalOrder.length) {
336
+ const ready = depGraph.topologicalOrder.filter((id) => !completed.has(id) &&
337
+ depGraph.steps
338
+ .find((s) => s.stepId === id)
339
+ ?.awaits.every((dep) => completed.has(dep)));
340
+ if (ready.length === 0)
341
+ break;
342
+ levels.push(ready);
343
+ for (const id of ready)
344
+ completed.add(id);
345
+ }
346
+ return {
347
+ steps: recipe.steps.map((s) => ({
348
+ id: s.id,
349
+ type: s.recipe ? "recipe" : s.agent ? "agent" : "tool",
350
+ dependencies: s.awaits ?? [],
351
+ condition: s.when,
352
+ risk: s.risk ?? "low",
353
+ optional: s.optional,
354
+ })),
355
+ parallelGroups: levels,
356
+ maxDepth: recipe.maxDepth ?? 3,
357
+ };
358
+ }
359
+ //# sourceMappingURL=chainedRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chainedRunner.js","sourceRoot":"","sources":["../../src/recipes/chainedRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AA6DtD,mDAAmD;AACnD,MAAM,UAAU,oBAAoB,CAClC,QAAwB,EACxB,GAAuC;IAEvC,OAAO,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,oBAAoB,CAClC,IAAiB,EACjB,OAAwB;IAMxB,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,qDAAqD;IACrD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;QAC7B,IAAI;QACJ,MAAM;QACN,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,MAAM;QACN,UAAU;QACV,MAAM;QACN,WAAW;KACZ,CAAC,CAAC;IAEH,sBAAsB;IACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,IAAI,CAAC;oBACH,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACP,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;QACtC,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,IAAI,eAAe,GAAG,IAAI,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,eAAe,GAAG,KAAK,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,iEAAiE;YACjE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC9C,eAAe;gBACb,CAAC,CAAC,GAAG;oBACL,GAAG,KAAK,GAAG;oBACX,GAAG,KAAK,OAAO;oBACf,GAAG,KAAK,MAAM;oBACd,GAAG,KAAK,WAAW,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC;AAC/C,CAAC;AAED,4BAA4B;AAC5B,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAyB,EACzB,IAAmB;IAOnB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,yBAAyB;IACzB,MAAM,eAAe,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAEpE,oBAAoB;IACpB,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAChE,IAAI,EACJ,eAAe,CAChB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,oBAAoB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACrE,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE;SACxD,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;gBAChE,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;gBAChE,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;aACxE;SACF,CAAC;IACJ,CAAC;IAED,kFAAkF;IAClF,SAAS,cAAc,CACrB,QAAgB,EAChB,SAAkB,EAClB,GAAoB;QAEpB,MAAM,SAAS,GACb,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACxE,MAAM,OAAO,GAA2B,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC/D,mCAAmC;QACnC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC;YACH,OAAO,QAAQ,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;gBAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBACxB,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,qBAAqB;YACrB,MAAM,YAAY,GAAuB;gBACvC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE;gBAC9B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,EAAE,EAAE,IAAI,CAAC,EAAE;aACZ,CAAC;YAEF,MAAM,aAAa,GAAwB;gBACzC,cAAc,EAAE,QAAQ;gBACxB,SAAS,EAAE,OAAO,CAAC,GAAG;gBACtB,cAAc,EAAE,OAAO,CAAC,QAAQ;gBAChC,YAAY,EAAE,KAAK;gBACnB,MAAM;aACP,CAAC;YAEF,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;gBACnE,OAAO;oBACL,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;iBACpB,CAAC;YACJ,CAAC;YAED,iCAAiC;YACjC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,kBAAkB,IAAI,CAAC,MAAM,aAAa;iBAClD,CAAC;YACJ,CAAC;YAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;YACrE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC;YACrD,CAAC;YAED,yBAAyB;YACzB,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,iBAAiB,CACrE,IAAI,CAAC,IAAI,IAAI,EAAE,EACf,eAAe,CAChB,CAAC;YAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,6BAA6B,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACjF,CAAC;YACJ,CAAC;YAED,8CAA8C;YAC9C,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;YAC7C,MAAM,YAAY,GAAe;gBAC/B,GAAG,OAAO;gBACV,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,EAAE,EAAE,+BAA+B;aAC1E,CAAC;YAEF,MAAM,WAAW,GAAG,MAAM,gBAAgB,CACxC,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,KAAK,GAAG,CAAC,CACV,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,WAAW,CAAC,YAAY;gBAClC,IAAI,EAAE;oBACJ,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,YAAY,EAAE,aAAa,CAAC,OAAO,EAAE;oBACrC,YAAY,EAAE,MAAM,CAAC,WAAW,CAC9B,aAAa,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CACjE;iBACF;aACF,CAAC;QACJ,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,aAAa;YACb,MAAM,MAAM,GAAI,QAAQ,CAAC,WAAsB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YACrE,IAAI,MAAM,GAAY,MAAM,IAAI,CAAC,YAAY,CAC3C,MAAM,EACN,IAAI,CAAC,KAAK,CAAC,KAAK,EAChB,IAAI,CAAC,KAAK,CAAC,MAAM,CAClB,CAAC;YACF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;gBACnE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,6BAA6B,IAAI,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,YAAY;YACZ,IAAI,MAAM,GAAY,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAClE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;gBACnE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,6BAA6B,IAAI,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;QACzE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAcD,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAqB,EACrB,OAAmB,EACnB,IAAmB,EACnB,gBAAiC,EACjC,KAAK,GAAG,CAAC;IAET,yEAAyE;IACzE,wFAAwF;IACxF,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC9D,MAAM,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,IAAI,oBAAoB,EAAE,CAAC;IAE5D,yBAAyB;IACzB,MAAM,QAAQ,GAAG,oBAAoB,CACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAC5E,CAAC;IAEF,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,IAAI,GAAG,EAAE;YACtB,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;YAC1D,YAAY,EAAE,kCAAkC;SACjD,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,mCAAmC;IACnC,MAAM,WAAW,GAAqB;QACpC,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC;IAEF,MAAM,YAAY,GAAiB,KAAK,EAAE,MAAc,EAAE,EAAE;QAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,YAAY,CAAC,CAAC;QAEvD,MAAM,GAAG,GAAyB;YAChC,QAAQ;YACR,IAAI;YACJ,OAAO;YACP,MAAM;YACN,KAAK;SACN,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC;QAC1C,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,IAAI,UAAU,CAAC;QAEtD,gDAAgD;QAChD,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,OAAO;gBACpB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,MAAM,CAAC,OAAO;oBACd,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,UAAU;wBACV,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,OAAO;YACf,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC,CAAC;QAEH,4DAA4D;QAC5D,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,QAAQ,MAAM,SAAS,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAC/C,QAAQ,EACR,YAAY,EACZ,WAAW,CACZ,CAAC;IAEF,4BAA4B;IAC5B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,KAAK,CAAC;QACrB,WAAW;QACX,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE;QAC3B,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,iBAAiB,CAAC,CAAC,CAAC,SAAS;KAClE,CAAC;AACJ,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IAYzD,MAAM,QAAQ,GAAG,oBAAoB,CACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAC5E,CAAC;IAEF,+CAA+C;IAC/C,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,OAAO,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAC5C,CAAC,EAAE,EAAE,EAAE,CACL,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,QAAQ,CAAC,KAAK;iBACX,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC;gBAC7B,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAChD,CAAC;QACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM;QAC9B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,KAAK,MAAM,EAAE,IAAI,KAAK;YAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC,CAAC,EAAG;YACT,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YACtD,YAAY,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;YAC5B,SAAS,EAAE,CAAC,CAAC,IAAI;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,KAAK;YACrB,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;QACH,cAAc,EAAE,MAAM;QACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * DependencyGraph — builds and executes recipe step dependencies.
3
+ *
4
+ * Supports:
5
+ * - Parallel execution up to maxConcurrency
6
+ * - Explicit dependencies (awaits: [stepA, stepB])
7
+ * - Conditional execution (when: condition)
8
+ * - Cycle detection
9
+ */
10
+ export interface StepDependency {
11
+ stepId: string;
12
+ awaits: string[];
13
+ index: number;
14
+ }
15
+ export interface DependencyGraph {
16
+ steps: StepDependency[];
17
+ hasCycles: boolean;
18
+ topologicalOrder: string[];
19
+ }
20
+ export interface ExecutionOptions {
21
+ maxConcurrency: number;
22
+ onStepStart?: (stepId: string) => void;
23
+ onStepComplete?: (stepId: string, error?: Error) => void;
24
+ }
25
+ export type StepExecutor = (stepId: string) => Promise<void>;
26
+ /** Build dependency graph from step definitions */
27
+ export declare function buildDependencyGraph(steps: Array<{
28
+ id: string;
29
+ awaits?: string[];
30
+ }>): DependencyGraph;
31
+ /** Format cycle for error message */
32
+ export declare function formatCycle(cycles: string[][]): string;
33
+ /** Execute steps respecting dependencies with limited concurrency */
34
+ export declare function executeWithDependencies(graph: DependencyGraph, executeStep: StepExecutor, options: ExecutionOptions): Promise<Map<string, {
35
+ success: boolean;
36
+ error?: Error;
37
+ }>>;
38
+ /** Get steps that can run immediately (no unresolved dependencies) */
39
+ export declare function getReadySteps(graph: DependencyGraph, completed: Set<string>): string[];