@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,356 @@
1
+ import type { RunSnapshot } from "../shared/store-types.js";
2
+ import type {
3
+ WorkflowDefinition,
4
+ WorkflowInputValues,
5
+ WorkflowOutputValues,
6
+ WorkflowRunContext,
7
+ } from "../shared/types.js";
8
+ import type { WorkflowFailure } from "../shared/workflow-failures.js";
9
+ import { classifyWorkflowFailure } from "../shared/workflow-failures.js";
10
+ import { store as defaultStore } from "../shared/store.js";
11
+ import { appendRunStart } from "../shared/persistence-session-entries.js";
12
+ import { GraphFrontierTracker } from "./graph-inference.js";
13
+ import { EngineRuntime } from "./runtime.js";
14
+ import type { EngineChildRunOptions, EngineStageRuntimeOptions, EngineWorkflowBoundaryOptions } from "./options.js";
15
+ import { createContinuationReplayIndex } from "./replay.js";
16
+ import { buildExitGatedUiContext } from "./primitives/ui.js";
17
+ import { createWorkflowExitManager } from "./primitives/exit.js";
18
+ import { createWorkflowTaskRunners } from "./primitives/task.js";
19
+ import { createChildWorkflowRunner } from "./primitives/workflow.js";
20
+ import { createRunLimiter } from "../runs/shared/concurrency.js";
21
+ import { stageControlRegistry as defaultStageControlRegistry } from "../runs/foreground/stage-control-registry.js";
22
+ import type { RunOpts, RunResult } from "../runs/foreground/executor-types.js";
23
+ import { unknownErrorMessage, findWorkflowExitSignal, parentWorkflowExitAbortReason } from "../runs/foreground/executor-abort.js";
24
+ import { resolveAndValidateInputs, resolveInputConcurrency, resolveInputRuntimeDefaults } from "../runs/foreground/executor-inputs.js";
25
+ import { workflowCwdWithInputWorktree } from "../runs/foreground/executor-direct-helpers.js";
26
+ import { createStageScheduler } from "../runs/foreground/executor-scheduler.js";
27
+ import { createRunFinalizers } from "../runs/foreground/executor-run-finalizers.js";
28
+ import { buildPromptNodeUiAdapter } from "../runs/foreground/executor-prompt-nodes.js";
29
+ import {
30
+ appendRunEndWhenRecorded,
31
+ assertWorkflowCreatedStage,
32
+ finalizeKilled,
33
+ finalizeKilledByFailure,
34
+ recordActiveBlockedFailure,
35
+ reconcileTerminalRunResult,
36
+ selectRunFailureDisposition,
37
+ } from "../runs/foreground/executor-lifecycle.js";
38
+ import { assertWorkflowRunOutputs, normalizeWorkflowRunOutput } from "../runs/foreground/executor-outputs.js";
39
+ import { isWorkflowDefinition, workflowDefinitionRequirementMessage } from "../runs/foreground/executor-child-helpers.js";
40
+
41
+ function nextEventLoopTurn(): Promise<void> {
42
+ return new Promise((resolve) => setTimeout(resolve, 0));
43
+ }
44
+
45
+ type WorkflowRunInputArgument = Parameters<typeof resolveAndValidateInputs>[1];
46
+
47
+ export function run<
48
+ TInputs extends WorkflowInputValues,
49
+ TOutputs extends WorkflowOutputValues,
50
+ TRunInputs extends WorkflowInputValues = TInputs,
51
+ >(
52
+ def: WorkflowDefinition<TInputs, TOutputs, TRunInputs>,
53
+ inputs: WorkflowRunInputArgument,
54
+ opts?: RunOpts,
55
+ ): Promise<RunResult<TOutputs>>;
56
+ export async function run<
57
+ TInputs extends WorkflowInputValues,
58
+ TRunInputs extends WorkflowInputValues = TInputs,
59
+ >(
60
+ def: WorkflowDefinition<TInputs, WorkflowOutputValues, TRunInputs>,
61
+ inputs: WorkflowRunInputArgument,
62
+ opts: RunOpts = {},
63
+ ): Promise<RunResult> {
64
+ if (!isWorkflowDefinition(def)) throw new Error(workflowDefinitionRequirementMessage("run(definition, inputs)", def));
65
+
66
+ const activeStore = opts.store ?? defaultStore;
67
+ const adapters = opts.adapters ?? {};
68
+ // Prompt-node UI is the graph-mode transport and intentionally takes precedence
69
+ // over an injected RunOpts.ui adapter; warn because that adapter will be ignored.
70
+ if (opts.usePromptNodesForUi === true && opts.ui !== undefined) {
71
+ console.warn("atomic-workflows: usePromptNodesForUi ignores the provided RunOpts.ui adapter");
72
+ }
73
+
74
+ const depth = opts.depth ?? 0;
75
+ const maxDepth = opts.config?.maxDepth ?? 4;
76
+ if (depth >= maxDepth) {
77
+ return {
78
+ runId: opts.runId ?? crypto.randomUUID(),
79
+ status: "failed",
80
+ error: `atomic-workflows: maxDepth exceeded (max ${maxDepth})`,
81
+ stages: [],
82
+ };
83
+ }
84
+
85
+ const resolvedInputs = resolveAndValidateInputs(def.inputs, inputs, `workflow "${def.name}"`);
86
+ const runId = opts.runId ?? crypto.randomUUID();
87
+ const exitScope = Symbol(`workflow-exit:${runId}`);
88
+ const ownController = new AbortController();
89
+ const callerSignal = opts.signal;
90
+ if (callerSignal) {
91
+ if (callerSignal.aborted) ownController.abort(callerSignal.reason);
92
+ else callerSignal.addEventListener("abort", () => { ownController.abort(callerSignal.reason); }, { once: true });
93
+ }
94
+ const exit = createWorkflowExitManager({ runId, exitScope, controller: ownController });
95
+
96
+ const runSnapshot: RunSnapshot = {
97
+ id: runId,
98
+ name: def.name,
99
+ inputs: Object.freeze(resolvedInputs),
100
+ status: "running" as const,
101
+ stages: [],
102
+ startedAt: Date.now(),
103
+ ...(opts.parentRun !== undefined ? {
104
+ parentRunId: opts.parentRun.runId,
105
+ parentStageId: opts.parentRun.stageId,
106
+ rootRunId: opts.parentRun.rootRunId,
107
+ } : {}),
108
+ ...(opts.continuation !== undefined ? {
109
+ resumedFromRunId: opts.continuation.source.id,
110
+ resumeFromStageId: opts.continuation.resumeFromStageId,
111
+ } : {}),
112
+ };
113
+
114
+ const classifiedFailures = new Map<unknown, WorkflowFailure>();
115
+ const classifyExecutorFailure = (error: unknown): WorkflowFailure => {
116
+ const cached = classifiedFailures.get(error);
117
+ if (cached !== undefined) return cached;
118
+ let classified: WorkflowFailure;
119
+ try {
120
+ classified = classifyWorkflowFailure(error);
121
+ } catch {
122
+ classified = classifyWorkflowFailure(new Error(unknownErrorMessage(error)));
123
+ }
124
+ classifiedFailures.set(error, classified);
125
+ return classified;
126
+ };
127
+
128
+ activeStore.recordRunStart(runSnapshot);
129
+ if (!opts.signal) opts.cancellation?.register(runId, ownController);
130
+ opts.onRunStart?.(runSnapshot);
131
+ if (opts.persistence) {
132
+ appendRunStart(opts.persistence, {
133
+ runId,
134
+ name: def.name,
135
+ inputs: resolvedInputs,
136
+ ...(runSnapshot.parentRunId !== undefined ? { parentRunId: runSnapshot.parentRunId } : {}),
137
+ ...(runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {}),
138
+ ...(runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {}),
139
+ ...(runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {}),
140
+ ...(runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {}),
141
+ ts: runSnapshot.startedAt,
142
+ });
143
+ }
144
+
145
+ const tracker = new GraphFrontierTracker();
146
+ const inputConcurrency = resolveInputConcurrency(def.inputs, resolvedInputs);
147
+ const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs);
148
+ const workflowInvocationCwd = opts.cwd ?? process.cwd();
149
+ let workflowCwd: string | undefined;
150
+ const resolveWorkflowCwd = (): string => {
151
+ workflowCwd ??= workflowCwdWithInputWorktree(inputRuntimeDefaults, workflowInvocationCwd);
152
+ return workflowCwd;
153
+ };
154
+ const limiter = createRunLimiter(inputConcurrency ?? opts.config?.defaultConcurrency);
155
+ const stageRegistry = opts.stageControlRegistry ?? defaultStageControlRegistry;
156
+ const replayIndex = createContinuationReplayIndex(opts.continuation);
157
+ const scheduler = createStageScheduler({
158
+ runId,
159
+ runSnapshot,
160
+ activeStore,
161
+ tracker,
162
+ stageRegistry: () => stageRegistry,
163
+ });
164
+ ownController.signal.addEventListener(
165
+ "abort",
166
+ () => scheduler.rejectReleaseBarriers(ownController.signal.reason ?? new Error("atomic-workflows: run aborted")),
167
+ { once: true },
168
+ );
169
+
170
+ const finalizers = createRunFinalizers({
171
+ def,
172
+ runId,
173
+ runSnapshot,
174
+ activeStore,
175
+ opts,
176
+ classifyExecutorFailure,
177
+ drainWorkflowExitCleanups: exit.drainWorkflowExitCleanups,
178
+ });
179
+ const stageOptions: EngineStageRuntimeOptions = {
180
+ continuation: opts.continuation,
181
+ models: opts.models,
182
+ executionMode: opts.executionMode,
183
+ defaultSessionDir: opts.defaultSessionDir,
184
+ persistence: opts.persistence,
185
+ onStageStart: opts.onStageStart,
186
+ onStageEnd: opts.onStageEnd,
187
+ confirmStageReadiness: opts.confirmStageReadiness,
188
+ usePromptNodesForUi: opts.usePromptNodesForUi,
189
+ };
190
+ const workflowBoundaryOptions: EngineWorkflowBoundaryOptions = {
191
+ persistence: opts.persistence,
192
+ onStageStart: opts.onStageStart,
193
+ onStageEnd: opts.onStageEnd,
194
+ };
195
+ const childRunOptions: EngineChildRunOptions = {
196
+ adapters: opts.adapters,
197
+ ui: opts.ui,
198
+ executionMode: opts.executionMode,
199
+ defaultSessionDir: opts.defaultSessionDir,
200
+ usePromptNodesForUi: opts.usePromptNodesForUi,
201
+ confirmStageReadiness: opts.confirmStageReadiness,
202
+ store: opts.store,
203
+ persistence: opts.persistence,
204
+ mcp: opts.mcp,
205
+ cancellation: opts.cancellation,
206
+ overlay: opts.overlay,
207
+ config: opts.config,
208
+ models: opts.models,
209
+ registry: opts.registry,
210
+ stageControlRegistry: opts.stageControlRegistry,
211
+ onStageStart: opts.onStageStart,
212
+ onStageEnd: opts.onStageEnd,
213
+ };
214
+ const runtime = new EngineRuntime({
215
+ runId,
216
+ depth,
217
+ runSnapshot,
218
+ activeStore,
219
+ stageOptions,
220
+ workflowBoundaryOptions,
221
+ childRunOptions,
222
+ parentRootRunId: opts.parentRun?.rootRunId,
223
+ adapters,
224
+ signal: ownController.signal,
225
+ tracker,
226
+ scheduler,
227
+ replayIndex,
228
+ limiter,
229
+ inputRuntimeDefaults,
230
+ workflowInvocationCwd,
231
+ stageRegistry,
232
+ exit,
233
+ classifyExecutorFailure,
234
+ });
235
+ const workflowBoundaryReplayCounts = new Map<string, number>();
236
+ const nextWorkflowBoundaryReplayKey = (name: string): string => {
237
+ const next = (workflowBoundaryReplayCounts.get(name) ?? 0) + 1;
238
+ workflowBoundaryReplayCounts.set(name, next);
239
+ return `workflow:${name}:${next}`;
240
+ };
241
+ const taskRunners = createWorkflowTaskRunners({ runtime });
242
+ const workflow = createChildWorkflowRunner({
243
+ runtime,
244
+ resolveWorkflowCwd,
245
+ nextWorkflowBoundaryReplayKey,
246
+ runWorkflow: run,
247
+ });
248
+
249
+ const ctx: WorkflowRunContext<TInputs> = {
250
+ inputs: resolvedInputs as TInputs,
251
+ get cwd() { return resolveWorkflowCwd(); },
252
+ exit: exit.exit,
253
+ ui: buildExitGatedUiContext({
254
+ opts,
255
+ throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
256
+ baseFromPromptNodes: () => buildPromptNodeUiAdapter({
257
+ runId,
258
+ activeStore,
259
+ opts,
260
+ tracker,
261
+ replayIndex,
262
+ signal: ownController.signal,
263
+ throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
264
+ registerWorkflowExitCleanup: exit.registerWorkflowExitCleanup,
265
+ workflowExitSkippedReason: exit.workflowExitSkippedReason,
266
+ preserveWorkflowExitSkippedReason: exit.preserveWorkflowExitSkippedReason,
267
+ classifyExecutorFailure,
268
+ }),
269
+ }),
270
+ stage: runtime.stage,
271
+ task: taskRunners.task,
272
+ chain: taskRunners.chain,
273
+ parallel: taskRunners.parallel,
274
+ workflow,
275
+ };
276
+
277
+ try {
278
+ if (opts.deferWorkflowStart === true) {
279
+ await nextEventLoopTurn();
280
+ if (ownController.signal.aborted) {
281
+ const selectedExit = findWorkflowExitSignal(ownController.signal.reason, exitScope);
282
+ if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
283
+ const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
284
+ if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
285
+ return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
286
+ }
287
+ }
288
+
289
+ const rawResult = await def.run(ctx);
290
+ if (ownController.signal.aborted) {
291
+ const selectedExit = findWorkflowExitSignal(ownController.signal.reason, exitScope);
292
+ if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
293
+ const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
294
+ if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
295
+ return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
296
+ }
297
+
298
+ const result = normalizeWorkflowRunOutput(def.name, rawResult);
299
+ assertWorkflowRunOutputs(def.name, result, def.outputs);
300
+ assertWorkflowCreatedStage(runSnapshot);
301
+ const recorded = activeStore.recordRunEnd(runId, "completed", result);
302
+ appendRunEndWhenRecorded(opts.persistence, recorded, { runId, status: "completed", result, ts: Date.now() });
303
+ return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "completed", result }, opts.onRunEnd);
304
+ } catch (err) {
305
+ const selectedExit = findWorkflowExitSignal(err, exitScope) ?? findWorkflowExitSignal(ownController.signal.reason, exitScope);
306
+ if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
307
+
308
+ if (ownController.signal.aborted) {
309
+ const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
310
+ if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
311
+ return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
312
+ }
313
+
314
+ const failure = classifyExecutorFailure(err);
315
+ const metadata = selectRunFailureDisposition({
316
+ outerFailure: failure,
317
+ thrownError: err,
318
+ stages: runSnapshot.stages,
319
+ classifyFailure: classifyExecutorFailure,
320
+ });
321
+
322
+ if (metadata.failureDisposition === "terminal_killed") {
323
+ for (const failedStageId of metadata.failedStageIds) scheduler.blockKnownNonTerminalDescendants(failedStageId);
324
+ return finalizeKilledByFailure(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd, { ...metadata, resumable: false });
325
+ }
326
+
327
+ if (metadata.failureDisposition === "active_blocked" && metadata.failedStageId !== undefined && metadata.failureRecoverability === "recoverable") {
328
+ for (const failedStageId of metadata.failedStageIds) scheduler.blockKnownNonTerminalDescendants(failedStageId);
329
+ return recordActiveBlockedFailure(runId, runSnapshot, activeStore, opts.persistence, {
330
+ ...metadata,
331
+ failureRecoverability: "recoverable",
332
+ failedStageId: metadata.failedStageId,
333
+ resumable: true,
334
+ });
335
+ }
336
+
337
+ const recorded = activeStore.recordRunEnd(runId, "failed", undefined, metadata.errorMessage, metadata);
338
+ appendRunEndWhenRecorded(opts.persistence, recorded, {
339
+ runId,
340
+ status: "failed",
341
+ error: metadata.errorMessage,
342
+ failureKind: metadata.failureKind,
343
+ ...(metadata.failureCode !== undefined ? { failureCode: metadata.failureCode } : {}),
344
+ ...(metadata.failureRecoverability !== undefined ? { failureRecoverability: metadata.failureRecoverability } : {}),
345
+ ...(metadata.failureDisposition !== undefined ? { failureDisposition: metadata.failureDisposition } : {}),
346
+ failureMessage: metadata.failureMessage,
347
+ ...(metadata.failedStageId !== undefined ? { failedStageId: metadata.failedStageId } : {}),
348
+ resumable: metadata.resumable,
349
+ ...(metadata.retryAfterMs !== undefined ? { retryAfterMs: metadata.retryAfterMs } : {}),
350
+ ts: Date.now(),
351
+ });
352
+ return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "failed", error: metadata.errorMessage }, opts.onRunEnd);
353
+ } finally {
354
+ opts.cancellation?.unregister(runId);
355
+ }
356
+ }
@@ -0,0 +1,160 @@
1
+ import type { RunSnapshot } from "../shared/store-types.js";
2
+ import type { Store } from "../shared/store.js";
3
+ import type { StageOptions } from "../shared/types.js";
4
+ import type { ConcurrencyLimiter } from "../runs/shared/concurrency.js";
5
+ import type { ParallelFailFastScope } from "../runs/foreground/executor-types.js";
6
+ import type { WorkflowExitManager } from "../runs/foreground/executor-exit-manager.js";
7
+ import type { ContinuationReplayIndex } from "../runs/foreground/executor-continuation.js";
8
+ import type { StageScheduler } from "../runs/foreground/executor-scheduler.js";
9
+ import type { StageControlRegistry } from "../runs/foreground/stage-control-registry.js";
10
+ import type { StageAdapters } from "../runs/foreground/stage-runner.js";
11
+ import type { LiveStageRuntime, StageMcpScope, StageContextWithMeta } from "../runs/foreground/executor-stage-types.js";
12
+ import { createWorkflowStageFactory } from "../runs/foreground/executor-stage-factory.js";
13
+ import { createWorkflowBoundaryFactory, type WorkflowBoundaryStage } from "../runs/foreground/executor-child-boundary.js";
14
+ import type { GraphFrontierTracker } from "./graph-inference.js";
15
+ import type { EngineChildRunOptions, EngineStageRuntimeOptions, EngineWorkflowBoundaryOptions } from "./options.js";
16
+
17
+ export interface EngineRuntimeInput {
18
+ readonly runId: string;
19
+ readonly depth: number;
20
+ readonly runSnapshot: RunSnapshot;
21
+ readonly activeStore: Store;
22
+ readonly stageOptions: EngineStageRuntimeOptions;
23
+ readonly workflowBoundaryOptions: EngineWorkflowBoundaryOptions;
24
+ readonly childRunOptions: EngineChildRunOptions;
25
+ readonly parentRootRunId?: string;
26
+ readonly adapters: StageAdapters;
27
+ readonly signal: AbortSignal;
28
+ readonly tracker: GraphFrontierTracker;
29
+ readonly scheduler: StageScheduler;
30
+ readonly replayIndex: ContinuationReplayIndex;
31
+ readonly limiter: ConcurrencyLimiter;
32
+ readonly inputRuntimeDefaults: Partial<StageOptions>;
33
+ readonly workflowInvocationCwd: string;
34
+ readonly stageRegistry: StageControlRegistry;
35
+ readonly exit: WorkflowExitManager;
36
+ readonly classifyExecutorFailure: LiveStageRuntime["classifyExecutorFailure"];
37
+ }
38
+
39
+ export interface EngineSpawnAgentStageOptions {
40
+ readonly kind?: "agent";
41
+ readonly options?: StageOptions;
42
+ readonly failFastScope?: ParallelFailFastScope;
43
+ }
44
+
45
+ export interface EngineSpawnWorkflowBoundaryOptions {
46
+ readonly kind: "workflow-boundary";
47
+ readonly replayKey: string;
48
+ }
49
+
50
+ export type EngineSpawnStageOptions = EngineSpawnAgentStageOptions | EngineSpawnWorkflowBoundaryOptions;
51
+
52
+ export interface EngineAgentStageHandle {
53
+ readonly kind: "agent";
54
+ readonly context: StageContextWithMeta;
55
+ }
56
+
57
+ export interface EngineWorkflowBoundaryHandle {
58
+ readonly kind: "workflow-boundary";
59
+ readonly boundary: WorkflowBoundaryStage;
60
+ }
61
+
62
+ export type StageHandle = EngineAgentStageHandle | EngineWorkflowBoundaryHandle;
63
+
64
+ export class EngineRuntime {
65
+ readonly runId: string;
66
+ readonly depth: number;
67
+ readonly activeStore: Store;
68
+ readonly childRunOptions: EngineChildRunOptions;
69
+ readonly parentRootRunId?: string;
70
+ readonly adapters: StageAdapters;
71
+ readonly signal: AbortSignal;
72
+ readonly tracker: GraphFrontierTracker;
73
+ readonly exit: WorkflowExitManager;
74
+ readonly inputRuntimeDefaults: Partial<StageOptions>;
75
+ readonly workflowInvocationCwd: string;
76
+
77
+ private readonly spawnAgentStage: (
78
+ name: string,
79
+ options?: StageOptions,
80
+ stageFailFastScope?: ParallelFailFastScope,
81
+ ) => StageContextWithMeta;
82
+ private readonly spawnWorkflowBoundary: (name: string, replayKey: string) => WorkflowBoundaryStage;
83
+
84
+ constructor(input: EngineRuntimeInput) {
85
+ this.runId = input.runId;
86
+ this.depth = input.depth;
87
+ this.activeStore = input.activeStore;
88
+ this.childRunOptions = input.childRunOptions;
89
+ this.parentRootRunId = input.parentRootRunId;
90
+ this.adapters = input.adapters;
91
+ this.signal = input.signal;
92
+ this.tracker = input.tracker;
93
+ this.exit = input.exit;
94
+ this.inputRuntimeDefaults = input.inputRuntimeDefaults;
95
+ this.workflowInvocationCwd = input.workflowInvocationCwd;
96
+
97
+ // The runtime only wires host-injected ports; stage sessions are still
98
+ // created lazily by the stage runner through input.adapters.agentSession.
99
+ this.spawnAgentStage = createWorkflowStageFactory({
100
+ runId: input.runId,
101
+ activeStore: input.activeStore,
102
+ opts: input.stageOptions,
103
+ adapters: input.adapters,
104
+ signal: input.signal,
105
+ tracker: input.tracker,
106
+ scheduler: input.scheduler,
107
+ replayIndex: input.replayIndex,
108
+ limiter: input.limiter,
109
+ inputRuntimeDefaults: input.inputRuntimeDefaults,
110
+ workflowInvocationCwd: input.workflowInvocationCwd,
111
+ stageRegistry: input.stageRegistry,
112
+ exit: input.exit,
113
+ classifyExecutorFailure: input.classifyExecutorFailure,
114
+ createMcpScope: (stageId, options) => this.createMcpScope(stageId, options),
115
+ });
116
+ this.spawnWorkflowBoundary = createWorkflowBoundaryFactory({
117
+ runId: input.runId,
118
+ runSnapshot: input.runSnapshot,
119
+ activeStore: input.activeStore,
120
+ opts: input.workflowBoundaryOptions,
121
+ tracker: input.tracker,
122
+ replayIndex: input.replayIndex,
123
+ registerWorkflowExitCleanup: input.exit.registerWorkflowExitCleanup,
124
+ workflowExitSkippedReason: input.exit.workflowExitSkippedReason,
125
+ classifyExecutorFailure: input.classifyExecutorFailure,
126
+ });
127
+ }
128
+
129
+ spawnStage(name: string, opts: EngineSpawnWorkflowBoundaryOptions): EngineWorkflowBoundaryHandle;
130
+ spawnStage(name: string, opts?: EngineSpawnAgentStageOptions): EngineAgentStageHandle;
131
+ spawnStage(name: string, opts: EngineSpawnStageOptions = {}): StageHandle {
132
+ if (opts.kind === "workflow-boundary") {
133
+ return { kind: "workflow-boundary", boundary: this.spawnWorkflowBoundary(name, opts.replayKey) };
134
+ }
135
+ return { kind: "agent", context: this.spawnAgentStage(name, opts.options, opts.failFastScope) };
136
+ }
137
+
138
+ readonly stage = (name: string, options?: StageOptions, failFastScope?: ParallelFailFastScope): StageContextWithMeta => {
139
+ const handle = this.spawnStage(name, {
140
+ kind: "agent",
141
+ ...(options !== undefined ? { options } : {}),
142
+ ...(failFastScope !== undefined ? { failFastScope } : {}),
143
+ });
144
+ return handle.context;
145
+ };
146
+
147
+ private createMcpScope(stageId: string, options: StageOptions | undefined): StageMcpScope {
148
+ const allow = options?.mcp?.allow ?? null;
149
+ const deny = options?.mcp?.deny ?? null;
150
+ const hasScope = allow !== null || deny !== null;
151
+ return {
152
+ apply: () => {
153
+ if (this.childRunOptions.mcp && hasScope) this.childRunOptions.mcp.setScope(stageId, allow, deny);
154
+ },
155
+ clear: () => {
156
+ if (this.childRunOptions.mcp && hasScope) this.childRunOptions.mcp.clearScope(stageId);
157
+ },
158
+ };
159
+ }
160
+ }
@@ -7,8 +7,9 @@
7
7
  */
8
8
 
9
9
  import { createJiti } from "jiti/static";
10
+ import * as typeboxModule from "typebox";
10
11
  import * as workflowsSdkSurface from "../sdk-surface.js";
11
- import { isBrandedWorkflowDefinition } from "../workflows/define-workflow.js";
12
+ import { isBrandedWorkflowDefinition } from "../authoring/workflow.js";
12
13
  import deepResearchCodebase from "../../builtin/deep-research-codebase.js";
13
14
  import goal from "../../builtin/goal.js";
14
15
  import openClaudeDesign from "../../builtin/open-claude-design.js";
@@ -16,6 +17,7 @@ import ralph from "../../builtin/ralph.js";
16
17
 
17
18
  const WORKFLOWS_MODULE_SPECIFIER = "@bastani/workflows";
18
19
  const WORKFLOWS_BUILTIN_MODULE_SPECIFIER = `${WORKFLOWS_MODULE_SPECIFIER}/builtin`;
20
+ const TYPEBOX_MODULE_SPECIFIER = "typebox";
19
21
  // Keep this in sync with index.ts through sdk-surface.ts.
20
22
  const WORKFLOWS_SDK_MODULE: Record<string, unknown> = {
21
23
  ...workflowsSdkSurface,
@@ -26,9 +28,13 @@ const WORKFLOWS_BUILTIN_MODULE: Record<string, unknown> = {
26
28
  openClaudeDesign,
27
29
  ralph,
28
30
  };
31
+ const TYPEBOX_MODULE: Record<string, unknown> = {
32
+ ...typeboxModule,
33
+ };
29
34
  const WORKFLOWS_VIRTUAL_MODULES: Record<string, unknown> = {
30
35
  [WORKFLOWS_MODULE_SPECIFIER]: WORKFLOWS_SDK_MODULE,
31
36
  [WORKFLOWS_BUILTIN_MODULE_SPECIFIER]: WORKFLOWS_BUILTIN_MODULE,
37
+ [TYPEBOX_MODULE_SPECIFIER]: TYPEBOX_MODULE,
32
38
  [`${WORKFLOWS_BUILTIN_MODULE_SPECIFIER}/deep-research-codebase`]: { default: deepResearchCodebase },
33
39
  [`${WORKFLOWS_BUILTIN_MODULE_SPECIFIER}/goal`]: { default: goal },
34
40
  [`${WORKFLOWS_BUILTIN_MODULE_SPECIFIER}/open-claude-design`]: { default: openClaudeDesign },
@@ -95,10 +101,10 @@ export function validateWorkflowDefinitionShape(value: unknown): string | null {
95
101
  const d = value as Record<string, unknown>;
96
102
 
97
103
  if (d["__piWorkflow"] !== true) {
98
- return "missing or incorrect __piWorkflow sentinel (expected true); export a workflow from defineWorkflow(...).compile()";
104
+ return "missing or incorrect __piWorkflow sentinel (expected true); export a workflow from workflow({...})";
99
105
  }
100
106
  if (!isBrandedWorkflowDefinition(value)) {
101
- return "workflow definition is not produced by defineWorkflow(...).compile(); hand-rolled __piWorkflow objects are not supported";
107
+ return "workflow definition is not produced by workflow({...}); hand-rolled __piWorkflow objects are not supported";
102
108
  }
103
109
  if (typeof d["name"] !== "string" || (d["name"] as string).trim().length === 0) {
104
110
  return "name must be a non-empty string";
@@ -43,23 +43,6 @@ const JsonSchemaObject = Type.Unsafe<Record<string, unknown>>({
43
43
  description: "Plain JSON Schema used as final-answer tool arguments for this workflow item.",
44
44
  });
45
45
 
46
- const BashCommandRuleSchema = Type.Union([
47
- Type.String(),
48
- Type.Object({ prefix: Type.String() }, { additionalProperties: false }),
49
- Type.Object({ glob: Type.String() }, { additionalProperties: false }),
50
- Type.Object({
51
- regex: Type.String(),
52
- flags: Type.Optional(Type.String()),
53
- }, { additionalProperties: false }),
54
- ]);
55
-
56
- const BashCommandPolicySchema = Type.Object({
57
- default: Type.Optional(Type.Union([Type.Literal("allow"), Type.Literal("deny")])),
58
- allow: Type.Optional(Type.Array(BashCommandRuleSchema)),
59
- deny: Type.Optional(Type.Array(BashCommandRuleSchema)),
60
- match: Type.Optional(Type.Union([Type.Literal("whole"), Type.Literal("segments")])),
61
- }, { additionalProperties: false });
62
-
63
46
  const StageSessionOptionProperties = {
64
47
  schema: Type.Optional(JsonSchemaObject),
65
48
  cwd: Type.Optional(Type.String()),
@@ -76,7 +59,6 @@ const StageSessionOptionProperties = {
76
59
  })),
77
60
  tools: Type.Optional(Type.Array(Type.String())),
78
61
  customTools: Type.Optional(Type.Array(SdkSessionOptionArrayElementSchema("customTools"))),
79
- bashPolicy: Type.Optional(BashCommandPolicySchema),
80
62
  resourceLoader: Type.Optional(SdkSessionOptionSchema("resourceLoader")),
81
63
  sessionManager: Type.Optional(SdkSessionOptionSchema("sessionManager")),
82
64
  settingsManager: Type.Optional(SdkSessionOptionSchema("settingsManager")),
@@ -6,5 +6,3 @@
6
6
  // Add new non-cyclic public runtime exports to sdk-surface.ts so the Bun
7
7
  // virtual SDK used by workflow discovery stays in lockstep with this entry.
8
8
  export * from "./sdk-surface.js";
9
-
10
- // Note: `Type` / `Static` / `TSchema` are re-exported via ./sdk-surface.js.
@@ -14,7 +14,7 @@
14
14
  * cross-ref: spec detached-runner
15
15
  */
16
16
 
17
- import type { WorkflowDefinition, WorkflowExecutionMode, WorkflowInputValues } from "../../shared/types.js";
17
+ import type { WorkflowDefinition, WorkflowExecutionMode, WorkflowInputValues, WorkflowOutputValues } from "../../shared/types.js";
18
18
  import type { RunOpts, RunResult } from "../foreground/executor.js";
19
19
  import type { CancellationRegistry } from "./cancellation-registry.js";
20
20
  import type { JobTracker } from "./job-tracker.js";
@@ -85,8 +85,11 @@ export function buildDetachedAccepted(
85
85
  * the store remains source of truth for run status. Cancellation is wired
86
86
  * through the provided (or default) CancellationRegistry.
87
87
  */
88
- export function runDetached<TInputs extends WorkflowInputValues>(
89
- def: WorkflowDefinition<TInputs>,
88
+ export function runDetached<
89
+ TInputs extends WorkflowInputValues,
90
+ TRunInputs extends WorkflowInputValues = TInputs,
91
+ >(
92
+ def: WorkflowDefinition<TInputs, WorkflowOutputValues, TRunInputs>,
90
93
  inputs: Readonly<Record<string, unknown>>,
91
94
  opts: DetachedRunOpts = {},
92
95
  ): DetachedAccepted {
@@ -4,12 +4,12 @@ import type { WorkflowChildResult } from "../../shared/types.js";
4
4
  import { appendStageEnd, appendStageStart } from "../../shared/persistence-session-entries.js";
5
5
  import { elapsedStageMs } from "../../shared/timing.js";
6
6
  import type { WorkflowFailure } from "../../shared/workflow-failures.js";
7
- import type { RunOpts } from "./executor-types.js";
7
+ import type { EngineWorkflowBoundaryOptions } from "../../engine/options.js";
8
8
  import type { ContinuationReplayIndex } from "./executor-continuation.js";
9
9
  import { sameStringSet } from "./executor-continuation.js";
10
10
  import { applyFailureToStage, stageReplayFields } from "./executor-lifecycle.js";
11
11
  import { cloneWorkflowChildReplaySnapshot, cloneWorkflowChildValue } from "./executor-child-helpers.js";
12
- import type { GraphFrontierTracker } from "../shared/graph-inference.js";
12
+ import type { GraphFrontierTracker } from "../../engine/graph-inference.js";
13
13
  import type { WorkflowExitCleanup } from "./executor-types.js";
14
14
  import { makeParentWorkflowExitAbortReason } from "./executor-abort.js";
15
15
 
@@ -71,7 +71,7 @@ export function createWorkflowBoundaryFactory(input: {
71
71
  readonly runId: string;
72
72
  readonly runSnapshot: RunSnapshot;
73
73
  readonly activeStore: Store;
74
- readonly opts: RunOpts;
74
+ readonly opts: EngineWorkflowBoundaryOptions;
75
75
  readonly tracker: GraphFrontierTracker;
76
76
  readonly replayIndex: ContinuationReplayIndex;
77
77
  readonly registerWorkflowExitCleanup: (stageId: string, cleanup: WorkflowExitCleanup) => () => void;
@@ -1,4 +1,4 @@
1
- import { isBrandedWorkflowDefinition } from "../../workflows/define-workflow.js";
1
+ import { isBrandedWorkflowDefinition } from "../../authoring/workflow.js";
2
2
  import type {
3
3
  WorkflowChildResult,
4
4
  WorkflowDefinition,
@@ -16,7 +16,7 @@ function workflowChildSerializationMessage(err: unknown): string {
16
16
  }
17
17
 
18
18
  export function isWorkflowDefinition(value: unknown): value is WorkflowDefinition {
19
- if (!isBrandedWorkflowDefinition(value)) return false;
19
+ if (value === null || typeof value !== "object" || !isBrandedWorkflowDefinition(value)) return false;
20
20
  const record = value as Partial<WorkflowDefinition>;
21
21
  return record.__piWorkflow === true &&
22
22
  typeof record.name === "string" && record.name.trim().length > 0 &&
@@ -27,9 +27,9 @@ export function isWorkflowDefinition(value: unknown): value is WorkflowDefinitio
27
27
 
28
28
  export function workflowDefinitionRequirementMessage(callSite: string, value: unknown): string {
29
29
  if (value !== null && typeof value === "object" && (value as { __piWorkflow?: unknown }).__piWorkflow === true) {
30
- return `atomic-workflows: ${callSite} requires a compiled workflow definition produced by defineWorkflow(...).compile(); hand-rolled __piWorkflow objects are not supported`;
30
+ return `atomic-workflows: ${callSite} requires a workflow definition produced by workflow({...}); hand-rolled __piWorkflow objects are not supported`;
31
31
  }
32
- return `atomic-workflows: ${callSite} requires a compiled workflow definition`;
32
+ return `atomic-workflows: ${callSite} requires a workflow definition`;
33
33
  }
34
34
 
35
35
  export function cloneWorkflowChildReplaySnapshot(snapshot: WorkflowChildReplaySnapshot): WorkflowChildReplaySnapshot {