@bastani/atomic 0.9.0-alpha.1 → 0.9.0-alpha.2

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 (211) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +6 -0
  3. package/dist/builtin/cursor/package.json +2 -2
  4. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  7. package/dist/builtin/mcp/package.json +3 -3
  8. package/dist/builtin/subagents/CHANGELOG.md +6 -0
  9. package/dist/builtin/subagents/package.json +4 -4
  10. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  11. package/dist/builtin/web-access/package.json +2 -2
  12. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  13. package/dist/builtin/workflows/README.md +189 -122
  14. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +30 -27
  15. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  16. package/dist/builtin/workflows/builtin/goal.ts +39 -44
  17. package/dist/builtin/workflows/builtin/index.d.ts +1 -0
  18. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +16 -17
  19. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +1 -0
  20. package/dist/builtin/workflows/builtin/open-claude-design.ts +42 -50
  21. package/dist/builtin/workflows/builtin/ralph.ts +44 -41
  22. package/dist/builtin/workflows/package.json +2 -2
  23. package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
  24. package/dist/builtin/workflows/src/authoring/typebox-defaults.ts +217 -0
  25. package/dist/builtin/workflows/src/authoring/workflow.ts +184 -0
  26. package/dist/builtin/workflows/src/authoring.d.ts +14 -66
  27. package/dist/builtin/workflows/src/engine/graph-inference.ts +100 -0
  28. package/dist/builtin/workflows/src/engine/options.ts +40 -0
  29. package/dist/builtin/workflows/src/engine/primitives/chain.ts +29 -0
  30. package/dist/builtin/workflows/src/engine/primitives/exit.ts +2 -0
  31. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +47 -0
  32. package/dist/builtin/workflows/src/engine/primitives/task.ts +108 -0
  33. package/dist/builtin/workflows/src/engine/primitives/ui.ts +41 -0
  34. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +159 -0
  35. package/dist/builtin/workflows/src/engine/replay.ts +8 -0
  36. package/dist/builtin/workflows/src/engine/run.ts +356 -0
  37. package/dist/builtin/workflows/src/engine/runtime.ts +160 -0
  38. package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +9 -3
  39. package/dist/builtin/workflows/src/extension/workflow-schema.ts +0 -18
  40. package/dist/builtin/workflows/src/index.ts +0 -2
  41. package/dist/builtin/workflows/src/runs/background/runner.ts +6 -3
  42. package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +3 -3
  43. package/dist/builtin/workflows/src/runs/foreground/executor-child-helpers.ts +4 -4
  44. package/dist/builtin/workflows/src/runs/foreground/executor-child-workflow.ts +1 -158
  45. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +1 -1
  46. package/dist/builtin/workflows/src/runs/foreground/executor-outputs.ts +2 -2
  47. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +1 -1
  48. package/dist/builtin/workflows/src/runs/foreground/executor-run.ts +1 -359
  49. package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +1 -1
  50. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +2 -5
  51. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +12 -4
  52. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +4 -3
  53. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +9 -2
  54. package/dist/builtin/workflows/src/runs/foreground/executor-task-context.ts +2 -132
  55. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -2
  56. package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +2 -100
  57. package/dist/builtin/workflows/src/sdk-surface.ts +6 -9
  58. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +9 -3
  59. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +17 -3
  60. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +3 -33
  61. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +9 -81
  62. package/dist/builtin/workflows/src/shared/types.ts +25 -8
  63. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +49 -0
  64. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +84 -0
  65. package/dist/builtin/workflows/src/workflows/registry.ts +7 -3
  66. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  67. package/dist/core/agent-session-auto-compaction.js +6 -1
  68. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  69. package/dist/core/agent-session-bash.d.ts.map +1 -1
  70. package/dist/core/agent-session-bash.js +0 -5
  71. package/dist/core/agent-session-bash.js.map +1 -1
  72. package/dist/core/agent-session-methods.d.ts +0 -2
  73. package/dist/core/agent-session-methods.d.ts.map +1 -1
  74. package/dist/core/agent-session-methods.js.map +1 -1
  75. package/dist/core/agent-session-services.d.ts +0 -1
  76. package/dist/core/agent-session-services.d.ts.map +1 -1
  77. package/dist/core/agent-session-services.js +0 -1
  78. package/dist/core/agent-session-services.js.map +1 -1
  79. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  80. package/dist/core/agent-session-tool-registry.js +0 -2
  81. package/dist/core/agent-session-tool-registry.js.map +1 -1
  82. package/dist/core/agent-session-types.d.ts +0 -2
  83. package/dist/core/agent-session-types.d.ts.map +1 -1
  84. package/dist/core/agent-session-types.js.map +1 -1
  85. package/dist/core/agent-session.d.ts +0 -2
  86. package/dist/core/agent-session.d.ts.map +1 -1
  87. package/dist/core/agent-session.js +0 -1
  88. package/dist/core/agent-session.js.map +1 -1
  89. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  90. package/dist/core/atomic-guide-command.js +1 -1
  91. package/dist/core/atomic-guide-command.js.map +1 -1
  92. package/dist/core/extensions/loader-core.d.ts +1 -3
  93. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  94. package/dist/core/extensions/loader-core.js +13 -6
  95. package/dist/core/extensions/loader-core.js.map +1 -1
  96. package/dist/core/extensions/loader-virtual-modules.d.ts +7 -1
  97. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  98. package/dist/core/extensions/loader-virtual-modules.js +34 -2
  99. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  100. package/dist/core/extensions/loader.d.ts +2 -1
  101. package/dist/core/extensions/loader.d.ts.map +1 -1
  102. package/dist/core/extensions/loader.js +2 -1
  103. package/dist/core/extensions/loader.js.map +1 -1
  104. package/dist/core/index.d.ts +0 -1
  105. package/dist/core/index.d.ts.map +1 -1
  106. package/dist/core/index.js +0 -1
  107. package/dist/core/index.js.map +1 -1
  108. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  109. package/dist/core/model-registry-builtins.js +6 -0
  110. package/dist/core/model-registry-builtins.js.map +1 -1
  111. package/dist/core/model-registry-schemas.d.ts +65 -13
  112. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  113. package/dist/core/model-registry-schemas.js +10 -0
  114. package/dist/core/model-registry-schemas.js.map +1 -1
  115. package/dist/core/resource-loader-core.d.ts +1 -0
  116. package/dist/core/resource-loader-core.d.ts.map +1 -1
  117. package/dist/core/resource-loader-core.js +2 -0
  118. package/dist/core/resource-loader-core.js.map +1 -1
  119. package/dist/core/resource-loader-extensions.d.ts.map +1 -1
  120. package/dist/core/resource-loader-extensions.js +3 -3
  121. package/dist/core/resource-loader-extensions.js.map +1 -1
  122. package/dist/core/resource-loader-internals.d.ts +1 -0
  123. package/dist/core/resource-loader-internals.d.ts.map +1 -1
  124. package/dist/core/resource-loader-internals.js.map +1 -1
  125. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  126. package/dist/core/resource-loader-reload.js +6 -2
  127. package/dist/core/resource-loader-reload.js.map +1 -1
  128. package/dist/core/sdk-exports.d.ts +1 -1
  129. package/dist/core/sdk-exports.d.ts.map +1 -1
  130. package/dist/core/sdk-exports.js.map +1 -1
  131. package/dist/core/sdk-types.d.ts +0 -3
  132. package/dist/core/sdk-types.d.ts.map +1 -1
  133. package/dist/core/sdk-types.js.map +1 -1
  134. package/dist/core/sdk.d.ts.map +1 -1
  135. package/dist/core/sdk.js +0 -1
  136. package/dist/core/sdk.js.map +1 -1
  137. package/dist/core/session-manager-history.d.ts.map +1 -1
  138. package/dist/core/session-manager-history.js +2 -1
  139. package/dist/core/session-manager-history.js.map +1 -1
  140. package/dist/core/tools/bash.d.ts +0 -5
  141. package/dist/core/tools/bash.d.ts.map +1 -1
  142. package/dist/core/tools/bash.js +10 -11
  143. package/dist/core/tools/bash.js.map +1 -1
  144. package/dist/core/tools/edit-diff-preserve.d.ts +18 -0
  145. package/dist/core/tools/edit-diff-preserve.d.ts.map +1 -0
  146. package/dist/core/tools/edit-diff-preserve.js +85 -0
  147. package/dist/core/tools/edit-diff-preserve.js.map +1 -0
  148. package/dist/core/tools/edit-diff.d.ts +3 -2
  149. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  150. package/dist/core/tools/edit-diff.js +15 -18
  151. package/dist/core/tools/edit-diff.js.map +1 -1
  152. package/dist/core/tools/index.d.ts +0 -1
  153. package/dist/core/tools/index.d.ts.map +1 -1
  154. package/dist/core/tools/index.js +0 -1
  155. package/dist/core/tools/index.js.map +1 -1
  156. package/dist/index.d.ts +2 -2
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +1 -1
  159. package/dist/index.js.map +1 -1
  160. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  161. package/dist/modes/interactive/components/model-selector.js +2 -2
  162. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  163. package/dist/modes/interactive/model-search.d.ts +5 -0
  164. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  165. package/dist/modes/interactive/model-search.js +9 -0
  166. package/dist/modes/interactive/model-search.js.map +1 -1
  167. package/dist/utils/shell.d.ts +1 -0
  168. package/dist/utils/shell.d.ts.map +1 -1
  169. package/dist/utils/shell.js +12 -5
  170. package/dist/utils/shell.js.map +1 -1
  171. package/docs/custom-provider.md +4 -3
  172. package/docs/models.md +3 -2
  173. package/docs/packages.md +2 -2
  174. package/docs/quickstart.md +1 -1
  175. package/docs/sdk.md +2 -40
  176. package/docs/security.md +1 -1
  177. package/docs/workflows.md +238 -173
  178. package/package.json +5 -5
  179. package/dist/builtin/workflows/src/workflows/define-workflow.ts +0 -277
  180. package/dist/core/tools/bash-policy-compile.d.ts +0 -5
  181. package/dist/core/tools/bash-policy-compile.d.ts.map +0 -1
  182. package/dist/core/tools/bash-policy-compile.js +0 -241
  183. package/dist/core/tools/bash-policy-compile.js.map +0 -1
  184. package/dist/core/tools/bash-policy-evaluate.d.ts +0 -3
  185. package/dist/core/tools/bash-policy-evaluate.d.ts.map +0 -1
  186. package/dist/core/tools/bash-policy-evaluate.js +0 -92
  187. package/dist/core/tools/bash-policy-evaluate.js.map +0 -1
  188. package/dist/core/tools/bash-policy-format.d.ts +0 -5
  189. package/dist/core/tools/bash-policy-format.d.ts.map +0 -1
  190. package/dist/core/tools/bash-policy-format.js +0 -49
  191. package/dist/core/tools/bash-policy-format.js.map +0 -1
  192. package/dist/core/tools/bash-policy-parser.d.ts +0 -4
  193. package/dist/core/tools/bash-policy-parser.d.ts.map +0 -1
  194. package/dist/core/tools/bash-policy-parser.js +0 -155
  195. package/dist/core/tools/bash-policy-parser.js.map +0 -1
  196. package/dist/core/tools/bash-policy-segment.d.ts +0 -3
  197. package/dist/core/tools/bash-policy-segment.d.ts.map +0 -1
  198. package/dist/core/tools/bash-policy-segment.js +0 -275
  199. package/dist/core/tools/bash-policy-segment.js.map +0 -1
  200. package/dist/core/tools/bash-policy-shell.d.ts +0 -11
  201. package/dist/core/tools/bash-policy-shell.d.ts.map +0 -1
  202. package/dist/core/tools/bash-policy-shell.js +0 -267
  203. package/dist/core/tools/bash-policy-shell.js.map +0 -1
  204. package/dist/core/tools/bash-policy-types.d.ts +0 -146
  205. package/dist/core/tools/bash-policy-types.d.ts.map +0 -1
  206. package/dist/core/tools/bash-policy-types.js +0 -2
  207. package/dist/core/tools/bash-policy-types.js.map +0 -1
  208. package/dist/core/tools/bash-policy.d.ts +0 -6
  209. package/dist/core/tools/bash-policy.d.ts.map +0 -1
  210. package/dist/core/tools/bash-policy.js +0 -5
  211. package/dist/core/tools/bash-policy.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ import type { WorkflowChainOptions, WorkflowTaskResult, WorkflowTaskStep } from "../../shared/types.js";
2
+ import type { EngineRuntime } from "../runtime.js";
3
+ import type { WorkflowTaskPrimitive } from "./task.js";
4
+ import {
5
+ chainStepPrompt,
6
+ replaceTaskPlaceholder,
7
+ taskOptionsFromStep,
8
+ taskPrevious,
9
+ taskWithSharedDefaults,
10
+ } from "../../runs/foreground/executor-task-prompts.js";
11
+
12
+ export function createChainPrimitive(input: {
13
+ readonly runtime: EngineRuntime;
14
+ readonly task: WorkflowTaskPrimitive;
15
+ }): (steps: readonly WorkflowTaskStep[], options?: WorkflowChainOptions) => Promise<WorkflowTaskResult[]> {
16
+ return async (steps: readonly WorkflowTaskStep[], options: WorkflowChainOptions = {}): Promise<WorkflowTaskResult[]> => {
17
+ input.runtime.exit.throwIfWorkflowExitSelected();
18
+ const results: WorkflowTaskResult[] = [];
19
+ for (let index = 0; index < steps.length; index += 1) {
20
+ input.runtime.exit.throwIfWorkflowExitSelected();
21
+ const step = steps[index]!;
22
+ const explicitPrevious = taskPrevious(step);
23
+ const previous = explicitPrevious ?? (index > 0 ? results[index - 1] : undefined);
24
+ const prompt = replaceTaskPlaceholder(chainStepPrompt(step, index), options.task ?? "");
25
+ results.push(await input.task(step.name, taskWithSharedDefaults(taskOptionsFromStep(step, prompt, previous), options)));
26
+ }
27
+ return results;
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ export { createWorkflowExitManager } from "../../runs/foreground/executor-exit-manager.js";
2
+ export type { WorkflowExitManager } from "../../runs/foreground/executor-exit-manager.js";
@@ -0,0 +1,47 @@
1
+ import type { WorkflowParallelOptions, WorkflowTaskResult, WorkflowTaskStep } from "../../shared/types.js";
2
+ import type { EngineRuntime } from "../runtime.js";
3
+ import type { WorkflowTaskPrimitive } from "./task.js";
4
+ import type { ParallelFailFastScope, ParallelFailFastStage } from "../../runs/foreground/executor-types.js";
5
+ import { findWorkflowExitSignal } from "../../runs/foreground/executor-abort.js";
6
+ import { mapParallelSteps } from "../../runs/foreground/executor-direct-helpers.js";
7
+ import {
8
+ parallelFallbackTask,
9
+ replaceTaskPlaceholder,
10
+ taskOptionsFromStep,
11
+ taskPrevious,
12
+ taskWithSharedDefaults,
13
+ } from "../../runs/foreground/executor-task-prompts.js";
14
+
15
+ export function createParallelPrimitive(input: {
16
+ readonly runtime: EngineRuntime;
17
+ readonly task: WorkflowTaskPrimitive;
18
+ }): (steps: readonly WorkflowTaskStep[], options?: WorkflowParallelOptions) => Promise<WorkflowTaskResult[]> {
19
+ return async (steps: readonly WorkflowTaskStep[], options: WorkflowParallelOptions = {}): Promise<WorkflowTaskResult[]> => {
20
+ input.runtime.exit.throwIfWorkflowExitSelected();
21
+ const fallback = parallelFallbackTask(steps, options);
22
+ const failFastEnabled = options.failFast !== false;
23
+ const parallelScope: ParallelFailFastScope = {
24
+ failed: false,
25
+ activeStages: new Map<string, ParallelFailFastStage>(),
26
+ parentIds: Object.freeze(input.runtime.tracker.currentParents()),
27
+ };
28
+ return mapParallelSteps(steps, options.concurrency, options.failFast, async (step) => {
29
+ input.runtime.exit.throwIfWorkflowExitSelected();
30
+ const prompt = replaceTaskPlaceholder(step.prompt ?? step.task ?? fallback, options.task ?? fallback);
31
+ return await input.task(
32
+ step.name,
33
+ taskWithSharedDefaults(taskOptionsFromStep(step, prompt, taskPrevious(step)), options),
34
+ parallelScope,
35
+ );
36
+ }, (error) => {
37
+ if (!failFastEnabled) return;
38
+ parallelScope.failed = true;
39
+ parallelScope.firstFailure = error;
40
+ for (const stage of parallelScope.activeStages.values()) stage.skip();
41
+ }, {
42
+ beforeDequeue: input.runtime.exit.throwIfWorkflowExitSelected,
43
+ beforeMap: input.runtime.exit.throwIfWorkflowExitSelected,
44
+ isControlSignal: (error) => findWorkflowExitSignal(error, input.runtime.exit.exitScope) !== undefined,
45
+ });
46
+ };
47
+ }
@@ -0,0 +1,108 @@
1
+ import type { WorkflowChainOptions, WorkflowParallelOptions, WorkflowTaskOptions, WorkflowTaskResult, WorkflowTaskStep } from "../../shared/types.js";
2
+ import type { ParallelFailFastScope } from "../../runs/foreground/executor-types.js";
3
+ import type { EngineRuntime } from "../runtime.js";
4
+ import {
5
+ applyTaskContext,
6
+ structuredTaskOutputText,
7
+ taskPrevious,
8
+ taskPrompt,
9
+ taskPromptOptions,
10
+ taskReadInstruction,
11
+ taskStageOptions,
12
+ truncateTaskOutput,
13
+ } from "../../runs/foreground/executor-task-prompts.js";
14
+ import {
15
+ cleanupPreparedWorktrees,
16
+ collectWorktreeDiffs,
17
+ prepareDirectWorktrees,
18
+ stageOptionsWithGitWorktree,
19
+ stageOptionsWithInputDefaults,
20
+ } from "../../runs/foreground/executor-direct-helpers.js";
21
+ import { createChainPrimitive } from "./chain.js";
22
+ import { createParallelPrimitive } from "./parallel.js";
23
+
24
+ export type WorkflowTaskPrimitive = (
25
+ name: string,
26
+ options: WorkflowTaskOptions,
27
+ stageFailFastScope?: ParallelFailFastScope,
28
+ ) => Promise<WorkflowTaskResult>;
29
+
30
+ export interface WorkflowTaskRunners {
31
+ task: WorkflowTaskPrimitive;
32
+ chain(steps: readonly WorkflowTaskStep[], options?: WorkflowChainOptions): Promise<WorkflowTaskResult[]>;
33
+ parallel(steps: readonly WorkflowTaskStep[], options?: WorkflowParallelOptions): Promise<WorkflowTaskResult[]>;
34
+ }
35
+
36
+ function createTaskPrimitive(runtime: EngineRuntime): WorkflowTaskPrimitive {
37
+ return async (name: string, options: WorkflowTaskOptions, stageFailFastScope?: ParallelFailFastScope): Promise<WorkflowTaskResult> => {
38
+ runtime.exit.throwIfWorkflowExitSelected();
39
+ const runTaskOnce = async (taskOptions: WorkflowTaskOptions): Promise<WorkflowTaskResult> => {
40
+ runtime.exit.throwIfWorkflowExitSelected();
41
+ const resolvedTaskOptions = stageOptionsWithGitWorktree(
42
+ stageOptionsWithInputDefaults(taskOptions, runtime.inputRuntimeDefaults),
43
+ runtime.workflowInvocationCwd,
44
+ ) ?? taskOptions;
45
+ const stageOptions = taskStageOptions(resolvedTaskOptions);
46
+ const stageHandle = runtime.spawnStage(name, {
47
+ kind: "agent",
48
+ ...(stageOptions !== undefined ? { options: stageOptions } : {}),
49
+ ...(stageFailFastScope !== undefined ? { failFastScope: stageFailFastScope } : {}),
50
+ });
51
+ const stage = stageHandle.context;
52
+ const rawOutput = await stage.prompt(
53
+ applyTaskContext(`${taskReadInstruction(resolvedTaskOptions)}${taskPrompt(resolvedTaskOptions)}`, taskPrevious(resolvedTaskOptions)),
54
+ taskPromptOptions(resolvedTaskOptions),
55
+ );
56
+ const structured = typeof rawOutput === "string" ? undefined : rawOutput;
57
+ const text = truncateTaskOutput(structuredTaskOutputText(rawOutput), resolvedTaskOptions.maxOutput);
58
+ const sessionId = (() => {
59
+ try {
60
+ return stage.sessionId;
61
+ } catch {
62
+ return undefined;
63
+ }
64
+ })();
65
+ const stageMeta = stage.__modelFallbackMeta();
66
+ return {
67
+ name,
68
+ stageName: name,
69
+ text,
70
+ ...(structured !== undefined ? { structured } : {}),
71
+ ...(sessionId !== undefined ? { sessionId } : {}),
72
+ ...(stage.sessionFile !== undefined ? { sessionFile: stage.sessionFile } : {}),
73
+ ...(stageMeta.model !== undefined ? { model: stageMeta.model } : {}),
74
+ ...(stageMeta.fastMode === true ? { fastMode: stageMeta.fastMode } : {}),
75
+ ...(stageMeta.attemptedModels !== undefined ? { attemptedModels: stageMeta.attemptedModels } : {}),
76
+ ...(stageMeta.modelAttempts !== undefined ? { modelAttempts: stageMeta.modelAttempts } : {}),
77
+ ...(stageMeta.warnings !== undefined ? { warnings: stageMeta.warnings } : {}),
78
+ };
79
+ };
80
+
81
+ if (options.worktree !== true) return runTaskOnce(options);
82
+ const prepared = prepareDirectWorktrees(
83
+ [{ ...options, name }],
84
+ { ...options, worktree: true },
85
+ `${runtime.runId}-${name}-${crypto.randomUUID()}`,
86
+ name,
87
+ );
88
+ const preparedTask = prepared.tasks[0]!;
89
+ try {
90
+ const result = await runTaskOnce(preparedTask);
91
+ const worktreeDiffs = collectWorktreeDiffs(prepared, options.artifacts !== false);
92
+ return worktreeDiffs.artifacts.length === 0
93
+ ? result
94
+ : { ...result, artifacts: [...(result.artifacts ?? []), ...worktreeDiffs.artifacts] };
95
+ } finally {
96
+ cleanupPreparedWorktrees(prepared);
97
+ }
98
+ };
99
+ }
100
+
101
+ export function createWorkflowTaskRunners(input: { readonly runtime: EngineRuntime }): WorkflowTaskRunners {
102
+ const task = createTaskPrimitive(input.runtime);
103
+ return {
104
+ task,
105
+ chain: createChainPrimitive({ runtime: input.runtime, task }),
106
+ parallel: createParallelPrimitive({ runtime: input.runtime, task }),
107
+ };
108
+ }
@@ -0,0 +1,41 @@
1
+ import type {
2
+ WorkflowCustomUiFactory,
3
+ WorkflowCustomUiOptions,
4
+ WorkflowUIContext,
5
+ } from "../../shared/types.js";
6
+ import type { RunOpts } from "../../runs/foreground/executor-types.js";
7
+ import { makeHeadlessUnavailableUIContext, normalizeUIContext } from "../../runs/foreground/executor-hil.js";
8
+
9
+ export function buildExitGatedUiContext(input: {
10
+ readonly opts: RunOpts;
11
+ readonly baseFromPromptNodes: () => WorkflowUIContext;
12
+ readonly throwIfWorkflowExitSelected: () => void;
13
+ }): WorkflowUIContext {
14
+ const base = input.opts.usePromptNodesForUi === true
15
+ ? input.baseFromPromptNodes()
16
+ : input.opts.executionMode === "non_interactive" && input.opts.ui === undefined
17
+ ? makeHeadlessUnavailableUIContext()
18
+ : normalizeUIContext(input.opts.ui);
19
+ return {
20
+ async input(promptText: string): Promise<string> {
21
+ input.throwIfWorkflowExitSelected();
22
+ return await base.input(promptText);
23
+ },
24
+ async confirm(message: string): Promise<boolean> {
25
+ input.throwIfWorkflowExitSelected();
26
+ return await base.confirm(message);
27
+ },
28
+ async select<T extends string>(message: string, options: readonly T[]): Promise<T> {
29
+ input.throwIfWorkflowExitSelected();
30
+ return await base.select(message, options);
31
+ },
32
+ async editor(initial?: string): Promise<string> {
33
+ input.throwIfWorkflowExitSelected();
34
+ return await base.editor(initial);
35
+ },
36
+ async custom<T>(factory: WorkflowCustomUiFactory<T>, options?: WorkflowCustomUiOptions): Promise<T> {
37
+ input.throwIfWorkflowExitSelected();
38
+ return await base.custom(factory, options);
39
+ },
40
+ };
41
+ }
@@ -0,0 +1,159 @@
1
+ import type {
2
+ WorkflowChildResult,
3
+ WorkflowDefinition,
4
+ WorkflowInputValues,
5
+ WorkflowOutputValues,
6
+ WorkflowRunChildArgs,
7
+ WorkflowRunChildOptions,
8
+ } from "../../shared/types.js";
9
+ import type { WorkflowChildRunRef } from "../../shared/store-types.js";
10
+ import type { ResolvedInputs, RunOpts, RunResult } from "../../runs/foreground/executor-types.js";
11
+ import type { EngineRuntime } from "../runtime.js";
12
+ import { findWorkflowExitSignal, isWorkflowExitStatus, makeParentWorkflowExitAbortReason } from "../../runs/foreground/executor-abort.js";
13
+ import { selectWorkflowOutputs } from "../../runs/foreground/executor-outputs.js";
14
+ import { resolveAndValidateInputs } from "../../runs/foreground/executor-inputs.js";
15
+ import {
16
+ isWorkflowDefinition,
17
+ workflowChildReplaySnapshot,
18
+ workflowDefinitionRequirementMessage,
19
+ } from "../../runs/foreground/executor-child-helpers.js";
20
+
21
+ export function createChildWorkflowRunner(input: {
22
+ readonly runtime: EngineRuntime;
23
+ readonly resolveWorkflowCwd: () => string;
24
+ readonly nextWorkflowBoundaryReplayKey: (name: string) => string;
25
+ readonly runWorkflow: <
26
+ TInputs extends WorkflowInputValues,
27
+ TRunInputs extends WorkflowInputValues = TInputs,
28
+ >(
29
+ def: WorkflowDefinition<TInputs, WorkflowOutputValues, TRunInputs>,
30
+ inputs: ResolvedInputs,
31
+ opts?: RunOpts,
32
+ ) => Promise<RunResult>;
33
+ }): <
34
+ TChildInputs extends WorkflowInputValues,
35
+ TChildOutputs extends WorkflowOutputValues,
36
+ TChildRunInputs extends WorkflowInputValues = TChildInputs,
37
+ >(
38
+ child: WorkflowDefinition<TChildInputs, TChildOutputs, TChildRunInputs>,
39
+ ...args: WorkflowRunChildArgs<TChildRunInputs>
40
+ ) => Promise<WorkflowChildResult<TChildOutputs>> {
41
+ return async <
42
+ TChildInputs extends WorkflowInputValues,
43
+ TChildOutputs extends WorkflowOutputValues,
44
+ TChildRunInputs extends WorkflowInputValues = TChildInputs,
45
+ >(
46
+ child: WorkflowDefinition<TChildInputs, TChildOutputs, TChildRunInputs>,
47
+ ...args: WorkflowRunChildArgs<TChildRunInputs>
48
+ ): Promise<WorkflowChildResult<TChildOutputs>> => {
49
+ const options: WorkflowRunChildOptions<TChildRunInputs> = args[0] ?? {};
50
+ const { runtime } = input;
51
+ runtime.exit.throwIfWorkflowExitSelected();
52
+ if (!isWorkflowDefinition(child)) throw new Error(workflowDefinitionRequirementMessage("ctx.workflow(definition)", child));
53
+ const childName = child.normalizedName;
54
+ const boundaryName = options.stageName ?? `workflow:${childName}`;
55
+ const boundaryReplayKey = input.nextWorkflowBoundaryReplayKey(boundaryName);
56
+ const boundary = runtime.spawnStage(boundaryName, { kind: "workflow-boundary", replayKey: boundaryReplayKey }).boundary;
57
+ let childRunId: string | undefined;
58
+ let detachParentAbort: (() => void) | undefined;
59
+ try {
60
+ if (boundary.replayedChild !== undefined) {
61
+ await Promise.resolve();
62
+ runtime.exit.throwIfWorkflowExitSelected();
63
+ boundary.finalizeReplay();
64
+ return boundary.replayedChild as WorkflowChildResult<TChildOutputs>;
65
+ }
66
+
67
+ const childInputs = resolveAndValidateInputs(child.inputs, options.inputs ?? {}, `child workflow "${childName}" (${child.name})`);
68
+ runtime.exit.throwIfWorkflowExitSelected();
69
+
70
+ childRunId = crypto.randomUUID();
71
+ const childController = new AbortController();
72
+ const childRef: WorkflowChildRunRef = { alias: childName, workflow: child.normalizedName, runId: childRunId };
73
+ boundary.linkChildRun(childRef, childController);
74
+
75
+ const abortChildFromParent = (): void => {
76
+ const parentExit = findWorkflowExitSignal(runtime.signal.reason, runtime.exit.exitScope);
77
+ childController.abort(parentExit !== undefined ? makeParentWorkflowExitAbortReason(parentExit.reason) : runtime.signal.reason);
78
+ };
79
+ if (runtime.signal.aborted) abortChildFromParent();
80
+ else {
81
+ runtime.signal.addEventListener("abort", abortChildFromParent, { once: true });
82
+ detachParentAbort = () => runtime.signal.removeEventListener("abort", abortChildFromParent);
83
+ }
84
+ runtime.exit.throwIfWorkflowExitSelected();
85
+ runtime.childRunOptions.cancellation?.register(childRunId, childController);
86
+ runtime.exit.throwIfWorkflowExitSelected();
87
+
88
+ // Ordering is intentional: linkChildRun happens before launch so parent
89
+ // cleanup can abort the child; observeChildRun happens immediately after
90
+ // promise creation, with no await in between, so cleanup can await teardown.
91
+ const childRunPromise = input.runWorkflow(child, childInputs, {
92
+ ...runtime.childRunOptions,
93
+ runId: childRunId,
94
+ cwd: input.resolveWorkflowCwd(),
95
+ depth: runtime.depth + 1,
96
+ parentRun: {
97
+ runId: runtime.runId,
98
+ stageId: boundary.id,
99
+ rootRunId: runtime.parentRootRunId ?? runtime.runId,
100
+ },
101
+ signal: childController.signal,
102
+ deferWorkflowStart: false,
103
+ });
104
+ boundary.observeChildRun(childRunPromise);
105
+ const childRun = await childRunPromise;
106
+ runtime.exit.throwIfWorkflowExitSelected();
107
+
108
+ if (!isWorkflowExitStatus(childRun.status)) {
109
+ const failedChildStage = childRun.stages.find((stage) => stage.failureKind !== undefined);
110
+ throw new Error(
111
+ `atomic-workflows: child workflow "${childName}" (${child.name}) failed with status ${childRun.status}${childRun.error !== undefined ? `: ${childRun.error}` : ""}`,
112
+ {
113
+ cause: {
114
+ ...(failedChildStage?.failureKind !== undefined ? { code: failedChildStage.failureKind } : {}),
115
+ ...(failedChildStage?.failureMessage !== undefined ? { message: failedChildStage.failureMessage } : {}),
116
+ },
117
+ },
118
+ );
119
+ }
120
+
121
+ const outputs = selectWorkflowOutputs(child, childRun.result);
122
+ const childExited = childRun.exited === true || childRun.status !== "completed";
123
+ const childResult: WorkflowChildResult<TChildOutputs> = childExited
124
+ ? {
125
+ workflow: child.normalizedName,
126
+ runId: childRun.runId,
127
+ status: childRun.status,
128
+ exited: true,
129
+ outputs: outputs as Partial<TChildOutputs>,
130
+ ...(childRun.exitReason !== undefined ? { exitReason: childRun.exitReason } : {}),
131
+ }
132
+ : {
133
+ workflow: child.normalizedName,
134
+ runId: childRun.runId,
135
+ status: "completed",
136
+ exited: false,
137
+ outputs: outputs as TChildOutputs,
138
+ };
139
+ const workflowChild = workflowChildReplaySnapshot(childName, childResult);
140
+ const outputKeys = Object.keys(outputs);
141
+ boundary.complete(
142
+ `Workflow "${child.name}" ${childRun.status} (runId: ${childRun.runId}; outputs: ${outputKeys.length > 0 ? outputKeys.join(", ") : "(none)"})`,
143
+ workflowChild,
144
+ );
145
+ return childResult;
146
+ } catch (err) {
147
+ const exit = findWorkflowExitSignal(err, runtime.exit.exitScope) ?? findWorkflowExitSignal(runtime.signal.reason, runtime.exit.exitScope);
148
+ if (exit !== undefined) {
149
+ await boundary.skipForWorkflowExit(exit.reason);
150
+ throw exit;
151
+ }
152
+ boundary.fail(err);
153
+ throw err;
154
+ } finally {
155
+ detachParentAbort?.();
156
+ if (childRunId !== undefined) runtime.childRunOptions.cancellation?.unregister(childRunId);
157
+ }
158
+ };
159
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ createContinuationReplayIndex,
3
+ sameStringSet,
4
+ } from "../runs/foreground/executor-continuation.js";
5
+ export type {
6
+ ContinuationReplayDecision,
7
+ ContinuationReplayIndex,
8
+ } from "../runs/foreground/executor-continuation.js";