@bastani/atomic 0.9.13-alpha.1 → 0.9.13-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 (1048) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +35 -17
  3. package/dist/builtin/i-have-adhd/CHANGELOG.md +17 -0
  4. package/dist/builtin/i-have-adhd/LICENSE +21 -0
  5. package/dist/builtin/i-have-adhd/README.md +18 -0
  6. package/dist/builtin/i-have-adhd/index.ts +238 -0
  7. package/dist/builtin/i-have-adhd/package.json +56 -0
  8. package/dist/builtin/i-have-adhd/skills/i-have-adhd/SKILL.md +140 -0
  9. package/dist/builtin/intercom/CHANGELOG.md +19 -0
  10. package/dist/builtin/intercom/README.md +25 -4
  11. package/dist/builtin/intercom/broker/bounded-stderr-install.ts +18 -0
  12. package/dist/builtin/intercom/broker/bounded-stderr.ts +132 -0
  13. package/dist/builtin/intercom/broker/broker.ts +12 -23
  14. package/dist/builtin/intercom/broker/client.ts +70 -3
  15. package/dist/builtin/intercom/broker/paths.ts +9 -0
  16. package/dist/builtin/intercom/broker/presence-handler.ts +103 -0
  17. package/dist/builtin/intercom/broker/spawn.ts +128 -29
  18. package/dist/builtin/intercom/foreground-detach-handoff.ts +30 -14
  19. package/dist/builtin/intercom/group.ts +64 -25
  20. package/dist/builtin/intercom/index-heavy.ts +38 -5
  21. package/dist/builtin/intercom/index.ts +7 -3
  22. package/dist/builtin/intercom/intercom-tool.ts +82 -5
  23. package/dist/builtin/intercom/lazy-subagent-ack.ts +11 -6
  24. package/dist/builtin/intercom/package.json +2 -3
  25. package/dist/builtin/intercom/runtime-group.ts +13 -0
  26. package/dist/builtin/intercom/skills/intercom/SKILL.md +30 -2
  27. package/dist/builtin/intercom/subagent-relay.ts +32 -16
  28. package/dist/builtin/intercom/terminal-ordering-barrier.ts +21 -4
  29. package/dist/builtin/intercom/types.ts +3 -1
  30. package/dist/builtin/intercom/ui/compose.ts +8 -6
  31. package/dist/builtin/intercom/ui/session-list.ts +7 -5
  32. package/dist/builtin/mcp/CHANGELOG.md +13 -0
  33. package/dist/builtin/mcp/glimpse-ui.ts +2 -1
  34. package/dist/builtin/mcp/index.ts +1 -11
  35. package/dist/builtin/mcp/mcp-panel.ts +35 -34
  36. package/dist/builtin/mcp/mcp-setup-panel.ts +35 -33
  37. package/dist/builtin/mcp/npx-resolver.ts +3 -2
  38. package/dist/builtin/mcp/package.json +3 -3
  39. package/dist/builtin/mcp/sampling-handler.ts +5 -1
  40. package/dist/builtin/mcp/server-manager.ts +4 -7
  41. package/dist/builtin/subagents/CHANGELOG.md +33 -0
  42. package/dist/builtin/subagents/README.md +124 -323
  43. package/dist/builtin/subagents/agents/worker.md +1 -1
  44. package/dist/builtin/subagents/package.json +5 -5
  45. package/dist/builtin/subagents/prompts/parallel-context-build.md +2 -2
  46. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +4 -4
  47. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  48. package/dist/builtin/subagents/skills/subagent/SKILL.md +39 -102
  49. package/dist/builtin/subagents/src/agents/agent-discovery.ts +1 -29
  50. package/dist/builtin/subagents/src/agents/agent-loaders.ts +1 -40
  51. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +6 -135
  52. package/dist/builtin/subagents/src/agents/agent-management.ts +52 -282
  53. package/dist/builtin/subagents/src/agents/agent-paths.ts +0 -22
  54. package/dist/builtin/subagents/src/agents/agent-types.ts +0 -40
  55. package/dist/builtin/subagents/src/agents/agents.ts +0 -3
  56. package/dist/builtin/subagents/src/agents/identity.ts +2 -4
  57. package/dist/builtin/subagents/src/agents/skills-paths.ts +8 -1
  58. package/dist/builtin/subagents/src/extension/doctor.ts +3 -23
  59. package/dist/builtin/subagents/src/extension/index.ts +9 -7
  60. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +2 -2
  61. package/dist/builtin/subagents/src/extension/schemas.ts +1 -157
  62. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +0 -2
  63. package/dist/builtin/subagents/src/extension/tool-description.ts +4 -13
  64. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +6 -2
  65. package/dist/builtin/subagents/src/intercom/result-intercom.ts +20 -22
  66. package/dist/builtin/subagents/src/intercom/supervisor-authorization.ts +9 -2
  67. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +97 -16
  68. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +8 -3
  69. package/dist/builtin/subagents/src/runs/background/notify.ts +54 -18
  70. package/dist/builtin/subagents/src/runs/foreground/execution-updates.ts +0 -5
  71. package/dist/builtin/subagents/src/runs/foreground/execution.ts +1 -4
  72. package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +117 -15
  73. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +11 -40
  74. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -22
  75. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +10 -173
  76. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +6 -4
  77. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +9 -2
  78. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +9 -2
  79. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +32 -12
  80. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -6
  81. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-worktree.ts +1 -14
  82. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +56 -31
  83. package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +46 -30
  84. package/dist/builtin/subagents/src/runs/inprocess/background.ts +2 -1
  85. package/dist/builtin/subagents/src/runs/inprocess/runner.ts +343 -89
  86. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +0 -2
  87. package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +1 -3
  88. package/dist/builtin/subagents/src/runs/shared/intercom-group.ts +23 -7
  89. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +0 -86
  90. package/dist/builtin/subagents/src/runs/shared/worktree.ts +7 -2
  91. package/dist/builtin/subagents/src/shared/formatters.ts +2 -56
  92. package/dist/builtin/subagents/src/shared/settings.ts +14 -350
  93. package/dist/builtin/subagents/src/shared/types-async.ts +8 -31
  94. package/dist/builtin/subagents/src/shared/types-config.ts +20 -22
  95. package/dist/builtin/subagents/src/shared/types-depth.ts +30 -56
  96. package/dist/builtin/subagents/src/shared/types-results.ts +9 -58
  97. package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -1
  98. package/dist/builtin/subagents/src/shared/utils.ts +5 -0
  99. package/dist/builtin/subagents/src/slash/bridge-settlement.ts +87 -0
  100. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +47 -7
  101. package/dist/builtin/subagents/src/slash/slash-bridge.ts +27 -7
  102. package/dist/builtin/subagents/src/slash/slash-commands.ts +37 -82
  103. package/dist/builtin/subagents/src/slash/slash-live-state.ts +1 -92
  104. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -35
  105. package/dist/builtin/subagents/src/tui/render-progress.ts +89 -0
  106. package/dist/builtin/subagents/src/tui/render-result-compact.ts +43 -71
  107. package/dist/builtin/subagents/src/tui/render-result.ts +41 -90
  108. package/dist/builtin/subagents/src/tui/render-stable-output.ts +0 -5
  109. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +6 -55
  110. package/dist/builtin/web-access/CHANGELOG.md +14 -0
  111. package/dist/builtin/web-access/chrome-cookies.ts +3 -2
  112. package/dist/builtin/web-access/github-api.ts +7 -6
  113. package/dist/builtin/web-access/github-extract.ts +2 -1
  114. package/dist/builtin/web-access/package.json +3 -3
  115. package/dist/builtin/web-access/subprocess.ts +3 -1
  116. package/dist/builtin/web-access/summary-review.ts +2 -2
  117. package/dist/builtin/web-access/web-search-features.ts +38 -22
  118. package/dist/builtin/web-access/web-search-summary.ts +2 -2
  119. package/dist/builtin/workflows/CHANGELOG.md +45 -0
  120. package/dist/builtin/workflows/README.md +41 -1
  121. package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +3 -0
  122. package/dist/builtin/workflows/builtin/ralph-models.ts +25 -20
  123. package/dist/builtin/workflows/builtin/shared-prompts.ts +5 -2
  124. package/dist/builtin/workflows/package.json +2 -2
  125. package/dist/builtin/workflows/src/durable/backend.ts +18 -1
  126. package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +60 -3
  127. package/dist/builtin/workflows/src/durable/completed-catalog.ts +67 -1
  128. package/dist/builtin/workflows/src/durable/completed-subtree.ts +22 -7
  129. package/dist/builtin/workflows/src/durable/dbos-metadata.ts +4 -0
  130. package/dist/builtin/workflows/src/durable/local-command.ts +2 -1
  131. package/dist/builtin/workflows/src/durable/types.ts +17 -1
  132. package/dist/builtin/workflows/src/durable/workflow-child-result.ts +3 -1
  133. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +1 -1
  134. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +10 -2
  135. package/dist/builtin/workflows/src/engine/run-durable-topology.ts +9 -2
  136. package/dist/builtin/workflows/src/extension/atomic-stage-session.ts +7 -1
  137. package/dist/builtin/workflows/src/extension/companions.ts +1 -1
  138. package/dist/builtin/workflows/src/extension/index.bundle.mjs +947 -447
  139. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +31 -3
  140. package/dist/builtin/workflows/src/extension/mcp.ts +13 -2
  141. package/dist/builtin/workflows/src/extension/render-result.ts +1 -0
  142. package/dist/builtin/workflows/src/extension/ui-surface.ts +7 -20
  143. package/dist/builtin/workflows/src/extension/wiring.ts +33 -6
  144. package/dist/builtin/workflows/src/extension/workflow-ports.ts +14 -6
  145. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +11 -6
  146. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +8 -0
  147. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +2 -0
  148. package/dist/builtin/workflows/src/intercom/intercom-routing.ts +12 -6
  149. package/dist/builtin/workflows/src/intercom/result-intercom.ts +35 -4
  150. package/dist/builtin/workflows/src/runs/background/status.ts +15 -0
  151. package/dist/builtin/workflows/src/runs/foreground/executor-abort.ts +11 -3
  152. package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +2 -1
  153. package/dist/builtin/workflows/src/runs/foreground/executor-exit-manager.ts +26 -2
  154. package/dist/builtin/workflows/src/runs/foreground/executor-run-finalizers.ts +3 -2
  155. package/dist/builtin/workflows/src/runs/shared/worktree-git-runner.ts +5 -2
  156. package/dist/builtin/workflows/src/runs/shared/worktree-setup.ts +2 -0
  157. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +5 -3
  158. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +5 -3
  159. package/dist/builtin/workflows/src/shared/graph-store-snapshot.ts +34 -2
  160. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +23 -6
  161. package/dist/builtin/workflows/src/shared/stage-ui-broker.ts +10 -4
  162. package/dist/builtin/workflows/src/shared/store-public-types.ts +4 -2
  163. package/dist/builtin/workflows/src/shared/store-types.ts +1 -1
  164. package/dist/builtin/workflows/src/shared/workflow-artifact-env.ts +21 -0
  165. package/dist/builtin/workflows/src/shared/workflow-artifacts.ts +2 -5
  166. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +37 -2
  167. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +0 -15
  168. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +38 -47
  169. package/dist/builtin/workflows/src/tui/graph-view-input.ts +48 -45
  170. package/dist/builtin/workflows/src/tui/graph-view-layout.ts +266 -0
  171. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +1 -86
  172. package/dist/builtin/workflows/src/tui/graph-view-render.ts +209 -91
  173. package/dist/builtin/workflows/src/tui/graph-view-state.ts +5 -7
  174. package/dist/builtin/workflows/src/tui/graph-view-types.ts +13 -7
  175. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +8 -6
  176. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +2 -1
  177. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +7 -4
  178. package/dist/builtin/workflows/src/tui/inputs-picker-input.ts +66 -0
  179. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +1 -0
  180. package/dist/builtin/workflows/src/tui/node-card.ts +1 -1
  181. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +18 -46
  182. package/dist/builtin/workflows/src/tui/overlay-terminal-modes.ts +15 -26
  183. package/dist/builtin/workflows/src/tui/session-overlays.ts +5 -2
  184. package/dist/builtin/workflows/src/tui/session-picker.ts +27 -0
  185. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +5 -14
  186. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +8 -7
  187. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +12 -3
  188. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +1 -11
  189. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +0 -8
  190. package/dist/builtin/workflows/src/tui/status-list.ts +1 -0
  191. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +2 -6
  192. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +0 -15
  193. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +2 -26
  194. package/dist/builtin/workflows/src/tui/workflow-status.ts +3 -3
  195. package/dist/bun/split-loader.js +2 -0
  196. package/dist/bun/split-loader.js.map +1 -1
  197. package/dist/cli/args.d.ts.map +1 -1
  198. package/dist/cli/args.js +6 -2
  199. package/dist/cli/args.js.map +1 -1
  200. package/dist/cli/auth-check.d.ts +35 -0
  201. package/dist/cli/auth-check.d.ts.map +1 -0
  202. package/dist/cli/auth-check.js +100 -0
  203. package/dist/cli/auth-check.js.map +1 -0
  204. package/dist/cli/auth-command.d.ts +27 -0
  205. package/dist/cli/auth-command.d.ts.map +1 -0
  206. package/dist/cli/auth-command.js +150 -0
  207. package/dist/cli/auth-command.js.map +1 -0
  208. package/dist/cli/config-selector.js +2 -2
  209. package/dist/cli/config-selector.js.map +1 -1
  210. package/dist/cli/credential-print.d.ts +18 -23
  211. package/dist/cli/credential-print.d.ts.map +1 -1
  212. package/dist/cli/credential-print.js +42 -88
  213. package/dist/cli/credential-print.js.map +1 -1
  214. package/dist/cli/experimental/auth.d.ts +16 -0
  215. package/dist/cli/experimental/auth.d.ts.map +1 -0
  216. package/dist/cli/experimental/auth.js +13 -0
  217. package/dist/cli/experimental/auth.js.map +1 -0
  218. package/dist/cli/experimental/cli.d.ts +6 -0
  219. package/dist/cli/experimental/cli.d.ts.map +1 -0
  220. package/dist/cli/experimental/cli.js +5 -0
  221. package/dist/cli/experimental/cli.js.map +1 -0
  222. package/dist/cli/experimental/command-options.d.ts +17 -0
  223. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  224. package/dist/cli/experimental/command-options.js +35 -0
  225. package/dist/cli/experimental/command-options.js.map +1 -0
  226. package/dist/cli/experimental/command.d.ts +63 -0
  227. package/dist/cli/experimental/command.d.ts.map +1 -0
  228. package/dist/cli/experimental/command.js +127 -0
  229. package/dist/cli/experimental/command.js.map +1 -0
  230. package/dist/cli/experimental/commands/client.d.ts +13 -0
  231. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  232. package/dist/cli/experimental/commands/client.js +25 -0
  233. package/dist/cli/experimental/commands/client.js.map +1 -0
  234. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  235. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  236. package/dist/cli/experimental/commands/pi.js +28 -0
  237. package/dist/cli/experimental/commands/pi.js.map +1 -0
  238. package/dist/cli/experimental/commands/server.d.ts +13 -0
  239. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  240. package/dist/cli/experimental/commands/server.js +25 -0
  241. package/dist/cli/experimental/commands/server.js.map +1 -0
  242. package/dist/cli/experimental/transport-address.d.ts +10 -0
  243. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  244. package/dist/cli/experimental/transport-address.js +38 -0
  245. package/dist/cli/experimental/transport-address.js.map +1 -0
  246. package/dist/cli/session-picker.js +2 -2
  247. package/dist/cli/session-picker.js.map +1 -1
  248. package/dist/cli/startup-ui.d.ts.map +1 -1
  249. package/dist/cli/startup-ui.js +4 -10
  250. package/dist/cli/startup-ui.js.map +1 -1
  251. package/dist/cli.js +2 -0
  252. package/dist/cli.js.map +1 -1
  253. package/dist/client/index.d.ts +3 -0
  254. package/dist/client/index.d.ts.map +1 -0
  255. package/dist/client/index.js +3 -0
  256. package/dist/client/index.js.map +1 -0
  257. package/dist/client/remote-session.d.ts +64 -0
  258. package/dist/client/remote-session.d.ts.map +1 -0
  259. package/dist/client/remote-session.js +351 -0
  260. package/dist/client/remote-session.js.map +1 -0
  261. package/dist/client/transcript.d.ts +12 -0
  262. package/dist/client/transcript.d.ts.map +1 -0
  263. package/dist/client/transcript.js +98 -0
  264. package/dist/client/transcript.js.map +1 -0
  265. package/dist/core/agent-session-auto-compaction.d.ts +17 -13
  266. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  267. package/dist/core/agent-session-auto-compaction.js +146 -64
  268. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  269. package/dist/core/agent-session-bash.d.ts.map +1 -1
  270. package/dist/core/agent-session-bash.js +2 -0
  271. package/dist/core/agent-session-bash.js.map +1 -1
  272. package/dist/core/agent-session-compaction.d.ts +3 -6
  273. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  274. package/dist/core/agent-session-compaction.js +64 -28
  275. package/dist/core/agent-session-compaction.js.map +1 -1
  276. package/dist/core/agent-session-events.d.ts +1 -11
  277. package/dist/core/agent-session-events.d.ts.map +1 -1
  278. package/dist/core/agent-session-events.js +15 -23
  279. package/dist/core/agent-session-events.js.map +1 -1
  280. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  281. package/dist/core/agent-session-extension-bindings.js +4 -2
  282. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  283. package/dist/core/agent-session-methods.d.ts +6 -2
  284. package/dist/core/agent-session-methods.d.ts.map +1 -1
  285. package/dist/core/agent-session-methods.js.map +1 -1
  286. package/dist/core/agent-session-models.d.ts +1 -0
  287. package/dist/core/agent-session-models.d.ts.map +1 -1
  288. package/dist/core/agent-session-models.js +11 -4
  289. package/dist/core/agent-session-models.js.map +1 -1
  290. package/dist/core/agent-session-post-tool-compaction.d.ts.map +1 -1
  291. package/dist/core/agent-session-post-tool-compaction.js +22 -6
  292. package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
  293. package/dist/core/agent-session-runtime-auth.d.ts.map +1 -1
  294. package/dist/core/agent-session-runtime-auth.js +3 -0
  295. package/dist/core/agent-session-runtime-auth.js.map +1 -1
  296. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  297. package/dist/core/agent-session-tool-hooks.js +25 -14
  298. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  299. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  300. package/dist/core/agent-session-tool-registry.js +4 -0
  301. package/dist/core/agent-session-tool-registry.js.map +1 -1
  302. package/dist/core/agent-session-types.d.ts +2 -0
  303. package/dist/core/agent-session-types.d.ts.map +1 -1
  304. package/dist/core/agent-session-types.js.map +1 -1
  305. package/dist/core/agent-session.d.ts +6 -0
  306. package/dist/core/agent-session.d.ts.map +1 -1
  307. package/dist/core/agent-session.js +30 -0
  308. package/dist/core/agent-session.js.map +1 -1
  309. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  310. package/dist/core/atomic-guide-command.js +2 -3
  311. package/dist/core/atomic-guide-command.js.map +1 -1
  312. package/dist/core/auth-storage.d.ts +18 -1
  313. package/dist/core/auth-storage.d.ts.map +1 -1
  314. package/dist/core/auth-storage.js +83 -0
  315. package/dist/core/auth-storage.js.map +1 -1
  316. package/dist/core/bash-executor.d.ts +5 -0
  317. package/dist/core/bash-executor.d.ts.map +1 -1
  318. package/dist/core/bash-executor.js +43 -19
  319. package/dist/core/bash-executor.js.map +1 -1
  320. package/dist/core/builtin-packages.d.ts.map +1 -1
  321. package/dist/core/builtin-packages.js +6 -0
  322. package/dist/core/builtin-packages.js.map +1 -1
  323. package/dist/core/codex-fast-mode.d.ts.map +1 -1
  324. package/dist/core/codex-fast-mode.js +8 -3
  325. package/dist/core/codex-fast-mode.js.map +1 -1
  326. package/dist/core/exec.d.ts.map +1 -1
  327. package/dist/core/exec.js +4 -3
  328. package/dist/core/exec.js.map +1 -1
  329. package/dist/core/extensions/agent-events.d.ts +0 -1
  330. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  331. package/dist/core/extensions/agent-events.js.map +1 -1
  332. package/dist/core/extensions/api-types.d.ts +5 -3
  333. package/dist/core/extensions/api-types.d.ts.map +1 -1
  334. package/dist/core/extensions/api-types.js.map +1 -1
  335. package/dist/core/extensions/context-types.d.ts +15 -0
  336. package/dist/core/extensions/context-types.d.ts.map +1 -1
  337. package/dist/core/extensions/context-types.js.map +1 -1
  338. package/dist/core/extensions/event-results.d.ts +5 -0
  339. package/dist/core/extensions/event-results.d.ts.map +1 -1
  340. package/dist/core/extensions/event-results.js.map +1 -1
  341. package/dist/core/extensions/index.d.ts +2 -1
  342. package/dist/core/extensions/index.d.ts.map +1 -1
  343. package/dist/core/extensions/index.js +1 -0
  344. package/dist/core/extensions/index.js.map +1 -1
  345. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  346. package/dist/core/extensions/loader-api.js +14 -1
  347. package/dist/core/extensions/loader-api.js.map +1 -1
  348. package/dist/core/extensions/loader-discovery.d.ts.map +1 -1
  349. package/dist/core/extensions/loader-discovery.js +3 -23
  350. package/dist/core/extensions/loader-discovery.js.map +1 -1
  351. package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
  352. package/dist/core/extensions/loader-runtime.js +20 -3
  353. package/dist/core/extensions/loader-runtime.js.map +1 -1
  354. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  355. package/dist/core/extensions/loader-virtual-modules.js +7 -1
  356. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  357. package/dist/core/extensions/message-types.d.ts +6 -0
  358. package/dist/core/extensions/message-types.d.ts.map +1 -1
  359. package/dist/core/extensions/message-types.js.map +1 -1
  360. package/dist/core/extensions/provider-types.d.ts +9 -3
  361. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  362. package/dist/core/extensions/provider-types.js.map +1 -1
  363. package/dist/core/extensions/runner-registries.d.ts +2 -1
  364. package/dist/core/extensions/runner-registries.d.ts.map +1 -1
  365. package/dist/core/extensions/runner-registries.js +3 -0
  366. package/dist/core/extensions/runner-registries.js.map +1 -1
  367. package/dist/core/extensions/runner-ui.d.ts.map +1 -1
  368. package/dist/core/extensions/runner-ui.js +1 -0
  369. package/dist/core/extensions/runner-ui.js.map +1 -1
  370. package/dist/core/extensions/runner.d.ts +2 -1
  371. package/dist/core/extensions/runner.d.ts.map +1 -1
  372. package/dist/core/extensions/runner.js +6 -2
  373. package/dist/core/extensions/runner.js.map +1 -1
  374. package/dist/core/extensions/runtime-types.d.ts +4 -1
  375. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  376. package/dist/core/extensions/runtime-types.js.map +1 -1
  377. package/dist/core/extensions/stale-context.d.ts +5 -0
  378. package/dist/core/extensions/stale-context.d.ts.map +1 -0
  379. package/dist/core/extensions/stale-context.js +11 -0
  380. package/dist/core/extensions/stale-context.js.map +1 -0
  381. package/dist/core/extensions/ui-types.d.ts +14 -11
  382. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  383. package/dist/core/extensions/ui-types.js.map +1 -1
  384. package/dist/core/footer-data-provider.d.ts.map +1 -1
  385. package/dist/core/footer-data-provider.js +3 -2
  386. package/dist/core/footer-data-provider.js.map +1 -1
  387. package/dist/core/index.d.ts +1 -1
  388. package/dist/core/index.d.ts.map +1 -1
  389. package/dist/core/index.js.map +1 -1
  390. package/dist/core/intercom-runtime-group.d.ts +13 -0
  391. package/dist/core/intercom-runtime-group.d.ts.map +1 -0
  392. package/dist/core/intercom-runtime-group.js +23 -0
  393. package/dist/core/intercom-runtime-group.js.map +1 -0
  394. package/dist/core/keybindings.d.ts +44 -4
  395. package/dist/core/keybindings.d.ts.map +1 -1
  396. package/dist/core/model-config.d.ts +39 -5
  397. package/dist/core/model-config.d.ts.map +1 -1
  398. package/dist/core/model-config.js +6 -0
  399. package/dist/core/model-config.js.map +1 -1
  400. package/dist/core/model-registry.d.ts +12 -5
  401. package/dist/core/model-registry.d.ts.map +1 -1
  402. package/dist/core/model-registry.js +20 -12
  403. package/dist/core/model-registry.js.map +1 -1
  404. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  405. package/dist/core/model-resolver-cli.js +46 -14
  406. package/dist/core/model-resolver-cli.js.map +1 -1
  407. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  408. package/dist/core/model-resolver-defaults.js +2 -0
  409. package/dist/core/model-resolver-defaults.js.map +1 -1
  410. package/dist/core/model-resolver-scope.d.ts +2 -0
  411. package/dist/core/model-resolver-scope.d.ts.map +1 -1
  412. package/dist/core/model-resolver-scope.js +12 -9
  413. package/dist/core/model-resolver-scope.js.map +1 -1
  414. package/dist/core/model-resolver.d.ts +1 -1
  415. package/dist/core/model-resolver.d.ts.map +1 -1
  416. package/dist/core/model-resolver.js +1 -1
  417. package/dist/core/model-resolver.js.map +1 -1
  418. package/dist/core/model-runtime-snapshot.d.ts +10 -0
  419. package/dist/core/model-runtime-snapshot.d.ts.map +1 -1
  420. package/dist/core/model-runtime-snapshot.js +14 -1
  421. package/dist/core/model-runtime-snapshot.js.map +1 -1
  422. package/dist/core/model-runtime-streaming.d.ts +3 -1
  423. package/dist/core/model-runtime-streaming.d.ts.map +1 -1
  424. package/dist/core/model-runtime-streaming.js +16 -0
  425. package/dist/core/model-runtime-streaming.js.map +1 -1
  426. package/dist/core/model-runtime-types.d.ts +2 -0
  427. package/dist/core/model-runtime-types.d.ts.map +1 -1
  428. package/dist/core/model-runtime-types.js.map +1 -1
  429. package/dist/core/model-runtime.d.ts +37 -10
  430. package/dist/core/model-runtime.d.ts.map +1 -1
  431. package/dist/core/model-runtime.js +312 -113
  432. package/dist/core/model-runtime.js.map +1 -1
  433. package/dist/core/oauth-login.d.ts.map +1 -1
  434. package/dist/core/oauth-login.js +2 -1
  435. package/dist/core/oauth-login.js.map +1 -1
  436. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  437. package/dist/core/openai-responses-payload-sanitizer.js +18 -2
  438. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  439. package/dist/core/package-manager-git.d.ts.map +1 -1
  440. package/dist/core/package-manager-git.js +56 -10
  441. package/dist/core/package-manager-git.js.map +1 -1
  442. package/dist/core/package-manager-manifest.d.ts +1 -1
  443. package/dist/core/package-manager-manifest.d.ts.map +1 -1
  444. package/dist/core/package-manager-manifest.js +19 -9
  445. package/dist/core/package-manager-manifest.js.map +1 -1
  446. package/dist/core/package-manager-resource-collector.js.map +1 -1
  447. package/dist/core/package-manager-resource-files.d.ts.map +1 -1
  448. package/dist/core/package-manager-resource-files.js +1 -2
  449. package/dist/core/package-manager-resource-files.js.map +1 -1
  450. package/dist/core/provider-composer-internal.d.ts +10 -2
  451. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  452. package/dist/core/provider-composer-internal.js +7 -3
  453. package/dist/core/provider-composer-internal.js.map +1 -1
  454. package/dist/core/provider-composer.d.ts.map +1 -1
  455. package/dist/core/provider-composer.js +19 -12
  456. package/dist/core/provider-composer.js.map +1 -1
  457. package/dist/core/provider-display-names.d.ts.map +1 -1
  458. package/dist/core/provider-display-names.js +2 -0
  459. package/dist/core/provider-display-names.js.map +1 -1
  460. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  461. package/dist/core/remote-catalog-provider.js +77 -67
  462. package/dist/core/remote-catalog-provider.js.map +1 -1
  463. package/dist/core/resolve-config-value.d.ts.map +1 -1
  464. package/dist/core/resolve-config-value.js +3 -0
  465. package/dist/core/resolve-config-value.js.map +1 -1
  466. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  467. package/dist/core/resource-loader-context-files.js +13 -5
  468. package/dist/core/resource-loader-context-files.js.map +1 -1
  469. package/dist/core/runtime-credentials.d.ts +5 -5
  470. package/dist/core/runtime-credentials.d.ts.map +1 -1
  471. package/dist/core/runtime-credentials.js +8 -8
  472. package/dist/core/runtime-credentials.js.map +1 -1
  473. package/dist/core/session-manager-list.d.ts.map +1 -1
  474. package/dist/core/session-manager-list.js +3 -1
  475. package/dist/core/session-manager-list.js.map +1 -1
  476. package/dist/core/settings-manager-ui-accessors.d.ts +8 -1
  477. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  478. package/dist/core/settings-manager-ui-accessors.js +31 -0
  479. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  480. package/dist/core/settings-manager.d.ts +2 -1
  481. package/dist/core/settings-manager.d.ts.map +1 -1
  482. package/dist/core/settings-manager.js.map +1 -1
  483. package/dist/core/settings-merge.d.ts.map +1 -1
  484. package/dist/core/settings-merge.js +13 -16
  485. package/dist/core/settings-merge.js.map +1 -1
  486. package/dist/core/settings-types.d.ts +5 -0
  487. package/dist/core/settings-types.d.ts.map +1 -1
  488. package/dist/core/settings-types.js.map +1 -1
  489. package/dist/core/slash-commands.d.ts.map +1 -1
  490. package/dist/core/slash-commands.js +0 -2
  491. package/dist/core/slash-commands.js.map +1 -1
  492. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +2 -2
  493. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -1
  494. package/dist/core/tools/ask-user-question/state/questionnaire-session.js +39 -2
  495. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
  496. package/dist/core/tools/bash-async-execution.d.ts +2 -0
  497. package/dist/core/tools/bash-async-execution.d.ts.map +1 -1
  498. package/dist/core/tools/bash-async-execution.js +4 -1
  499. package/dist/core/tools/bash-async-execution.js.map +1 -1
  500. package/dist/core/tools/bash-async-output.d.ts +1 -0
  501. package/dist/core/tools/bash-async-output.d.ts.map +1 -1
  502. package/dist/core/tools/bash-async-output.js +62 -27
  503. package/dist/core/tools/bash-async-output.js.map +1 -1
  504. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  505. package/dist/core/tools/bash-pty-native.js +2 -1
  506. package/dist/core/tools/bash-pty-native.js.map +1 -1
  507. package/dist/core/tools/bash.d.ts +9 -0
  508. package/dist/core/tools/bash.d.ts.map +1 -1
  509. package/dist/core/tools/bash.js +34 -16
  510. package/dist/core/tools/bash.js.map +1 -1
  511. package/dist/core/tools/directory-tree.d.ts +11 -0
  512. package/dist/core/tools/directory-tree.d.ts.map +1 -1
  513. package/dist/core/tools/directory-tree.js +26 -0
  514. package/dist/core/tools/directory-tree.js.map +1 -1
  515. package/dist/core/tools/edit.d.ts +4 -0
  516. package/dist/core/tools/edit.d.ts.map +1 -1
  517. package/dist/core/tools/edit.js +12 -8
  518. package/dist/core/tools/edit.js.map +1 -1
  519. package/dist/core/tools/errno.d.ts +25 -0
  520. package/dist/core/tools/errno.d.ts.map +1 -0
  521. package/dist/core/tools/errno.js +29 -0
  522. package/dist/core/tools/errno.js.map +1 -0
  523. package/dist/core/tools/find.d.ts +8 -1
  524. package/dist/core/tools/find.d.ts.map +1 -1
  525. package/dist/core/tools/find.js +20 -15
  526. package/dist/core/tools/find.js.map +1 -1
  527. package/dist/core/tools/grep.d.ts.map +1 -1
  528. package/dist/core/tools/grep.js +5 -1
  529. package/dist/core/tools/grep.js.map +1 -1
  530. package/dist/core/tools/index.d.ts +7 -7
  531. package/dist/core/tools/index.d.ts.map +1 -1
  532. package/dist/core/tools/index.js +7 -7
  533. package/dist/core/tools/index.js.map +1 -1
  534. package/dist/core/tools/ls.d.ts +4 -0
  535. package/dist/core/tools/ls.d.ts.map +1 -1
  536. package/dist/core/tools/ls.js +5 -1
  537. package/dist/core/tools/ls.js.map +1 -1
  538. package/dist/core/tools/output-accumulator.d.ts +8 -1
  539. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  540. package/dist/core/tools/output-accumulator.js +50 -28
  541. package/dist/core/tools/output-accumulator.js.map +1 -1
  542. package/dist/core/tools/oversized-tool-result.d.ts.map +1 -1
  543. package/dist/core/tools/oversized-tool-result.js +129 -22
  544. package/dist/core/tools/oversized-tool-result.js.map +1 -1
  545. package/dist/core/tools/persisted-output-file.d.ts +80 -0
  546. package/dist/core/tools/persisted-output-file.d.ts.map +1 -0
  547. package/dist/core/tools/persisted-output-file.js +284 -0
  548. package/dist/core/tools/persisted-output-file.js.map +1 -0
  549. package/dist/core/tools/read.d.ts +10 -0
  550. package/dist/core/tools/read.d.ts.map +1 -1
  551. package/dist/core/tools/read.js +20 -8
  552. package/dist/core/tools/read.js.map +1 -1
  553. package/dist/core/tools/search.d.ts +4 -0
  554. package/dist/core/tools/search.d.ts.map +1 -1
  555. package/dist/core/tools/search.js +5 -1
  556. package/dist/core/tools/search.js.map +1 -1
  557. package/dist/core/tools/session-temp-cleanup.d.ts +133 -0
  558. package/dist/core/tools/session-temp-cleanup.d.ts.map +1 -0
  559. package/dist/core/tools/session-temp-cleanup.js +669 -0
  560. package/dist/core/tools/session-temp-cleanup.js.map +1 -0
  561. package/dist/core/tools/session-temp-dir.d.ts +116 -0
  562. package/dist/core/tools/session-temp-dir.d.ts.map +1 -0
  563. package/dist/core/tools/session-temp-dir.js +409 -0
  564. package/dist/core/tools/session-temp-dir.js.map +1 -0
  565. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  566. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  567. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  568. package/dist/core/tools/tool-limits.d.ts +11 -0
  569. package/dist/core/tools/tool-limits.d.ts.map +1 -1
  570. package/dist/core/tools/tool-limits.js +11 -0
  571. package/dist/core/tools/tool-limits.js.map +1 -1
  572. package/dist/core/tools/windows-directory-security.d.ts +82 -0
  573. package/dist/core/tools/windows-directory-security.d.ts.map +1 -0
  574. package/dist/core/tools/windows-directory-security.js +238 -0
  575. package/dist/core/tools/windows-directory-security.js.map +1 -0
  576. package/dist/core/tools/write.d.ts +4 -0
  577. package/dist/core/tools/write.d.ts.map +1 -1
  578. package/dist/core/tools/write.js +8 -4
  579. package/dist/core/tools/write.js.map +1 -1
  580. package/dist/core/trust-manager.js +1 -1
  581. package/dist/core/trust-manager.js.map +1 -1
  582. package/dist/extensions/llama/huggingface-ui.d.ts +1 -1
  583. package/dist/extensions/llama/huggingface-ui.d.ts.map +1 -1
  584. package/dist/extensions/llama/huggingface-ui.js +6 -5
  585. package/dist/extensions/llama/huggingface-ui.js.map +1 -1
  586. package/dist/extensions/llama/index.d.ts.map +1 -1
  587. package/dist/extensions/llama/index.js +11 -2
  588. package/dist/extensions/llama/index.js.map +1 -1
  589. package/dist/extensions/llama/provider.d.ts.map +1 -1
  590. package/dist/extensions/llama/provider.js +24 -8
  591. package/dist/extensions/llama/provider.js.map +1 -1
  592. package/dist/extensions/llama/ui.d.ts.map +1 -1
  593. package/dist/extensions/llama/ui.js +5 -2
  594. package/dist/extensions/llama/ui.js.map +1 -1
  595. package/dist/index-extensions.d.ts +2 -2
  596. package/dist/index-extensions.d.ts.map +1 -1
  597. package/dist/index-extensions.js +1 -1
  598. package/dist/index-extensions.js.map +1 -1
  599. package/dist/index.d.ts +5 -2
  600. package/dist/index.d.ts.map +1 -1
  601. package/dist/index.js +6 -2
  602. package/dist/index.js.map +1 -1
  603. package/dist/main-runtime-api-key.d.ts +2 -2
  604. package/dist/main-runtime-api-key.d.ts.map +1 -1
  605. package/dist/main-runtime-api-key.js +7 -2
  606. package/dist/main-runtime-api-key.js.map +1 -1
  607. package/dist/main-session.js +2 -2
  608. package/dist/main-session.js.map +1 -1
  609. package/dist/main.d.ts.map +1 -1
  610. package/dist/main.js +130 -26
  611. package/dist/main.js.map +1 -1
  612. package/dist/modes/index.d.ts +1 -0
  613. package/dist/modes/index.d.ts.map +1 -1
  614. package/dist/modes/index.js.map +1 -1
  615. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  616. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  617. package/dist/modes/interactive/components/assistant-message.js +18 -5
  618. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  619. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  620. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  621. package/dist/modes/interactive/components/bordered-loader.js +5 -4
  622. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  623. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  624. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  625. package/dist/modes/interactive/components/branch-summary-message.js +3 -2
  626. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  627. package/dist/modes/interactive/components/chat-message-renderer.d.ts +17 -7
  628. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  629. package/dist/modes/interactive/components/chat-message-renderer.js +35 -69
  630. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  631. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  632. package/dist/modes/interactive/components/chat-session-host-actions.js +11 -3
  633. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  634. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  635. package/dist/modes/interactive/components/chat-session-host-events.js +25 -15
  636. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  637. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  638. package/dist/modes/interactive/components/chat-session-host-rendering.js +9 -4
  639. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  640. package/dist/modes/interactive/components/chat-session-host-state.d.ts +2 -0
  641. package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
  642. package/dist/modes/interactive/components/chat-session-host-state.js +2 -0
  643. package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
  644. package/dist/modes/interactive/components/chat-session-host.d.ts +9 -0
  645. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  646. package/dist/modes/interactive/components/chat-session-host.js +14 -0
  647. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  648. package/dist/modes/interactive/components/chat-transcript.d.ts +32 -0
  649. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  650. package/dist/modes/interactive/components/chat-transcript.js +173 -5
  651. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  652. package/dist/modes/interactive/components/config-selector-list.d.ts +1 -1
  653. package/dist/modes/interactive/components/config-selector-list.d.ts.map +1 -1
  654. package/dist/modes/interactive/components/config-selector-list.js +9 -8
  655. package/dist/modes/interactive/components/config-selector-list.js.map +1 -1
  656. package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
  657. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  658. package/dist/modes/interactive/components/custom-editor.js +32 -10
  659. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  660. package/dist/modes/interactive/components/custom-message.d.ts +2 -1
  661. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  662. package/dist/modes/interactive/components/custom-message.js +3 -2
  663. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  664. package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
  665. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  666. package/dist/modes/interactive/components/extension-editor.js +3 -2
  667. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  668. package/dist/modes/interactive/components/extension-input.d.ts +1 -1
  669. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  670. package/dist/modes/interactive/components/extension-input.js +1 -0
  671. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  672. package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
  673. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  674. package/dist/modes/interactive/components/extension-selector.js +4 -0
  675. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  676. package/dist/modes/interactive/components/fast-mode-selector.d.ts +1 -1
  677. package/dist/modes/interactive/components/fast-mode-selector.d.ts.map +1 -1
  678. package/dist/modes/interactive/components/fast-mode-selector.js +7 -5
  679. package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
  680. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  681. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  682. package/dist/modes/interactive/components/first-time-setup.js +3 -0
  683. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  684. package/dist/modes/interactive/components/footer.js +1 -1
  685. package/dist/modes/interactive/components/footer.js.map +1 -1
  686. package/dist/modes/interactive/components/host-input-form.d.ts +1 -1
  687. package/dist/modes/interactive/components/host-input-form.d.ts.map +1 -1
  688. package/dist/modes/interactive/components/host-input-form.js +6 -5
  689. package/dist/modes/interactive/components/host-input-form.js.map +1 -1
  690. package/dist/modes/interactive/components/index.d.ts +1 -1
  691. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  692. package/dist/modes/interactive/components/index.js.map +1 -1
  693. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  694. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  695. package/dist/modes/interactive/components/login-dialog.js +2 -1
  696. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  697. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  698. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  699. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  700. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  701. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  702. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  703. package/dist/modes/interactive/components/mermaid.js +81 -0
  704. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  705. package/dist/modes/interactive/components/model-selector.d.ts +2 -2
  706. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  707. package/dist/modes/interactive/components/model-selector.js +9 -6
  708. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  709. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
  710. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  711. package/dist/modes/interactive/components/oauth-selector.js +3 -2
  712. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  713. package/dist/modes/interactive/components/scoped-models-selector.d.ts +6 -2
  714. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  715. package/dist/modes/interactive/components/scoped-models-selector.js +39 -13
  716. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  717. package/dist/modes/interactive/components/session-selector-delete.d.ts.map +1 -1
  718. package/dist/modes/interactive/components/session-selector-delete.js +2 -1
  719. package/dist/modes/interactive/components/session-selector-delete.js.map +1 -1
  720. package/dist/modes/interactive/components/session-selector-list.d.ts +1 -1
  721. package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
  722. package/dist/modes/interactive/components/session-selector-list.js +12 -11
  723. package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
  724. package/dist/modes/interactive/components/session-selector.d.ts +1 -1
  725. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  726. package/dist/modes/interactive/components/session-selector.js +3 -3
  727. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  728. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  729. package/dist/modes/interactive/components/settings-selector-handlers.js +9 -0
  730. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  731. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  732. package/dist/modes/interactive/components/settings-selector-items.js +21 -0
  733. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  734. package/dist/modes/interactive/components/settings-selector-submenus.d.ts +3 -3
  735. package/dist/modes/interactive/components/settings-selector-submenus.d.ts.map +1 -1
  736. package/dist/modes/interactive/components/settings-selector-submenus.js +6 -1
  737. package/dist/modes/interactive/components/settings-selector-submenus.js.map +1 -1
  738. package/dist/modes/interactive/components/settings-selector-types.d.ts +8 -1
  739. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  740. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  741. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  742. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  743. package/dist/modes/interactive/components/skill-invocation-message.js +3 -2
  744. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  745. package/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  746. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  747. package/dist/modes/interactive/components/tool-execution.js +50 -27
  748. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  749. package/dist/modes/interactive/components/tree-selector-component.d.ts +1 -1
  750. package/dist/modes/interactive/components/tree-selector-component.d.ts.map +1 -1
  751. package/dist/modes/interactive/components/tree-selector-component.js +2 -3
  752. package/dist/modes/interactive/components/tree-selector-component.js.map +1 -1
  753. package/dist/modes/interactive/components/tree-selector-help.d.ts +1 -1
  754. package/dist/modes/interactive/components/tree-selector-help.d.ts.map +1 -1
  755. package/dist/modes/interactive/components/tree-selector-help.js +3 -1
  756. package/dist/modes/interactive/components/tree-selector-help.js.map +1 -1
  757. package/dist/modes/interactive/components/tree-selector-label-input.d.ts +1 -1
  758. package/dist/modes/interactive/components/tree-selector-label-input.d.ts.map +1 -1
  759. package/dist/modes/interactive/components/tree-selector-label-input.js +1 -0
  760. package/dist/modes/interactive/components/tree-selector-label-input.js.map +1 -1
  761. package/dist/modes/interactive/components/tree-selector-list.d.ts +1 -1
  762. package/dist/modes/interactive/components/tree-selector-list.d.ts.map +1 -1
  763. package/dist/modes/interactive/components/tree-selector-list.js +3 -0
  764. package/dist/modes/interactive/components/tree-selector-list.js.map +1 -1
  765. package/dist/modes/interactive/components/trust-selector.d.ts +1 -1
  766. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  767. package/dist/modes/interactive/components/trust-selector.js +4 -0
  768. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  769. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -1
  770. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  771. package/dist/modes/interactive/components/user-message-selector.js +4 -0
  772. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  773. package/dist/modes/interactive/components/user-message.d.ts +4 -1
  774. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  775. package/dist/modes/interactive/components/user-message.js +10 -2
  776. package/dist/modes/interactive/components/user-message.js.map +1 -1
  777. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  778. package/dist/modes/interactive/external-editor.js +2 -1
  779. package/dist/modes/interactive/external-editor.js.map +1 -1
  780. package/dist/modes/interactive/interactive-agent-events.js +36 -18
  781. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  782. package/dist/modes/interactive/interactive-auth-login.js +9 -2
  783. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  784. package/dist/modes/interactive/interactive-auth-routing.d.ts.map +1 -1
  785. package/dist/modes/interactive/interactive-auth-routing.js +5 -1
  786. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  787. package/dist/modes/interactive/interactive-bash-compact.js +16 -4
  788. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  789. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  790. package/dist/modes/interactive/interactive-deferred-startup.js +3 -0
  791. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  792. package/dist/modes/interactive/interactive-editor-actions.js +2 -0
  793. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  794. package/dist/modes/interactive/interactive-extension-context.js +12 -7
  795. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  796. package/dist/modes/interactive/interactive-extension-custom-ui.js +1 -0
  797. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  798. package/dist/modes/interactive/interactive-extension-dialogs.js +7 -0
  799. package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  800. package/dist/modes/interactive/interactive-extension-widgets.js +7 -24
  801. package/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  802. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  803. package/dist/modes/interactive/interactive-input-handling.js +9 -8
  804. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  805. package/dist/modes/interactive/interactive-mode-base.d.ts +52 -3
  806. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  807. package/dist/modes/interactive/interactive-mode-base.js +143 -5
  808. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  809. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  810. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  811. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  812. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  813. package/dist/modes/interactive/interactive-mode-surface.d.ts +9 -3
  814. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  815. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  816. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  817. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  818. package/dist/modes/interactive/interactive-mode.js +1 -0
  819. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  820. package/dist/modes/interactive/interactive-model-routing.js +107 -41
  821. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  822. package/dist/modes/interactive/interactive-process-lifecycle.js +1 -1
  823. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  824. package/dist/modes/interactive/interactive-render-chat.js +24 -6
  825. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  826. package/dist/modes/interactive/interactive-selectors.js +44 -5
  827. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  828. package/dist/modes/interactive/interactive-session-runtime.js +1 -0
  829. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  830. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  831. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  832. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  833. package/dist/modes/interactive/interactive-startup.js +37 -18
  834. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  835. package/dist/modes/interactive/interactive-tui.d.ts +21 -0
  836. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -0
  837. package/dist/modes/interactive/interactive-tui.js +279 -0
  838. package/dist/modes/interactive/interactive-tui.js.map +1 -0
  839. package/dist/modes/interactive/streaming-assistant-message.d.ts +34 -0
  840. package/dist/modes/interactive/streaming-assistant-message.d.ts.map +1 -0
  841. package/dist/modes/interactive/streaming-assistant-message.js +76 -0
  842. package/dist/modes/interactive/streaming-assistant-message.js.map +1 -0
  843. package/dist/modes/interactive/theme/catppuccin-frappe.json +1 -0
  844. package/dist/modes/interactive/theme/catppuccin-latte.json +1 -0
  845. package/dist/modes/interactive/theme/catppuccin-macchiato.json +1 -0
  846. package/dist/modes/interactive/theme/catppuccin-mocha.json +1 -0
  847. package/dist/modes/interactive/theme/dark.json +1 -0
  848. package/dist/modes/interactive/theme/light.json +1 -0
  849. package/dist/modes/interactive/theme/terminal-detection.d.ts +10 -0
  850. package/dist/modes/interactive/theme/terminal-detection.d.ts.map +1 -1
  851. package/dist/modes/interactive/theme/terminal-detection.js +19 -0
  852. package/dist/modes/interactive/theme/terminal-detection.js.map +1 -1
  853. package/dist/modes/interactive/theme/theme-class.d.ts +2 -2
  854. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  855. package/dist/modes/interactive/theme/theme-class.js +5 -1
  856. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  857. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -1
  858. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  859. package/dist/modes/interactive/theme/theme-controller.js +10 -13
  860. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  861. package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
  862. package/dist/modes/interactive/theme/theme-loading.js +1 -0
  863. package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
  864. package/dist/modes/interactive/theme/theme-schema.d.ts +4 -0
  865. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  866. package/dist/modes/interactive/theme/theme-schema.js +2 -1
  867. package/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  868. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  869. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  870. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  871. package/dist/modes/interactive/theme/theme.js +1 -1
  872. package/dist/modes/interactive/theme/theme.js.map +1 -1
  873. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +1 -1
  874. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  875. package/dist/modes/interactive-engine/engine-custom-ui.js +28 -11
  876. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  877. package/dist/modes/interactive-engine/engine-render-service.js +3 -3
  878. package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
  879. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +2 -1
  880. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
  881. package/dist/modes/interactive-engine/extension-ui-bridge.js +2 -2
  882. package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
  883. package/dist/modes/interactive-engine/isolated-runtime.d.ts +7 -0
  884. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  885. package/dist/modes/interactive-engine/isolated-runtime.js +7 -0
  886. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  887. package/dist/modes/interactive-engine/protocol.d.ts +12 -10
  888. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  889. package/dist/modes/interactive-engine/protocol.js +14 -11
  890. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  891. package/dist/modes/interactive-engine/remote-component.d.ts +11 -1
  892. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  893. package/dist/modes/interactive-engine/remote-component.js +48 -8
  894. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  895. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts +19 -12
  896. package/dist/modes/interactive-engine/terminal-mode-controller.d.ts.map +1 -1
  897. package/dist/modes/interactive-engine/terminal-mode-controller.js +54 -35
  898. package/dist/modes/interactive-engine/terminal-mode-controller.js.map +1 -1
  899. package/dist/modes/json-event.d.ts +28 -0
  900. package/dist/modes/json-event.d.ts.map +1 -0
  901. package/dist/modes/json-event.js +12 -0
  902. package/dist/modes/json-event.js.map +1 -0
  903. package/dist/modes/print-mode.d.ts.map +1 -1
  904. package/dist/modes/print-mode.js +2 -1
  905. package/dist/modes/print-mode.js.map +1 -1
  906. package/dist/modes/rpc/rpc-client-process.d.ts +1 -0
  907. package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
  908. package/dist/modes/rpc/rpc-client-process.js +5 -1
  909. package/dist/modes/rpc/rpc-client-process.js.map +1 -1
  910. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  911. package/dist/modes/rpc/rpc-client.js +7 -2
  912. package/dist/modes/rpc/rpc-client.js.map +1 -1
  913. package/dist/modes/rpc/rpc-command-handler.js +1 -1
  914. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  915. package/dist/modes/rpc/rpc-event-buffer.d.ts +9 -0
  916. package/dist/modes/rpc/rpc-event-buffer.d.ts.map +1 -1
  917. package/dist/modes/rpc/rpc-event-buffer.js +10 -5
  918. package/dist/modes/rpc/rpc-event-buffer.js.map +1 -1
  919. package/dist/modes/rpc/rpc-extension-ui.d.ts.map +1 -1
  920. package/dist/modes/rpc/rpc-extension-ui.js +3 -0
  921. package/dist/modes/rpc/rpc-extension-ui.js.map +1 -1
  922. package/dist/modes/rpc/rpc-input.js +1 -1
  923. package/dist/modes/rpc/rpc-input.js.map +1 -1
  924. package/dist/modes/rpc/rpc-output-buffer.d.ts +9 -0
  925. package/dist/modes/rpc/rpc-output-buffer.d.ts.map +1 -1
  926. package/dist/modes/rpc/rpc-output-buffer.js +10 -5
  927. package/dist/modes/rpc/rpc-output-buffer.js.map +1 -1
  928. package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
  929. package/dist/modes/rpc/rpc-provider-auth.js +3 -0
  930. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  931. package/dist/modes/rpc/rpc-responses.d.ts +1 -1
  932. package/dist/modes/rpc/rpc-responses.d.ts.map +1 -1
  933. package/dist/modes/rpc/rpc-responses.js +13 -1
  934. package/dist/modes/rpc/rpc-responses.js.map +1 -1
  935. package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
  936. package/dist/modes/rpc/rpc-session-binding.js +2 -1
  937. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  938. package/dist/modes/rpc/rpc-types.d.ts +9 -2
  939. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  940. package/dist/modes/rpc/rpc-types.js.map +1 -1
  941. package/dist/rpc-entry.js +2 -0
  942. package/dist/rpc-entry.js.map +1 -1
  943. package/dist/self-update-plan.d.ts.map +1 -1
  944. package/dist/self-update-plan.js +5 -4
  945. package/dist/self-update-plan.js.map +1 -1
  946. package/dist/server/create-harness.d.ts +53 -0
  947. package/dist/server/create-harness.d.ts.map +1 -0
  948. package/dist/server/create-harness.js +349 -0
  949. package/dist/server/create-harness.js.map +1 -0
  950. package/dist/utils/agent-attribution.d.ts +2 -0
  951. package/dist/utils/agent-attribution.d.ts.map +1 -0
  952. package/dist/utils/agent-attribution.js +2 -0
  953. package/dist/utils/agent-attribution.js.map +1 -0
  954. package/dist/utils/child-process.d.ts +3 -1
  955. package/dist/utils/child-process.d.ts.map +1 -1
  956. package/dist/utils/child-process.js +24 -4
  957. package/dist/utils/child-process.js.map +1 -1
  958. package/dist/utils/clipboard-image.d.ts.map +1 -1
  959. package/dist/utils/clipboard-image.js +2 -1
  960. package/dist/utils/clipboard-image.js.map +1 -1
  961. package/dist/utils/clipboard.d.ts.map +1 -1
  962. package/dist/utils/clipboard.js +12 -3
  963. package/dist/utils/clipboard.js.map +1 -1
  964. package/dist/utils/management-http.d.ts +23 -0
  965. package/dist/utils/management-http.d.ts.map +1 -0
  966. package/dist/utils/management-http.js +50 -0
  967. package/dist/utils/management-http.js.map +1 -0
  968. package/dist/utils/open-browser.d.ts.map +1 -1
  969. package/dist/utils/open-browser.js +2 -1
  970. package/dist/utils/open-browser.js.map +1 -1
  971. package/dist/utils/paths.d.ts +2 -0
  972. package/dist/utils/paths.d.ts.map +1 -1
  973. package/dist/utils/paths.js +13 -0
  974. package/dist/utils/paths.js.map +1 -1
  975. package/dist/utils/shell.d.ts.map +1 -1
  976. package/dist/utils/shell.js +17 -4
  977. package/dist/utils/shell.js.map +1 -1
  978. package/dist/utils/tool-result-images.d.ts +17 -0
  979. package/dist/utils/tool-result-images.d.ts.map +1 -0
  980. package/dist/utils/tool-result-images.js +41 -0
  981. package/dist/utils/tool-result-images.js.map +1 -0
  982. package/dist/utils/tools-manager.d.ts.map +1 -1
  983. package/dist/utils/tools-manager.js +7 -8
  984. package/dist/utils/tools-manager.js.map +1 -1
  985. package/dist/utils/version-check.d.ts +4 -0
  986. package/dist/utils/version-check.d.ts.map +1 -1
  987. package/dist/utils/version-check.js +20 -2
  988. package/dist/utils/version-check.js.map +1 -1
  989. package/docs/compaction.md +2 -1
  990. package/docs/custom-provider.md +15 -7
  991. package/docs/development.md +1 -0
  992. package/docs/docs.json +1 -0
  993. package/docs/environment-variables.md +4 -0
  994. package/docs/extensions.md +102 -18
  995. package/docs/i-have-adhd.md +36 -0
  996. package/docs/intercom.md +26 -6
  997. package/docs/json.md +2 -2
  998. package/docs/keybindings.md +55 -12
  999. package/docs/models/model-selection.md +34 -8
  1000. package/docs/models.md +28 -3
  1001. package/docs/providers.md +20 -2
  1002. package/docs/quickstart.md +5 -5
  1003. package/docs/rpc.md +18 -12
  1004. package/docs/sdk.md +43 -7
  1005. package/docs/security.md +10 -10
  1006. package/docs/sessions.md +2 -0
  1007. package/docs/settings.md +25 -5
  1008. package/docs/subagents.md +15 -30
  1009. package/docs/themes.md +5 -3
  1010. package/docs/tools.md +21 -1
  1011. package/docs/tui.md +41 -24
  1012. package/docs/usage.md +40 -14
  1013. package/docs/windows.md +2 -0
  1014. package/docs/workflows.md +216 -20
  1015. package/examples/extensions/custom-provider-anthropic/index.ts +9 -2
  1016. package/examples/extensions/custom-provider-gitlab-duo/index.ts +9 -2
  1017. package/examples/extensions/modal-editor.ts +8 -10
  1018. package/examples/extensions/rainbow-editor.ts +3 -2
  1019. package/examples/extensions/subagent/README.md +16 -45
  1020. package/examples/extensions/subagent/index.ts +6 -96
  1021. package/examples/extensions/subagent/render.ts +0 -78
  1022. package/examples/extensions/subagent/runner.ts +0 -3
  1023. package/examples/extensions/subagent/schemas.ts +0 -13
  1024. package/examples/extensions/subagent/types.ts +1 -2
  1025. package/examples/sdk/09-api-keys-and-oauth.ts +6 -2
  1026. package/examples/sdk/12-full-control.ts +8 -2
  1027. package/examples/sdk/README.md +4 -1
  1028. package/npm-shrinkwrap.json +191 -634
  1029. package/package.json +14 -7
  1030. package/dist/builtin/subagents/src/agents/chain-serializer.ts +0 -257
  1031. package/dist/builtin/subagents/src/runs/foreground/chain-execution-details.ts +0 -38
  1032. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +0 -280
  1033. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +0 -217
  1034. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +0 -271
  1035. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +0 -271
  1036. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +0 -200
  1037. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +0 -184
  1038. package/dist/builtin/subagents/src/runs/foreground/execution-structured-retries.ts +0 -19
  1039. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +0 -109
  1040. package/dist/builtin/subagents/src/runs/shared/chain-outputs.ts +0 -126
  1041. package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +0 -393
  1042. package/dist/builtin/subagents/src/runs/shared/structured-output.ts +0 -150
  1043. package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +0 -232
  1044. package/dist/builtin/subagents/src/slash/saved-chain-mapping.ts +0 -60
  1045. package/dist/builtin/subagents/src/tui/render-chain-graph.ts +0 -341
  1046. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  1047. package/examples/extensions/subagent/prompts/implement.md +0 -10
  1048. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -35556,6 +35556,7 @@ Defaulting to 2020, but this will stop working in the future.`)), t3.ecmaVersion
35556
35556
  });
35557
35557
 
35558
35558
  // dist/builtin/workflows/src/intercom/intercom-routing.ts
35559
+ import { isStaleExtensionContextError } from "@bastani/atomic";
35559
35560
  function toNoticeLevel(raw) {
35560
35561
  if (raw === "warning" || raw === "error")
35561
35562
  return raw;
@@ -35579,12 +35580,17 @@ function buildIntercomCallbacks(deps) {
35579
35580
  requiresAck: true
35580
35581
  });
35581
35582
  const accepted = typeof confirm === "function" ? await confirm("Subagent needs decision", payload.message).catch(() => false) : false;
35582
- emit?.("subagent:control-intercom:response", {
35583
- requestId: payload.requestId ?? "",
35584
- runId: payload.runId ?? "",
35585
- stageId: payload.stageId ?? "",
35586
- accepted
35587
- });
35583
+ try {
35584
+ emit?.("subagent:control-intercom:response", {
35585
+ requestId: payload.requestId ?? "",
35586
+ runId: payload.runId ?? "",
35587
+ stageId: payload.stageId ?? "",
35588
+ accepted
35589
+ });
35590
+ } catch (error) {
35591
+ if (!isStaleExtensionContextError(error))
35592
+ throw error;
35593
+ }
35588
35594
  store.ackNotice(noticeId);
35589
35595
  },
35590
35596
  onNotify(payload) {
@@ -35611,6 +35617,7 @@ function buildIntercomCallbacks(deps) {
35611
35617
  }
35612
35618
 
35613
35619
  // dist/builtin/workflows/src/intercom/result-intercom.ts
35620
+ import { isStaleExtensionContextError as isStaleExtensionContextError2 } from "@bastani/atomic";
35614
35621
  function subscribeIntercomControl(pi, callbacks) {
35615
35622
  if (typeof pi.events?.on !== "function")
35616
35623
  return null;
@@ -35635,11 +35642,23 @@ function subscribeIntercomControl(pi, callbacks) {
35635
35642
  Promise.reject(new Error(`atomic-workflows: intercom callback error (type=${payload.type}): ${err instanceof Error ? err.message : String(err)}`));
35636
35643
  });
35637
35644
  };
35638
- const unsubscribe = pi.events.on("subagent:control-intercom", handler);
35645
+ let unsubscribe;
35646
+ try {
35647
+ unsubscribe = pi.events.on("subagent:control-intercom", handler);
35648
+ } catch (error) {
35649
+ if (!isStaleExtensionContextError2(error))
35650
+ throw error;
35651
+ return null;
35652
+ }
35639
35653
  return () => {
35640
35654
  active = false;
35641
- if (typeof unsubscribe === "function")
35642
- unsubscribe();
35655
+ try {
35656
+ if (typeof unsubscribe === "function")
35657
+ unsubscribe();
35658
+ } catch (error) {
35659
+ if (!isStaleExtensionContextError2(error))
35660
+ throw error;
35661
+ }
35643
35662
  };
35644
35663
  }
35645
35664
 
@@ -35650,6 +35669,7 @@ function flattenTruncatedString(value2) {
35650
35669
 
35651
35670
  // dist/builtin/workflows/src/shared/graph-store-snapshot.ts
35652
35671
  var COMPACT_RESULT_FIELD_LIMIT = 1024;
35672
+ var COMPACT_EXIT_OUTPUT_LIMIT = COMPACT_RESULT_FIELD_LIMIT * 4;
35653
35673
  function compactResultField(value2) {
35654
35674
  if (typeof value2 !== "string")
35655
35675
  return;
@@ -35657,7 +35677,7 @@ function compactResultField(value2) {
35657
35677
  return value2;
35658
35678
  return flattenTruncatedString(value2.slice(0, COMPACT_RESULT_FIELD_LIMIT));
35659
35679
  }
35660
- function compactRunResult(result) {
35680
+ function compactRunResult(result, preserveExitedOutputs = false) {
35661
35681
  if (result === undefined)
35662
35682
  return;
35663
35683
  const status = compactResultField(result.status);
@@ -35670,8 +35690,31 @@ function compactRunResult(result) {
35670
35690
  ...remainingWork !== undefined ? { remaining_work: remainingWork } : {},
35671
35691
  ...resultText !== undefined ? { result: resultText } : {}
35672
35692
  };
35693
+ if (!preserveExitedOutputs)
35694
+ return Object.keys(compact).length === 0 ? undefined : compact;
35695
+ return compactExitedOutputs(result, compact);
35696
+ }
35697
+ function compactExitedOutputs(result, compact) {
35698
+ try {
35699
+ const serialized = JSON.stringify(result);
35700
+ if (serialized !== undefined && serialized.length <= COMPACT_EXIT_OUTPUT_LIMIT) {
35701
+ const parsed = JSON.parse(serialized);
35702
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
35703
+ return compactExitedObject(parsed);
35704
+ }
35705
+ }
35706
+ } catch {}
35673
35707
  return Object.keys(compact).length === 0 ? undefined : compact;
35674
35708
  }
35709
+ function compactExitedObject(result) {
35710
+ const compacted = { ...result };
35711
+ for (const key of ["status", "summary", "remaining_work", "result"]) {
35712
+ const value2 = compacted[key];
35713
+ if (typeof value2 === "string")
35714
+ compacted[key] = compactResultField(value2) ?? "";
35715
+ }
35716
+ return Object.keys(compacted).length === 0 ? undefined : compacted;
35717
+ }
35675
35718
  function clonePrompt(prompt) {
35676
35719
  return {
35677
35720
  ...prompt,
@@ -35730,7 +35773,7 @@ function compactToolNode(node) {
35730
35773
  }
35731
35774
  function compactRun(run) {
35732
35775
  const { inputs: _inputs, result: sourceResult, stages, toolNodes, pendingPrompt, ...metadata } = run;
35733
- const result = compactRunResult(sourceResult);
35776
+ const result = compactRunResult(sourceResult, run.exited === true && run.status === "failed");
35734
35777
  return {
35735
35778
  ...metadata,
35736
35779
  inputs: {},
@@ -37296,10 +37339,14 @@ function renderInputsSegment(inputs, budget, theme) {
37296
37339
  fitted: false
37297
37340
  };
37298
37341
  }
37342
+ var ROW_BREAKING_RE = /[\p{Cc}\u2028\u2029]+/gu;
37343
+ function toSingleLine(value2) {
37344
+ return value2.replace(ROW_BREAKING_RE, " ");
37345
+ }
37299
37346
  function renderInputValue(value2, budget) {
37300
37347
  if (typeof value2 === "string") {
37301
37348
  const interior = Math.max(0, budget - 2);
37302
- const trimmed = truncateToWidth(value2, interior, ELLIPSIS);
37349
+ const trimmed = truncateToWidth(toSingleLine(value2), interior, ELLIPSIS);
37303
37350
  return `"${trimmed}"`;
37304
37351
  }
37305
37352
  if (typeof value2 === "number" || typeof value2 === "boolean") {
@@ -37308,7 +37355,7 @@ function renderInputValue(value2, budget) {
37308
37355
  if (value2 === null)
37309
37356
  return "null";
37310
37357
  const json = JSON.stringify(value2);
37311
- return truncateToWidth(json ?? "", budget, ELLIPSIS);
37358
+ return truncateToWidth(toSingleLine(json ?? ""), budget, ELLIPSIS);
37312
37359
  }
37313
37360
  function effectiveWidth(width) {
37314
37361
  return chatWidth(width);
@@ -37961,6 +38008,8 @@ function runCardMeta(run, now) {
37961
38008
  return parts.join(" · ");
37962
38009
  }
37963
38010
  if (effectiveRunStatus(run) === "failed" || effectiveRunStatus(run) === "killed") {
38011
+ if (run.exitReason !== undefined && run.exitReason.length > 0 && run.exited === true)
38012
+ parts.push(run.exitReason);
37964
38013
  const failed = run.stages.find((s) => s.status === "failed");
37965
38014
  if (failed && isChain)
37966
38015
  parts.push(`failed at ${failed.name}`);
@@ -38526,6 +38575,9 @@ function deriveGraphThemeFromPiTheme(theme) {
38526
38575
  return deriveGraphTheme(cleaned);
38527
38576
  }
38528
38577
 
38578
+ // dist/builtin/workflows/src/tui/inline-form-overlay.ts
38579
+ import { isStaleExtensionContextError as isStaleExtensionContextError3 } from "@bastani/atomic";
38580
+
38529
38581
  // dist/builtin/workflows/src/tui/header.ts
38530
38582
  function pillFor(run, theme) {
38531
38583
  if (run.status === "failed")
@@ -38887,7 +38939,8 @@ function computeInvalid(fields, raw) {
38887
38939
 
38888
38940
  // dist/builtin/workflows/src/tui/keybindings-adapter.ts
38889
38941
  var APP_ACTION = {
38890
- toolsExpand: "app.tools.expand"
38942
+ toolsExpand: "app.tools.expand",
38943
+ thinkingToggle: "app.thinking.toggle"
38891
38944
  };
38892
38945
  var TUI_ACTION = {
38893
38946
  editorCursorUp: "tui.editor.cursorUp",
@@ -38958,6 +39011,30 @@ function deleteRange(text, start, end, caret) {
38958
39011
  }
38959
39012
 
38960
39013
  // dist/builtin/workflows/src/tui/inputs-picker-input.ts
39014
+ function isInputsPickerKey(key, state, fields, keybindings) {
39015
+ if (fields.length === 0)
39016
+ return isCancelKey(key);
39017
+ if (isCancelKey(key) || matchesKey(key, Key.tab) || matchesKey(key, Key.shift("tab")))
39018
+ return true;
39019
+ if (state.focusedIdx === fields.length) {
39020
+ return matchesAction(keybindings, key, TUI_ACTION.selectUp) || matchesAction(keybindings, key, TUI_ACTION.selectDown) || matchesAction(keybindings, key, TUI_ACTION.editorCursorUp) || matchesAction(keybindings, key, TUI_ACTION.editorCursorDown) || matchesKey(key, Key.enter) || matchesAction(keybindings, key, TUI_ACTION.selectConfirm) || matchesAction(keybindings, key, TUI_ACTION.inputSubmit);
39021
+ }
39022
+ const field = fields[state.focusedIdx];
39023
+ if (!field)
39024
+ return false;
39025
+ if (field.type === "select") {
39026
+ if ((field.choices ?? []).length === 0)
39027
+ return false;
39028
+ return matchesAction(keybindings, key, TUI_ACTION.selectUp) || matchesAction(keybindings, key, TUI_ACTION.selectDown) || matchesAction(keybindings, key, TUI_ACTION.editorCursorLeft) || matchesAction(keybindings, key, TUI_ACTION.editorCursorRight) || matchesAction(keybindings, key, TUI_ACTION.selectConfirm) || matchesAction(keybindings, key, TUI_ACTION.inputSubmit);
39029
+ }
39030
+ if (field.type === "boolean") {
39031
+ return matchesKey(key, Key.space) || matchesAction(keybindings, key, TUI_ACTION.selectUp) || matchesAction(keybindings, key, TUI_ACTION.selectDown) || matchesAction(keybindings, key, TUI_ACTION.editorCursorLeft) || matchesAction(keybindings, key, TUI_ACTION.editorCursorRight) || matchesAction(keybindings, key, TUI_ACTION.selectConfirm) || matchesAction(keybindings, key, TUI_ACTION.inputSubmit);
39032
+ }
39033
+ if (matchesAction(keybindings, key, TUI_ACTION.editorCursorUp) || matchesAction(keybindings, key, TUI_ACTION.editorCursorDown) || matchesAction(keybindings, key, "tui.editor.cursorWordLeft") || matchesAction(keybindings, key, "tui.editor.cursorWordRight") || matchesAction(keybindings, key, "tui.editor.cursorLineStart") || matchesAction(keybindings, key, "tui.editor.cursorLineEnd") || matchesAction(keybindings, key, TUI_ACTION.editorCursorLeft) || matchesAction(keybindings, key, TUI_ACTION.editorCursorRight) || matchesAction(keybindings, key, "tui.editor.deleteWordBackward") || matchesAction(keybindings, key, "tui.editor.deleteWordForward") || matchesAction(keybindings, key, "tui.editor.deleteToLineStart") || matchesAction(keybindings, key, "tui.editor.deleteToLineEnd") || matchesAction(keybindings, key, "tui.editor.deleteCharBackward") || matchesAction(keybindings, key, "tui.editor.deleteCharForward") || matchesAction(keybindings, key, TUI_ACTION.inputSubmit) || matchesAction(keybindings, key, "tui.input.newLine")) {
39034
+ return true;
39035
+ }
39036
+ return isPrintableGrapheme(decodePrintableKey(key) ?? key);
39037
+ }
38961
39038
  function handleInputsPickerInput(key, state, fields, keybindings) {
38962
39039
  if (fields.length === 0) {
38963
39040
  if (isCancelKey(key))
@@ -39855,7 +39932,7 @@ class InlineFormEditor {
39855
39932
  handleInput(data) {
39856
39933
  const state = getForm(this.opts.formId);
39857
39934
  if (state?.status !== "editing")
39858
- return;
39935
+ return false;
39859
39936
  if (data.includes(PASTE_START)) {
39860
39937
  this.isInPaste = true;
39861
39938
  this.pasteBuffer = "";
@@ -39865,7 +39942,7 @@ class InlineFormEditor {
39865
39942
  this.pasteBuffer += data;
39866
39943
  const endIdx = this.pasteBuffer.indexOf(PASTE_END);
39867
39944
  if (endIdx === -1)
39868
- return;
39945
+ return true;
39869
39946
  const content = this.pasteBuffer.slice(0, endIdx);
39870
39947
  const remaining = this.pasteBuffer.slice(endIdx + PASTE_END.length);
39871
39948
  this.isInPaste = false;
@@ -39876,20 +39953,22 @@ class InlineFormEditor {
39876
39953
  }
39877
39954
  if (remaining.length > 0)
39878
39955
  this.handleInput(remaining);
39879
- return;
39956
+ return true;
39880
39957
  }
39881
39958
  if (data.length > 1 && isPrintableTextChunk(data)) {
39882
- if (this.applyPaste(data, state)) {
39959
+ const consumed2 = this.applyPaste(data, state);
39960
+ if (consumed2) {
39883
39961
  touch(state);
39884
39962
  this.tui.requestRender?.();
39885
39963
  }
39886
- return;
39964
+ return consumed2;
39887
39965
  }
39888
39966
  const consumed = this.routeKey(data, state);
39889
39967
  if (consumed) {
39890
39968
  touch(state);
39891
39969
  this.tui.requestRender?.();
39892
39970
  }
39971
+ return consumed;
39893
39972
  }
39894
39973
  applyPaste(content, state) {
39895
39974
  const field = state.fields[state.focusedIdx];
@@ -40209,7 +40288,7 @@ async function openInlineInputsForm(pi, ctx, opts) {
40209
40288
  try {
40210
40289
  return getEditor.call(ctx.ui) === installedFactory;
40211
40290
  } catch (err) {
40212
- if (err instanceof Error && err.message.includes("This extension ctx is stale")) {
40291
+ if (isStaleExtensionContextError3(err)) {
40213
40292
  return false;
40214
40293
  }
40215
40294
  return true;
@@ -40505,15 +40584,8 @@ function subscribeStoreInvalidation(store2, listener) {
40505
40584
  }
40506
40585
 
40507
40586
  // dist/builtin/workflows/src/tui/overlay-terminal-modes.ts
40508
- var MOUSE_SCROLL_TRACKING_ON = "\x1B[?1000h\x1B[?1002h\x1B[?1006h";
40509
- var MOUSE_SCROLL_TRACKING_OFF = "\x1B[?1006l\x1B[?1002l\x1B[?1000l";
40510
40587
  var TERMINAL_AUTOWRAP_ON = "\x1B[?7h";
40511
40588
  var TERMINAL_AUTOWRAP_OFF = "\x1B[?7l";
40512
- function setMouseScrollTracking(enabled, output) {
40513
- if (!output.isTTY)
40514
- return;
40515
- output.write(enabled ? MOUSE_SCROLL_TRACKING_ON : MOUSE_SCROLL_TRACKING_OFF);
40516
- }
40517
40589
  function setTerminalAutowrap(enabled, output) {
40518
40590
  if (output.platform !== "win32" || !output.isTTY)
40519
40591
  return;
@@ -40521,13 +40593,9 @@ function setTerminalAutowrap(enabled, output) {
40521
40593
  }
40522
40594
  function remoteTerminalControlFrom(tui) {
40523
40595
  const terminal = tui.terminal;
40524
- if (terminal === undefined || typeof terminal.setMouseScrollTracking !== "function" || typeof terminal.setAutowrap !== "function") {
40596
+ if (terminal === undefined || typeof terminal.setAutowrap !== "function")
40525
40597
  return null;
40526
- }
40527
- return {
40528
- setMouseScrollTracking: terminal.setMouseScrollTracking.bind(terminal),
40529
- setAutowrap: terminal.setAutowrap.bind(terminal)
40530
- };
40598
+ return { setAutowrap: terminal.setAutowrap.bind(terminal) };
40531
40599
  }
40532
40600
 
40533
40601
  // dist/builtin/workflows/src/runs/foreground/stage-queued-user-messages.ts
@@ -40957,12 +41025,9 @@ var COMPACT_HINT_KEYS = [
40957
41025
  { key: "↵", label: "stage chat" }
40958
41026
  ];
40959
41027
  var MODE_PILL_LABEL = "GRAPH";
40960
- var OVERLAY_LINE_COUNT = 32;
40961
- var OVERLAY_VERTICAL_MARGIN_ROWS = 1;
40962
41028
  var ANIMATION_TICK_MS = 100;
40963
41029
  var PULSE_PERIOD_MS = 2000;
40964
41030
  var GRAPH_SCROLL_STEP_COLS = 4;
40965
- var GRAPH_SCROLL_STEP_ROWS = 4;
40966
41031
 
40967
41032
  // dist/builtin/workflows/src/tui/graph-canvas.ts
40968
41033
  function dirsForGlyph(ch) {
@@ -42016,7 +42081,7 @@ class GraphViewState {
42016
42081
  onDetach;
42017
42082
  initialFocusedStageId;
42018
42083
  initialFocusedRunId;
42019
- getViewportRows;
42084
+ piTui;
42020
42085
  requestRender;
42021
42086
  piKeybindings;
42022
42087
  footerData;
@@ -42036,12 +42101,11 @@ class GraphViewState {
42036
42101
  targets: new Map
42037
42102
  };
42038
42103
  currentSnapshot = null;
42039
- graphScrollOffset = 0;
42040
42104
  graphScrollColOffset = 0;
42041
42105
  graphNodeHitRects = [];
42042
42106
  lastGraphViewport = null;
42043
- lastGraphTotalRows = 0;
42044
- lastOverlayFrameWidth = 80;
42107
+ lastGraphTopPad = 0;
42108
+ lastGraphVisibleRows = 0;
42045
42109
  pendingEnsureFocusedVisible = true;
42046
42110
  lastAutoFocusedAwaitingInputKey = null;
42047
42111
  lastBuiltSnapshotVersion = null;
@@ -42063,7 +42127,7 @@ class GraphViewState {
42063
42127
  this.onDetach = opts.onDetach;
42064
42128
  this.initialFocusedStageId = opts.initialFocusedStageId;
42065
42129
  this.initialFocusedRunId = opts.initialFocusedRunId;
42066
- this.getViewportRows = opts.getViewportRows;
42130
+ this.piTui = opts.piTui;
42067
42131
  this.requestRender = opts.requestRender;
42068
42132
  this.piKeybindings = opts.piKeybindings;
42069
42133
  this.footerData = opts.footerData;
@@ -42098,7 +42162,6 @@ class GraphViewState {
42098
42162
  this.cachedRenderGeometry = { canvasWidth: 0, totalRows: 0, bands: [], edges: [] };
42099
42163
  this.expandedGraph = { stages: [], renderStages: [], tools: [], nodes: [], targets: new Map };
42100
42164
  this.focusedIndex = 0;
42101
- this.graphScrollOffset = 0;
42102
42165
  this.graphScrollColOffset = 0;
42103
42166
  this.graphNodeHitRects = [];
42104
42167
  this.lastGraphViewport = null;
@@ -42230,7 +42293,6 @@ class GraphViewState {
42230
42293
  }
42231
42294
  if (this.cachedLayout.length === 0) {
42232
42295
  this.focusedIndex = 0;
42233
- this.graphScrollOffset = 0;
42234
42296
  this.graphScrollColOffset = 0;
42235
42297
  } else if (this.focusedIndex >= this.cachedLayout.length) {
42236
42298
  this.focusedIndex = this.cachedLayout.length - 1;
@@ -42373,48 +42435,10 @@ class GraphViewState {
42373
42435
 
42374
42436
  // dist/builtin/workflows/src/tui/workflow-status.ts
42375
42437
  var WORKFLOW_STATUS_KEY = "pi-workflows";
42376
- var OVERLAY_HIDDEN_STATUS_KEYS = new Set(["mcp"]);
42438
+ var OVERLAY_HIDDEN_STATUS_KEYS = new Set(["mcp", "i-have-adhd"]);
42377
42439
 
42378
42440
  // dist/builtin/workflows/src/tui/graph-view-render-helpers.ts
42379
42441
  class GraphViewRenderHelpers extends GraphViewState {
42380
- _overlayLineCount() {
42381
- const reported = this.getViewportRows?.();
42382
- if (typeof reported !== "number" || !Number.isFinite(reported)) {
42383
- return OVERLAY_LINE_COUNT;
42384
- }
42385
- return Math.max(7, Math.floor(reported));
42386
- }
42387
- _overlayBodyRows(lineCount) {
42388
- return Math.max(1, lineCount - 3 - 3);
42389
- }
42390
- _overlayVerticalMarginRows(lineCount = this._overlayLineCount()) {
42391
- return lineCount >= 9 ? OVERLAY_VERTICAL_MARGIN_ROWS : 0;
42392
- }
42393
- _overlayPanelLineCount() {
42394
- const lineCount = this._overlayLineCount();
42395
- const margins = this._overlayVerticalMarginRows(lineCount) * 2;
42396
- return Math.max(7, lineCount - margins);
42397
- }
42398
- _marginRow(width) {
42399
- return " ".repeat(width);
42400
- }
42401
- _withVerticalMargins(panelLines, width) {
42402
- const expected = this._overlayLineCount();
42403
- const marginRows = this._overlayVerticalMarginRows(expected);
42404
- const panelTarget = this._overlayPanelLineCount();
42405
- const body = panelLines.slice(0, panelTarget);
42406
- while (body.length < panelTarget)
42407
- body.push(this._blankRow(width));
42408
- const margins = Array.from({ length: marginRows }, () => this._marginRow(width));
42409
- const lines = [...margins, ...body, ...margins];
42410
- if (lines.length > expected)
42411
- return lines.slice(0, expected);
42412
- while (lines.length < expected) {
42413
- const insertAt = marginRows > 0 ? Math.max(0, lines.length - marginRows) : lines.length;
42414
- lines.splice(insertAt, 0, this._blankRow(width));
42415
- }
42416
- return lines;
42417
- }
42418
42442
  _externalStatusText() {
42419
42443
  const entries = Array.from(this.footerData?.getExtensionStatuses() ?? []).filter(([key, value2]) => value2.trim().length > 0 && key !== WORKFLOW_STATUS_KEY && !key.startsWith(`${WORKFLOW_STATUS_KEY}:`) && !OVERLAY_HIDDEN_STATUS_KEYS.has(key)).sort(([a], [b]) => a.localeCompare(b));
42420
42444
  if (entries.length === 0)
@@ -42477,10 +42501,6 @@ class GraphViewRenderHelpers extends GraphViewState {
42477
42501
  const rightPadLen = Math.max(0, totalWidth - leftPad - cardW);
42478
42502
  return `${bg}${" ".repeat(leftPad)}${RESET}${cardLine}${bg}${" ".repeat(rightPadLen)}${RESET}`;
42479
42503
  }
42480
- _clampGraphScroll(totalRows, bodyRows) {
42481
- const maxOffset = Math.max(0, totalRows - bodyRows);
42482
- this.graphScrollOffset = Math.max(0, Math.min(maxOffset, this.graphScrollOffset));
42483
- }
42484
42504
  _clampGraphHorizontalScroll(totalCols, viewportCols) {
42485
42505
  const maxOffset = Math.max(0, totalCols - viewportCols);
42486
42506
  this.graphScrollColOffset = Math.max(0, Math.min(maxOffset, this.graphScrollColOffset));
@@ -42498,23 +42518,6 @@ class GraphViewRenderHelpers extends GraphViewState {
42498
42518
  }
42499
42519
  this._clampGraphHorizontalScroll(totalCols, viewportCols);
42500
42520
  }
42501
- _scrollFocusedIntoView(frameWidth, bodyRows, totalRows) {
42502
- const range = this._focusedGraphRowRange(frameWidth);
42503
- if (!range)
42504
- return;
42505
- if (range.start < this.graphScrollOffset) {
42506
- this.graphScrollOffset = range.start;
42507
- } else if (range.end >= this.graphScrollOffset + bodyRows) {
42508
- this.graphScrollOffset = range.end - bodyRows + 1;
42509
- }
42510
- this._clampGraphScroll(totalRows, bodyRows);
42511
- }
42512
- _focusedGraphRowRange(_frameWidth) {
42513
- const node = this.cachedLayout[this.focusedIndex];
42514
- if (!node)
42515
- return null;
42516
- return { start: node.y, end: node.y + NODE_H - 1 };
42517
- }
42518
42521
  _plotEdge(canvas, px, py, cx, cy, color) {
42519
42522
  const parentCol = px + Math.floor(NODE_W / 2);
42520
42523
  const childCol = cx + Math.floor(NODE_W / 2);
@@ -42649,7 +42652,7 @@ function metaText(stage) {
42649
42652
  return "topology unavailable";
42650
42653
  const deps = stage.parentIds.length;
42651
42654
  const dependencyText = deps === 0 ? "root" : deps === 1 ? "1 dep" : `${deps} deps`;
42652
- return stage.fastMode === true ? `${dependencyText} · fast` : dependencyText;
42655
+ return dependencyText;
42653
42656
  }
42654
42657
  function workflowChildRunRows(stage, width) {
42655
42658
  const child = stage.workflowChild ?? stage.workflowChildRun;
@@ -42767,56 +42770,53 @@ function renderNodeCard(stage, opts) {
42767
42770
 
42768
42771
  // dist/builtin/workflows/src/tui/graph-view-graph-render.ts
42769
42772
  class GraphViewGraphRenderer extends GraphViewRenderHelpers {
42770
- _renderGraph(width) {
42771
- const run = this._getCurrentRun();
42773
+ _renderGraph(width, viewportTop, viewportRows, renderRun) {
42774
+ const safeRows = Math.max(0, Math.floor(viewportRows));
42775
+ const run = renderRun !== undefined ? renderRun : this._getCurrentRun();
42772
42776
  if (!run || this.cachedLayout.length === 0) {
42773
42777
  this.lastGraphViewport = null;
42774
42778
  this.graphNodeHitRects = [];
42775
- this.lastGraphTotalRows = 1;
42776
- const dim = hexToAnsi(this.graphTheme.dim);
42777
- return [this._centerCanvasContent(`${dim}waiting for stage events…${RESET}`, width)];
42779
+ this.lastGraphTopPad = 0;
42780
+ this.lastGraphVisibleRows = safeRows;
42781
+ const lines = Array.from({ length: safeRows }, () => "");
42782
+ if (safeRows > 0) {
42783
+ const dim = hexToAnsi(this.graphTheme.dim);
42784
+ lines[Math.floor((safeRows - 1) / 2)] = this._centerCanvasContent(`${dim}waiting for stage events…${RESET}`, width);
42785
+ }
42786
+ return lines;
42778
42787
  }
42779
42788
  const graphInner = Math.max(1, width - 4);
42780
42789
  const { canvasWidth, totalRows, bands, edges } = this.cachedRenderGeometry;
42781
- this.lastGraphTotalRows = totalRows;
42782
42790
  const leftMargin = Math.max(2, canvasWidth <= graphInner ? Math.floor((graphInner - canvasWidth) / 2) : 2);
42783
42791
  const viewportWidth = Math.max(1, width - leftMargin);
42784
42792
  const fullCanvasWidth = Math.max(canvasWidth, viewportWidth);
42785
42793
  this.lastGraphViewport = { leftMargin, viewportWidth };
42794
+ const safeTop = Math.max(0, Math.min(totalRows, Math.floor(viewportTop)));
42795
+ const graphRows = Math.max(0, Math.min(safeRows, totalRows - safeTop));
42796
+ const viewportBottom = safeTop + graphRows;
42786
42797
  this._clampGraphHorizontalScroll(fullCanvasWidth, viewportWidth);
42787
- if (this.pendingEnsureFocusedVisible) {
42788
- this._scrollFocusedColumnIntoView(viewportWidth, fullCanvasWidth);
42789
- }
42790
- const bodyRows = this._overlayBodyRows(this._overlayPanelLineCount());
42791
- if (totalRows > bodyRows) {
42792
- this._clampGraphScroll(totalRows, bodyRows);
42793
- if (this.pendingEnsureFocusedVisible)
42794
- this._scrollFocusedIntoView(width, bodyRows, totalRows);
42795
- this._clampGraphScroll(totalRows, bodyRows);
42796
- } else {
42797
- this.graphScrollOffset = 0;
42798
- }
42799
- const viewportTop = this.graphScrollOffset;
42800
- const viewportBottom = Math.min(totalRows, viewportTop + bodyRows);
42798
+ const topPad = safeTop === 0 && totalRows <= safeRows ? Math.min(3, Math.floor((safeRows - totalRows) / 2)) : 0;
42799
+ this.lastGraphTopPad = topPad;
42800
+ this.lastGraphVisibleRows = graphRows;
42801
42801
  const viewportLeft = this.graphScrollColOffset;
42802
42802
  const viewportRight = viewportLeft + viewportWidth;
42803
42803
  const pulsePhase = Date.now() % PULSE_PERIOD_MS / PULSE_PERIOD_MS;
42804
42804
  const edgeCanvas = new GraphCanvas({
42805
- top: viewportTop,
42805
+ top: safeTop,
42806
42806
  bottom: viewportBottom,
42807
42807
  left: viewportLeft,
42808
42808
  right: viewportRight
42809
42809
  });
42810
42810
  const edgeColor = this.graphTheme.borderDim;
42811
42811
  for (const edge of edges) {
42812
- if (edge.bottom <= viewportTop || edge.top >= viewportBottom || edge.right <= viewportLeft || edge.left >= viewportRight) {
42812
+ if (edge.bottom <= safeTop || edge.top >= viewportBottom || edge.right <= viewportLeft || edge.left >= viewportRight) {
42813
42813
  continue;
42814
42814
  }
42815
42815
  this._plotEdge(edgeCanvas, edge.parentX, edge.parentY, edge.childX, edge.childY, edgeColor);
42816
42816
  }
42817
42817
  const edgeLines = edgeCanvas.toLines();
42818
42818
  const placements = new Map;
42819
- for (let bandIndex = this._firstVisibleLayoutBand(viewportTop);bandIndex < bands.length; bandIndex++) {
42819
+ for (let bandIndex = this._firstVisibleLayoutBand(safeTop);bandIndex < bands.length; bandIndex++) {
42820
42820
  const band = bands[bandIndex];
42821
42821
  if (band.top >= viewportBottom)
42822
42822
  break;
@@ -42837,9 +42837,9 @@ class GraphViewGraphRenderer extends GraphViewRenderHelpers {
42837
42837
  const visibleRight = Math.min(node.x + NODE_W, viewportRight);
42838
42838
  for (let li = 0;li < cardLines.length; li++) {
42839
42839
  const globalRow = node.y + li;
42840
- if (globalRow < viewportTop || globalRow >= viewportBottom)
42840
+ if (globalRow < safeTop || globalRow >= viewportBottom)
42841
42841
  continue;
42842
- const localRow = globalRow - viewportTop;
42842
+ const localRow = globalRow - safeTop;
42843
42843
  let bucket = placements.get(localRow);
42844
42844
  if (!bucket) {
42845
42845
  bucket = [];
@@ -42855,10 +42855,10 @@ class GraphViewGraphRenderer extends GraphViewRenderHelpers {
42855
42855
  }
42856
42856
  const bg = hexBg(this.graphTheme.bg);
42857
42857
  const leftPad = `${bg}${" ".repeat(leftMargin)}${RESET}`;
42858
- const composed = [];
42859
- for (let localRow = 0;localRow < viewportBottom - viewportTop; localRow++) {
42858
+ const composed = Array.from({ length: safeRows }, () => "");
42859
+ for (let localRow = 0;localRow < graphRows; localRow++) {
42860
42860
  const line = this._composeRow(edgeLines[localRow] ?? "", placements.get(localRow) ?? [], edgeColor);
42861
- composed.push(`${leftPad}${this._padCanvas(line, viewportWidth)}`);
42861
+ composed[topPad + localRow] = `${leftPad}${this._padCanvas(line, viewportWidth)}`;
42862
42862
  }
42863
42863
  return composed;
42864
42864
  }
@@ -42873,8 +42873,8 @@ class GraphViewGraphRenderer extends GraphViewRenderHelpers {
42873
42873
  const viewportLeft = viewport.leftMargin;
42874
42874
  const viewportRight = viewport.leftMargin + viewport.viewportWidth;
42875
42875
  const rects = [];
42876
- const viewportTop = this.graphScrollOffset;
42877
- const viewportBottom = viewportTop + visibleRowCount;
42876
+ const viewportTop = this._graphScrollTop();
42877
+ const viewportBottom = Math.min(this.cachedRenderGeometry.totalRows, viewportTop + visibleRowCount);
42878
42878
  const { bands } = this.cachedRenderGeometry;
42879
42879
  for (let bandIndex = this._firstVisibleLayoutBand(viewportTop);bandIndex < bands.length; bandIndex++) {
42880
42880
  const band = bands[bandIndex];
@@ -42897,13 +42897,260 @@ class GraphViewGraphRenderer extends GraphViewRenderHelpers {
42897
42897
  }
42898
42898
  this.graphNodeHitRects = rects;
42899
42899
  }
42900
- _visibleGraphLines(graphLines, _frameWidth, bodyRows) {
42901
- this.pendingEnsureFocusedVisible = false;
42900
+ }
42901
+
42902
+ // dist/builtin/workflows/src/tui/graph-view-layout.ts
42903
+ import { ScrollView, VStack } from "@earendil-works/pi-tui";
42904
+ import {
42905
+ getScrollbarGeometry,
42906
+ getScrollViewBox,
42907
+ renderLayoutFrame
42908
+ } from "@earendil-works/pi-tui/dist/layout.js";
42909
+
42910
+ // dist/builtin/workflows/src/tui/mouse-input.ts
42911
+ function parseTerminalMouseInput(data) {
42912
+ const sgr = data.match(/^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/);
42913
+ if (sgr) {
42914
+ const oneBasedCol = Number.parseInt(sgr[2], 10);
42915
+ const oneBasedRow = Number.parseInt(sgr[3], 10);
42916
+ if (oneBasedCol < 1 || oneBasedRow < 1)
42917
+ return null;
42902
42918
  return {
42903
- lines: graphLines,
42904
- topPad: this.lastGraphTotalRows <= bodyRows ? Math.min(3, Math.max(0, Math.floor((bodyRows - this.lastGraphTotalRows) / 2))) : 0
42919
+ protocol: "sgr",
42920
+ action: sgr[4] === "M" ? "press" : "release",
42921
+ buttonCode: Number.parseInt(sgr[1], 10),
42922
+ col: oneBasedCol - 1,
42923
+ row: oneBasedRow - 1
42905
42924
  };
42906
42925
  }
42926
+ if (!data.startsWith("\x1B[M") || data.length !== 6)
42927
+ return null;
42928
+ const buttonCode = data.charCodeAt(3) - 32;
42929
+ const col = data.charCodeAt(4) - 33;
42930
+ const row = data.charCodeAt(5) - 33;
42931
+ if (buttonCode < 0 || col < 0 || row < 0)
42932
+ return null;
42933
+ return {
42934
+ protocol: "x10",
42935
+ action: (buttonCode & (64 | 32)) === 0 && (buttonCode & 3) === 3 ? "release" : "press",
42936
+ buttonCode,
42937
+ col,
42938
+ row
42939
+ };
42940
+ }
42941
+ function terminalMouseWheelDirection(event) {
42942
+ if (event.action !== "press" || (event.buttonCode & 64) === 0)
42943
+ return null;
42944
+ const direction = event.buttonCode & 3;
42945
+ if (direction === 0)
42946
+ return "up";
42947
+ if (direction === 1)
42948
+ return "down";
42949
+ if (direction === 2)
42950
+ return "left";
42951
+ return "right";
42952
+ }
42953
+ function isTerminalLeftMousePress(event) {
42954
+ return event.action === "press" && (event.buttonCode & 64) === 0 && (event.buttonCode & 32) === 0 && (event.buttonCode & 3) === 0;
42955
+ }
42956
+
42957
+ // dist/builtin/workflows/src/tui/graph-view-layout.ts
42958
+ var EMPTY_RENDER = () => {};
42959
+ var GRAPH_HEADER_ROWS = 3;
42960
+ var GRAPH_FOOTER_ROWS = 3;
42961
+ function graphLayoutMarginRows(height) {
42962
+ return Math.max(1, Math.floor(height)) >= 9 ? 1 : 0;
42963
+ }
42964
+ function graphLayoutBodyRows(height) {
42965
+ const safeHeight = Math.max(1, Math.floor(height));
42966
+ return Math.max(0, safeHeight - GRAPH_HEADER_ROWS - GRAPH_FOOTER_ROWS - graphLayoutMarginRows(safeHeight) * 2);
42967
+ }
42968
+ function graphLayoutNaturalHeight(bodyRows) {
42969
+ const safeBodyRows = Math.max(1, Math.floor(bodyRows));
42970
+ const base = GRAPH_HEADER_ROWS + GRAPH_FOOTER_ROWS + safeBodyRows;
42971
+ return base >= GRAPH_HEADER_ROWS + GRAPH_FOOTER_ROWS + 3 ? base + 2 : base;
42972
+ }
42973
+ function collectWrappedRows(box, height, wrappedRows) {
42974
+ if (box.lines) {
42975
+ const offset = box.lineOffset ?? 0;
42976
+ const firstRow = Math.max(box.rect.y, box.clip.y, 0);
42977
+ const lastRow = Math.min(box.rect.y + box.rect.height, box.clip.y + box.clip.height, height);
42978
+ for (let row = firstRow;row < lastRow; row++) {
42979
+ if (box.lines[offset + row - box.rect.y] !== undefined)
42980
+ wrappedRows[row] = true;
42981
+ }
42982
+ }
42983
+ for (const child of box.children)
42984
+ collectWrappedRows(child, height, wrappedRows);
42985
+ }
42986
+
42987
+ class CallbackComponent {
42988
+ renderLines;
42989
+ constructor(renderLines) {
42990
+ this.renderLines = renderLines;
42991
+ }
42992
+ render(width) {
42993
+ return this.renderLines(width);
42994
+ }
42995
+ invalidate() {}
42996
+ }
42997
+
42998
+ class GraphViewLayout {
42999
+ scrollView;
43000
+ root;
43001
+ callbacks;
43002
+ bodyViewportRows = 0;
43003
+ bodyContentRows = 0;
43004
+ scrollbar;
43005
+ draggingScrollbar;
43006
+ constructor(callbacks) {
43007
+ this.callbacks = callbacks;
43008
+ const margin = new CallbackComponent(() => [""]);
43009
+ const header = new CallbackComponent((width) => this.callbacks.renderHeader(width));
43010
+ const body = new CallbackComponent((width) => this.renderBody(width));
43011
+ const footer = new CallbackComponent((width) => this.callbacks.renderFooter(width));
43012
+ this.scrollView = new ScrollView(body, {
43013
+ axis: "vertical",
43014
+ follow: "none",
43015
+ overscroll: "contain",
43016
+ scrollbar: "hidden"
43017
+ });
43018
+ const marginVisible = ({ height }) => graphLayoutMarginRows(height) > 0;
43019
+ this.root = new VStack([
43020
+ { component: margin, basis: 1, grow: 0, shrink: 0, minSize: 0, visible: marginVisible },
43021
+ { component: header, basis: GRAPH_HEADER_ROWS, grow: 0, shrink: 1, minSize: 0 },
43022
+ { component: this.scrollView, basis: 0, grow: 1, shrink: 1, minSize: 0 },
43023
+ { component: footer, basis: GRAPH_FOOTER_ROWS, grow: 0, shrink: 1, minSize: 1 },
43024
+ { component: margin, basis: 1, grow: 0, shrink: 0, minSize: 0, visible: marginVisible }
43025
+ ]);
43026
+ }
43027
+ render(width, height) {
43028
+ const safeWidth = Math.max(1, Math.floor(width));
43029
+ const safeHeight = Math.max(1, Math.floor(height));
43030
+ const marginRows = graphLayoutMarginRows(safeHeight);
43031
+ this.bodyViewportRows = graphLayoutBodyRows(safeHeight);
43032
+ this.bodyContentRows = Math.max(0, Math.floor(this.callbacks.bodyContentHeight(safeWidth, this.bodyViewportRows)));
43033
+ const requestRender = this.callbacks.requestRender ?? EMPTY_RENDER;
43034
+ this.scrollView.updateLayout(this.bodyContentRows, this.bodyViewportRows, requestRender);
43035
+ this.scrollView.setScrollbar(this.bodyContentRows > this.bodyViewportRows ? "always" : "hidden");
43036
+ this.callbacks.beforeFrame?.(this.scrollView, this.bodyViewportRows, this.bodyContentRows, safeWidth);
43037
+ const frame = renderLayoutFrame(this.root, safeWidth, safeHeight, requestRender);
43038
+ const bodyBox = getScrollViewBox(frame, this.scrollView);
43039
+ this.scrollbar = bodyBox ? getScrollbarGeometry(bodyBox) : undefined;
43040
+ if (!this.scrollbar)
43041
+ this.draggingScrollbar = undefined;
43042
+ const wrappedRows = Array.from({ length: safeHeight }, () => false);
43043
+ collectWrappedRows(frame.root, safeHeight, wrappedRows);
43044
+ return {
43045
+ frame,
43046
+ bodyBox,
43047
+ topMarginRows: marginRows,
43048
+ bottomMarginRows: marginRows,
43049
+ wrappedRows,
43050
+ scrollbar: this.scrollbar
43051
+ };
43052
+ }
43053
+ paintScrollbar(lines, width) {
43054
+ const geometry = this.scrollbar;
43055
+ if (!geometry)
43056
+ return;
43057
+ for (let offset = 0;offset < geometry.thumbHeight; offset++) {
43058
+ const row = geometry.thumbTop + offset;
43059
+ if (row < 0 || row >= lines.length || geometry.column < 0 || geometry.column >= width)
43060
+ continue;
43061
+ const line = lines[row] ?? " ".repeat(width);
43062
+ const before = sliceColumns(line, 0, geometry.column, true);
43063
+ const after = sliceColumns(line, geometry.column + 1, width - geometry.column - 1, true);
43064
+ const beforePad = " ".repeat(Math.max(0, geometry.column - visibleWidth(before)));
43065
+ const afterPad = " ".repeat(Math.max(0, width - geometry.column - 1 - visibleWidth(after)));
43066
+ lines[row] = `${before}${beforePad}${this.scrollView.scrollbarStyle(" ")}${after}${afterPad}`;
43067
+ }
43068
+ }
43069
+ dispose() {
43070
+ this.draggingScrollbar = undefined;
43071
+ this.scrollbar = undefined;
43072
+ this.scrollView.updateLayout(this.bodyContentRows, this.bodyViewportRows, EMPTY_RENDER);
43073
+ this.scrollView.setScrollbarActive(false);
43074
+ this.scrollView.setScrollbar("hidden");
43075
+ }
43076
+ get viewportRows() {
43077
+ return this.bodyViewportRows;
43078
+ }
43079
+ get contentRows() {
43080
+ return this.bodyContentRows;
43081
+ }
43082
+ get scrollbarGeometry() {
43083
+ return this.scrollbar;
43084
+ }
43085
+ isScrollbarInput(data) {
43086
+ const event = parseTerminalMouseInput(data);
43087
+ if (!event)
43088
+ return false;
43089
+ if (this.draggingScrollbar) {
43090
+ return event.action === "release" || (event.buttonCode & 32) !== 0 && (event.buttonCode & 3) === 0;
43091
+ }
43092
+ const geometry = this.scrollbar;
43093
+ return geometry !== undefined && event.action === "press" && (event.buttonCode & 64) === 0 && (event.buttonCode & 32) === 0 && (event.buttonCode & 3) === 0 && event.col === geometry.column && event.row >= geometry.trackTop && event.row < geometry.trackTop + geometry.trackHeight;
43094
+ }
43095
+ handleScrollbarInput(data) {
43096
+ const event = parseTerminalMouseInput(data);
43097
+ if (!event)
43098
+ return false;
43099
+ if (event.action === "release") {
43100
+ if (!this.draggingScrollbar)
43101
+ return false;
43102
+ this.draggingScrollbar = undefined;
43103
+ return true;
43104
+ }
43105
+ const moving = (event.buttonCode & 32) !== 0;
43106
+ const leftButton = (event.buttonCode & 3) === 0;
43107
+ if (this.draggingScrollbar && moving && leftButton) {
43108
+ this.scrollToScrollbarRow(event.row);
43109
+ return true;
43110
+ }
43111
+ const geometry = this.scrollbar;
43112
+ if (!geometry)
43113
+ return false;
43114
+ if (!isTerminalLeftMousePress(event) || event.col !== geometry.column)
43115
+ return false;
43116
+ if (event.row < geometry.trackTop || event.row >= geometry.trackTop + geometry.trackHeight)
43117
+ return false;
43118
+ if (event.row >= geometry.thumbTop && event.row < geometry.thumbTop + geometry.thumbHeight) {
43119
+ this.draggingScrollbar = { grabOffset: event.row - geometry.thumbTop };
43120
+ } else {
43121
+ this.scrollToScrollbarRow(event.row - Math.floor(geometry.thumbHeight / 2));
43122
+ }
43123
+ return true;
43124
+ }
43125
+ invalidate() {
43126
+ this.root.invalidate();
43127
+ }
43128
+ renderBody(width) {
43129
+ const contentRows = this.bodyContentRows;
43130
+ const lines = new Array(contentRows);
43131
+ const top = Math.max(0, Math.min(contentRows, this.scrollView.scrollTop));
43132
+ const rows = Math.max(0, Math.min(this.bodyViewportRows, contentRows - top));
43133
+ const visible = this.callbacks.renderBody(width, top, rows, contentRows);
43134
+ for (let index = 0;index < visible.length && index < rows; index++) {
43135
+ lines[top + index] = visible[index];
43136
+ }
43137
+ if (top > 0)
43138
+ lines[top - 1] = " ";
43139
+ return lines;
43140
+ }
43141
+ scrollToScrollbarRow(row) {
43142
+ const geometry = this.scrollbar;
43143
+ if (!geometry || geometry.maxScrollTop <= 0)
43144
+ return;
43145
+ const maxThumbTop = Math.max(0, geometry.trackHeight - geometry.thumbHeight);
43146
+ if (maxThumbTop === 0) {
43147
+ this.scrollView.scrollTo(0);
43148
+ return;
43149
+ }
43150
+ const thumbTop = Math.max(geometry.trackTop, Math.min(geometry.trackTop + maxThumbTop, row - (this.draggingScrollbar?.grabOffset ?? 0)));
43151
+ const ratio = (thumbTop - geometry.trackTop) / maxThumbTop;
43152
+ this.scrollView.scrollTo(Math.round(ratio * geometry.maxScrollTop));
43153
+ }
42907
43154
  }
42908
43155
 
42909
43156
  // dist/builtin/workflows/src/tui/switcher.ts
@@ -43000,18 +43247,47 @@ function renderSwitcher(stages, state, opts) {
43000
43247
  }
43001
43248
 
43002
43249
  // dist/builtin/workflows/src/tui/graph-view-render.ts
43250
+ var LAYOUT_OSC_RESET = "\x1B[0m\x1B]8;;\x07";
43251
+ function stripLayoutWrapper(line) {
43252
+ const startsWithWrapper = line.startsWith(LAYOUT_OSC_RESET);
43253
+ const endsWithWrapper = line.endsWith(LAYOUT_OSC_RESET);
43254
+ const start = startsWithWrapper ? LAYOUT_OSC_RESET.length : 0;
43255
+ const end = endsWithWrapper ? line.length - LAYOUT_OSC_RESET.length : line.length;
43256
+ return line.slice(start, Math.max(start, end));
43257
+ }
43258
+
43003
43259
  class GraphViewRenderer extends GraphViewGraphRenderer {
43260
+ graphLayout;
43261
+ lastOverlayFrameHeight = 0;
43262
+ hasReportedViewportRows = false;
43263
+ renderRun;
43264
+ constructor(opts) {
43265
+ super(opts);
43266
+ this.graphLayout = new GraphViewLayout({
43267
+ renderHeader: (width) => this._renderHeader(width),
43268
+ renderBody: (width, top, rows, contentRows) => this._renderBody(width, top, rows, contentRows),
43269
+ renderFooter: (width) => this._renderStatusline(width),
43270
+ bodyContentHeight: (_width, viewportRows) => this._graphBodyContentHeight(viewportRows),
43271
+ beforeFrame: (scrollView, viewportRows, contentRows, width) => this._prepareGraphScroll(scrollView, viewportRows, contentRows, width),
43272
+ requestRender: () => this.requestRender?.()
43273
+ });
43274
+ }
43275
+ _graphScrollTop() {
43276
+ return this.graphLayout.scrollView.scrollTop;
43277
+ }
43004
43278
  render(width) {
43005
- if (this.mode === "widget") {
43279
+ if (this.mode === "widget")
43006
43280
  return this._renderWidget(width);
43007
- }
43008
43281
  return this._renderOverlay(width);
43009
43282
  }
43283
+ dispose() {
43284
+ this.graphLayout.dispose();
43285
+ super.dispose();
43286
+ }
43010
43287
  _renderWidget(width) {
43011
43288
  const run = this._getCurrentRun();
43012
- if (!run) {
43289
+ if (!run)
43013
43290
  return [`${hexToAnsi(this.graphTheme.dim)}no active workflow${RESET}`];
43014
- }
43015
43291
  const displayStages = this._displayStages(run);
43016
43292
  const headerLines = renderHeader({ ...run, stages: displayStages }, { width, theme: this.graphTheme });
43017
43293
  const counts = this._counts(displayStages);
@@ -43020,95 +43296,150 @@ class GraphViewRenderer extends GraphViewGraphRenderer {
43020
43296
  }
43021
43297
  _renderOverlay(width) {
43022
43298
  const frameWidth = Math.max(40, width);
43023
- this.lastOverlayFrameWidth = frameWidth;
43024
- const lines = [];
43025
43299
  const run = this._getCurrentRun();
43026
- if (!run) {
43027
- return this._renderEmptyState(frameWidth);
43028
- }
43029
- lines.push(...renderHeader({ ...run, stages: this._displayStages(run) }, { width: frameWidth, theme: this.graphTheme }));
43030
- const graphLines = this._renderGraph(frameWidth);
43031
- const bodyTarget = this._overlayBodyRows(this._overlayPanelLineCount());
43032
- const visibleGraph = this._visibleGraphLines(graphLines, frameWidth, bodyTarget);
43033
- this._recordGraphNodeHitRects(this._overlayVerticalMarginRows() + 3 + visibleGraph.topPad, visibleGraph.lines.length);
43034
- for (let i = 0;i < visibleGraph.topPad; i++)
43035
- lines.push(this._blankRow(frameWidth));
43036
- for (const line of visibleGraph.lines) {
43037
- lines.push(this._canvasRow(line, frameWidth));
43038
- }
43039
- while (lines.length < 3 + bodyTarget)
43040
- lines.push(this._blankRow(frameWidth));
43041
- if (lines.length > 3 + bodyTarget)
43042
- lines.length = 3 + bodyTarget;
43043
- this._renderSwitcherOverlay(lines, run, frameWidth, bodyTarget);
43044
- this._renderPromptOverlay(lines, frameWidth, bodyTarget);
43045
- lines.push(...this._renderStatusline(frameWidth));
43046
- return this._withVerticalMargins(lines, frameWidth);
43047
- }
43048
- _renderEmptyState(width) {
43049
- this.graphNodeHitRects = [];
43050
- this.lastGraphViewport = null;
43300
+ this.renderRun = run;
43301
+ try {
43302
+ const frameHeight = this._overlayFrameHeight(run);
43303
+ const layoutFrame = this.graphLayout.render(frameWidth, frameHeight);
43304
+ const lines = this._normalizeLayoutLines(layoutFrame.frame.lines, layoutFrame.wrappedRows, frameWidth, frameHeight, layoutFrame.topMarginRows, layoutFrame.bottomMarginRows);
43305
+ const bodyStart = layoutFrame.bodyBox?.rect.y ?? layoutFrame.topMarginRows + GRAPH_HEADER_ROWS;
43306
+ const bodyRows = layoutFrame.bodyBox?.rect.height ?? this.graphLayout.viewportRows;
43307
+ if (run) {
43308
+ this._recordGraphNodeHitRects(bodyStart + this.lastGraphTopPad, this.lastGraphVisibleRows);
43309
+ this._renderSwitcherOverlay(lines, run, frameWidth, bodyStart, bodyRows);
43310
+ this._renderPromptOverlay(lines, frameWidth, bodyStart, bodyRows);
43311
+ } else {
43312
+ this.graphNodeHitRects = [];
43313
+ this.lastGraphViewport = null;
43314
+ }
43315
+ this.graphLayout.paintScrollbar(lines, frameWidth);
43316
+ return lines;
43317
+ } finally {
43318
+ this.renderRun = undefined;
43319
+ }
43320
+ }
43321
+ _overlayFrameHeight(run = this._currentRenderRun()) {
43322
+ const reported = this.piTui?.terminal?.rows;
43323
+ if (typeof reported === "number" && Number.isFinite(reported) && reported > 0) {
43324
+ this.hasReportedViewportRows = true;
43325
+ this.lastOverlayFrameHeight = Math.max(1, Math.floor(reported));
43326
+ return this.lastOverlayFrameHeight;
43327
+ }
43328
+ if (this.hasReportedViewportRows && this.lastOverlayFrameHeight > 0)
43329
+ return this.lastOverlayFrameHeight;
43330
+ const bodyRows = run ? Math.max(1, this.cachedRenderGeometry.totalRows) : 2;
43331
+ this.lastOverlayFrameHeight = graphLayoutNaturalHeight(bodyRows);
43332
+ return this.lastOverlayFrameHeight;
43333
+ }
43334
+ _currentRenderRun() {
43335
+ return this.renderRun !== undefined ? this.renderRun : this._getCurrentRun();
43336
+ }
43337
+ _graphBodyContentHeight(viewportRows) {
43338
+ const rows = Math.max(0, Math.floor(viewportRows));
43339
+ if (!this._currentRenderRun() || this.cachedRenderGeometry.totalRows <= 0)
43340
+ return rows;
43341
+ return Math.max(rows, this.cachedRenderGeometry.totalRows);
43342
+ }
43343
+ _prepareGraphScroll(scrollView, viewportRows, _contentRows, width) {
43344
+ const run = this._currentRenderRun();
43345
+ if (viewportRows <= 0)
43346
+ return;
43347
+ if (!run || this.cachedRenderGeometry.totalRows <= 0) {
43348
+ scrollView.scrollToStart();
43349
+ this.pendingEnsureFocusedVisible = false;
43350
+ return;
43351
+ }
43352
+ if (this.pendingEnsureFocusedVisible) {
43353
+ const node = this.cachedLayout[this.focusedIndex];
43354
+ if (node) {
43355
+ let next = scrollView.scrollTop;
43356
+ if (node.y < next)
43357
+ next = node.y;
43358
+ else if (node.y + NODE_H > next + viewportRows)
43359
+ next = node.y + NODE_H - viewportRows;
43360
+ scrollView.scrollTo(next);
43361
+ const graphInner = Math.max(1, width - 4);
43362
+ const leftMargin = Math.max(2, this.cachedRenderGeometry.canvasWidth <= graphInner ? Math.floor((graphInner - this.cachedRenderGeometry.canvasWidth) / 2) : 2);
43363
+ const viewportWidth = Math.max(1, width - leftMargin);
43364
+ const fullCanvasWidth = Math.max(this.cachedRenderGeometry.canvasWidth, viewportWidth);
43365
+ this._scrollFocusedColumnIntoView(viewportWidth, fullCanvasWidth);
43366
+ }
43367
+ this.pendingEnsureFocusedVisible = false;
43368
+ }
43369
+ }
43370
+ _renderHeader(width) {
43371
+ const run = this._currentRenderRun();
43372
+ if (run)
43373
+ return renderHeader({ ...run, stages: this._displayStages(run) }, { width, theme: this.graphTheme });
43051
43374
  const t = this.graphTheme;
43052
43375
  const muted = hexToAnsi(t.textMuted);
43053
- const dim = hexToAnsi(t.dim);
43054
- const accent = hexToAnsi(t.accent);
43055
43376
  const chromeBg = hexBg(t.backgroundPanel);
43056
43377
  const { top, mid, bot, visibleWidth: pillW } = renderOutlinePill("ORCHESTRATOR", t.accent, chromeBg);
43057
- const idleLabel = ` ${muted}idle${RESET}`;
43058
43378
  const fillerVisible = Math.max(0, width - 1 - pillW - 6 - 2);
43059
43379
  const filler = " ".repeat(fillerVisible);
43060
- const lines = [
43380
+ return [
43061
43381
  `${chromeBg} ${RESET}${top}${chromeBg}${" ".repeat(6 + fillerVisible)}${" ".repeat(2)}${RESET}`,
43062
- `${chromeBg} ${RESET}${mid}${chromeBg}${idleLabel}${filler}${" ".repeat(2)}${RESET}`,
43382
+ `${chromeBg} ${RESET}${mid}${chromeBg} ${muted}idle${RESET}${filler}${" ".repeat(2)}${RESET}`,
43063
43383
  `${chromeBg} ${RESET}${bot}${chromeBg}${" ".repeat(6 + fillerVisible)}${" ".repeat(2)}${RESET}`
43064
43384
  ];
43065
- const bodyTarget = this._overlayBodyRows(this._overlayPanelLineCount());
43385
+ }
43386
+ _renderBody(width, top, rows, _contentRows) {
43387
+ const run = this._currentRenderRun();
43388
+ const raw = run ? this._renderGraph(width, top, rows, run) : this._renderEmptyBody(width, rows);
43389
+ return raw.map((line) => this._canvasRow(line, width));
43390
+ }
43391
+ _renderEmptyBody(width, rows) {
43066
43392
  const body = [
43067
- this._canvasRow(` ${muted}No active workflow run.${RESET}`, width),
43068
- this._canvasRow(` ${dim}Start one with ${accent}/workflow <name>${RESET}${dim} or press ${accent}F2${RESET}${dim} on an active run.${RESET}`, width)
43393
+ this._centerCanvasContent(` ${hexToAnsi(this.graphTheme.textMuted)}No active workflow run.${RESET}`, width),
43394
+ this._centerCanvasContent(` ${hexToAnsi(this.graphTheme.dim)}Start one with ${hexToAnsi(this.graphTheme.accent)}/workflow <name>${RESET}${hexToAnsi(this.graphTheme.dim)} or press ${hexToAnsi(this.graphTheme.accent)}F2${RESET}${hexToAnsi(this.graphTheme.dim)} on an active run.${RESET}`, width)
43069
43395
  ];
43070
- const topPad = Math.max(0, Math.floor((bodyTarget - body.length) / 2));
43071
- for (let i = 0;i < topPad; i++)
43072
- lines.push(this._blankRow(width));
43073
- for (const l of body)
43074
- lines.push(l);
43075
- while (lines.length < 3 + bodyTarget)
43076
- lines.push(this._blankRow(width));
43077
- lines.push(...this._renderStatusline(width));
43078
- return this._withVerticalMargins(lines, width);
43079
- }
43080
- _renderSwitcherOverlay(lines, run, frameWidth, bodyTarget) {
43396
+ const lines = Array.from({ length: rows }, () => "");
43397
+ const topPad = Math.max(0, Math.floor((rows - body.length) / 2));
43398
+ for (let index = 0;index < body.length; index++) {
43399
+ const target = topPad + index;
43400
+ if (target < lines.length)
43401
+ lines[target] = body[index];
43402
+ }
43403
+ return lines;
43404
+ }
43405
+ _normalizeLayoutLines(lines, wrappedRows, width, height, topMarginRows, bottomMarginRows) {
43406
+ return Array.from({ length: height }, (_, row) => {
43407
+ if (row < topMarginRows || row >= height - bottomMarginRows)
43408
+ return " ".repeat(width);
43409
+ const source = lines[row] ?? "";
43410
+ const clean = wrappedRows[row] === true ? stripLayoutWrapper(source) : source;
43411
+ if (visibleWidth(clean) === 0)
43412
+ return this._blankRow(width);
43413
+ if (visibleWidth(clean) > width)
43414
+ return truncateToWidth(clean, width, "…", true);
43415
+ return `${clean}${" ".repeat(width - visibleWidth(clean))}`;
43416
+ });
43417
+ }
43418
+ _renderSwitcherOverlay(lines, run, frameWidth, bodyStart, bodyRows) {
43081
43419
  if (!this.switcherOpen)
43082
43420
  return;
43083
- const bodyStart = 3;
43084
- const bodyEnd = 3 + bodyTarget;
43085
- for (let row = bodyStart;row < bodyEnd; row++) {
43421
+ const bodyEnd = bodyStart + bodyRows;
43422
+ for (let row = bodyStart;row < bodyEnd; row++)
43086
43423
  lines[row] = this._blankRow(frameWidth);
43087
- }
43088
43424
  const switcherWidth = Math.min(60, Math.max(40, frameWidth - 8));
43089
43425
  const switcherLines = renderSwitcher(this._displayStages(run), this.switcherState, {
43090
43426
  width: switcherWidth,
43091
43427
  theme: this.graphTheme,
43092
43428
  canOpenStageChat: (stage) => this._stageChatTarget(stage) !== undefined
43093
43429
  });
43094
- const insertAt = Math.max(bodyStart, bodyStart + Math.min(2, Math.floor((bodyTarget - switcherLines.length) / 3)));
43430
+ const insertAt = Math.max(bodyStart, bodyStart + Math.min(2, Math.floor((bodyRows - switcherLines.length) / 3)));
43095
43431
  const switcherLeft = Math.max(2, Math.floor((frameWidth - switcherWidth) / 2));
43096
- for (let i = 0;i < switcherLines.length; i++) {
43097
- const lineIdx = insertAt + i;
43098
- if (lineIdx >= bodyEnd)
43432
+ for (let index = 0;index < switcherLines.length; index++) {
43433
+ const lineIndex = insertAt + index;
43434
+ if (lineIndex >= bodyEnd)
43099
43435
  break;
43100
- const base = lines[lineIdx] ?? this._blankRow(frameWidth);
43101
- const merged = this._overlayCard(base, switcherLines[i], switcherLeft, frameWidth);
43102
- if (lineIdx < lines.length)
43103
- lines[lineIdx] = merged;
43104
- else
43105
- lines.push(merged);
43436
+ lines[lineIndex] = this._overlayCard(lines[lineIndex] ?? this._blankRow(frameWidth), switcherLines[index], switcherLeft, frameWidth);
43106
43437
  }
43107
43438
  }
43108
- _renderPromptOverlay(lines, frameWidth, bodyTarget) {
43439
+ _renderPromptOverlay(lines, frameWidth, bodyStart, bodyRows) {
43109
43440
  if (!this.promptState || this.switcherOpen)
43110
43441
  return;
43111
- const run = this._getCurrentRun();
43442
+ const run = this._currentRenderRun();
43112
43443
  const cardWidth = Math.min(72, Math.max(40, frameWidth - 6));
43113
43444
  const cardLines = renderPromptCard({
43114
43445
  state: this.promptState,
@@ -43116,93 +43447,43 @@ class GraphViewRenderer extends GraphViewGraphRenderer {
43116
43447
  width: cardWidth,
43117
43448
  cursorOn: (Date.now() / 530 | 0) % 2 === 0,
43118
43449
  identity: run ? { runId: run.id, name: run.name } : undefined,
43119
- maxRows: bodyTarget
43450
+ maxRows: bodyRows
43120
43451
  });
43121
- const bodyStart = 3;
43122
- const bodyEnd = bodyStart + bodyTarget;
43123
- const slot = Math.max(bodyStart, bodyStart + Math.floor((bodyTarget - cardLines.length) / 2));
43124
- if (cardLines.length > bodyTarget || slot + cardLines.length > bodyEnd)
43452
+ const bodyEnd = bodyStart + bodyRows;
43453
+ const slot = Math.max(bodyStart, bodyStart + Math.floor((bodyRows - cardLines.length) / 2));
43454
+ if (cardLines.length > bodyRows || slot + cardLines.length > bodyEnd)
43125
43455
  return;
43126
43456
  const leftPad = Math.max(0, Math.floor((frameWidth - cardWidth) / 2));
43127
- for (let i = 0;i < cardLines.length; i++) {
43128
- const lineIdx = slot + i;
43129
- const base = lines[lineIdx] ?? this._blankRow(frameWidth);
43130
- lines[lineIdx] = this._overlayCard(base, cardLines[i], leftPad, frameWidth);
43457
+ for (let index = 0;index < cardLines.length; index++) {
43458
+ const lineIndex = slot + index;
43459
+ lines[lineIndex] = this._overlayCard(lines[lineIndex] ?? this._blankRow(frameWidth), cardLines[index], leftPad, frameWidth);
43131
43460
  }
43132
43461
  }
43133
43462
  }
43134
43463
 
43135
- // dist/builtin/workflows/src/tui/mouse-input.ts
43136
- function parseTerminalMouseInput(data) {
43137
- const sgr = data.match(/^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/);
43138
- if (sgr) {
43139
- const oneBasedCol = Number.parseInt(sgr[2], 10);
43140
- const oneBasedRow = Number.parseInt(sgr[3], 10);
43141
- if (oneBasedCol < 1 || oneBasedRow < 1)
43142
- return null;
43143
- return {
43144
- protocol: "sgr",
43145
- action: sgr[4] === "M" ? "press" : "release",
43146
- buttonCode: Number.parseInt(sgr[1], 10),
43147
- col: oneBasedCol - 1,
43148
- row: oneBasedRow - 1
43149
- };
43150
- }
43151
- if (!data.startsWith("\x1B[M") || data.length !== 6)
43152
- return null;
43153
- const buttonCode = data.charCodeAt(3) - 32;
43154
- const col = data.charCodeAt(4) - 33;
43155
- const row = data.charCodeAt(5) - 33;
43156
- if (buttonCode < 0 || col < 0 || row < 0)
43157
- return null;
43158
- return {
43159
- protocol: "x10",
43160
- action: (buttonCode & (64 | 32)) === 0 && (buttonCode & 3) === 3 ? "release" : "press",
43161
- buttonCode,
43162
- col,
43163
- row
43164
- };
43165
- }
43166
- function terminalMouseWheelDirection(event) {
43167
- if (event.action !== "press" || (event.buttonCode & 64) === 0)
43168
- return null;
43169
- const direction = event.buttonCode & 3;
43170
- if (direction === 0)
43171
- return "up";
43172
- if (direction === 1)
43173
- return "down";
43174
- if (direction === 2)
43175
- return "left";
43176
- return "right";
43177
- }
43178
- function isTerminalLeftMousePress(event) {
43179
- return event.action === "press" && (event.buttonCode & 64) === 0 && (event.buttonCode & 32) === 0 && (event.buttonCode & 3) === 0;
43180
- }
43181
-
43182
43464
  // dist/builtin/workflows/src/tui/graph-view-input.ts
43465
+ var GRAPH_SCROLL_WHEEL_LINES = 4;
43466
+
43183
43467
  class GraphViewInputController extends GraphViewRenderer {
43184
43468
  handleInput(data) {
43185
43469
  if (this._isReturnToMainChatInput(data)) {
43186
43470
  this._returnToMainChat();
43187
43471
  return true;
43188
43472
  }
43189
- if (this.switcherOpen) {
43473
+ if (this.graphLayout.isScrollbarInput(data))
43474
+ return this._handleGraphInput(data);
43475
+ if (this.switcherOpen)
43190
43476
  return this._handleSwitcherInput(data);
43191
- }
43192
- if (this.promptState) {
43193
- if (this._isNonTextGraphControlBeforePrompt(data)) {
43194
- return this._handleGraphInput(data);
43195
- }
43477
+ const wheelDelta = this._mouseWheelDelta(data);
43478
+ if (wheelDelta)
43479
+ return this._handleWheelDelta(wheelDelta);
43480
+ if (this.promptState)
43196
43481
  return this._handlePromptInput(data);
43197
- }
43198
43482
  return this._handleGraphInput(data);
43199
43483
  }
43200
43484
  _promptKeybindings() {
43201
43485
  return isKeybindingsLike(this.piKeybindings) ? this.piKeybindings : undefined;
43202
43486
  }
43203
- _isNonTextGraphControlBeforePrompt(data) {
43204
- return this._mouseWheelDelta(data) !== null;
43205
- }
43206
43487
  _isReturnToMainChatInput(data) {
43207
43488
  return matchesKey(data, Key.ctrl("x"));
43208
43489
  }
@@ -43236,14 +43517,13 @@ class GraphViewInputController extends GraphViewRenderer {
43236
43517
  }
43237
43518
  _handleGraphInput(data) {
43238
43519
  const stageCount = this.cachedLayout.length;
43239
- const wheelDelta = this._mouseWheelDelta(data);
43240
- if (wheelDelta) {
43241
- if (wheelDelta.rows !== 0)
43242
- this._scrollGraphBy(wheelDelta.rows);
43243
- if (wheelDelta.cols !== 0)
43244
- this._scrollGraphHorizontallyBy(wheelDelta.cols);
43520
+ if (this.graphLayout.handleScrollbarInput(data)) {
43521
+ this.pendingEnsureFocusedVisible = false;
43245
43522
  return true;
43246
43523
  }
43524
+ const wheelDelta = this._mouseWheelDelta(data);
43525
+ if (wheelDelta)
43526
+ return this._handleWheelDelta(wheelDelta);
43247
43527
  const clickedNodeIndex = this._graphNodeIndexForClick(data);
43248
43528
  if (clickedNodeIndex !== undefined) {
43249
43529
  if (clickedNodeIndex !== null) {
@@ -43318,21 +43598,18 @@ class GraphViewInputController extends GraphViewRenderer {
43318
43598
  this.switcherOpen = false;
43319
43599
  return true;
43320
43600
  }
43321
- if (matchesKey(data, Key.down)) {
43322
- const filtered = filterStages(stages, this.switcherState.query);
43323
- this.switcherState = {
43324
- ...this.switcherState,
43325
- selectedIndex: Math.min(this.switcherState.selectedIndex + 1, filtered.length - 1)
43326
- };
43601
+ const wheelEvent = parseTerminalMouseInput(data);
43602
+ const wheelDirection = wheelEvent ? terminalMouseWheelDirection(wheelEvent) : null;
43603
+ if (wheelDirection === "down")
43604
+ return this._moveSwitcherSelection(1);
43605
+ if (wheelDirection === "up")
43606
+ return this._moveSwitcherSelection(-1);
43607
+ if (wheelDirection !== null)
43327
43608
  return true;
43328
- }
43329
- if (matchesKey(data, Key.up)) {
43330
- this.switcherState = {
43331
- ...this.switcherState,
43332
- selectedIndex: Math.max(this.switcherState.selectedIndex - 1, 0)
43333
- };
43334
- return true;
43335
- }
43609
+ if (matchesKey(data, Key.down))
43610
+ return this._moveSwitcherSelection(1);
43611
+ if (matchesKey(data, Key.up))
43612
+ return this._moveSwitcherSelection(-1);
43336
43613
  if (matchesKey(data, Key.backspace)) {
43337
43614
  this.switcherState = {
43338
43615
  query: this.switcherState.query.slice(0, -1),
@@ -43349,6 +43626,16 @@ class GraphViewInputController extends GraphViewRenderer {
43349
43626
  }
43350
43627
  return false;
43351
43628
  }
43629
+ _moveSwitcherSelection(step) {
43630
+ const stages = this.cachedLayout.map((layoutNode) => layoutNode.stage);
43631
+ const filtered = filterStages(stages, this.switcherState.query);
43632
+ const maxIndex = Math.max(0, filtered.length - 1);
43633
+ this.switcherState = {
43634
+ ...this.switcherState,
43635
+ selectedIndex: Math.max(0, Math.min(this.switcherState.selectedIndex + step, maxIndex))
43636
+ };
43637
+ return true;
43638
+ }
43352
43639
  _moveByDepth(step) {
43353
43640
  const cur = this.cachedLayout[this.focusedIndex];
43354
43641
  if (!cur)
@@ -43405,9 +43692,16 @@ class GraphViewInputController extends GraphViewRenderer {
43405
43692
  this.focusedIndex = next;
43406
43693
  this.pendingEnsureFocusedVisible = true;
43407
43694
  }
43408
- _scrollGraphBy(deltaRows) {
43695
+ _scrollGraphVertically(deltaRows) {
43409
43696
  this.pendingEnsureFocusedVisible = false;
43410
- this.graphScrollOffset = Math.max(0, this.graphScrollOffset + deltaRows);
43697
+ this.graphLayout.scrollView.scrollBy(deltaRows);
43698
+ }
43699
+ _handleWheelDelta(delta) {
43700
+ if (delta.rows !== 0)
43701
+ this._scrollGraphVertically(delta.rows);
43702
+ if (delta.cols !== 0)
43703
+ this._scrollGraphHorizontallyBy(delta.cols);
43704
+ return true;
43411
43705
  }
43412
43706
  _scrollGraphHorizontallyBy(deltaCols) {
43413
43707
  this.pendingEnsureFocusedVisible = false;
@@ -43440,15 +43734,18 @@ class GraphViewInputController extends GraphViewRenderer {
43440
43734
  return null;
43441
43735
  const direction = terminalMouseWheelDirection(event);
43442
43736
  if (direction === "up")
43443
- return { cols: 0, rows: -GRAPH_SCROLL_STEP_ROWS };
43737
+ return { cols: 0, rows: -GRAPH_SCROLL_WHEEL_LINES };
43444
43738
  if (direction === "down")
43445
- return { cols: 0, rows: GRAPH_SCROLL_STEP_ROWS };
43739
+ return { cols: 0, rows: GRAPH_SCROLL_WHEEL_LINES };
43446
43740
  if (direction === "left")
43447
43741
  return { cols: -GRAPH_SCROLL_STEP_COLS, rows: 0 };
43448
43742
  if (direction === "right")
43449
43743
  return { cols: GRAPH_SCROLL_STEP_COLS, rows: 0 };
43450
43744
  return null;
43451
43745
  }
43746
+ get _graphScrollbarGeometry() {
43747
+ return this.graphLayout.scrollbarGeometry;
43748
+ }
43452
43749
  get _focusedIndex() {
43453
43750
  return this.focusedIndex;
43454
43751
  }
@@ -43459,7 +43756,7 @@ class GraphViewInputController extends GraphViewRenderer {
43459
43756
  return this.switcherState;
43460
43757
  }
43461
43758
  get _graphScrollOffset() {
43462
- return this.graphScrollOffset;
43759
+ return this._graphScrollTop();
43463
43760
  }
43464
43761
  get _graphScrollColOffset() {
43465
43762
  return this.graphScrollColOffset;
@@ -43664,16 +43961,6 @@ function renderHintsForPrompt(kind, theme) {
43664
43961
  return `${paint2("enter", theme.textMuted, { bold: true })} Select · ${paint2("ctrl+c", theme.textMuted, { bold: true })} Skip`;
43665
43962
  }
43666
43963
 
43667
- // dist/builtin/workflows/src/tui/stage-chat-view-types.ts
43668
- var VIEW_LINE_COUNT = 32;
43669
- var PROMPT_SCROLL_STEP_ROWS = 4;
43670
- var HEADER_ROWS = 2;
43671
- var SEP_ROWS = 1;
43672
- var STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL = "ctrl+t";
43673
- function isReadOnlyArchiveStatus(status) {
43674
- return status === "completed" || status === "failed" || status === "skipped";
43675
- }
43676
-
43677
43964
  // dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts
43678
43965
  function renderHeader2(ctx, width, stage) {
43679
43966
  const t = ctx.theme;
@@ -43762,14 +44049,13 @@ function embedOrchestratorReturnHintInWidget(ctx, widgetLines, width) {
43762
44049
  return lines;
43763
44050
  }
43764
44051
  function mergeOrchestratorReturnHintIntoLine(ctx, line, width, options = {}) {
43765
- const copyModeState = ctx.mouseScrollCaptureEnabled ? "off" : "on";
43766
44052
  const fullHint = {
43767
- plain: `ctrl+x return to graph · ${STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL} copy mode ${copyModeState}`,
43768
- styled: paint2("ctrl+x", ctx.theme.text, { bold: true }) + paint2(" return to graph · ", ctx.theme.textMuted) + paint2(STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL, ctx.theme.text, { bold: true }) + paint2(` copy mode ${copyModeState}`, ctx.theme.textMuted)
44053
+ plain: "ctrl+x return to graph",
44054
+ styled: paint2("ctrl+x", ctx.theme.text, { bold: true }) + paint2(" return to graph", ctx.theme.textMuted)
43769
44055
  };
43770
44056
  const compactHint = {
43771
- plain: `ctrl+x graph · ${STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL} ${copyModeState}`,
43772
- styled: paint2("ctrl+x", ctx.theme.text, { bold: true }) + paint2(" graph · ", ctx.theme.textMuted) + paint2(STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL, ctx.theme.text, { bold: true }) + paint2(` ${copyModeState}`, ctx.theme.textMuted)
44057
+ plain: "ctrl+x graph",
44058
+ styled: paint2("ctrl+x", ctx.theme.text, { bold: true }) + paint2(" graph", ctx.theme.textMuted)
43773
44059
  };
43774
44060
  const trailingBorder = options.preserveTrailingBorder === true ? trailingWidgetBorderChar(line) : "";
43775
44061
  const suffixWidth = visibleWidth(trailingBorder);
@@ -44286,7 +44572,7 @@ async function mountStageCustomUi(request, tui, theme, keybindings, broker, onDo
44286
44572
  });
44287
44573
  const component = {
44288
44574
  render: (width) => rawComponent.render(width),
44289
- ...rawComponent.handleInput !== undefined ? { handleInput: (data) => rawComponent.handleInput?.(data) } : {},
44575
+ ...rawComponent.handleInput !== undefined ? { handleInput: (data) => rawComponent.handleInput?.(data) === true } : {},
44290
44576
  invalidate: () => rawComponent.invalidate?.(),
44291
44577
  ...rawComponent.dispose !== undefined ? { dispose: () => rawComponent.dispose?.() } : {}
44292
44578
  };
@@ -44870,6 +45156,15 @@ function stageNoticeFields(entry, valueTone = "text") {
44870
45156
  ];
44871
45157
  }
44872
45158
 
45159
+ // dist/builtin/workflows/src/tui/stage-chat-view-types.ts
45160
+ var VIEW_LINE_COUNT = 32;
45161
+ var PROMPT_SCROLL_STEP_ROWS = 4;
45162
+ var HEADER_ROWS = 2;
45163
+ var SEP_ROWS = 1;
45164
+ function isReadOnlyArchiveStatus(status) {
45165
+ return status === "completed" || status === "failed" || status === "skipped";
45166
+ }
45167
+
44873
45168
  // dist/builtin/workflows/src/tui/stage-chat-view-state.ts
44874
45169
  function initializeStageChatView(ctx, opts) {
44875
45170
  ctx.store = opts.store;
@@ -44884,7 +45179,6 @@ function initializeStageChatView(ctx, opts) {
44884
45179
  ctx.requestRender = opts.requestRender;
44885
45180
  ctx.requestFocus = opts.requestFocus;
44886
45181
  ctx.focusHoldTimer = undefined;
44887
- ctx.getViewportRows = opts.getViewportRows;
44888
45182
  ctx.piTui = opts.piTui;
44889
45183
  ctx.piTheme = opts.piTheme;
44890
45184
  ctx.piKeybindings = opts.piKeybindings;
@@ -44904,7 +45198,6 @@ function initializeStageChatView(ctx, opts) {
44904
45198
  ctx.promptMaxScroll = 0;
44905
45199
  ctx.promptVisibleRows = 0;
44906
45200
  ctx.localPaused = false;
44907
- ctx.mouseScrollCaptureEnabled = true;
44908
45201
  ctx.lastObservedStageStatus = undefined;
44909
45202
  ctx.lastObservedRunStatus = undefined;
44910
45203
  ctx.seenNoticeIds = new Set;
@@ -45113,6 +45406,7 @@ function snapshotMessagesFromHandle(ctx) {
45113
45406
  if (!handle)
45114
45407
  return;
45115
45408
  ctx.chatHost.appendMessages(handle.messages);
45409
+ ctx.chatHost.hydrateStreamingAssistantMessage(handle.agentSession?.agent?.state.streamingMessage);
45116
45410
  }
45117
45411
  function snapshotMessagesFromSessionFile(ctx, stage) {
45118
45412
  ctx.chatHost.loadSessionFile(liveHandle(ctx)?.sessionFile ?? stage?.sessionFile);
@@ -45245,7 +45539,7 @@ function resolvePromptResponse(ctx, promptId, response, metadata = {}) {
45245
45539
  ctx.onDetach("prompt-resolved", metadata);
45246
45540
  }
45247
45541
  function viewLineCount(ctx) {
45248
- const reported = ctx.getViewportRows?.();
45542
+ const reported = ctx.piTui?.terminal?.rows;
45249
45543
  if (typeof reported !== "number" || !Number.isFinite(reported)) {
45250
45544
  return VIEW_LINE_COUNT;
45251
45545
  }
@@ -45342,6 +45636,10 @@ function promptPageSize(ctx) {
45342
45636
 
45343
45637
  // dist/builtin/workflows/src/tui/stage-chat-view-input.ts
45344
45638
  function handleStageChatInput(ctx, data) {
45639
+ const keybindings = isKeybindingsLike(ctx.piKeybindings) ? ctx.piKeybindings : undefined;
45640
+ if (matchesKey(data, Key.ctrl("t")) && matchesAction(keybindings, data, APP_ACTION.thinkingToggle)) {
45641
+ return false;
45642
+ }
45345
45643
  if (matchesKey(data, Key.ctrl("x"))) {
45346
45644
  if (ctx.mountedCustomUi)
45347
45645
  releaseMountedCustomUi(ctx);
@@ -45353,11 +45651,6 @@ function handleStageChatInput(ctx, data) {
45353
45651
  ctx.onDetach();
45354
45652
  return true;
45355
45653
  }
45356
- if (matchesKey(data, Key.ctrl("t"))) {
45357
- ctx.mouseScrollCaptureEnabled = !ctx.mouseScrollCaptureEnabled;
45358
- ctx.requestRender?.();
45359
- return true;
45360
- }
45361
45654
  if (ctx.mountedCustomUi) {
45362
45655
  return handleMountedCustomUiInput(ctx, data);
45363
45656
  }
@@ -45435,9 +45728,9 @@ function handleMountedCustomUiInput(ctx, data) {
45435
45728
  }
45436
45729
  const component = mounted.component;
45437
45730
  setComponentFocused(component, ctx.focused);
45438
- component.handleInput?.(data);
45731
+ const handled = component.handleInput?.(data) === true;
45439
45732
  ctx.requestRender?.();
45440
- return true;
45733
+ return handled;
45441
45734
  }
45442
45735
  function handlePromptInput(ctx, data) {
45443
45736
  const state = ctx.promptState;
@@ -45535,7 +45828,6 @@ class StageChatView {
45535
45828
  requestRender;
45536
45829
  requestFocus;
45537
45830
  focusHoldTimer;
45538
- getViewportRows;
45539
45831
  piTui;
45540
45832
  piTheme;
45541
45833
  piKeybindings;
@@ -45556,7 +45848,6 @@ class StageChatView {
45556
45848
  promptMaxScroll;
45557
45849
  promptVisibleRows;
45558
45850
  localPaused;
45559
- mouseScrollCaptureEnabled;
45560
45851
  seenNoticeIds;
45561
45852
  _unsubscribeStore;
45562
45853
  _unsubscribeHandle;
@@ -45630,9 +45921,6 @@ class StageChatView {
45630
45921
  ];
45631
45922
  return fitStageChatFrame(lines, totalRows, blankLine(w));
45632
45923
  }
45633
- wantsMouseScrollTracking() {
45634
- return this.mouseScrollCaptureEnabled;
45635
- }
45636
45924
  handleInput(data) {
45637
45925
  return handleStageChatInput(this._ctx(), data);
45638
45926
  }
@@ -45655,7 +45943,6 @@ class StageChatView {
45655
45943
  this.requestRender;
45656
45944
  this.requestFocus;
45657
45945
  this.focusHoldTimer;
45658
- this.getViewportRows;
45659
45946
  this.piTui;
45660
45947
  this.piTheme;
45661
45948
  this.piKeybindings;
@@ -45672,7 +45959,6 @@ class StageChatView {
45672
45959
  this.promptScrollOffset;
45673
45960
  this.promptMaxScroll;
45674
45961
  this.promptVisibleRows;
45675
- this.mouseScrollCaptureEnabled;
45676
45962
  this.seenNoticeIds;
45677
45963
  this._unsubscribeStore;
45678
45964
  this._unsubscribeHandle;
@@ -45727,10 +46013,8 @@ class WorkflowAttachPane {
45727
46013
  onClose;
45728
46014
  onHide;
45729
46015
  onPromptResolve;
45730
- getViewportRows;
45731
46016
  hostRequestRender;
45732
46017
  hostRequestFocus;
45733
- setMouseScrollTracking;
45734
46018
  piTui;
45735
46019
  piTheme;
45736
46020
  piKeybindings;
@@ -45762,10 +46046,8 @@ class WorkflowAttachPane {
45762
46046
  this.onClose = opts.onClose;
45763
46047
  this.onHide = opts.onHide;
45764
46048
  this.onPromptResolve = opts.onPromptResolve;
45765
- this.getViewportRows = opts.getViewportRows;
45766
46049
  this.hostRequestRender = opts.requestRender;
45767
46050
  this.hostRequestFocus = opts.requestFocus;
45768
- this.setMouseScrollTracking = opts.setMouseScrollTracking;
45769
46051
  this.piTui = opts.piTui;
45770
46052
  this.piTheme = opts.piTheme;
45771
46053
  this.piKeybindings = opts.piKeybindings;
@@ -45783,7 +46065,6 @@ class WorkflowAttachPane {
45783
46065
  } else {
45784
46066
  this._syncAwaitingInputKeys(readGraphStoreSnapshot(this.store));
45785
46067
  this._armGraphEnterQuarantineIfRunNeedsInput();
45786
- this._syncMouseScrollTracking();
45787
46068
  }
45788
46069
  }
45789
46070
  _buildGraphView(initialFocusedStageId, initialFocusedRunId) {
@@ -45804,7 +46085,7 @@ class WorkflowAttachPane {
45804
46085
  },
45805
46086
  initialFocusedStageId,
45806
46087
  initialFocusedRunId,
45807
- getViewportRows: this.getViewportRows,
46088
+ piTui: this.piTui,
45808
46089
  piKeybindings: this.piKeybindings,
45809
46090
  footerData: this.footerData,
45810
46091
  getStageQueuedMessageCount: (runId, stageId) => this._stageQueuedMessageCount(runId, stageId),
@@ -45866,14 +46147,12 @@ class WorkflowAttachPane {
45866
46147
  getToolsExpanded: this.getToolsExpanded,
45867
46148
  setToolsExpanded: this.setToolsExpanded,
45868
46149
  footerData: this.footerData,
45869
- getViewportRows: this.getViewportRows,
45870
46150
  stageUiBroker: this.stageUiBroker,
45871
46151
  canSubmitPrompt: (candidateRunId, candidateStageId) => this.visible && this.mode === "stage-chat" && this.chatView === chatView && this.attachedRunId === candidateRunId && this.lastAttachedStageId === candidateStageId && this._isStageMarkedAttached(candidateRunId, candidateStageId)
45872
46152
  });
45873
46153
  this.chatView = chatView;
45874
46154
  this.mode = "stage-chat";
45875
46155
  this.store.recordStageAttached(runId, stageId, this.visible);
45876
- this._syncMouseScrollTracking();
45877
46156
  }
45878
46157
  _detachFromStage(reason = "user", metadata = {}) {
45879
46158
  this.composerDrafts.capture(this.attachedRunId, this.lastAttachedStageId, this.chatView?._inputBuffer);
@@ -45890,7 +46169,6 @@ class WorkflowAttachPane {
45890
46169
  this.lastStageAwaitingInputKey = null;
45891
46170
  this.lastGraphAwaitingInputKey = this.runId ? this._runAwaitingInputKey(readGraphStoreSnapshot(this.store), this.runId) : null;
45892
46171
  this.graphEnterQuarantineUntil = reason === "prompt-resolved" && metadata.suppressNextGraphSubmit === true ? this.now() + ENTER_TRANSITION_QUARANTINE_MS : 0;
45893
- this._syncMouseScrollTracking();
45894
46172
  }
45895
46173
  retarget(runId, stageId, stageRunId) {
45896
46174
  if (this.chatView && this.attachedRunId && this.lastAttachedStageId) {
@@ -45915,7 +46193,6 @@ class WorkflowAttachPane {
45915
46193
  }
45916
46194
  }
45917
46195
  this._armGraphEnterQuarantineIfRunNeedsInput();
45918
- this._syncMouseScrollTracking();
45919
46196
  }
45920
46197
  _resolveGraphStageTarget(rootRunId, stageId) {
45921
46198
  const graph = expandWorkflowGraph(readGraphStoreSnapshot(this.store), rootRunId);
@@ -45971,15 +46248,6 @@ class WorkflowAttachPane {
45971
46248
  this.store.recordStageAttached(this.attachedRunId, this.lastAttachedStageId, visible);
45972
46249
  }
45973
46250
  }
45974
- _syncMouseScrollTracking() {
45975
- this.setMouseScrollTracking?.(this.wantsMouseScrollTracking());
45976
- }
45977
- wantsMouseScrollTracking() {
45978
- if (this.mode === "stage-chat" && this.chatView) {
45979
- return this.chatView.wantsMouseScrollTracking();
45980
- }
45981
- return this.mode === "graph";
45982
- }
45983
46251
  wantsFocusForAwaitingInput(snapshot) {
45984
46252
  if (!this.visible)
45985
46253
  return false;
@@ -46010,12 +46278,7 @@ class WorkflowAttachPane {
46010
46278
  if (this.mode === "stage-chat" && this.chatView) {
46011
46279
  if (this._shouldQuarantineStagePromptEnter(data))
46012
46280
  return true;
46013
- const beforeMouseTracking = this.chatView.wantsMouseScrollTracking();
46014
- const handled = this.chatView.handleInput(data);
46015
- const afterMouseTracking = this.chatView?.wantsMouseScrollTracking();
46016
- if (afterMouseTracking !== undefined && afterMouseTracking !== beforeMouseTracking)
46017
- this._syncMouseScrollTracking();
46018
- return handled;
46281
+ return this.chatView.handleInput(data);
46019
46282
  }
46020
46283
  if (this._shouldQuarantineGraphEnter(data))
46021
46284
  return true;
@@ -46133,7 +46396,6 @@ class WorkflowAttachPane {
46133
46396
  this.chatView?.dispose();
46134
46397
  this.chatView = null;
46135
46398
  this.graphView.dispose();
46136
- this.setMouseScrollTracking?.(false);
46137
46399
  }
46138
46400
  get _mode() {
46139
46401
  return this.mode;
@@ -46173,12 +46435,7 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46173
46435
  }
46174
46436
  };
46175
46437
  let remoteTerminalControl = null;
46176
- const updateMouseScrollTracking = (enabled) => {
46177
- if (remoteTerminalControl)
46178
- remoteTerminalControl.setMouseScrollTracking(enabled);
46179
- else
46180
- setMouseScrollTracking(enabled, terminalOutput);
46181
- };
46438
+ let localTerminalModesSuppressed = false;
46182
46439
  let currentView = null;
46183
46440
  let currentHandle = null;
46184
46441
  let mounted = false;
@@ -46197,7 +46454,8 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46197
46454
  remoteTerminalControl.setAutowrap(!visible);
46198
46455
  return;
46199
46456
  }
46200
- setTerminalAutowrap(!visible, terminalOutput);
46457
+ if (!localTerminalModesSuppressed)
46458
+ setTerminalAutowrap(!visible, terminalOutput);
46201
46459
  }
46202
46460
  function readHostCustomUiActive(ui = observedUi) {
46203
46461
  const state = ui?.getHostCustomUiState?.();
@@ -46231,7 +46489,6 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46231
46489
  updateMainChatInputHint(readHostCustomUiActive(ui));
46232
46490
  }
46233
46491
  function close() {
46234
- updateMouseScrollTracking(false);
46235
46492
  currentHandle?.hide();
46236
46493
  updateTerminalAutowrap(false);
46237
46494
  finishMounted?.();
@@ -46242,11 +46499,11 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46242
46499
  currentView = null;
46243
46500
  mounted = false;
46244
46501
  remoteTerminalControl = null;
46502
+ localTerminalModesSuppressed = false;
46245
46503
  requestMountedRender = null;
46246
46504
  clearHostCustomUiObservation();
46247
46505
  }
46248
46506
  function hideMounted() {
46249
- updateMouseScrollTracking(false);
46250
46507
  observedUi?.setStatus?.(MAIN_CHAT_INPUT_STATUS_KEY, undefined);
46251
46508
  if (currentHandle) {
46252
46509
  currentView?.setVisible(false);
@@ -46289,11 +46546,11 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46289
46546
  const consumed = view.handleInput(data);
46290
46547
  if (consumed)
46291
46548
  tui.requestRender?.();
46549
+ return consumed === true;
46292
46550
  },
46293
46551
  invalidate: () => tui.requestRender?.(),
46294
46552
  dispose: () => {
46295
46553
  updateTerminalAutowrap(false);
46296
- updateMouseScrollTracking(false);
46297
46554
  remoteTerminalControl = null;
46298
46555
  requestMountedRender = null;
46299
46556
  unsubscribe();
@@ -46308,7 +46565,6 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46308
46565
  currentView?.retarget(runId, stageId, stageRunId);
46309
46566
  currentView?.setVisible(true);
46310
46567
  updateTerminalAutowrap(true);
46311
- updateMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
46312
46568
  currentHandle.setHidden(false);
46313
46569
  currentHandle.focus();
46314
46570
  requestMountedRender?.();
@@ -46317,7 +46573,6 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46317
46573
  if (mounted) {
46318
46574
  currentView?.retarget(runId, stageId, stageRunId);
46319
46575
  updateTerminalAutowrap(true);
46320
- updateMouseScrollTracking(currentView?.wantsMouseScrollTracking() ?? true);
46321
46576
  currentHandle?.focus();
46322
46577
  return;
46323
46578
  }
@@ -46326,12 +46581,12 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46326
46581
  return;
46327
46582
  let settled = false;
46328
46583
  const factory = (tui, theme, keybindings, done) => {
46584
+ localTerminalModesSuppressed = tui.mode === "fullscreen";
46329
46585
  remoteTerminalControl = remoteTerminalControlFrom(tui);
46330
46586
  const finish = () => {
46331
46587
  if (settled)
46332
46588
  return;
46333
46589
  settled = true;
46334
- updateMouseScrollTracking(false);
46335
46590
  observedUi?.setStatus?.(MAIN_CHAT_INPUT_STATUS_KEY, undefined);
46336
46591
  currentView?.dispose();
46337
46592
  currentView = null;
@@ -46345,6 +46600,7 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46345
46600
  } finally {
46346
46601
  updateTerminalAutowrap(false);
46347
46602
  remoteTerminalControl = null;
46603
+ localTerminalModesSuppressed = false;
46348
46604
  }
46349
46605
  };
46350
46606
  const view = new WorkflowAttachPane({
@@ -46366,7 +46622,6 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46366
46622
  getToolsExpanded: ui?.getToolsExpanded,
46367
46623
  setToolsExpanded: ui?.setToolsExpanded,
46368
46624
  footerData: ui?.getFooterDataProvider?.(),
46369
- getViewportRows: () => tui.terminal?.rows,
46370
46625
  requestRender: () => {
46371
46626
  if (currentHandle?.isHidden() === true)
46372
46627
  return;
@@ -46379,14 +46634,12 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46379
46634
  return;
46380
46635
  currentHandle?.focus();
46381
46636
  },
46382
- setMouseScrollTracking: updateMouseScrollTracking,
46383
46637
  now: buildOpts.now
46384
46638
  });
46385
46639
  currentView = view;
46386
46640
  finishMounted = finish;
46387
46641
  mounted = true;
46388
46642
  updateTerminalAutowrap(true);
46389
- updateMouseScrollTracking(view.wantsMouseScrollTracking());
46390
46643
  updateMainChatInputHint(readHostCustomUiActive(ui));
46391
46644
  return makeComponent2(view, tui);
46392
46645
  };
@@ -46409,7 +46662,6 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46409
46662
  currentView?.setVisible(!nowHidden);
46410
46663
  if (!nowHidden)
46411
46664
  updateTerminalAutowrap(true);
46412
- updateMouseScrollTracking(nowHidden ? false : currentView?.wantsMouseScrollTracking() ?? true);
46413
46665
  currentHandle.setHidden(nowHidden);
46414
46666
  if (nowHidden)
46415
46667
  updateTerminalAutowrap(false);
@@ -46431,7 +46683,8 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
46431
46683
  // dist/builtin/workflows/src/tui/store-widget-installer.ts
46432
46684
  import {
46433
46685
  decideReactiveWidgetAction,
46434
- installReactiveWidget
46686
+ installReactiveWidget,
46687
+ isStaleExtensionContextError as isStaleExtensionContextError4
46435
46688
  } from "@bastani/atomic";
46436
46689
 
46437
46690
  // dist/builtin/workflows/src/tui/widget.ts
@@ -46710,10 +46963,6 @@ var defaultTimerApi = {
46710
46963
  clearTimeout: (handle) => clearTimeout(handle)
46711
46964
  };
46712
46965
  var WIDGET_KEY = "workflow.run";
46713
- var STALE_CONTEXT = "This extension ctx is stale";
46714
- function isStale(err) {
46715
- return err instanceof Error && err.message.includes(STALE_CONTEXT);
46716
- }
46717
46966
  function liveWidgetSnapshot(storeInstance) {
46718
46967
  return {
46719
46968
  runs: storeInstance.runs(),
@@ -46740,7 +46989,7 @@ function installStoreWidget(pi, storeInstance, timers = defaultTimerApi) {
46740
46989
  render: (snap, { theme, width, now }) => buildThemedWidgetLines(snap, theme, width, now),
46741
46990
  getNextRefreshDelayMs: (snap, now) => nextWidgetRefreshDelayMs(snap, now),
46742
46991
  requestRenderOnStateNoop: false,
46743
- isStaleError: isStale
46992
+ isStaleError: isStaleExtensionContextError4
46744
46993
  });
46745
46994
  return () => controller.dispose();
46746
46995
  }
@@ -47818,7 +48067,7 @@ class InMemoryDurableBackend {
47818
48067
  ...handle.label !== undefined ? { label: handle.label } : {},
47819
48068
  ...handle.rootWorkflowId !== undefined ? { rootWorkflowId: handle.rootWorkflowId } : {},
47820
48069
  ...handle.resumable !== undefined ? { resumable: handle.resumable } : {},
47821
- ...workflowFailureFields(handle.error !== undefined ? handle : handle.status === "running" ? undefined : existing?.handle),
48070
+ ...workflowFailureFields(hasWorkflowFailureMetadata(handle) ? handle : handle.status === "running" ? undefined : existing?.handle),
47822
48071
  ...handle.ownerExecutorId !== undefined ? { ownerExecutorId: handle.ownerExecutorId } : existing?.handle.ownerExecutorId !== undefined ? { ownerExecutorId: existing.handle.ownerExecutorId } : {}
47823
48072
  };
47824
48073
  if (existing)
@@ -47927,6 +48176,8 @@ class InMemoryDurableBackend {
47927
48176
  rec.handle = {
47928
48177
  ...rec.handle,
47929
48178
  error: undefined,
48179
+ exited: undefined,
48180
+ exitReason: undefined,
47930
48181
  failureKind: undefined,
47931
48182
  failureCode: undefined,
47932
48183
  failureRecoverability: undefined,
@@ -48061,11 +48312,16 @@ function hasResumeProgress(handle) {
48061
48312
  function isHistoricalHandle(handle) {
48062
48313
  return handle.status === "completed" && hasResumeProgress(handle) || handle.status === "failed" && !isDurableWorkflowResumable(handle) && hasResumeProgress(handle);
48063
48314
  }
48315
+ function hasWorkflowFailureMetadata(handle) {
48316
+ return handle.error !== undefined || handle.exited !== undefined || handle.exitReason !== undefined || handle.failureKind !== undefined || handle.failureCode !== undefined || handle.failureRecoverability !== undefined || handle.failureDisposition !== undefined || handle.failedToolNodeId !== undefined;
48317
+ }
48064
48318
  function workflowFailureFields(handle) {
48065
48319
  if (handle === undefined)
48066
48320
  return {};
48067
48321
  return {
48068
48322
  ...handle.error !== undefined ? { error: handle.error } : {},
48323
+ ...handle.exited !== undefined ? { exited: handle.exited } : {},
48324
+ ...handle.exitReason !== undefined ? { exitReason: handle.exitReason } : {},
48069
48325
  ...handle.failureKind !== undefined ? { failureKind: handle.failureKind } : {},
48070
48326
  ...handle.failureCode !== undefined ? { failureCode: handle.failureCode } : {},
48071
48327
  ...handle.failureRecoverability !== undefined ? { failureRecoverability: handle.failureRecoverability } : {},
@@ -48306,7 +48562,7 @@ function isWorkflowChildResult(value2) {
48306
48562
  return parseWorkflowChildResult(value2) !== undefined;
48307
48563
  }
48308
48564
  function isWorkflowExitStatus(value2) {
48309
- return value2 === "completed" || value2 === "skipped" || value2 === "cancelled" || value2 === "blocked";
48565
+ return value2 === "completed" || value2 === "skipped" || value2 === "cancelled" || value2 === "blocked" || value2 === "failed";
48310
48566
  }
48311
48567
  function isOrdinaryObject(value2) {
48312
48568
  if (typeof value2 !== "object" || value2 === null || Array.isArray(value2))
@@ -49294,6 +49550,8 @@ function encodeMetadata(metadata) {
49294
49550
  ...metadata.label !== undefined ? { label: metadata.label } : {},
49295
49551
  ...metadata.rootWorkflowId !== undefined ? { rootWorkflowId: metadata.rootWorkflowId } : {},
49296
49552
  ...metadata.resumable !== undefined ? { resumable: metadata.resumable } : {},
49553
+ ...metadata.exited !== undefined ? { exited: metadata.exited } : {},
49554
+ ...metadata.exitReason !== undefined ? { exitReason: metadata.exitReason } : {},
49297
49555
  ...metadata.error !== undefined ? { error: metadata.error } : {},
49298
49556
  ...metadata.failureKind !== undefined ? { failureKind: metadata.failureKind } : {},
49299
49557
  ...metadata.failureCode !== undefined ? { failureCode: metadata.failureCode } : {},
@@ -49344,7 +49602,7 @@ function parseDurableWorkflowMetadata(value2, workflowId) {
49344
49602
  if (typeof value2 !== "object" || value2 === null || Array.isArray(value2))
49345
49603
  return;
49346
49604
  const metadata = value2;
49347
- if (metadata.workflowId !== workflowId || typeof metadata.workflowId !== "string" || typeof metadata.name !== "string" || typeof metadata.inputs !== "object" || metadata.inputs === null || Array.isArray(metadata.inputs) || typeof metadata.status !== "string" || !isDurableWorkflowStatus(metadata.status) || typeof metadata.completedCheckpoints !== "number" || typeof metadata.createdAt !== "number" || typeof metadata.pendingPrompts !== "number" || typeof metadata.promptReservationEpoch !== "string" || typeof metadata.updatedAt !== "number" || metadata.ownerExecutorId !== undefined && typeof metadata.ownerExecutorId !== "string" || metadata.transitionClaimId !== undefined && typeof metadata.transitionClaimId !== "string" || metadata.sessionFile !== undefined && typeof metadata.sessionFile !== "string" || metadata.label !== undefined && typeof metadata.label !== "string" || metadata.rootWorkflowId !== undefined && typeof metadata.rootWorkflowId !== "string" || metadata.resumable !== undefined && typeof metadata.resumable !== "boolean" || metadata.error !== undefined && typeof metadata.error !== "string" || metadata.failureKind !== undefined && !isWorkflowFailureKind(metadata.failureKind) || metadata.failureCode !== undefined && !isWorkflowFailureCode(metadata.failureCode) || metadata.failureRecoverability !== undefined && !isWorkflowFailureRecoverability(metadata.failureRecoverability) || metadata.failureDisposition !== undefined && !isWorkflowFailureDisposition(metadata.failureDisposition) || metadata.failedToolNodeId !== undefined && typeof metadata.failedToolNodeId !== "string" || metadata.invocationCwd !== undefined && typeof metadata.invocationCwd !== "string" || metadata.workflowCwd !== undefined && typeof metadata.workflowCwd !== "string" || metadata.repositoryRoot !== undefined && typeof metadata.repositoryRoot !== "string" || metadata.gitWorktreeRoot !== undefined && typeof metadata.gitWorktreeRoot !== "string")
49605
+ if (metadata.workflowId !== workflowId || typeof metadata.workflowId !== "string" || typeof metadata.name !== "string" || typeof metadata.inputs !== "object" || metadata.inputs === null || Array.isArray(metadata.inputs) || typeof metadata.status !== "string" || !isDurableWorkflowStatus(metadata.status) || typeof metadata.completedCheckpoints !== "number" || typeof metadata.createdAt !== "number" || typeof metadata.pendingPrompts !== "number" || typeof metadata.promptReservationEpoch !== "string" || typeof metadata.updatedAt !== "number" || metadata.ownerExecutorId !== undefined && typeof metadata.ownerExecutorId !== "string" || metadata.transitionClaimId !== undefined && typeof metadata.transitionClaimId !== "string" || metadata.sessionFile !== undefined && typeof metadata.sessionFile !== "string" || metadata.label !== undefined && typeof metadata.label !== "string" || metadata.rootWorkflowId !== undefined && typeof metadata.rootWorkflowId !== "string" || metadata.resumable !== undefined && typeof metadata.resumable !== "boolean" || metadata.exited !== undefined && typeof metadata.exited !== "boolean" || metadata.exitReason !== undefined && typeof metadata.exitReason !== "string" || metadata.error !== undefined && typeof metadata.error !== "string" || metadata.failureKind !== undefined && !isWorkflowFailureKind(metadata.failureKind) || metadata.failureCode !== undefined && !isWorkflowFailureCode(metadata.failureCode) || metadata.failureRecoverability !== undefined && !isWorkflowFailureRecoverability(metadata.failureRecoverability) || metadata.failureDisposition !== undefined && !isWorkflowFailureDisposition(metadata.failureDisposition) || metadata.failedToolNodeId !== undefined && typeof metadata.failedToolNodeId !== "string" || metadata.invocationCwd !== undefined && typeof metadata.invocationCwd !== "string" || metadata.workflowCwd !== undefined && typeof metadata.workflowCwd !== "string" || metadata.repositoryRoot !== undefined && typeof metadata.repositoryRoot !== "string" || metadata.gitWorktreeRoot !== undefined && typeof metadata.gitWorktreeRoot !== "string")
49348
49606
  return;
49349
49607
  const { origin, ...metadataWithoutOrigin } = metadata;
49350
49608
  return {
@@ -50158,13 +50416,14 @@ import { dirname, join } from "node:path";
50158
50416
  // dist/builtin/workflows/src/durable/local-command.ts
50159
50417
  import { spawn } from "node:child_process";
50160
50418
  import { connect } from "node:net";
50419
+ import { createChildProcessEnvironment } from "@bastani/atomic";
50161
50420
  var OUTPUT_LIMIT_BYTES = 16384;
50162
50421
  function runLocalCommand(command, args, options) {
50163
50422
  return new Promise((resolve, reject) => {
50164
50423
  const child = spawn(command, [...args], {
50165
50424
  stdio: ["ignore", "pipe", "pipe"],
50166
50425
  windowsHide: true,
50167
- ...options?.env !== undefined ? { env: { ...process.env, ...options.env } } : {},
50426
+ env: createChildProcessEnvironment(options?.env ? { ...options.env } : undefined),
50168
50427
  ...options?.uid !== undefined ? { uid: options.uid } : {},
50169
50428
  ...options?.gid !== undefined ? { gid: options.gid } : {}
50170
50429
  });
@@ -51669,6 +51928,16 @@ async function resumeRun(runId, opts) {
51669
51928
  message: "This workflow is not resumable; inspect the snapshot and start a new workflow run when ready."
51670
51929
  };
51671
51930
  }
51931
+ if (current.status === "failed" && current.endedAt !== undefined && current.exited === true && current.resumable === true) {
51932
+ return {
51933
+ ok: true,
51934
+ runId,
51935
+ snapshot,
51936
+ resumed: resumedCopy,
51937
+ mode: "snapshot",
51938
+ message: `This failed run is marked resumable; use /workflow resume ${runId} to ask the durable backend to retry it or start a new workflow run.`
51939
+ };
51940
+ }
51672
51941
  if (current.endedAt === undefined && current.resumable === true && current.failureRecoverability === "recoverable" && current.failedStageId !== undefined) {
51673
51942
  return {
51674
51943
  ok: true,
@@ -52303,7 +52572,9 @@ function formatWorkflowLifecycleNoticeText(details) {
52303
52572
  const tool = lifecycleToolOrigin(details);
52304
52573
  const failureSite = stage2 ? `, stage ${stage2}` : tool !== undefined ? `, tool ${tool}` : "";
52305
52574
  const errorText = details.error ? `: ${details.error}` : "";
52306
- return `✗ Workflow "${workflowName}" failed (run ${details.runId}${failureSite})${origin}${errorText}. Inspect: /workflow status ${details.runId}`;
52575
+ const outputsText = formatLifecycleOutputs(details.outputs);
52576
+ const outputSuffix = outputsText === undefined ? "" : ` Partial outputs: ${outputsText}`;
52577
+ return `✗ Workflow "${workflowName}" failed (run ${details.runId}${failureSite})${origin}${errorText}${outputSuffix}. Inspect: /workflow status ${details.runId}`;
52307
52578
  }
52308
52579
  if (details.kind === "blocked") {
52309
52580
  const errorText = details.error ? `: ${details.error}` : "";
@@ -52339,7 +52610,8 @@ function makeTerminalNotice(run, kind) {
52339
52610
  const failedToolNodeId = kind === "failed" && run.failedStageId === undefined ? run.failedToolNodeId : undefined;
52340
52611
  const failedTool = (run.toolNodes ?? []).find((node) => node.id === failedToolNodeId);
52341
52612
  const activeBlocked = kind === "blocked" && isActiveRecoverableBlockedRun(run);
52342
- const error = activeBlocked ? run.failureMessage ?? structuredRecoverableWorkflowFailureText(run) ?? run.error : run.error ?? returnedNoticeError(run, kind) ?? (kind === "blocked" ? run.exitReason : undefined);
52613
+ const outputs = kind === "failed" && run.exited === true && run.result !== undefined ? run.result : undefined;
52614
+ const error = activeBlocked ? run.failureMessage ?? structuredRecoverableWorkflowFailureText(run) ?? run.error : run.error ?? returnedNoticeError(run, kind) ?? (kind === "blocked" || kind === "failed" ? run.exitReason : undefined);
52343
52615
  return {
52344
52616
  kind,
52345
52617
  scope: "run",
@@ -52347,7 +52619,9 @@ function makeTerminalNotice(run, kind) {
52347
52619
  workflowName: run.name,
52348
52620
  status: effectiveRunStatus(run),
52349
52621
  ...activeBlocked ? { active: true } : {},
52622
+ ...run.exited === true && run.status === "failed" && run.resumable !== undefined ? { resumable: run.resumable } : {},
52350
52623
  ...error ? { error: truncateSnippet(error) } : {},
52624
+ ...outputs !== undefined ? { outputs } : {},
52351
52625
  ...run.failedStageId ? { failedStageId: run.failedStageId } : {},
52352
52626
  ...failedStage ? { stageId: failedStage.id, stageName: failedStage.name } : {},
52353
52627
  ...failedToolNodeId !== undefined ? { toolNodeId: failedToolNodeId } : {},
@@ -52409,6 +52683,8 @@ function lifecycleOccurrenceAt(run, kind) {
52409
52683
  return run.endedAt;
52410
52684
  }
52411
52685
  function returnedNoticeError(run, kind) {
52686
+ if (run.exited === true && (kind === "failed" || kind === "blocked"))
52687
+ return run.exitReason;
52412
52688
  const structuredFailureText = structuredRecoverableWorkflowFailureText(run);
52413
52689
  if (kind === "blocked" && structuredFailureText !== undefined)
52414
52690
  return structuredFailureText;
@@ -52491,6 +52767,16 @@ function truncateSnippet(value2) {
52491
52767
  return normalized;
52492
52768
  return `${normalized.slice(0, LIFECYCLE_NOTICE_SNIPPET_LIMIT - 1)}…`;
52493
52769
  }
52770
+ function formatLifecycleOutputs(outputs) {
52771
+ if (outputs === undefined)
52772
+ return;
52773
+ try {
52774
+ const serialized = JSON.stringify(outputs);
52775
+ return serialized === undefined ? "available; inspect the run result" : truncateSnippet(serialized);
52776
+ } catch {
52777
+ return "available; inspect the run result";
52778
+ }
52779
+ }
52494
52780
  function makeNoticeComponent2(details, theme) {
52495
52781
  const text = formatWorkflowLifecycleNoticeText(details);
52496
52782
  return {
@@ -52522,6 +52808,11 @@ function renderLifecycleNoticeCard(details, opts) {
52522
52808
  { label: "launched", value: details.origin, tone: "muted" },
52523
52809
  { label: "prompt", value: details.promptMessage, tone: "muted" },
52524
52810
  { label: "error", value: details.error, tone: "error" },
52811
+ {
52812
+ label: "partial outputs",
52813
+ value: formatLifecycleOutputs(details.outputs),
52814
+ tone: "muted"
52815
+ },
52525
52816
  { label: "resumable", value: resumableFieldValue(details), tone: "muted" },
52526
52817
  { label: "duration", value: formatDurationMs(details.durationMs), tone: "muted" }
52527
52818
  ],
@@ -53504,10 +53795,13 @@ var CONTRACT_FIDELITY_AUDIT = [
53504
53795
  ].join(`
53505
53796
  `);
53506
53797
  var REVIEWER_INTERCOM_COORDINATION_PROTOCOL = [
53507
- "Concurrent reviewer coordination:",
53798
+ "Concurrent reviewer coordination (constructive quorum):",
53508
53799
  "- At review start, use Intercom to discover sibling reviewers and share validation plans and check ownership.",
53509
53800
  "- Claim, serialize, announce, and release expensive or conflicting shared-checkout/environment work such as suites, builds, package operations, browser/E2E sessions, migrations, and generated-artifact steps; share reusable command evidence.",
53510
- "- Coordination is operational only: inspect independently and return your own verdict rather than copying or deferring to sibling conclusions."
53801
+ "- First, inspect independently and form a preliminary assessment before reading or relying on sibling findings or verdicts. After the exchange, inspect independently and return your own verdict rather than copying or deferring to sibling conclusions.",
53802
+ "- Then run exactly one bounded evidence-exchange round over Intercom: share your preliminary verdict, concise findings, and evidence; challenge blocking findings, surface defects a sibling missed, and correct objective/acceptance-criteria misreadings. Do not start a second round or continue substantive discussion.",
53803
+ "- Verdicts change only through concrete evidence, never through deference to a sibling's approval or rejection; inspect shared evidence yourself before deciding.",
53804
+ "- In `overall_explanation`, record whether deliberation changed your preliminary verdict and, if it did, which concrete evidence caused the change. If it did not, say so; return your own structured decision even when dissent remains."
53511
53805
  ].join(`
53512
53806
  `);
53513
53807
  var REVIEWER_INDEPENDENT_VERIFICATION_CONTRACT = [
@@ -54636,8 +54930,12 @@ import { existsSync as existsSync3 } from "node:fs";
54636
54930
  import { mkdir as mkdir2, readdir, rm, stat } from "node:fs/promises";
54637
54931
  import { dirname as dirname3, join as join10 } from "node:path";
54638
54932
  import { getAgentDir as getAgentDir2, getEnvValue as getEnvValue2 } from "@bastani/atomic";
54933
+
54934
+ // dist/builtin/workflows/src/shared/workflow-artifact-env.ts
54639
54935
  var WORKFLOW_ARTIFACT_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
54640
54936
  var ENV_WORKFLOW_ARTIFACT_DIR = "ATOMIC_WORKFLOW_ARTIFACT_DIR";
54937
+
54938
+ // dist/builtin/workflows/src/shared/workflow-artifacts.ts
54641
54939
  var ARTIFACT_PRUNE_RECHECK_MS = 60 * 60 * 1000;
54642
54940
  var lastArtifactPruneAt = new Map;
54643
54941
  var pendingArtifactPrunes = new Map;
@@ -55703,6 +56001,7 @@ import { mkdirSync as mkdirSync2 } from "node:fs";
55703
56001
  import { tmpdir as tmpdir2, userInfo } from "node:os";
55704
56002
  import { join as join13 } from "node:path";
55705
56003
  import { Type as Type11 } from "typebox";
56004
+ import { createChildProcessEnvironment as createChildProcessEnvironment2 } from "@bastani/atomic";
55706
56005
  var OUTPUT_TYPES = [
55707
56006
  "prototype",
55708
56007
  "wireframe",
@@ -55812,7 +56111,8 @@ function ensurePlaywrightCli() {
55812
56111
  const probe = spawnSync(isWindows ? "where" : "which", ["playwright-cli"], {
55813
56112
  stdio: "ignore",
55814
56113
  timeout: 15000,
55815
- shell: isWindows
56114
+ shell: isWindows,
56115
+ env: createChildProcessEnvironment2()
55816
56116
  });
55817
56117
  return probe.status === 0;
55818
56118
  } catch {
@@ -55832,7 +56132,8 @@ function ensurePlaywrightCli() {
55832
56132
  const install = spawnSync("npm", ["install", "-g", "@playwright/cli@latest"], {
55833
56133
  stdio: "ignore",
55834
56134
  timeout: 180000,
55835
- shell: isWindows
56135
+ shell: isWindows,
56136
+ env: createChildProcessEnvironment2()
55836
56137
  });
55837
56138
  if (install.status === 0) {
55838
56139
  return {
@@ -57617,29 +57918,34 @@ var promptEngineerModelConfig = {
57617
57918
  excludedTools: ["ask_user_question"]
57618
57919
  };
57619
57920
  var researchModelConfig = {
57620
- model: "openai-codex/gpt-5.6-luna:max",
57921
+ model: "anthropic/claude-opus-5:high",
57621
57922
  fallbackModels: [
57622
- "github-copilot/gpt-5.6-luna:max",
57623
- "openai/gpt-5.6-luna:max",
57624
- "anthropic/claude-opus-5:low",
57625
- "github-copilot/claude-opus-5:low",
57626
- "anthropic/claude-fable-5:low",
57627
- "github-copilot/claude-fable-5:low",
57628
- "openai-codex/gpt-5.5:medium",
57629
- "github-copilot/gpt-5.5:medium",
57630
- "openai/gpt-5.5:medium",
57631
- "anthropic/claude-opus-4-8:medium",
57632
- "github-copilot/claude-opus-4.8:medium",
57923
+ "github-copilot/claude-opus-5:high",
57924
+ "openai-codex/gpt-5.6-sol:xhigh",
57925
+ "github-copilot/gpt-5.6-sol:xhigh",
57926
+ "openai/gpt-5.6-sol:xhigh",
57927
+ "anthropic/claude-fable-5:high",
57928
+ "github-copilot/claude-fable-5:high",
57929
+ "kimi-coding/k3:max",
57930
+ "moonshotai/kimi-k3:max",
57931
+ "moonshotai-cn/kimi-k3:max",
57932
+ "openai-codex/gpt-5.5:xhigh",
57933
+ "github-copilot/gpt-5.5:xhigh",
57934
+ "openai/gpt-5.5:xhigh",
57935
+ "anthropic/claude-opus-4-8:high",
57936
+ "github-copilot/claude-opus-4.8:high",
57633
57937
  "xai/grok-4.5:high",
57634
- "zai/glm-5.2:high",
57635
- "zai-coding-cn/glm-5.2:high",
57636
- "openrouter/openai/gpt-5.6-luna:max",
57637
- "openrouter/anthropic/claude-opus-5:low",
57638
- "openrouter/openai/gpt-5.5:medium",
57639
- "openrouter/anthropic/claude-fable-5:low",
57640
- "openrouter/anthropic/claude-opus-4-8:medium",
57938
+ "zai/glm-5.2:xhigh",
57939
+ "zai-coding-cn/glm-5.2:xhigh",
57940
+ "openrouter/anthropic/claude-opus-5:high",
57941
+ "openrouter/openai/gpt-5.6-sol:xhigh",
57942
+ "openrouter/anthropic/claude-fable-5:high",
57943
+ "openrouter/moonshotai/kimi-k3:max",
57944
+ "openrouter/sakana/fugu-ultra:high",
57945
+ "openrouter/openai/gpt-5.5:xhigh",
57946
+ "openrouter/anthropic/claude-opus-4-8:high",
57641
57947
  "openrouter/x-ai/grok-4.5",
57642
- "openrouter/z-ai/glm-5.2:high"
57948
+ "openrouter/z-ai/glm-5.2:xhigh"
57643
57949
  ],
57644
57950
  excludedTools: ["ask_user_question"]
57645
57951
  };
@@ -58615,7 +58921,8 @@ var WORKFLOW_EXIT_STATUSES = new Set([
58615
58921
  "completed",
58616
58922
  "skipped",
58617
58923
  "cancelled",
58618
- "blocked"
58924
+ "blocked",
58925
+ "failed"
58619
58926
  ]);
58620
58927
  function makeWorkflowExitSignal(input) {
58621
58928
  return {
@@ -58623,6 +58930,7 @@ function makeWorkflowExitSignal(input) {
58623
58930
  scope: input.scope,
58624
58931
  status: input.status,
58625
58932
  ...input.reason !== undefined ? { reason: input.reason } : {},
58933
+ ...input.resumable !== undefined ? { resumable: input.resumable } : {},
58626
58934
  ...input.outputSnapshot !== undefined ? { outputSnapshot: input.outputSnapshot } : {},
58627
58935
  ...input.validationError !== undefined ? { validationError: input.validationError } : {}
58628
58936
  };
@@ -58859,6 +59167,9 @@ function readWorkflowExitSignalCandidate(value2, scope) {
58859
59167
  const reason = safeGetProperty(value2, "reason");
58860
59168
  if (!reason.ok || reason.value !== undefined && typeof reason.value !== "string")
58861
59169
  return;
59170
+ const resumable = safeGetProperty(value2, "resumable");
59171
+ if (!resumable.ok || resumable.value !== undefined && typeof resumable.value !== "boolean")
59172
+ return;
58862
59173
  const outputSnapshotValue = safeGetProperty(value2, "outputSnapshot");
58863
59174
  if (!outputSnapshotValue.ok)
58864
59175
  return;
@@ -58873,6 +59184,7 @@ function readWorkflowExitSignalCandidate(value2, scope) {
58873
59184
  scope,
58874
59185
  status: status.value,
58875
59186
  ...reason.value !== undefined ? { reason: reason.value } : {},
59187
+ ...resumable.value !== undefined ? { resumable: resumable.value } : {},
58876
59188
  ...outputSnapshot !== undefined ? { outputSnapshot } : {},
58877
59189
  ...validationError.value !== undefined ? { validationError: safeErrorValue(validationError.value) } : {}
58878
59190
  };
@@ -61138,7 +61450,7 @@ function openGitWorktreeGenerationAnchor(worktreeRoot) {
61138
61450
 
61139
61451
  // dist/builtin/workflows/src/runs/shared/worktree-git-runner.ts
61140
61452
  import { spawnSync as spawnSync2 } from "node:child_process";
61141
- import { createGitEnvironment } from "@bastani/atomic";
61453
+ import { createChildProcessEnvironment as createChildProcessEnvironment3, createGitEnvironment } from "@bastani/atomic";
61142
61454
  var DISABLED_GIT_HOOKS_PATH = process.platform === "win32" ? "NUL" : "/dev/null";
61143
61455
  var GIT_COMMAND_TIMEOUT_MS = 60000;
61144
61456
  var GIT_READ_ONLY_PROBE_TIMEOUT_ATTEMPTS = 2;
@@ -61162,7 +61474,7 @@ function spawnGit(cwd, args, plain) {
61162
61474
  const result = spawnSync2("git", plain ? args : gitCommandArgs(args), {
61163
61475
  cwd,
61164
61476
  encoding: "utf-8",
61165
- env: createGitEnvironment({ GIT_OPTIONAL_LOCKS: "0", GIT_TERMINAL_PROMPT: "0", GCM_INTERACTIVE: "never" }),
61477
+ env: createGitEnvironment({ GIT_OPTIONAL_LOCKS: "0", GIT_TERMINAL_PROMPT: "0", GCM_INTERACTIVE: "never" }, createChildProcessEnvironment3()),
61166
61478
  timeout: GIT_COMMAND_TIMEOUT_MS
61167
61479
  });
61168
61480
  return {
@@ -61798,6 +62110,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
61798
62110
  import * as fs6 from "node:fs";
61799
62111
  import * as os from "node:os";
61800
62112
  import * as path6 from "node:path";
62113
+ import { createChildProcessEnvironment as createChildProcessEnvironment4 } from "@bastani/atomic";
61801
62114
 
61802
62115
  // dist/builtin/workflows/src/runs/shared/worktree-post-create.ts
61803
62116
  import * as fs5 from "node:fs";
@@ -62080,6 +62393,7 @@ function runWorktreeSetupHook(hook, input) {
62080
62393
  cwd: input.worktreePath,
62081
62394
  encoding: "utf-8",
62082
62395
  input: JSON.stringify(input),
62396
+ env: createChildProcessEnvironment4(),
62083
62397
  timeout: hook.timeoutMs,
62084
62398
  shell: false
62085
62399
  });
@@ -63499,8 +63813,9 @@ function createRunFinalizers(input) {
63499
63813
  } catch (err) {
63500
63814
  return finalizeWorkflowExitValidationFailure(err, signal.reason);
63501
63815
  }
63816
+ const resumable = signal.status === "failed" && signal.resumable === true;
63502
63817
  const metadata = {
63503
- resumable: false,
63818
+ resumable,
63504
63819
  exited: true,
63505
63820
  ...signal.reason !== undefined ? { exitReason: signal.reason } : {}
63506
63821
  };
@@ -63511,7 +63826,7 @@ function createRunFinalizers(input) {
63511
63826
  result: outputs,
63512
63827
  exited: true,
63513
63828
  ...signal.reason !== undefined ? { exitReason: signal.reason } : {},
63514
- resumable: false,
63829
+ resumable,
63515
63830
  ts: Date.now()
63516
63831
  });
63517
63832
  return reconcileTerminalRunResult(input.runId, input.runSnapshot, input.activeStore, {
@@ -63879,7 +64194,7 @@ function createWorkflowExitManager(input) {
63879
64194
  if (!statusRead.ok) {
63880
64195
  captureValidationError(statusRead.error);
63881
64196
  } else if (!isWorkflowExitStatus2(rawStatus)) {
63882
- captureValidationError(new TypeError(`atomic-workflows: ctx.exit() status must be one of completed, skipped, cancelled, blocked; got ${describeWorkflowExitOptionValue(rawStatus)}`));
64197
+ captureValidationError(new TypeError(`atomic-workflows: ctx.exit() status must be one of completed, skipped, cancelled, blocked, failed; got ${describeWorkflowExitOptionValue(rawStatus)}`));
63883
64198
  }
63884
64199
  const status = isWorkflowExitStatus2(rawStatus) ? rawStatus : "completed";
63885
64200
  const reasonRead = readWorkflowExitOption(rawOptions, "reason");
@@ -63891,6 +64206,17 @@ function createWorkflowExitManager(input) {
63891
64206
  captureValidationError(new TypeError(`atomic-workflows: ctx.exit() reason must be a string when provided; got ${workflowSerializableTypeName(rawReason)}`));
63892
64207
  }
63893
64208
  const reason = typeof rawReason === "string" ? rawReason : undefined;
64209
+ const resumableRead = readWorkflowExitOption(rawOptions, "resumable");
64210
+ throwNestedSelectedExit();
64211
+ const rawResumable = resumableRead.ok ? resumableRead.value : undefined;
64212
+ if (!resumableRead.ok) {
64213
+ captureValidationError(resumableRead.error);
64214
+ } else if (rawResumable !== undefined && typeof rawResumable !== "boolean") {
64215
+ captureValidationError(new TypeError(`atomic-workflows: ctx.exit() resumable must be a boolean when provided; got ${workflowSerializableTypeName(rawResumable)}`));
64216
+ } else if (rawResumable !== undefined && rawStatus !== "failed") {
64217
+ captureValidationError(new TypeError(`atomic-workflows: ctx.exit() resumable is only valid with status failed; got ${describeWorkflowExitOptionValue(rawStatus)}`));
64218
+ }
64219
+ const resumable = status === "failed" && rawResumable === true;
63894
64220
  const outputsRead = readWorkflowExitOption(rawOptions, "outputs");
63895
64221
  throwNestedSelectedExit();
63896
64222
  const outputSnapshot = !outputsRead.ok ? freezeWorkflowExitOutputSnapshot({ ok: false, error: outputsRead.error }) : outputsRead.value !== undefined ? captureWorkflowExitOutputSnapshot(outputsRead.value) : undefined;
@@ -63899,6 +64225,7 @@ function createWorkflowExitManager(input) {
63899
64225
  scope: input.exitScope,
63900
64226
  status,
63901
64227
  ...reason !== undefined ? { reason } : {},
64228
+ ...status === "failed" ? { resumable } : {},
63902
64229
  ...outputSnapshot !== undefined ? { outputSnapshot } : {},
63903
64230
  ...validationError !== undefined ? { validationError } : {}
63904
64231
  }));
@@ -64329,7 +64656,7 @@ function createChildWorkflowRunner(input) {
64329
64656
  if (childRun.status === "paused" && childRun.exitReason === WORKFLOW_GRACEFUL_QUIT_EXIT_REASON && childRunId !== undefined) {
64330
64657
  throw new WorkflowGracefulQuitError(childRunId, `child workflow "${childName}" (${child.name})`);
64331
64658
  }
64332
- if (!isWorkflowExitStatus2(childRun.status)) {
64659
+ if (!isWorkflowExitStatus2(childRun.status) || childRun.status === "failed" && childRun.exited !== true) {
64333
64660
  const failedChildStage = childRun.stages.find((stage) => stage.failureKind !== undefined);
64334
64661
  throw new Error(`atomic-workflows: child workflow "${childName}" (${child.name}) failed with status ${childRun.status}${childRun.error !== undefined ? `: ${childRun.error}` : ""}`, {
64335
64662
  cause: {
@@ -64418,8 +64745,12 @@ async function finalizeDurableTerminalStatus(input) {
64418
64745
  if (durableStatus === "failed" || durableStatus === "blocked") {
64419
64746
  recordRunTimingCheckpoint(input.durableBackend, input.runSnapshot);
64420
64747
  }
64421
- const failure3 = durableStatus === "failed" && input.runSnapshot.error !== undefined ? {
64422
- error: input.runSnapshot.error,
64748
+ const failure3 = durableStatus === "failed" ? {
64749
+ ...input.runSnapshot.error !== undefined ? { error: input.runSnapshot.error } : {},
64750
+ ...input.runSnapshot.exited === true ? {
64751
+ exited: true,
64752
+ ...input.runSnapshot.exitReason !== undefined ? { exitReason: input.runSnapshot.exitReason } : {}
64753
+ } : {},
64423
64754
  ...input.runSnapshot.failureKind !== undefined ? { failureKind: input.runSnapshot.failureKind } : {},
64424
64755
  ...input.runSnapshot.failureCode !== undefined ? { failureCode: input.runSnapshot.failureCode } : {},
64425
64756
  ...input.runSnapshot.failureRecoverability !== undefined ? { failureRecoverability: input.runSnapshot.failureRecoverability } : {},
@@ -64568,16 +64899,24 @@ function compareDraftSourceOrder(left, right) {
64568
64899
  function runTopologyFor(drafts, tools) {
64569
64900
  return drafts.find((draft) => draft.topology?.run !== undefined)?.topology?.run ?? tools.find((checkpoint) => checkpoint.topology?.run !== undefined)?.topology?.run;
64570
64901
  }
64571
- function validateRunGroups(grouped, rootRunId, tools) {
64902
+ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
64572
64903
  const toolsFor = (runId) => tools.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
64573
64904
  const owners = new Map;
64905
+ const syntheticChildIds = new Set;
64574
64906
  for (const [parentRunId, drafts] of grouped) {
64575
64907
  for (const draft of drafts) {
64576
64908
  const childRunId = childRunIdFromDraft(draft);
64577
64909
  if (childRunId === undefined)
64578
64910
  continue;
64579
- if (!grouped.has(childRunId) || childRunId === parentRunId || owners.has(childRunId))
64911
+ if (childRunId === parentRunId || owners.has(childRunId))
64580
64912
  return false;
64913
+ if (!grouped.has(childRunId)) {
64914
+ if (!isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId))
64915
+ return false;
64916
+ syntheticChildIds.add(childRunId);
64917
+ owners.set(childRunId, draft);
64918
+ continue;
64919
+ }
64581
64920
  const childRun = runTopologyFor(grouped.get(childRunId), toolsFor(childRunId));
64582
64921
  if (childRun?.parentRunId !== parentRunId || childRun.parentStageId !== draft.topology?.stageId || childRun.rootRunId !== undefined && childRun.rootRunId !== rootRunId)
64583
64922
  return false;
@@ -64589,6 +64928,8 @@ function validateRunGroups(grouped, rootRunId, tools) {
64589
64928
  return false;
64590
64929
  }
64591
64930
  for (const runId of owners.keys()) {
64931
+ if (syntheticChildIds.has(runId))
64932
+ continue;
64592
64933
  const seen = new Set;
64593
64934
  let current = runId;
64594
64935
  while (current !== undefined && current !== rootRunId) {
@@ -64602,6 +64943,18 @@ function validateRunGroups(grouped, rootRunId, tools) {
64602
64943
  }
64603
64944
  return true;
64604
64945
  }
64946
+ function isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) {
64947
+ const child = workflowChildFromDraft(draft);
64948
+ const boundary = draft.topology?.boundary;
64949
+ return child?.runId === childRunId && child.exited === true && boundary?.event === "terminal" && boundary.status === "completed" && boundary.child.runId === childRunId && boundary.child.parentRunId === parentRunId && boundary.child.parentStageId === draft.topology?.stageId && boundary.child.rootRunId === rootRunId;
64950
+ }
64951
+ function childScopedEvidenceExists(checkpoints, boundaryReplayKey, childRunId) {
64952
+ const prefix = `${boundaryReplayKey}:`;
64953
+ return checkpoints.some((checkpoint) => {
64954
+ const lookupIdentity = checkpoint.kind === "tool" ? checkpoint.argsHash : checkpoint.kind === "ui" ? checkpoint.promptHash : checkpoint.replayKey;
64955
+ return checkpoint.checkpointId.startsWith(prefix) || lookupIdentity.startsWith(prefix) || checkpoint.kind !== "ui" && checkpoint.topology?.run?.runId === childRunId;
64956
+ });
64957
+ }
64605
64958
  function retainReachableRunGroups(grouped, rootRunId) {
64606
64959
  const reachable = new Set([rootRunId]);
64607
64960
  const pending = [rootRunId];
@@ -64699,15 +65052,17 @@ function valueOrExisting(key2, checkpoint, existing) {
64699
65052
  }
64700
65053
  function workflowChildFromDraft(draft) {
64701
65054
  const strict = parseWorkflowChildResult(draft.output);
64702
- const child = strict ?? (hasCurrentStageIdentity(draft) ? undefined : parseLegacyWorkflowChildResult(draft.output));
65055
+ const legacy = hasCurrentStageIdentity(draft) ? undefined : parseLegacyWorkflowChildResult(draft.output);
65056
+ const child = strict ?? legacy;
64703
65057
  if (child === undefined)
64704
65058
  return;
65059
+ const exited = strict?.exited ?? false;
64705
65060
  return {
64706
65061
  alias: child.workflow,
64707
65062
  workflow: child.workflow,
64708
65063
  runId: child.runId,
64709
65064
  status: child.status,
64710
- ...child.exited !== undefined ? { exited: child.exited } : {},
65065
+ exited,
64711
65066
  outputs: child.outputs,
64712
65067
  ...typeof child.exitReason === "string" ? { exitReason: child.exitReason } : {}
64713
65068
  };
@@ -65083,6 +65438,8 @@ function completedWorkflowRunSnapshots(backend, entry) {
65083
65438
  endedAt: handle.updatedAt,
65084
65439
  durationMs: rootDuration,
65085
65440
  ...handle.error !== undefined ? { error: handle.error } : {},
65441
+ ...handle.exited !== undefined ? { exited: handle.exited } : {},
65442
+ ...handle.exitReason !== undefined ? { exitReason: handle.exitReason } : {},
65086
65443
  ...handle.failureKind !== undefined ? { failureKind: handle.failureKind } : {},
65087
65444
  ...handle.failureCode !== undefined ? { failureCode: handle.failureCode } : {},
65088
65445
  ...handle.failureRecoverability !== undefined ? { failureRecoverability: handle.failureRecoverability } : {},
@@ -65208,8 +65565,22 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
65208
65565
  for (const group of grouped.values())
65209
65566
  group.sort(compareDraftSourceOrder);
65210
65567
  retainReachableRunGroups(grouped, rootRunId);
65211
- if (!validateRunGroups(grouped, rootRunId, toolCheckpoints))
65568
+ if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
65212
65569
  return [];
65570
+ const syntheticChildren = [];
65571
+ for (const [parentRunId, runDrafts] of grouped) {
65572
+ for (const draft of runDrafts) {
65573
+ const child = workflowChildFromDraft(draft);
65574
+ if (child?.exited !== true || grouped.has(child.runId))
65575
+ continue;
65576
+ if (!isSyntheticExitedChild(draft, parentRunId, child.runId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, child.runId)) {
65577
+ if (strict)
65578
+ return [];
65579
+ continue;
65580
+ }
65581
+ syntheticChildren.push({ parentRunId, owner: draft, child });
65582
+ }
65583
+ }
65213
65584
  const idMaps = new Map;
65214
65585
  for (const [runId, runDrafts] of grouped) {
65215
65586
  const ownedToolIds = new Set(toolCheckpoints.flatMap((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId ? [checkpoint.topology?.nodeId ?? checkpoint.checkpointId] : []));
@@ -65243,6 +65614,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
65243
65614
  idMaps.set(runId, ids);
65244
65615
  }
65245
65616
  const runs = [];
65617
+ const emittedRunIds = new Set;
65246
65618
  for (const [runId, runDrafts] of grouped) {
65247
65619
  const ids = idMaps.get(runId);
65248
65620
  const ownedTools = toolCheckpoints.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
@@ -65262,6 +65634,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
65262
65634
  const boundarySourceId = grouped.get(parentRunId)?.find((draft) => childRunIdFromDraft(draft) === runId)?.topology?.stageId;
65263
65635
  const declaredParentStageId = run2?.parentStageId === undefined ? undefined : idMaps.get(parentRunId)?.get(run2.parentStageId);
65264
65636
  const parentStageId = declaredParentStageId ?? (boundarySourceId === undefined ? undefined : idMaps.get(parentRunId)?.get(boundarySourceId));
65637
+ const ownerChild = owner === undefined ? undefined : workflowChildFromDraft(owner);
65265
65638
  runs.push({
65266
65639
  id: runId,
65267
65640
  name: run2?.runName ?? rootRunName,
@@ -65275,6 +65648,47 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
65275
65648
  ...run2?.parentRunId !== undefined ? { parentRunId: run2.parentRunId } : {},
65276
65649
  ...parentStageId !== undefined ? { parentStageId } : {},
65277
65650
  ...run2?.rootRunId !== undefined ? { rootRunId: run2.rootRunId } : {},
65651
+ ...ownerChild?.exited === true ? {
65652
+ result: ownerChild.outputs,
65653
+ exited: true,
65654
+ ...ownerChild.exitReason !== undefined ? { exitReason: ownerChild.exitReason } : {}
65655
+ } : {},
65656
+ resumable: false
65657
+ });
65658
+ emittedRunIds.add(runId);
65659
+ }
65660
+ for (const { parentRunId, owner, child } of syntheticChildren) {
65661
+ if (!emittedRunIds.has(parentRunId)) {
65662
+ if (strict)
65663
+ return [];
65664
+ continue;
65665
+ }
65666
+ const topology = owner.topology;
65667
+ const boundary = topology.boundary;
65668
+ const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
65669
+ if (parentStageId === undefined) {
65670
+ if (strict)
65671
+ return [];
65672
+ continue;
65673
+ }
65674
+ const startedAt = owner.startedAt ?? owner.firstCompletedAt;
65675
+ const endedAt = owner.endedAt ?? owner.firstCompletedAt;
65676
+ runs.push({
65677
+ id: child.runId,
65678
+ name: boundary.child.runName,
65679
+ inputs: {},
65680
+ status: child.status,
65681
+ stages: [],
65682
+ toolNodes: [],
65683
+ startedAt,
65684
+ endedAt,
65685
+ durationMs: Math.max(0, endedAt - startedAt),
65686
+ parentRunId,
65687
+ parentStageId,
65688
+ rootRunId: boundary.child.rootRunId,
65689
+ result: child.outputs,
65690
+ exited: true,
65691
+ ...child.exitReason !== undefined ? { exitReason: child.exitReason } : {},
65278
65692
  resumable: false
65279
65693
  });
65280
65694
  }
@@ -65355,6 +65769,14 @@ function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
65355
65769
  const nested = durableNestedRunSnapshots(backend, rootWorkflowId);
65356
65770
  if (!nested.some((run2) => run2.id === childRunId))
65357
65771
  return;
65772
+ const intentionalExitStatuses = new Map;
65773
+ for (const checkpoint of backend.listCheckpoints(rootWorkflowId)) {
65774
+ if (checkpoint.kind !== "stage")
65775
+ continue;
65776
+ const child = parseWorkflowChildResult(checkpoint.output);
65777
+ if (child?.exited === true)
65778
+ intentionalExitStatuses.set(child.runId, child.status);
65779
+ }
65358
65780
  const included = new Set([childRunId]);
65359
65781
  let priorSize = -1;
65360
65782
  while (priorSize !== included.size) {
@@ -65365,9 +65787,17 @@ function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
65365
65787
  }
65366
65788
  }
65367
65789
  const subtree = nested.filter((run2) => included.has(run2.id));
65368
- const complete = subtree.length === included.size && subtree.every((run2) => run2.status === "completed" && run2.endedAt !== undefined && run2.stages.every((stage) => isTerminalStage2(stage.status) && stage.endedAt !== undefined));
65790
+ const complete = subtree.length === included.size && subtree.every((run2) => isCompleteCachedRun(run2, intentionalExitStatuses));
65369
65791
  return complete ? subtree : undefined;
65370
65792
  }
65793
+ function isCompleteCachedRun(run2, intentionalExitStatuses) {
65794
+ if (run2.endedAt === undefined || !run2.stages.every((stage) => isTerminalStage2(stage.status) && stage.endedAt !== undefined)) {
65795
+ return false;
65796
+ }
65797
+ if (run2.status === "completed" || run2.exited === true)
65798
+ return true;
65799
+ return intentionalExitStatuses.get(run2.id) === run2.status;
65800
+ }
65371
65801
  function isTerminalStage2(status) {
65372
65802
  return status === "completed" || status === "failed" || status === "skipped";
65373
65803
  }
@@ -65509,6 +65939,8 @@ function createDurableCachedStageRecorder(input) {
65509
65939
  }
65510
65940
  function reconcileCachedDirectChildParentStage(input) {
65511
65941
  const existingRun = input.store.runs().find((run2) => run2.id === input.checkpointChildRunId);
65942
+ if (existingRun === undefined)
65943
+ return false;
65512
65944
  const runById = new Map(input.store.runs().map((run2) => [run2.id, run2]));
65513
65945
  const storedParentRun = runById.get(input.parentRun.id);
65514
65946
  if (storedParentRun !== undefined && (storedParentRun.parentRunId !== input.parentRun.parentRunId || storedParentRun.parentStageId !== input.parentRun.parentStageId))
@@ -65519,7 +65951,8 @@ function reconcileCachedDirectChildParentStage(input) {
65519
65951
  if (expectedRootRunId === undefined)
65520
65952
  return false;
65521
65953
  const storedBoundary = storedParentRun?.stages.find((stage) => stage.id === input.boundary.id);
65522
- if (!rootMatches(input.parentRun.rootRunId, expectedRootRunId) || !rootMatches(storedParentRun?.rootRunId, expectedRootRunId) || authoritativeWorkflowChildRunId(input.boundary) !== input.checkpointChildRunId || storedParentRun !== undefined && authoritativeWorkflowChildRunId(storedBoundary) !== input.checkpointChildRunId || input.catalogRun.id !== input.checkpointChildRunId || existingRun?.status !== "completed" || input.catalogRun.status !== "completed" || existingRun.parentRunId !== input.parentRun.id || input.catalogRun.parentRunId !== input.parentRun.id || input.catalogRun.parentStageId === undefined || existingRun.parentStageId !== input.catalogRun.parentStageId || !rootMatches(existingRun.rootRunId, expectedRootRunId) || !rootMatches(input.catalogRun.rootRunId, expectedRootRunId))
65954
+ const cachedChildStatusMatches = existingRun?.status === "completed" && input.catalogRun.status === "completed" || input.boundary.workflowChild?.exited === true && input.boundary.workflowChild.runId === input.checkpointChildRunId && existingRun?.status === input.catalogRun.status && input.boundary.workflowChild.status === input.catalogRun.status;
65955
+ if (!rootMatches(input.parentRun.rootRunId, expectedRootRunId) || !rootMatches(storedParentRun?.rootRunId, expectedRootRunId) || authoritativeWorkflowChildRunId(input.boundary) !== input.checkpointChildRunId || storedParentRun !== undefined && authoritativeWorkflowChildRunId(storedBoundary) !== input.checkpointChildRunId || input.catalogRun.id !== input.checkpointChildRunId || !cachedChildStatusMatches || existingRun.parentRunId !== input.parentRun.id || input.catalogRun.parentRunId !== input.parentRun.id || input.catalogRun.parentStageId === undefined || existingRun.parentStageId !== input.catalogRun.parentStageId || !rootMatches(existingRun.rootRunId, expectedRootRunId) || !rootMatches(input.catalogRun.rootRunId, expectedRootRunId))
65523
65956
  return false;
65524
65957
  return input.store.reconcileRunParentStage(existingRun.id, input.catalogRun.parentStageId, input.boundary.id);
65525
65958
  }
@@ -65873,11 +66306,12 @@ function createTrackedToolPrimitive(input) {
65873
66306
 
65874
66307
  // dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts
65875
66308
  function workflowChildResultFromReplay(snapshot) {
66309
+ const exited = snapshot.exited ?? (snapshot.status === "completed" ? false : undefined);
65876
66310
  const candidate = {
65877
66311
  workflow: snapshot.workflow,
65878
66312
  runId: snapshot.runId,
65879
66313
  status: snapshot.status,
65880
- exited: snapshot.exited,
66314
+ exited,
65881
66315
  outputs: cloneWorkflowChildValue(snapshot.outputs),
65882
66316
  ...snapshot.exitReason !== undefined ? { exitReason: snapshot.exitReason } : {}
65883
66317
  };
@@ -71387,6 +71821,7 @@ function workflowModelCatalogFromContext(ctx) {
71387
71821
  }
71388
71822
 
71389
71823
  // dist/builtin/workflows/src/extension/mcp.ts
71824
+ import { isStaleExtensionContextError as isStaleExtensionContextError5 } from "@bastani/atomic";
71390
71825
  function setMcpScope(pi, opts) {
71391
71826
  if (!pi.events)
71392
71827
  return;
@@ -71395,7 +71830,12 @@ function setMcpScope(pi, opts) {
71395
71830
  allow: opts.allow ?? null,
71396
71831
  deny: opts.deny ?? null
71397
71832
  };
71398
- pi.events.emit("mcp.scope.set", payload);
71833
+ try {
71834
+ pi.events.emit("mcp.scope.set", payload);
71835
+ } catch (error) {
71836
+ if (!isStaleExtensionContextError5(error))
71837
+ throw error;
71838
+ }
71399
71839
  }
71400
71840
  function clearMcpScope(pi, stageId) {
71401
71841
  if (!pi.events)
@@ -71405,7 +71845,12 @@ function clearMcpScope(pi, stageId) {
71405
71845
  allow: null,
71406
71846
  deny: null
71407
71847
  };
71408
- pi.events.emit("mcp.scope.set", payload);
71848
+ try {
71849
+ pi.events.emit("mcp.scope.set", payload);
71850
+ } catch (error) {
71851
+ if (!isStaleExtensionContextError5(error))
71852
+ throw error;
71853
+ }
71409
71854
  }
71410
71855
 
71411
71856
  // dist/builtin/workflows/src/extension/workflow-ports.ts
@@ -71433,14 +71878,18 @@ function makeMcpPort(pi) {
71433
71878
  };
71434
71879
  return {
71435
71880
  setScope(stageId, allow, deny) {
71436
- setMcpScope(piForMcp, {
71437
- stageId,
71438
- allow: allow ?? undefined,
71439
- deny: deny ?? undefined
71440
- });
71881
+ try {
71882
+ setMcpScope(piForMcp, {
71883
+ stageId,
71884
+ allow: allow ?? undefined,
71885
+ deny: deny ?? undefined
71886
+ });
71887
+ } catch {}
71441
71888
  },
71442
71889
  clearScope(stageId) {
71443
- clearMcpScope(piForMcp, stageId);
71890
+ try {
71891
+ clearMcpScope(piForMcp, stageId);
71892
+ } catch {}
71444
71893
  }
71445
71894
  };
71446
71895
  }
@@ -71919,11 +72368,16 @@ function renderRunSummary(payload) {
71919
72368
  return `${icon} workflow [${payload.runId}] ${payload.status}`;
71920
72369
  }
71921
72370
 
72371
+ // dist/builtin/workflows/src/extension/wiring.ts
72372
+ import {
72373
+ isStaleExtensionContextError as isStaleExtensionContextError6
72374
+ } from "@bastani/atomic";
72375
+
71922
72376
  // dist/builtin/workflows/src/extension/atomic-stage-session.ts
71923
72377
  import { basename as basename5 } from "node:path";
71924
72378
  var WORKFLOW_STAGE_SUBAGENT_POLICY = {
71925
72379
  managementActions: "full",
71926
- fanoutAuthorized: false,
72380
+ fanoutAuthorized: true,
71927
72381
  inheritProjectContext: true,
71928
72382
  inheritSkills: true
71929
72383
  };
@@ -72130,11 +72584,26 @@ function emitLateIntercomRoute(pi, meta2, messages, options, batch) {
72130
72584
  workflowStageId: meta2.stageId,
72131
72585
  workflowStageName: meta2.stageName
72132
72586
  };
72133
- pi.events.emit(LATE_STAGE_MESSAGE_EVENT2, event);
72587
+ try {
72588
+ pi.events.emit(LATE_STAGE_MESSAGE_EVENT2, event);
72589
+ } catch (error) {
72590
+ if (!isStaleExtensionContextError6(error))
72591
+ throw error;
72592
+ return Promise.reject(error);
72593
+ }
72134
72594
  if (!event.handled)
72135
72595
  return;
72136
72596
  return event.completion ?? Promise.resolve();
72137
72597
  }
72598
+ function routeThroughStaleContextGuard(route) {
72599
+ try {
72600
+ return route();
72601
+ } catch (error) {
72602
+ if (!isStaleExtensionContextError6(error))
72603
+ throw error;
72604
+ return Promise.reject(error);
72605
+ }
72606
+ }
72138
72607
  function makeWorkflowStageOrchestrationContext(meta2, pi) {
72139
72608
  const intercomGroup = stageHasIntercomAccess(meta2.stageOptions) ? resolveStageGroup(meta2.stageOptions, meta2.workflowIntercomGroup) : undefined;
72140
72609
  return {
@@ -72149,16 +72618,18 @@ function makeWorkflowStageOrchestrationContext(meta2, pi) {
72149
72618
  const intercomRoute = emitLateIntercomRoute(pi, meta2, [message], options, false);
72150
72619
  if (intercomRoute)
72151
72620
  return intercomRoute;
72152
- if (!pi.sendMessage)
72621
+ const sendMessage = pi.sendMessage;
72622
+ if (!sendMessage)
72153
72623
  throw new Error("atomic-workflows: main-chat late-message route is unavailable");
72154
- return pi.sendMessage(message, options);
72624
+ return routeThroughStaleContextGuard(() => sendMessage(message, options));
72155
72625
  },
72156
72626
  routeMessages(messages, options) {
72157
72627
  const intercomRoute = emitLateIntercomRoute(pi, meta2, messages, options, true);
72158
72628
  if (intercomRoute)
72159
72629
  return intercomRoute;
72160
- if (pi.sendMessages)
72161
- return pi.sendMessages(messages, options);
72630
+ const sendMessages = pi.sendMessages;
72631
+ if (sendMessages)
72632
+ return routeThroughStaleContextGuard(() => sendMessages(messages, options));
72162
72633
  const sendMessage = pi.sendMessage;
72163
72634
  if (!sendMessage)
72164
72635
  throw new Error("atomic-workflows: main-chat late-message route is unavailable");
@@ -72489,12 +72960,14 @@ function openInputsPicker(ui, opts) {
72489
72960
  }),
72490
72961
  handleInput: (data) => {
72491
72962
  const kb = keys;
72963
+ const consumed = isInputsPickerKey(data, state2, fields, kb);
72492
72964
  const action = handleInputsPickerInput(data, state2, fields, kb);
72493
72965
  if (action.kind === "noop") {
72494
72966
  tui.requestRender?.();
72495
- return;
72967
+ return consumed;
72496
72968
  }
72497
72969
  finish(action);
72970
+ return true;
72498
72971
  },
72499
72972
  invalidate: () => tui.requestRender?.(),
72500
72973
  dispose: () => {
@@ -72733,6 +73206,15 @@ function renderSessionPicker(opts) {
72733
73206
  lines.push(renderHintsRow(width, theme, state2));
72734
73207
  return lines;
72735
73208
  }
73209
+ function isSessionPickerKey(data, state2, rows) {
73210
+ if (state2.filterFocused) {
73211
+ return matchesKey(data, Key.escape) || data === DOUBLE_ESCAPE_SEQUENCE || matchesKey(data, Key.enter) || matchesKey(data, Key.backspace) || data.length === 1 && data >= " " && data <= "~";
73212
+ }
73213
+ if (matchesKey(data, "/") || matchesKey(data, Key.escape) || matchesKey(data, "q") || matchesKey(data, Key.shift("q")) || matchesKey(data, "a") || matchesKey(data, Key.shift("a")) || matchesKey(data, Key.down) || matchesKey(data, "j") || matchesKey(data, Key.up) || matchesKey(data, "k")) {
73214
+ return true;
73215
+ }
73216
+ return matchesKey(data, Key.enter) && rows[state2.selectedIndex] !== undefined;
73217
+ }
72736
73218
  function handleSessionPickerInput(data, state2, rows) {
72737
73219
  if (state2.filterFocused) {
72738
73220
  if (matchesKey(data, Key.escape) || data === DOUBLE_ESCAPE_SEQUENCE) {
@@ -73115,10 +73597,11 @@ function openSessionPicker(ui, store2, theme, intent = "connect") {
73115
73597
  },
73116
73598
  handleInput: (data) => {
73117
73599
  const rows = selectRows();
73600
+ const consumed = isSessionPickerKey(data, state2, rows);
73118
73601
  const action = handleSessionPickerInput(data, state2, rows);
73119
73602
  if (action.kind === "noop") {
73120
73603
  tui.requestRender?.();
73121
- return;
73604
+ return consumed;
73122
73605
  }
73123
73606
  if (action.kind === "close")
73124
73607
  finish({ kind: "close" });
@@ -73126,6 +73609,7 @@ function openSessionPicker(ui, store2, theme, intent = "connect") {
73126
73609
  finish(toResult(action));
73127
73610
  else
73128
73611
  finish(toResult(action));
73612
+ return true;
73129
73613
  },
73130
73614
  invalidate: () => tui.requestRender?.(),
73131
73615
  dispose: () => {
@@ -73811,7 +74295,11 @@ Picker requires an interactive UI surface. Pass a runId: /workflow attach <id> [
73811
74295
  }
73812
74296
  const run3 = store.runs().find((r) => r.id === resolved.runId);
73813
74297
  const isPaused3 = run3 !== undefined && workflowHasPausedState(store, resolved.runId);
74298
+ const isDurableAuthorExit2 = run3?.exited === true && run3.status === "failed" && run3.resumable === true;
73814
74299
  const isResumableContinuation2 = run3 !== undefined && !isPaused3 && run3.exitReason !== "quit" && isWorkflowRunResumable(workflowRunResumeCandidate(run3));
74300
+ if (isDurableAuthorExit2) {
74301
+ return await handleDurableResume(resolved.runId, ctx, reporter, deps);
74302
+ }
73815
74303
  if (isResumableContinuation2) {
73816
74304
  await ensureWorkflowResourcesVisible();
73817
74305
  const continuation = await deps.runtimeForContext(ctx).resumeFailedRun(resolved.runId, undefined, { policy, actor: "user" });
@@ -73945,12 +74433,16 @@ Picker requires an interactive UI surface. Pass a runId: /workflow attach <id> [
73945
74433
  const hadPausedRunState = run2?.status === "paused";
73946
74434
  const hadPausedStageState = run2 !== undefined && workflowHasPausedStages(store, stageRunId);
73947
74435
  const isPaused2 = run2 !== undefined && workflowHasPausedState(store, stageRunId);
74436
+ const isDurableAuthorExit = run2?.exited === true && run2.status === "failed" && run2.resumable === true;
73948
74437
  const isResumableContinuation = run2 !== undefined && !isPaused2 && run2.exitReason !== "quit" && isWorkflowRunResumable(workflowRunResumeCandidate(run2));
73949
74438
  const isActivelyRunning = run2 !== undefined && run2.endedAt === undefined && run2.status === "running" && !isPaused2 && run2.exitReason !== "quit";
73950
74439
  if (isActivelyRunning && !isResumableContinuation && action === "resume" && !hasPendingDurableResumeTransition(stageRunId)) {
73951
74440
  fail(`Workflow ${stageRunId} is already running in this session. Attach with \`/workflow connect ${stageRunId}\` instead of resuming.`);
73952
74441
  return true;
73953
74442
  }
74443
+ if (isDurableAuthorExit) {
74444
+ return await handleDurableResume(stageRunId, ctx, reporter, deps);
74445
+ }
73954
74446
  if (isResumableContinuation) {
73955
74447
  await ensureWorkflowResourcesVisible();
73956
74448
  const continuation = await deps.runtimeForContext(ctx).resumeFailedRun(stageRunId, stageId, { policy, actor: "user" });
@@ -74942,7 +75434,10 @@ async function workflowResumeAction(args, deps) {
74942
75434
  const hadPausedRunState = run2?.status === "paused";
74943
75435
  const hadPausedStageState = run2 !== undefined && workflowHasPausedStages(store, stageRunId);
74944
75436
  const isPaused2 = run2 !== undefined && workflowHasPausedState(store, stageRunId);
75437
+ const isDurableAuthorExit = run2?.exited === true && run2.status === "failed" && run2.resumable === true;
74945
75438
  const isResumableContinuation = run2 !== undefined && !isPaused2 && run2.exitReason !== "quit" && isWorkflowRunResumable(workflowRunResumeCandidate(run2));
75439
+ if (isDurableAuthorExit)
75440
+ return resumeDurableShadow(stageRunId, deps);
74946
75441
  if (isResumableContinuation) {
74947
75442
  try {
74948
75443
  await deps.ensureWorkflowResourcesLoaded();
@@ -75789,7 +76284,7 @@ function renderResult(result, opts) {
75789
76284
  const guidance = r.details.message === undefined ? "" : ` — ${r.details.message}`;
75790
76285
  return renderNotice("WORKFLOW RUN", `${r.runId}${label2}: ${r.details.mode} ${r.details.status}${guidance}`, opts, themed);
75791
76286
  }
75792
- if (r.status === "completed" || r.status === "skipped" || r.status === "cancelled" || r.status === "blocked" || r.status === "killed") {
76287
+ if (r.status === "completed" || r.status === "failed" || r.status === "skipped" || r.status === "cancelled" || r.status === "blocked" || r.status === "killed") {
75793
76288
  const label2 = r.name ? ` (${r.name})` : "";
75794
76289
  return renderNotice("WORKFLOW RUN", `${r.runId}${label2}: ${r.status}`, opts, themed);
75795
76290
  }
@@ -75876,7 +76371,7 @@ var DEFAULT_PROMPT_GUIDANCE = [
75876
76371
  - Workflow fit check: prefer a workflow for implementation, build, debug/diagnosis, bug-fix, migration, new-feature, scoped multi-file, or docs/code changes with validation; and whenever there are multiple steps, dependencies, handoffs, uncertainty, review/validation needs, long-running work, measurable done criteria, or an outcome that needs evidence.
75877
76372
  - Treat loop or stop-condition wording as a strong workflow signal, especially "do X until Y", "repeat until", "iterate until", "review/fix until passing", "run checks and fix until green", "keep going until done", or any prompt that names an approval gate or evidence requirement.
75878
76373
  - Do not force-fit an installed workflow. When another graph better matches the task, write a task-specific TypeScript workflow inline. Rich custom workflows may use deterministic branching, dynamic fan-out, child workflows, artifacts, structured outputs, human-in-the-loop prompts, gates, retries, and explicit stop conditions.
75879
- - Before launching any workflow for a non-trivial task, perform a short workflow-architecture pass. Derive implementation lifecycle needs, whole-codebase research needs, independent slices, competing strategies, exact API/type/build contracts, schema or generated-artifact contracts, state transitions/lifecycle behavior, deterministic stop conditions, and required evidence. Use a compact internal coverage matrix: \`requirement/risk | required evidence | workflow/stage that produces it | gap\`. Add the topology row \`acyclic topology | node/edge sketch for branches and loops | architecture pass | unresolved back-edge\`. Unresolved material rows or back-edges must change the graph before launch.
76374
+ - Before launching any workflow for a non-trivial task, perform a short workflow-architecture pass. Derive implementation lifecycle needs, whole-codebase research needs, independent slices, competing strategies, exact API/type/build contracts, schema or generated-artifact contracts, state transitions/lifecycle behavior, deterministic stop conditions, and required evidence. Enumerate implementation slices in this same pass, not a second planning ritual; give each slice its own objective, acceptance criteria, and gates, and require each to leave a buildable, testable repository state before the next slice. Use a compact internal coverage matrix: \`requirement/risk | required evidence | workflow/stage that produces it | gap\`. Add the topology row \`acyclic topology | node/edge sketch for branches and loops | architecture pass | unresolved back-edge\`. Unresolved material rows or back-edges must change the graph before launch.
75880
76375
  - In that architecture pass, sketch each branch, loop, and nested workflow boundary. Identify which stages repeat, require distinct tracked work for every iteration, name the current frontier before each repeat, reject self-edges and ancestor edges, compose nested workflows through \`ctx.workflow(...)\` boundaries rather than recursive \`run\` invocation, and preserve stable per-iteration identity and call order for resume/replay.
75881
76376
  - Compare candidate workflows by guarantees, not broad objectives: run one named workflow only when it covers the lifecycle and produces evidence for every material requirement/risk. A generic implementation workflow may cover the lifecycle without covering exact API/type/build contracts, schemas/generated artifacts, state transitions, or domain-specific gates. Do not treat "has reviewers" as proof that a task-specific risk is covered.
75882
76377
  - Use these routing signals without adding decorative stages: broad repository uncertainty → Fan-out-and-synthesize with repository-focused branches; independent slices → Fan-out-and-synthesize; plausible-but-wrong contract risk → Adversarial verification or a task-specific verification stage; competing architectures or implementations → Generate-and-filter or Tournament; an explicit repeat-until condition → Loop until done; implementation lifecycle → a task-specific worker/reviewer loop; exact API/build/schema requirements → dedicated deterministic gates.
@@ -75890,9 +76385,11 @@ var DEFAULT_PROMPT_GUIDANCE = [
75890
76385
  - When plausible-but-wrong behavior is a material risk in an arbitrary task-specific workflow, prefer a bounded evidence-backed adversarial loop. Give a fresh-context grumpy/skeptical-but-fair reviewer the literal objective and require actionable, evidence-backed falsification probes without invented requirements. Have it emit a structured verifier plan containing each exact probe, inputs, command/assertion, expected success condition, and requirement/risk covered.
75891
76386
  - Support both verifier shapes: for explicit known contracts, author direct task-specific \`ctx.tool(...)\` gates before launch; for risks requiring adversarial discovery, let the model select high-value probes through structured output, then execute the selected compile, test, schema generation/validation, runtime, or artifact-inspection checks authoritatively through durable \`ctx.tool(...)\` calls. Actual tool results—not model self-report—must feed skeptical evaluation, consolidated evidence-backed repair findings, and reruns after the implementation child repairs them.
75892
76387
  - Define bounded pass, repair, failure, and iteration-limit conditions before launch. Use \`ctx.tool\` for workflow-owned external checks and side effects whose results should be durably checkpointed. Each \`ctx.tool\` call is tracked as a durable, non-chat graph node and may run before, between, after, or without model stages; a tool-only workflow is valid tracked execution; keep pure transformations as ordinary TypeScript, and do not wrap every model-stage action in a tool call.
75893
- - Choose the cheapest graph that covers every material coverage row. Avoid decorative composition and duplicated research or review loops. Prefer composing a proven builtin or shared child over copying its prompt/graph.
76388
+ - Choose the cheapest graph that covers every material coverage row without collapsing independently verifiable implementation slices merely to minimize stage count. Avoid decorative composition and duplicated research or review loops. Prefer composing a proven builtin or shared child over copying its prompt/graph.
75894
76389
  - Before the first launch, state the selected graph, why one broad builtin is sufficient or insufficient, the evidence each major stage produces, and the stop/repair conditions. A simple direct match may use one sentence; a composed graph must briefly name its children and task-specific gates. For a custom adversarial loop, also name the skeptical reviewer, deterministic \`ctx.tool\` verifier gates, how model-selected plans become tool executions, and how failures reach bounded repair.
75895
- - Example custom shapes: classify a request and dispatch category-specific stages; fan out per package and synthesize artifact-backed results; implement, run fresh-context verifiers, reduce findings, and loop through repairs until approved; generate several plans and filter or tournament-rank them; or rerun checks and fixes until green with a progress ledger and max-iteration escape hatch.
76390
+ - Before launching an authored workflow, assign every model stage a role, failure cost, primary model, thinking level, and fallback policy. Use the role/risk defaults in the model-selection guide: reserve \`max\` for high-cost-of-error roles such as security, identity, adversarial challenge, and final approval; use \`high\` for demanding codebase mapping, lifecycle analysis, compatibility, planning, synthesis, triage, and repair; use \`medium\` for user-impact review and final reporting; keep deterministic checks as tool nodes with no model call. An explicit user request for a thinking level always wins over these defaults, subject to catalog support. For a mixed workflow, mapping may be \`high\`, approval \`max\`, reporting \`medium\`, and tests tool-only; never assign \`max\` to every model stage without a stage-specific reason.
76391
+ - Print a compact \`Stage | Model | Thinking | Role\` assignment before launch with a short cost/quality rationale for each model stage. Apply the same role/risk policy to every fallback attempt rather than inheriting \`max\` mechanically; choose each primary and fallback level from the configured catalog, and if no selected catalog model supports the role's level, leave the stage unpinned rather than inventing an unsupported level.
76392
+ - Example custom shapes: classify a request and dispatch category-specific stages; fan out per package and synthesize artifact-backed results; decompose one implementation objective into stacked, independently verified slices with a bounded child lifecycle per slice; implement, run fresh-context verifiers, reduce findings, and loop through repairs until approved; generate several plans and filter or tournament-rank them; or rerun checks and fixes until green with a progress ledger and max-iteration escape hatch.
75896
76393
  - Budget reconnaissance: once workflow fit is clear, keep pre-workflow exploration to a few quick reads that sharpen the objective and validation criteria. Put deep research, upstream/design comparison, and behavior probing inside the workflow. Pass large context through files/artifacts and \`reads\` rather than injecting it into prompts.
75897
76394
  - Course-correct instead of drifting: after roughly ten exploratory tool calls with no artifact, edit, or commit, or repeated "let me verify one more thing" loops, stop, write findings to a context file, and hand the task to the best-fit named or custom workflow. Sunk inline research transfers through files; it is not a reason to stay inline.
75898
76395
  - Only skip workflows for tiny, deterministic, low-risk answers or direct edits where stage tracking clearly costs more than it adds, typically a single-file/no-test/no-review change or a simple answer.`,
@@ -75908,12 +76405,15 @@ var DEFAULT_PROMPT_GUIDANCE = [
75908
76405
  `**Workflow authoring and handoffs**:
75909
76406
  - When a user asks to create or edit a workflow, clarify only unresolved requirements that materially affect its purpose, inputs, stages, handoffs, validation, success criteria, or starter pattern. Read the workflow docs/examples, implement the TypeScript definition with normal coding tools, reload it, and run representative test inputs before presenting it. Use the create-spec skill when it adds value; it is not mandatory when context is already sufficient.
75910
76407
  - After creating and reloading a newly authored custom workflow, close the loop by stating the folder containing the workflow file just written, for example \`.atomic/workflows/\`, in this shape: \`Custom workflow created. You can inspect its code at: <workflow-folder-path>\`. Do this only for newly created custom workflows, never builtin or pre-existing workflows.
75911
- - When creating or editing a workflow that pins an explicit stage \`model\` or \`fallbackModels\`, consult \`packages/coding-agent/docs/models/model-selection.md\` for role-based recommendations, then call \`workflow({ action: "models" })\` to see the models actually present in the user's configured catalog. Use only the catalog's returned \`fullId\` values as model strings, and append a thinking suffix only when that exact level appears in the entry's \`availableThinkingLevels\`; treat an absent or empty \`availableThinkingLevels\` as no suffix support rather than inferring one. If a guide-recommended model for the role is unavailable, try another guide-recommended model that is present in the catalog. If no recommendation intersects with the catalog, leave the stage unpinned rather than inventing a substitute, and mention the limitation, asking the user only if the workflow requires an explicit model choice. If the catalog is empty, continue with unpinned stages, state that no configured models were returned, and do not fabricate model IDs. Do not inspect or infer credentials, environment variables, auth files, token validity, entitlements, or the reason a model is absent; \`isCurrent\` marks the active selection, not a quality recommendation.
75912
- - Consult docs/workflows.md and its starter patterns (Classify-and-act, Fan-out-and-synthesize, Adversarial verification, Generate-and-filter, Tournament, and Loop until done) when designing a stage graph.
76408
+ - When creating or editing a workflow that pins an explicit stage \`model\` or \`fallbackModels\`, consult \`packages/coding-agent/docs/models/model-selection.md\` for role-based recommendations, treating benchmark thinking levels as measurement configurations rather than universal workflow defaults, then call \`workflow({ action: "models" })\` to see the models actually present in the user's configured catalog. Use only the catalog's returned \`fullId\` values as model strings, and append a thinking suffix only when that exact level appears in the entry's \`availableThinkingLevels\`; apply the stage role and failure-cost policy independently to the primary and every fallback; treat an absent or empty \`availableThinkingLevels\` as no suffix support rather than inferring one. If a guide-recommended model for the role is unavailable, try another guide-recommended model that is present in the catalog. If the selected model does not support the role's level, choose another catalog model that does or leave the stage unpinned rather than inventing or silently promoting a level. An explicit user request for a level overrides the role default, but never fabricate an unsupported catalog level. If no recommendation intersects with the catalog, leave the stage unpinned rather than inventing a substitute, and mention the limitation, asking the user only if the workflow requires an explicit model choice. If the catalog is empty, continue with unpinned stages, state that no configured models were returned, and do not fabricate model IDs. Do not inspect or infer credentials, environment variables, auth files, token validity, entitlements, or the reason a model is absent; \`isCurrent\` marks the active selection, not a quality recommendation.
76409
+ - Consult docs/workflows.md and its starter patterns (Classify-and-act, Fan-out-and-synthesize, Adversarial verification, Generate-and-filter, Tournament, Loop until done, and Stacked implementation slices) when designing a stage graph.
75913
76410
  - Treat workflow composition as a first-class authoring option. Before duplicating stages, inspect reusable workflow modules and builtin exports; import their definitions and invoke them with \`ctx.workflow(...)\`, mapping typed inputs and consuming only declared outputs. Nested workflows can themselves import children, so combine small reusable graphs into a richer parent while respecting \`maxDepth\`.
76411
+ - For implementation objectives, prefer the smallest independently verifiable slice: target roughly 100–500 changed lines between verification points by default, with one reviewable concern that builds and tests on its own. This is a default, not a law: a genuinely atomic change (for example, a mechanical rename across many files or a generated-artifact refresh) stays one slice, and a small objective is not split merely to reach a count.
76412
+ - Decompose those slices during the pre-launch architecture pass, not in a second planning ritual. Run every slice through a child workflow with its own implement/review/repair lifecycle: invoke imported \`goal\`, \`ralph\`, or a task-specific child via \`ctx.workflow(...)\`, rather than making one parent stage own all slices.
76413
+ - Stack implementation slices in order: give each slice an explicit branch input and, before invoking its child, create or check out that named branch in its worktree with a durable \`ctx.tool(...)\` step; \`base_branch\` and \`git_worktree_dir\` alone do not create/check out a feature branch. Slice N+1 must be created from slice N's verified branch, pass that branch as \`base_branch\`, and use a distinct worktree. Verify each slice before proceeding; if a slice fails its gates, stop at the first unverified slice; earlier verified slices remain verified and are reported as such; do not roll them back or continue past the failure.
75914
76414
  - Atomic \`workflow({ run })\` definitions are imperative, dynamic TypeScript. Discovery validates module loading, imports, and definition shape, including schemas and the \`run\` function, but it does not compile \`run\` into a complete graph or prove acyclicity. Runtime inputs, branches, loops, files, network data, model or human output, helpers, and nested workflows determine the materialized graph during execution.
75915
76415
  - Cyclic workflow graphs are unsupported. Workflow authors and coding agents MUST NOT create self-edges or dependency edges from the current frontier to an existing ancestor. Every materialized execution topology must remain a DAG. Redesign or stop before launch if a cycle cannot be removed.
75916
- - Bounded loops must create distinct tracked work for every iteration; never reopen an ancestor below its downstream work. If a retained session receives follow-up without new dependency work, keep it as non-topological activity metadata rather than adding a back-edge. Before launch, sketch nodes and dependencies for every branch and loop and reject any proposed parent edge to the node itself or an ancestor.
76416
+ - Bounded loops must create distinct tracked work for every iteration; never reopen an ancestor below its downstream work. Stacked implementation slices are unrolled, not looped: each slice gets a fresh child boundary and distinct tracked nodes, and no slice may add an edge back to the current frontier, itself, or an ancestor. If a retained session receives follow-up without new dependency work, keep it as non-topological activity metadata rather than adding a back-edge. Before launch, sketch nodes and dependencies for every branch and loop and reject any proposed parent edge to the node itself or an ancestor.
75917
76417
  - Treat dynamic graph validation during execution, replay, and DBOS hydration as the authoritative cycle boundary. If runtime topology code changes, require incremental edge checks and DBOS hydration validation; prompt guidance and TypeScript types cannot replace those runtime checks.
75918
76418
  - Every workflow invocation automatically receives one stable, non-default Intercom group. Intercom-capable stages inherit it, nested workflows keep the top-level invocation group, and subagents inherit their launching stage's group. Do not mint or thread group names through ordinary workflow definitions. Use an explicit \`group\` only for an intentional override: a named group or \`group: true\` creates a subgroup, while \`group: "default"\` opts into the shared default group. Stages without Intercom access receive no group, and \`contact_supervisor\` still crosses group boundaries for authorized escalation.
75919
76419
  - Prefer \`ctx.tool(name, args, fn)\` for workflow-owned TypeScript operations with side effects, such as filesystem writes, network mutations, and external API actions. It creates a tracked, non-attachable durable graph node before invoking \`fn\`; it may be used before, between, after, or without model stages. A completed \`ctx.tool\` call is durably checkpointed with its serializable result, so resume replays that result without rerunning \`fn\`. For checks that may fail during a bounded repair loop, opt into \`failureMode: "return"\`, branch on the typed outcome, and pass only the needed error fields to the repair stage or artifact yourself; Atomic does not inject failure evidence into later prompts. Cancellation and storage faults still throw. Keep pure computation and side-effect-free transformations as ordinary TypeScript. Do not wrap agent-stage internals or every function call indiscriminately; this rule applies to side effects orchestrated directly by the workflow definition.