@bastani/atomic 0.8.4-0 → 0.8.5-0

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 (245) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +24 -23
  3. package/dist/builtin/intercom/README.md +5 -5
  4. package/dist/builtin/intercom/index.ts +1 -1
  5. package/dist/builtin/intercom/package.json +1 -1
  6. package/dist/builtin/intercom/ui/compose.ts +19 -1
  7. package/dist/builtin/intercom/ui/session-list.ts +19 -1
  8. package/dist/builtin/mcp/README.md +3 -3
  9. package/dist/builtin/mcp/commands.ts +1 -1
  10. package/dist/builtin/mcp/host-html-template.ts +1 -1
  11. package/dist/builtin/mcp/mcp-panel.ts +14 -14
  12. package/dist/builtin/mcp/mcp-setup-panel.ts +4 -4
  13. package/dist/builtin/mcp/package.json +1 -1
  14. package/dist/builtin/mcp/tool-result-renderer.ts +1 -1
  15. package/dist/builtin/subagents/README.md +3 -3
  16. package/dist/builtin/subagents/package.json +1 -1
  17. package/dist/builtin/subagents/src/tui/render.ts +1844 -1062
  18. package/dist/builtin/web-access/README.md +1 -1
  19. package/dist/builtin/web-access/curator-page.ts +2 -2
  20. package/dist/builtin/web-access/index.ts +1 -1
  21. package/dist/builtin/web-access/package.json +1 -1
  22. package/dist/builtin/workflows/README.md +34 -7
  23. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +23 -4
  24. package/dist/builtin/workflows/builtin/ralph.ts +1 -1
  25. package/dist/builtin/workflows/package.json +1 -1
  26. package/dist/builtin/workflows/skills/workflow/SKILL.md +75 -16
  27. package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +34 -11
  28. package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +111 -20
  29. package/dist/builtin/workflows/src/extension/discovery.ts +32 -4
  30. package/dist/builtin/workflows/src/extension/index.ts +347 -63
  31. package/dist/builtin/workflows/src/extension/render-call.ts +3 -1
  32. package/dist/builtin/workflows/src/extension/render-result.ts +7 -0
  33. package/dist/builtin/workflows/src/extension/runtime.ts +4 -2
  34. package/dist/builtin/workflows/src/extension/wiring.ts +32 -8
  35. package/dist/builtin/workflows/src/extension/workflow-schema.ts +36 -14
  36. package/dist/builtin/workflows/src/runs/background/runner.ts +2 -2
  37. package/dist/builtin/workflows/src/runs/background/status.ts +89 -0
  38. package/dist/builtin/workflows/src/runs/foreground/executor.ts +338 -78
  39. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +2 -0
  40. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +55 -7
  41. package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +146 -10
  42. package/dist/builtin/workflows/src/shared/store.ts +29 -0
  43. package/dist/builtin/workflows/src/shared/types.ts +25 -4
  44. package/dist/builtin/workflows/src/tui/graph-canvas.ts +69 -2
  45. package/dist/builtin/workflows/src/tui/graph-view.ts +97 -182
  46. package/dist/builtin/workflows/src/tui/header.ts +36 -20
  47. package/dist/builtin/workflows/src/tui/inline-form-card.ts +129 -46
  48. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +111 -36
  49. package/dist/builtin/workflows/src/tui/inputs-picker.ts +311 -91
  50. package/dist/builtin/workflows/src/tui/layout.ts +1 -1
  51. package/dist/builtin/workflows/src/tui/node-card.ts +66 -37
  52. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +20 -6
  53. package/dist/builtin/workflows/src/tui/prompt-card.ts +262 -85
  54. package/dist/builtin/workflows/src/tui/run-detail.ts +50 -31
  55. package/dist/builtin/workflows/src/tui/session-confirm.ts +21 -14
  56. package/dist/builtin/workflows/src/tui/session-picker.ts +35 -26
  57. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +531 -960
  58. package/dist/builtin/workflows/src/tui/status-helpers.ts +6 -0
  59. package/dist/builtin/workflows/src/tui/status-list.ts +8 -4
  60. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +7 -2
  61. package/dist/builtin/workflows/src/tui/switcher.ts +55 -25
  62. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +33 -1
  63. package/dist/builtin/workflows/src/tui/workflow-list.ts +10 -6
  64. package/dist/cli/args.d.ts.map +1 -1
  65. package/dist/cli/args.js +1 -1
  66. package/dist/cli/args.js.map +1 -1
  67. package/dist/config.d.ts.map +1 -1
  68. package/dist/config.js +20 -6
  69. package/dist/config.js.map +1 -1
  70. package/dist/core/agent-session-services.d.ts +3 -3
  71. package/dist/core/agent-session-services.d.ts.map +1 -1
  72. package/dist/core/agent-session-services.js.map +1 -1
  73. package/dist/core/agent-session.d.ts +7 -7
  74. package/dist/core/agent-session.d.ts.map +1 -1
  75. package/dist/core/agent-session.js.map +1 -1
  76. package/dist/core/compaction/branch-summarization.d.ts +2 -2
  77. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  78. package/dist/core/compaction/branch-summarization.js.map +1 -1
  79. package/dist/core/compaction/compaction.d.ts +3 -3
  80. package/dist/core/compaction/compaction.d.ts.map +1 -1
  81. package/dist/core/compaction/compaction.js.map +1 -1
  82. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  83. package/dist/core/export-html/tool-renderer.js.map +1 -1
  84. package/dist/core/extensions/loader.d.ts +3 -2
  85. package/dist/core/extensions/loader.d.ts.map +1 -1
  86. package/dist/core/extensions/loader.js +24 -12
  87. package/dist/core/extensions/loader.js.map +1 -1
  88. package/dist/core/extensions/runner.d.ts.map +1 -1
  89. package/dist/core/extensions/runner.js +6 -0
  90. package/dist/core/extensions/runner.js.map +1 -1
  91. package/dist/core/extensions/types.d.ts +28 -17
  92. package/dist/core/extensions/types.d.ts.map +1 -1
  93. package/dist/core/extensions/types.js.map +1 -1
  94. package/dist/core/package-manager.d.ts +1 -0
  95. package/dist/core/package-manager.d.ts.map +1 -1
  96. package/dist/core/package-manager.js +65 -28
  97. package/dist/core/package-manager.js.map +1 -1
  98. package/dist/core/resource-loader.d.ts.map +1 -1
  99. package/dist/core/resource-loader.js +13 -5
  100. package/dist/core/resource-loader.js.map +1 -1
  101. package/dist/core/sdk.d.ts +3 -3
  102. package/dist/core/sdk.d.ts.map +1 -1
  103. package/dist/core/sdk.js.map +1 -1
  104. package/dist/core/session-manager.d.ts.map +1 -1
  105. package/dist/core/session-manager.js +1 -1
  106. package/dist/core/session-manager.js.map +1 -1
  107. package/dist/core/settings-manager.d.ts +2 -0
  108. package/dist/core/settings-manager.d.ts.map +1 -1
  109. package/dist/core/settings-manager.js.map +1 -1
  110. package/dist/core/slash-commands.d.ts.map +1 -1
  111. package/dist/core/slash-commands.js +1 -1
  112. package/dist/core/slash-commands.js.map +1 -1
  113. package/dist/core/system-prompt.d.ts.map +1 -1
  114. package/dist/core/system-prompt.js +5 -3
  115. package/dist/core/system-prompt.js.map +1 -1
  116. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +1 -1
  117. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts.map +1 -1
  118. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js +1 -1
  119. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -1
  120. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +8 -8
  121. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts.map +1 -1
  122. package/dist/core/tools/ask-user-question/view/dialog-builder.js +6 -6
  123. package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -1
  124. package/dist/core/tools/bash.d.ts.map +1 -1
  125. package/dist/core/tools/bash.js +1 -1
  126. package/dist/core/tools/bash.js.map +1 -1
  127. package/dist/core/tools/find.d.ts.map +1 -1
  128. package/dist/core/tools/find.js +1 -1
  129. package/dist/core/tools/find.js.map +1 -1
  130. package/dist/core/tools/grep.d.ts.map +1 -1
  131. package/dist/core/tools/grep.js +7 -4
  132. package/dist/core/tools/grep.js.map +1 -1
  133. package/dist/core/tools/index.d.ts +3 -2
  134. package/dist/core/tools/index.d.ts.map +1 -1
  135. package/dist/core/tools/index.js.map +1 -1
  136. package/dist/core/tools/ls.d.ts.map +1 -1
  137. package/dist/core/tools/ls.js +3 -2
  138. package/dist/core/tools/ls.js.map +1 -1
  139. package/dist/core/tools/read.d.ts.map +1 -1
  140. package/dist/core/tools/read.js +2 -2
  141. package/dist/core/tools/read.js.map +1 -1
  142. package/dist/core/tools/render-utils.d.ts +2 -1
  143. package/dist/core/tools/render-utils.d.ts.map +1 -1
  144. package/dist/core/tools/render-utils.js.map +1 -1
  145. package/dist/core/tools/todos.d.ts.map +1 -1
  146. package/dist/core/tools/todos.js +1 -1
  147. package/dist/core/tools/todos.js.map +1 -1
  148. package/dist/core/tools/tool-definition-wrapper.d.ts +4 -3
  149. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  150. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  151. package/dist/core/tools/write.d.ts.map +1 -1
  152. package/dist/core/tools/write.js +1 -1
  153. package/dist/core/tools/write.js.map +1 -1
  154. package/dist/index.d.ts +2 -1
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js +2 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/main.d.ts.map +1 -1
  159. package/dist/main.js +2 -2
  160. package/dist/main.js.map +1 -1
  161. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  162. package/dist/modes/interactive/components/assistant-message.js +3 -3
  163. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  164. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  165. package/dist/modes/interactive/components/bash-execution.js +3 -3
  166. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  167. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  168. package/dist/modes/interactive/components/branch-summary-message.js +1 -1
  169. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  170. package/dist/modes/interactive/components/chat-message-renderer.d.ts +2 -1
  171. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  172. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  173. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  175. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  176. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  177. package/dist/modes/interactive/components/config-selector.js +1 -1
  178. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  179. package/dist/modes/interactive/components/custom-editor.d.ts +3 -0
  180. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  181. package/dist/modes/interactive/components/custom-editor.js +13 -3
  182. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  183. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  184. package/dist/modes/interactive/components/footer.js +1 -1
  185. package/dist/modes/interactive/components/footer.js.map +1 -1
  186. package/dist/modes/interactive/components/index.d.ts +2 -1
  187. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  188. package/dist/modes/interactive/components/index.js +2 -1
  189. package/dist/modes/interactive/components/index.js.map +1 -1
  190. package/dist/modes/interactive/components/keybinding-hints.d.ts +1 -0
  191. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  192. package/dist/modes/interactive/components/keybinding-hints.js +47 -5
  193. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  194. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/login-dialog.js +5 -5
  196. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  197. package/dist/modes/interactive/components/model-selector.d.ts +3 -3
  198. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  200. package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
  201. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/scoped-models-selector.js +7 -7
  203. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  204. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  205. package/dist/modes/interactive/components/session-selector.js +8 -8
  206. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  207. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  208. package/dist/modes/interactive/components/settings-selector.js +3 -3
  209. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  210. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  211. package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  212. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  213. package/dist/modes/interactive/components/tool-execution.d.ts +10 -12
  214. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  215. package/dist/modes/interactive/components/tool-execution.js +3 -3
  216. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  217. package/dist/modes/interactive/components/working-status.d.ts +25 -0
  218. package/dist/modes/interactive/components/working-status.d.ts.map +1 -0
  219. package/dist/modes/interactive/components/working-status.js +28 -0
  220. package/dist/modes/interactive/components/working-status.js.map +1 -0
  221. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  222. package/dist/modes/interactive/interactive-mode.js +8 -7
  223. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  224. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  225. package/dist/modes/rpc/rpc-mode.js +8 -0
  226. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  227. package/dist/modes/rpc/rpc-types.d.ts +5 -5
  228. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  229. package/dist/modes/rpc/rpc-types.js.map +1 -1
  230. package/dist/utils/tools-manager.d.ts.map +1 -1
  231. package/dist/utils/tools-manager.js.map +1 -1
  232. package/docs/development.md +2 -2
  233. package/docs/extensions.md +7 -7
  234. package/docs/packages.md +11 -8
  235. package/docs/quickstart.md +2 -2
  236. package/docs/rpc.md +1 -1
  237. package/docs/sdk.md +14 -11
  238. package/docs/session-format.md +1 -1
  239. package/docs/sessions.md +10 -10
  240. package/docs/settings.md +1 -1
  241. package/docs/terminal-setup.md +9 -9
  242. package/docs/tmux.md +10 -10
  243. package/docs/tui.md +2 -2
  244. package/docs/usage.md +9 -9
  245. package/package.json +6 -1
@@ -6,7 +6,7 @@
6
6
  export interface WorkflowToolArgs {
7
7
  workflow?: string;
8
8
  inputs?: Record<string, unknown>;
9
- action?: "run" | "list" | "get" | "status" | "interrupt" | "resume" | "inputs";
9
+ action?: "run" | "list" | "get" | "status" | "interrupt" | "kill" | "resume" | "inputs";
10
10
  runId?: string;
11
11
  }
12
12
 
@@ -29,6 +29,8 @@ export function renderCall(args: WorkflowToolArgs): string {
29
29
  return `workflow: run "${name}"`;
30
30
  case "interrupt":
31
31
  return `workflow: interrupt run "${name}"`;
32
+ case "kill":
33
+ return `workflow: kill run "${name}"`;
32
34
  case "resume":
33
35
  return `workflow: resume run "${name}"`;
34
36
  case "get":
@@ -96,6 +96,7 @@ type RunResult = {
96
96
  message?: string;
97
97
  };
98
98
  type InterruptResult = { action: "interrupt"; runId: string; status: string; message: string };
99
+ type KillResult = { action: "kill"; runId: string; status: string; message: string };
99
100
  type ResumeResult = { action: "resume"; runId: string; status: string; message: string };
100
101
 
101
102
  export type WorkflowToolResult =
@@ -106,6 +107,7 @@ export type WorkflowToolResult =
106
107
  | GetResult
107
108
  | RunResult
108
109
  | InterruptResult
110
+ | KillResult
109
111
  | ResumeResult;
110
112
 
111
113
  export interface RenderResultOpts {
@@ -200,6 +202,11 @@ export function renderResult(result: WorkflowToolResult, opts?: RenderResultOpts
200
202
  return `workflow interrupt ${r.runId}: ${r.message}`;
201
203
  }
202
204
 
205
+ case "kill": {
206
+ const r = result as KillResult;
207
+ return `workflow kill ${r.runId}: ${r.message}`;
208
+ }
209
+
203
210
  case "resume": {
204
211
  const r = result as ResumeResult;
205
212
  return `workflow resume ${r.runId}: ${r.message}`;
@@ -170,14 +170,15 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
170
170
  chain: _chain,
171
171
  chainName,
172
172
  concurrency,
173
+ failFast,
173
174
  async: _async,
174
175
  intercom: _intercom,
175
176
  output,
176
177
  outputMode,
178
+ reads,
177
179
  chainDir,
178
180
  maxOutput,
179
181
  artifacts,
180
- progress,
181
182
  worktree,
182
183
  ...stageOptions
183
184
  } = args;
@@ -187,12 +188,13 @@ export function createExtensionRuntime(opts: ExtensionRuntimeOpts = {}): Extensi
187
188
  ...(typeof task === "string" ? { task } : {}),
188
189
  ...(typeof chainName === "string" ? { chainName } : {}),
189
190
  ...(typeof concurrency === "number" ? { concurrency } : {}),
191
+ ...(typeof failFast === "boolean" ? { failFast } : {}),
190
192
  ...(typeof chainDir === "string" ? { chainDir } : {}),
191
193
  ...(output !== undefined ? { output } : {}),
192
194
  ...(outputMode !== undefined ? { outputMode } : {}),
195
+ ...(reads !== undefined ? { reads } : {}),
193
196
  ...(maxOutput !== undefined ? { maxOutput } : {}),
194
197
  ...(typeof artifacts === "boolean" ? { artifacts } : {}),
195
- ...(typeof progress === "boolean" ? { progress } : {}),
196
198
  ...(typeof worktree === "boolean" ? { worktree } : {}),
197
199
  };
198
200
  }
@@ -87,11 +87,14 @@ function isTestContext(): boolean {
87
87
  * cross-ref: node_modules/@bastani/atomic/docs/sdk.md
88
88
  * node_modules/@bastani/atomic/dist/core/sdk.d.ts
89
89
  */
90
- interface PiSdkSettingsManager {}
91
- interface PiSdkResourceLoader {
90
+ export interface PiSdkSettingsManager {}
91
+ export interface PiSdkResourceLoader {
92
92
  reload(): Promise<void>;
93
93
  }
94
- interface PiCodingAgentSdk {
94
+ interface PiSdkSessionManager {
95
+ getCwd(): string;
96
+ }
97
+ export interface PiCodingAgentSdk {
95
98
  getAgentDir(): string;
96
99
  SettingsManager: {
97
100
  create(cwd?: string, agentDir?: string): PiSdkSettingsManager;
@@ -103,19 +106,40 @@ interface PiCodingAgentSdk {
103
106
  }) => PiSdkResourceLoader;
104
107
  createAgentSession(options?: AtomicCreateAgentSessionOptions): Promise<{ session: StageSessionRuntime }>;
105
108
  }
106
- type AtomicCreateAgentSessionOptions = Omit<CreateAgentSessionOptions, "settingsManager" | "resourceLoader"> & {
109
+ type AtomicCreateAgentSessionOptions = Omit<CreateAgentSessionOptions, "settingsManager" | "resourceLoader" | "sessionManager"> & {
107
110
  settingsManager?: PiSdkSettingsManager;
108
111
  resourceLoader?: PiSdkResourceLoader;
112
+ sessionManager?: PiSdkSessionManager;
109
113
  };
110
114
 
111
- async function withDefaultStageResourceLoader(
115
+ function resolveSessionCwd(options: AtomicCreateAgentSessionOptions | undefined): string {
116
+ return options?.cwd ?? options?.sessionManager?.getCwd() ?? process.cwd();
117
+ }
118
+
119
+ /**
120
+ * Prepare Atomic SDK stage-session options with Atomic-first resource loading.
121
+ *
122
+ * The Atomic SDK's documented defaults are intentionally significant:
123
+ * omitted `agentDir` means credentials/models/settings can be read from the
124
+ * primary `~/.atomic/agent` paths first while still considering legacy
125
+ * `~/.pi/agent` compatibility paths when the SDK supports multiple config
126
+ * directories. Passing the computed default back as an explicit `agentDir`
127
+ * would accidentally turn that multi-dir behavior into a single-dir override.
128
+ *
129
+ * A user-supplied `agentDir` is still preserved exactly and remains an
130
+ * explicit override. A user-supplied `resourceLoader` is also preserved; in
131
+ * that case cwd/agentDir no longer control resource discovery and only affect
132
+ * session naming/tool path resolution, matching the pi SDK docs.
133
+ */
134
+ export async function prepareAtomicStageSessionOptions(
112
135
  options: CreateAgentSessionOptions | undefined,
113
136
  sdk: PiCodingAgentSdk,
114
137
  ): Promise<AtomicCreateAgentSessionOptions | undefined> {
115
138
  const atomicOptions = options as AtomicCreateAgentSessionOptions | undefined;
116
139
  if (atomicOptions?.resourceLoader !== undefined) return atomicOptions;
117
140
 
118
- const cwd = atomicOptions?.cwd ?? process.cwd();
141
+ const cwd = resolveSessionCwd(atomicOptions);
142
+ const hasAgentDirOverride = atomicOptions?.agentDir !== undefined;
119
143
  const agentDir = atomicOptions?.agentDir ?? sdk.getAgentDir();
120
144
  const settingsManager =
121
145
  atomicOptions?.settingsManager ?? sdk.SettingsManager.create(cwd, agentDir);
@@ -129,7 +153,7 @@ async function withDefaultStageResourceLoader(
129
153
  return {
130
154
  ...atomicOptions,
131
155
  cwd,
132
- agentDir,
156
+ ...(hasAgentDirOverride ? { agentDir } : {}),
133
157
  settingsManager,
134
158
  resourceLoader,
135
159
  };
@@ -139,7 +163,7 @@ async function createPiSdkAgentSession(
139
163
  options?: CreateAgentSessionOptions,
140
164
  ): Promise<{ session: StageSessionRuntime }> {
141
165
  const sdk = await import("@bastani/atomic") as PiCodingAgentSdk;
142
- const sessionOptions = await withDefaultStageResourceLoader(options, sdk);
166
+ const sessionOptions = await prepareAtomicStageSessionOptions(options, sdk);
143
167
  const result = await sdk.createAgentSession(sessionOptions);
144
168
  // `CreateAgentSessionResult` is `{ session, extensionsResult, modelFallbackMessage? }`;
145
169
  // workflow stages only consume `.session` (structurally an `AgentSession`,
@@ -1,4 +1,14 @@
1
+ import type { CreateAgentSessionOptions } from "@bastani/atomic";
1
2
  import { Type, type Static } from "typebox";
3
+ import type { WorkflowModelValue } from "../shared/types.js";
4
+
5
+ type ArrayElement<T> = T extends readonly (infer Element)[] ? Element : never;
6
+
7
+ const SdkSessionOptionSchema = <Key extends keyof CreateAgentSessionOptions>(_key: Key) =>
8
+ Type.Unsafe<NonNullable<CreateAgentSessionOptions[Key]>>({});
9
+
10
+ const SdkSessionOptionArrayElementSchema = <Key extends keyof CreateAgentSessionOptions>(_key: Key) =>
11
+ Type.Unsafe<ArrayElement<NonNullable<CreateAgentSessionOptions[Key]>>>({});
2
12
 
3
13
  const IntercomOptionsSchema = Type.Object({
4
14
  enabled: Type.Optional(Type.Boolean()),
@@ -30,18 +40,20 @@ const McpOptionsSchema = Type.Object({
30
40
  const StageSessionOptionProperties = {
31
41
  cwd: Type.Optional(Type.String()),
32
42
  agentDir: Type.Optional(Type.String()),
33
- authStorage: Type.Optional(Type.Any()),
34
- modelRegistry: Type.Optional(Type.Any()),
35
- model: Type.Optional(Type.Any()),
36
- thinkingLevel: Type.Optional(Type.String()),
37
- scopedModels: Type.Optional(Type.Array(Type.Any())),
38
- noTools: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("builtin")])),
43
+ authStorage: Type.Optional(SdkSessionOptionSchema("authStorage")),
44
+ modelRegistry: Type.Optional(SdkSessionOptionSchema("modelRegistry")),
45
+ model: Type.Optional(Type.Unsafe<WorkflowModelValue>({})),
46
+ thinkingLevel: Type.Optional(SdkSessionOptionSchema("thinkingLevel")),
47
+ scopedModels: Type.Optional(Type.Array(SdkSessionOptionArrayElementSchema("scopedModels"))),
48
+ noTools: Type.Optional(Type.Unsafe<NonNullable<CreateAgentSessionOptions["noTools"]>>({
49
+ enum: ["all", "builtin"],
50
+ })),
39
51
  tools: Type.Optional(Type.Array(Type.String())),
40
- customTools: Type.Optional(Type.Array(Type.Any())),
41
- resourceLoader: Type.Optional(Type.Any()),
42
- sessionManager: Type.Optional(Type.Any()),
43
- settingsManager: Type.Optional(Type.Any()),
44
- sessionStartEvent: Type.Optional(Type.Any()),
52
+ customTools: Type.Optional(Type.Array(SdkSessionOptionArrayElementSchema("customTools"))),
53
+ resourceLoader: Type.Optional(SdkSessionOptionSchema("resourceLoader")),
54
+ sessionManager: Type.Optional(SdkSessionOptionSchema("sessionManager")),
55
+ settingsManager: Type.Optional(SdkSessionOptionSchema("settingsManager")),
56
+ sessionStartEvent: Type.Optional(SdkSessionOptionSchema("sessionStartEvent")),
45
57
  fallbackModels: Type.Optional(Type.Array(Type.String())),
46
58
  mcp: Type.Optional(McpOptionsSchema),
47
59
  sessionDir: Type.Optional(Type.String()),
@@ -53,7 +65,6 @@ const WorkflowTaskOptionProperties = {
53
65
  output: Type.Optional(Type.Union([Type.String(), Type.Literal(false)])),
54
66
  outputMode: Type.Optional(Type.Union([Type.Literal("inline"), Type.Literal("file-only")])),
55
67
  reads: Type.Optional(Type.Union([Type.Array(Type.String()), Type.Literal(false)])),
56
- progress: Type.Optional(Type.Boolean()),
57
68
  worktree: Type.Optional(Type.Boolean()),
58
69
  maxOutput: Type.Optional(MaxOutputSchema),
59
70
  artifacts: Type.Optional(Type.Boolean()),
@@ -78,7 +89,7 @@ export const WorkflowParametersSchema = Type.Object({
78
89
  workflow: Type.Optional(Type.String({
79
90
  description: "Named workflow ID for named-workflow execution.",
80
91
  })),
81
- inputs: Type.Optional(Type.Record(Type.String(), Type.Any(), {
92
+ inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown(), {
82
93
  default: {},
83
94
  description: "Key/value inputs passed to a named workflow run.",
84
95
  })),
@@ -89,10 +100,20 @@ export const WorkflowParametersSchema = Type.Object({
89
100
  Type.Literal("inputs"),
90
101
  Type.Literal("status"),
91
102
  Type.Literal("interrupt"),
103
+ Type.Literal("kill"),
92
104
  Type.Literal("resume"),
93
105
  ])),
94
106
  runId: Type.Optional(Type.String({
95
- description: "Run identifier for status/interrupt/resume.",
107
+ description: "Run identifier or unique prefix for status/interrupt/kill/resume. Use '--all' for interrupt/kill all.",
108
+ })),
109
+ all: Type.Optional(Type.Boolean({
110
+ description: "Apply supported run-control actions (interrupt/kill) to all in-flight runs.",
111
+ })),
112
+ stageId: Type.Optional(Type.String({
113
+ description: "Stage id, unique prefix, or stage name for stage-scoped resume.",
114
+ })),
115
+ message: Type.Optional(Type.String({
116
+ description: "Optional message forwarded when resuming paused work.",
96
117
  })),
97
118
  task: Type.Optional(Type.Union([
98
119
  DirectTaskSchema,
@@ -102,6 +123,7 @@ export const WorkflowParametersSchema = Type.Object({
102
123
  tasks: Type.Optional(Type.Array(DirectTaskSchema)),
103
124
  chain: Type.Optional(Type.Array(Type.Union([DirectTaskSchema, ParallelChainStepSchema]))),
104
125
  concurrency: Type.Optional(Type.Number()),
126
+ failFast: Type.Optional(Type.Boolean()),
105
127
  async: Type.Optional(Type.Boolean()),
106
128
  intercom: Type.Optional(IntercomOptionsSchema),
107
129
  ...StageSessionOptionProperties,
@@ -84,8 +84,8 @@ export function buildDetachedAccepted(
84
84
  * the store remains source of truth for run status. Cancellation is wired
85
85
  * through the provided (or default) CancellationRegistry.
86
86
  */
87
- export function runDetached(
88
- def: WorkflowDefinition,
87
+ export function runDetached<TInputs extends Record<string, unknown>>(
88
+ def: WorkflowDefinition<TInputs>,
89
89
  inputs: Record<string, unknown>,
90
90
  opts: DetachedRunOpts = {},
91
91
  ): DetachedAccepted {
@@ -34,6 +34,10 @@ export type KillResult =
34
34
  | { ok: true; runId: string; previousStatus: RunStatus }
35
35
  | { ok: false; runId: string; reason: "not_found" | "already_ended" };
36
36
 
37
+ export type DestroyRunResult =
38
+ | { ok: true; runId: string; previousStatus: RunStatus; wasInFlight: boolean }
39
+ | { ok: false; runId: string; reason: "not_found" };
40
+
37
41
  export type ResumeResult =
38
42
  | { ok: true; runId: string; snapshot: RunSnapshot; resumed: readonly StageSnapshot[] }
39
43
  | { ok: false; runId: string; reason: "not_found" };
@@ -50,6 +54,8 @@ export type PauseResult =
50
54
  reason: "not_found" | "already_ended" | "no_active_stages" | "stage_not_found";
51
55
  };
52
56
 
57
+ export type InterruptRunResult = PauseResult;
58
+
53
59
  /**
54
60
  * Per-run detail returned by {@link inspectRun}. A read-only view over the
55
61
  * store snapshot suitable for the "▎ RUN" detail surface — same data the
@@ -163,6 +169,57 @@ export function killAllRuns(opts?: {
163
169
  );
164
170
  }
165
171
 
172
+ // ---------------------------------------------------------------------------
173
+ // destroyRun
174
+ // ---------------------------------------------------------------------------
175
+
176
+ /**
177
+ * Destructively kills a workflow run and removes it from live history/status.
178
+ *
179
+ * In-flight runs are aborted and persisted with a terminal `killed` entry so
180
+ * session restore will not resurrect them. Ended runs are simply removed from
181
+ * the live store without appending a duplicate terminal event.
182
+ */
183
+ export function destroyRun(
184
+ runId: string,
185
+ opts?: { store?: Store; cancellation?: CancellationRegistry; persistence?: WorkflowPersistencePort },
186
+ ): DestroyRunResult {
187
+ const activeStore = opts?.store ?? defaultStore;
188
+ const run = activeStore.runs().find((r) => r.id === runId);
189
+
190
+ if (!run) {
191
+ return { ok: false, runId, reason: "not_found" };
192
+ }
193
+
194
+ const previousStatus = run.status;
195
+ const wasInFlight = run.endedAt === undefined;
196
+
197
+ if (wasInFlight) {
198
+ opts?.cancellation?.abort(runId, "workflow killed");
199
+ if (opts?.persistence) {
200
+ appendRunEnd(opts.persistence, { runId, status: "killed", ts: Date.now() });
201
+ }
202
+ }
203
+
204
+ activeStore.removeRun(runId);
205
+ return { ok: true, runId, previousStatus, wasInFlight };
206
+ }
207
+
208
+ /**
209
+ * Destructively kills and removes all in-flight runs.
210
+ */
211
+ export function destroyAllRuns(opts?: {
212
+ store?: Store;
213
+ cancellation?: CancellationRegistry;
214
+ persistence?: WorkflowPersistencePort;
215
+ }): DestroyRunResult[] {
216
+ const activeStore = opts?.store ?? defaultStore;
217
+ const inFlight = activeStore.runs().filter((r) => r.endedAt === undefined);
218
+ return inFlight.map((r) =>
219
+ destroyRun(r.id, { store: activeStore, cancellation: opts?.cancellation, persistence: opts?.persistence }),
220
+ );
221
+ }
222
+
166
223
  // ---------------------------------------------------------------------------
167
224
  // resumeRun
168
225
  // ---------------------------------------------------------------------------
@@ -308,6 +365,38 @@ export function pauseRun(
308
365
  return { ok: true, runId, paused: pausedSnaps };
309
366
  }
310
367
 
368
+ // ---------------------------------------------------------------------------
369
+ // interruptRun
370
+ // ---------------------------------------------------------------------------
371
+
372
+ /**
373
+ * Interrupt a run in a resumable way by pausing live stage handles when
374
+ * available. Unlike `destroyRun`, this never aborts the workflow controller and
375
+ * never removes the run from status/history.
376
+ */
377
+ export function interruptRun(
378
+ runId: string,
379
+ opts?: {
380
+ store?: Store;
381
+ stageControlRegistry?: StageControlRegistry;
382
+ stageId?: string;
383
+ },
384
+ ): InterruptRunResult {
385
+ return pauseRun(runId, opts);
386
+ }
387
+
388
+ /** Interrupt all in-flight runs without removing them from history/status. */
389
+ export function interruptAllRuns(opts?: {
390
+ store?: Store;
391
+ stageControlRegistry?: StageControlRegistry;
392
+ }): InterruptRunResult[] {
393
+ const activeStore = opts?.store ?? defaultStore;
394
+ const inFlight = activeStore.runs().filter((r) => r.endedAt === undefined);
395
+ return inFlight.map((r) =>
396
+ interruptRun(r.id, { store: activeStore, stageControlRegistry: opts?.stageControlRegistry }),
397
+ );
398
+ }
399
+
311
400
  // ---------------------------------------------------------------------------
312
401
  // inspectRun
313
402
  // ---------------------------------------------------------------------------