@bastani/atomic 0.9.2 → 0.9.3-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 (606) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +15 -0
  4. package/dist/builtin/cursor/README.md +2 -1
  5. package/dist/builtin/cursor/package.json +2 -2
  6. package/dist/builtin/cursor/src/cursor-models-raw.json +2 -9
  7. package/dist/builtin/cursor/src/model-mapper.ts +14 -3
  8. package/dist/builtin/cursor/src/proto/protobuf-codec-base64.ts +22 -0
  9. package/dist/builtin/cursor/src/proto/protobuf-codec-request.ts +53 -13
  10. package/dist/builtin/cursor/src/proto/protobuf-codec-wire.ts +24 -7
  11. package/dist/builtin/cursor/src/proto/protobuf-codec.ts +3 -2
  12. package/dist/builtin/cursor/src/stream.ts +5 -11
  13. package/dist/builtin/cursor/src/transport-types.ts +3 -0
  14. package/dist/builtin/cursor/src/transport.ts +1 -0
  15. package/dist/builtin/intercom/package.json +1 -1
  16. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  17. package/dist/builtin/mcp/direct-tools.ts +4 -2
  18. package/dist/builtin/mcp/package.json +1 -1
  19. package/dist/builtin/mcp/proxy-call.ts +3 -1
  20. package/dist/builtin/mcp/utils.ts +18 -7
  21. package/dist/builtin/subagents/CHANGELOG.md +20 -0
  22. package/dist/builtin/subagents/README.md +6 -6
  23. package/dist/builtin/subagents/agents/code-simplifier.md +7 -6
  24. package/dist/builtin/subagents/agents/codebase-analyzer.md +5 -4
  25. package/dist/builtin/subagents/agents/codebase-locator.md +3 -3
  26. package/dist/builtin/subagents/agents/codebase-online-researcher.md +10 -10
  27. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +4 -4
  28. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +3 -3
  29. package/dist/builtin/subagents/agents/codebase-research-locator.md +4 -4
  30. package/dist/builtin/subagents/agents/debugger.md +5 -5
  31. package/dist/builtin/subagents/agents/worker.md +56 -0
  32. package/dist/builtin/subagents/package.json +1 -1
  33. package/dist/builtin/subagents/skills/subagent/SKILL.md +11 -11
  34. package/dist/builtin/subagents/src/agents/agent-loaders.ts +3 -5
  35. package/dist/builtin/subagents/src/agents/agent-management-helpers.ts +3 -3
  36. package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -0
  37. package/dist/builtin/subagents/src/extension/index.ts +6 -3
  38. package/dist/builtin/subagents/src/extension/schemas.ts +2 -7
  39. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -3
  40. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -4
  41. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +15 -1
  42. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +35 -1
  43. package/dist/builtin/subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +1 -1
  44. package/dist/builtin/subagents/src/runs/shared/nested-render.ts +2 -2
  45. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -1
  46. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +4 -2
  47. package/dist/builtin/subagents/src/shared/types-async.ts +1 -0
  48. package/dist/builtin/subagents/src/shared/types-depth.ts +5 -5
  49. package/dist/builtin/subagents/src/shared/types-runtime.ts +2 -1
  50. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +27 -5
  51. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -2
  52. package/dist/builtin/subagents/src/tui/render-layout.ts +27 -4
  53. package/dist/builtin/subagents/src/tui/render-result-animation.ts +22 -31
  54. package/dist/builtin/subagents/src/tui/render-result-compact.ts +6 -6
  55. package/dist/builtin/subagents/src/tui/render-result.ts +20 -19
  56. package/dist/builtin/subagents/src/tui/render-status-progress.ts +3 -3
  57. package/dist/builtin/subagents/src/tui/render-widget.ts +46 -7
  58. package/dist/builtin/subagents/src/tui/render.ts +2 -2
  59. package/dist/builtin/web-access/package.json +1 -1
  60. package/dist/builtin/workflows/CHANGELOG.md +56 -0
  61. package/dist/builtin/workflows/README.md +3 -3
  62. package/dist/builtin/workflows/builtin/goal-artifacts.ts +11 -6
  63. package/dist/builtin/workflows/builtin/goal-ledger.ts +33 -1
  64. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -28
  65. package/dist/builtin/workflows/builtin/goal-reducer.ts +2 -2
  66. package/dist/builtin/workflows/builtin/goal-reports.ts +2 -5
  67. package/dist/builtin/workflows/builtin/goal-review.ts +1 -1
  68. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  69. package/dist/builtin/workflows/builtin/open-claude-design-feedback.ts +3 -3
  70. package/dist/builtin/workflows/builtin/open-claude-design-phases.ts +1 -3
  71. package/dist/builtin/workflows/builtin/open-claude-design-setup.ts +1 -1
  72. package/dist/builtin/workflows/builtin/ralph-core.ts +7 -17
  73. package/dist/builtin/workflows/builtin/ralph-runner.ts +11 -18
  74. package/dist/builtin/workflows/builtin/shared-prompts.ts +1 -1
  75. package/dist/builtin/workflows/package.json +1 -1
  76. package/dist/builtin/workflows/src/authoring.d.ts +1 -1
  77. package/dist/builtin/workflows/src/durable/backend.ts +343 -0
  78. package/dist/builtin/workflows/src/durable/child-primitive.ts +79 -0
  79. package/dist/builtin/workflows/src/durable/dbos-backend.ts +421 -0
  80. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +171 -0
  81. package/dist/builtin/workflows/src/durable/factory.ts +96 -0
  82. package/dist/builtin/workflows/src/durable/file-backend.ts +433 -0
  83. package/dist/builtin/workflows/src/durable/index.ts +73 -0
  84. package/dist/builtin/workflows/src/durable/resume-catalog.ts +217 -0
  85. package/dist/builtin/workflows/src/durable/resume-runtime.ts +299 -0
  86. package/dist/builtin/workflows/src/durable/scoped-backend.ts +171 -0
  87. package/dist/builtin/workflows/src/durable/stage-primitive.ts +284 -0
  88. package/dist/builtin/workflows/src/durable/tool-primitive.ts +180 -0
  89. package/dist/builtin/workflows/src/durable/types.ts +168 -0
  90. package/dist/builtin/workflows/src/durable/ui-primitive.ts +96 -0
  91. package/dist/builtin/workflows/src/engine/options.ts +3 -0
  92. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +2 -2
  93. package/dist/builtin/workflows/src/engine/primitives/task.ts +4 -4
  94. package/dist/builtin/workflows/src/engine/primitives/ui.ts +22 -8
  95. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +8 -0
  96. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +69 -0
  97. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +31 -0
  98. package/dist/builtin/workflows/src/engine/run.ts +148 -6
  99. package/dist/builtin/workflows/src/engine/runtime.ts +8 -2
  100. package/dist/builtin/workflows/src/extension/config-loader.ts +35 -15
  101. package/dist/builtin/workflows/src/extension/discovery.ts +20 -8
  102. package/dist/builtin/workflows/src/extension/extension-factory.ts +6 -12
  103. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +5 -1
  104. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +4 -2
  105. package/dist/builtin/workflows/src/extension/runtime.ts +48 -9
  106. package/dist/builtin/workflows/src/extension/wiring.ts +1 -1
  107. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +143 -4
  108. package/dist/builtin/workflows/src/runs/background/quit.ts +61 -0
  109. package/dist/builtin/workflows/src/runs/background/status.ts +1 -0
  110. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +5 -5
  111. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +74 -33
  112. package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +20 -1
  113. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +8 -7
  114. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +1 -0
  115. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +1 -1
  116. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +19 -2
  117. package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +4 -0
  118. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +10 -10
  119. package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +5 -1
  120. package/dist/builtin/workflows/src/runs/foreground/stage-runner-send-user-message.ts +25 -0
  121. package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -0
  122. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +16 -0
  123. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +20 -0
  124. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +23 -1
  125. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +30 -1
  126. package/dist/builtin/workflows/src/shared/store-public-types.ts +6 -2
  127. package/dist/builtin/workflows/src/shared/store-run-methods.ts +12 -6
  128. package/dist/builtin/workflows/src/shared/types.ts +55 -0
  129. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +11 -10
  130. package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -1
  131. package/dist/builtin/workflows/src/tui/graph-view-graph-render.ts +41 -0
  132. package/dist/builtin/workflows/src/tui/graph-view-input.ts +82 -24
  133. package/dist/builtin/workflows/src/tui/graph-view-render.ts +7 -0
  134. package/dist/builtin/workflows/src/tui/graph-view-state.ts +22 -2
  135. package/dist/builtin/workflows/src/tui/graph-view-types.ts +4 -5
  136. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +9 -11
  137. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +9 -3
  138. package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +11 -2
  139. package/dist/builtin/workflows/src/tui/stage-chat-view-live-events.ts +35 -0
  140. package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +51 -17
  141. package/dist/builtin/workflows/src/tui/stage-chat-view-status.ts +36 -0
  142. package/dist/builtin/workflows/src/tui/stage-chat-view-types.ts +5 -1
  143. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +3 -1
  144. package/dist/builtin/workflows/src/tui/status-list.ts +14 -2
  145. package/dist/builtin/workflows/src/tui/widget.ts +23 -8
  146. package/dist/builtin/workflows/src/tui/workflow-attach-pane-types.ts +5 -4
  147. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +8 -8
  148. package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +151 -0
  149. package/dist/cli/args.d.ts.map +1 -1
  150. package/dist/cli/args.js +9 -9
  151. package/dist/cli/args.js.map +1 -1
  152. package/dist/config-self-update.d.ts.map +1 -1
  153. package/dist/config-self-update.js +3 -4
  154. package/dist/config-self-update.js.map +1 -1
  155. package/dist/config.d.ts.map +1 -1
  156. package/dist/config.js +4 -5
  157. package/dist/config.js.map +1 -1
  158. package/dist/core/agent-session-bash.d.ts +1 -0
  159. package/dist/core/agent-session-bash.d.ts.map +1 -1
  160. package/dist/core/agent-session-bash.js +1 -0
  161. package/dist/core/agent-session-bash.js.map +1 -1
  162. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  163. package/dist/core/agent-session-tool-registry.js +23 -0
  164. package/dist/core/agent-session-tool-registry.js.map +1 -1
  165. package/dist/core/bash-executor.d.ts +2 -0
  166. package/dist/core/bash-executor.d.ts.map +1 -1
  167. package/dist/core/bash-executor.js +1 -0
  168. package/dist/core/bash-executor.js.map +1 -1
  169. package/dist/core/compaction/compaction.d.ts +29 -0
  170. package/dist/core/compaction/compaction.d.ts.map +1 -1
  171. package/dist/core/compaction/compaction.js +36 -1
  172. package/dist/core/compaction/compaction.js.map +1 -1
  173. package/dist/core/compaction/context-compaction-metrics.d.ts +14 -2
  174. package/dist/core/compaction/context-compaction-metrics.d.ts.map +1 -1
  175. package/dist/core/compaction/context-compaction-metrics.js +50 -1
  176. package/dist/core/compaction/context-compaction-metrics.js.map +1 -1
  177. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  178. package/dist/core/compaction/context-compaction-prompt.js +2 -0
  179. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  180. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  181. package/dist/core/compaction/context-compaction-runner.js +1 -1
  182. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  183. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  184. package/dist/core/compaction/context-deletion-application.js +5 -5
  185. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  186. package/dist/core/compaction/context-deletion-targets.d.ts +2 -0
  187. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  188. package/dist/core/compaction/context-deletion-targets.js +23 -3
  189. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  190. package/dist/core/compaction/context-deletion-tool-definitions.d.ts +6 -0
  191. package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +1 -1
  192. package/dist/core/compaction/context-deletion-tool-definitions.js.map +1 -1
  193. package/dist/core/compaction/context-deletion-tools.d.ts.map +1 -1
  194. package/dist/core/compaction/context-deletion-tools.js +18 -10
  195. package/dist/core/compaction/context-deletion-tools.js.map +1 -1
  196. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  197. package/dist/core/compaction/context-transcript-analysis.js +2 -4
  198. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  199. package/dist/core/copilot-gemini-tool-arguments.d.ts.map +1 -1
  200. package/dist/core/copilot-gemini-tool-arguments.js +2 -60
  201. package/dist/core/copilot-gemini-tool-arguments.js.map +1 -1
  202. package/dist/core/extensions/context-types.d.ts +2 -0
  203. package/dist/core/extensions/context-types.d.ts.map +1 -1
  204. package/dist/core/extensions/context-types.js.map +1 -1
  205. package/dist/core/extensions/index.d.ts +2 -2
  206. package/dist/core/extensions/index.d.ts.map +1 -1
  207. package/dist/core/extensions/index.js +1 -1
  208. package/dist/core/extensions/index.js.map +1 -1
  209. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  210. package/dist/core/extensions/loader-virtual-modules.js +57 -32
  211. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  212. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  213. package/dist/core/extensions/runner-context.js +11 -0
  214. package/dist/core/extensions/runner-context.js.map +1 -1
  215. package/dist/core/extensions/tool-events.d.ts +13 -13
  216. package/dist/core/extensions/tool-events.d.ts.map +1 -1
  217. package/dist/core/extensions/tool-events.js +3 -3
  218. package/dist/core/extensions/tool-events.js.map +1 -1
  219. package/dist/core/extensions/types.d.ts +1 -1
  220. package/dist/core/extensions/types.d.ts.map +1 -1
  221. package/dist/core/extensions/types.js +1 -1
  222. package/dist/core/extensions/types.js.map +1 -1
  223. package/dist/core/flattened-tool-arguments.d.ts +18 -0
  224. package/dist/core/flattened-tool-arguments.d.ts.map +1 -1
  225. package/dist/core/flattened-tool-arguments.js +104 -0
  226. package/dist/core/flattened-tool-arguments.js.map +1 -1
  227. package/dist/core/messages.d.ts +1 -0
  228. package/dist/core/messages.d.ts.map +1 -1
  229. package/dist/core/messages.js +46 -1
  230. package/dist/core/messages.js.map +1 -1
  231. package/dist/core/sdk-exports.d.ts +1 -1
  232. package/dist/core/sdk-exports.d.ts.map +1 -1
  233. package/dist/core/sdk-exports.js +1 -1
  234. package/dist/core/sdk-exports.js.map +1 -1
  235. package/dist/core/sdk-types.d.ts +2 -2
  236. package/dist/core/sdk-types.d.ts.map +1 -1
  237. package/dist/core/sdk-types.js.map +1 -1
  238. package/dist/core/sdk.d.ts.map +1 -1
  239. package/dist/core/sdk.js +12 -0
  240. package/dist/core/sdk.js.map +1 -1
  241. package/dist/core/session-manager-core.d.ts +15 -7
  242. package/dist/core/session-manager-core.d.ts.map +1 -1
  243. package/dist/core/session-manager-core.js +20 -9
  244. package/dist/core/session-manager-core.js.map +1 -1
  245. package/dist/core/session-manager-entries.d.ts +2 -2
  246. package/dist/core/session-manager-entries.d.ts.map +1 -1
  247. package/dist/core/session-manager-entries.js +9 -3
  248. package/dist/core/session-manager-entries.js.map +1 -1
  249. package/dist/core/session-manager-history.d.ts.map +1 -1
  250. package/dist/core/session-manager-history.js +2 -1
  251. package/dist/core/session-manager-history.js.map +1 -1
  252. package/dist/core/session-manager-list.d.ts +3 -3
  253. package/dist/core/session-manager-list.d.ts.map +1 -1
  254. package/dist/core/session-manager-list.js +27 -8
  255. package/dist/core/session-manager-list.js.map +1 -1
  256. package/dist/core/session-manager-storage.d.ts +3 -1
  257. package/dist/core/session-manager-storage.d.ts.map +1 -1
  258. package/dist/core/session-manager-storage.js +55 -12
  259. package/dist/core/session-manager-storage.js.map +1 -1
  260. package/dist/core/session-manager-tool-dependencies.d.ts +10 -0
  261. package/dist/core/session-manager-tool-dependencies.d.ts.map +1 -0
  262. package/dist/core/session-manager-tool-dependencies.js +133 -0
  263. package/dist/core/session-manager-tool-dependencies.js.map +1 -0
  264. package/dist/core/session-manager-types.d.ts +22 -0
  265. package/dist/core/session-manager-types.d.ts.map +1 -1
  266. package/dist/core/session-manager-types.js.map +1 -1
  267. package/dist/core/session-manager.d.ts +2 -2
  268. package/dist/core/session-manager.d.ts.map +1 -1
  269. package/dist/core/session-manager.js +1 -1
  270. package/dist/core/session-manager.js.map +1 -1
  271. package/dist/core/settings-manager-basic-accessors.d.ts +4 -0
  272. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  273. package/dist/core/settings-manager-basic-accessors.js +18 -0
  274. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  275. package/dist/core/settings-manager-resource-accessors.d.ts +4 -0
  276. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  277. package/dist/core/settings-manager-resource-accessors.js +15 -0
  278. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  279. package/dist/core/settings-types.d.ts +11 -0
  280. package/dist/core/settings-types.d.ts.map +1 -1
  281. package/dist/core/settings-types.js.map +1 -1
  282. package/dist/core/system-prompt.d.ts +1 -1
  283. package/dist/core/system-prompt.d.ts.map +1 -1
  284. package/dist/core/system-prompt.js +3 -2
  285. package/dist/core/system-prompt.js.map +1 -1
  286. package/dist/core/tools/artifact-protocol.d.ts +11 -0
  287. package/dist/core/tools/artifact-protocol.d.ts.map +1 -0
  288. package/dist/core/tools/artifact-protocol.js +76 -0
  289. package/dist/core/tools/artifact-protocol.js.map +1 -0
  290. package/dist/core/tools/artifacts.d.ts +18 -0
  291. package/dist/core/tools/artifacts.d.ts.map +1 -0
  292. package/dist/core/tools/artifacts.js +90 -0
  293. package/dist/core/tools/artifacts.js.map +1 -0
  294. package/dist/core/tools/bash-async-jobs.d.ts +20 -0
  295. package/dist/core/tools/bash-async-jobs.d.ts.map +1 -0
  296. package/dist/core/tools/bash-async-jobs.js +59 -0
  297. package/dist/core/tools/bash-async-jobs.js.map +1 -0
  298. package/dist/core/tools/bash-async-output.d.ts +10 -0
  299. package/dist/core/tools/bash-async-output.d.ts.map +1 -0
  300. package/dist/core/tools/bash-async-output.js +80 -0
  301. package/dist/core/tools/bash-async-output.js.map +1 -0
  302. package/dist/core/tools/bash-interceptor.d.ts +10 -0
  303. package/dist/core/tools/bash-interceptor.d.ts.map +1 -0
  304. package/dist/core/tools/bash-interceptor.js +39 -0
  305. package/dist/core/tools/bash-interceptor.js.map +1 -0
  306. package/dist/core/tools/bash-leading-cd.d.ts +7 -0
  307. package/dist/core/tools/bash-leading-cd.d.ts.map +1 -0
  308. package/dist/core/tools/bash-leading-cd.js +59 -0
  309. package/dist/core/tools/bash-leading-cd.js.map +1 -0
  310. package/dist/core/tools/bash-pty-native.d.ts +14 -0
  311. package/dist/core/tools/bash-pty-native.d.ts.map +1 -0
  312. package/dist/core/tools/bash-pty-native.js +71 -0
  313. package/dist/core/tools/bash-pty-native.js.map +1 -0
  314. package/dist/core/tools/bash.d.ts +28 -17
  315. package/dist/core/tools/bash.d.ts.map +1 -1
  316. package/dist/core/tools/bash.js +152 -35
  317. package/dist/core/tools/bash.js.map +1 -1
  318. package/dist/core/tools/block-resolver.d.ts +16 -0
  319. package/dist/core/tools/block-resolver.d.ts.map +1 -0
  320. package/dist/core/tools/block-resolver.js +74 -0
  321. package/dist/core/tools/block-resolver.js.map +1 -0
  322. package/dist/core/tools/conflict-registry.d.ts +16 -0
  323. package/dist/core/tools/conflict-registry.d.ts.map +1 -0
  324. package/dist/core/tools/conflict-registry.js +44 -0
  325. package/dist/core/tools/conflict-registry.js.map +1 -0
  326. package/dist/core/tools/directory-tree.d.ts +13 -0
  327. package/dist/core/tools/directory-tree.d.ts.map +1 -0
  328. package/dist/core/tools/directory-tree.js +81 -0
  329. package/dist/core/tools/directory-tree.js.map +1 -0
  330. package/dist/core/tools/edit.d.ts +4 -29
  331. package/dist/core/tools/edit.d.ts.map +1 -1
  332. package/dist/core/tools/edit.js +136 -228
  333. package/dist/core/tools/edit.js.map +1 -1
  334. package/dist/core/tools/fetch-url.d.ts +74 -0
  335. package/dist/core/tools/fetch-url.d.ts.map +1 -0
  336. package/dist/core/tools/fetch-url.js +518 -0
  337. package/dist/core/tools/fetch-url.js.map +1 -0
  338. package/dist/core/tools/find.d.ts +27 -9
  339. package/dist/core/tools/find.d.ts.map +1 -1
  340. package/dist/core/tools/find.js +400 -176
  341. package/dist/core/tools/find.js.map +1 -1
  342. package/dist/core/tools/glob-path-utils.d.ts +8 -0
  343. package/dist/core/tools/glob-path-utils.d.ts.map +1 -0
  344. package/dist/core/tools/glob-path-utils.js +26 -0
  345. package/dist/core/tools/glob-path-utils.js.map +1 -0
  346. package/dist/core/tools/grep.d.ts +12 -0
  347. package/dist/core/tools/grep.d.ts.map +1 -1
  348. package/dist/core/tools/grep.js +141 -17
  349. package/dist/core/tools/grep.js.map +1 -1
  350. package/dist/core/tools/hashline-engine/apply.d.ts +11 -0
  351. package/dist/core/tools/hashline-engine/apply.d.ts.map +1 -0
  352. package/dist/core/tools/hashline-engine/apply.js +752 -0
  353. package/dist/core/tools/hashline-engine/apply.js.map +1 -0
  354. package/dist/core/tools/hashline-engine/block.d.ts +40 -0
  355. package/dist/core/tools/hashline-engine/block.d.ts.map +1 -0
  356. package/dist/core/tools/hashline-engine/block.js +117 -0
  357. package/dist/core/tools/hashline-engine/block.js.map +1 -0
  358. package/dist/core/tools/hashline-engine/diff-preview.d.ts +15 -0
  359. package/dist/core/tools/hashline-engine/diff-preview.d.ts.map +1 -0
  360. package/dist/core/tools/hashline-engine/diff-preview.js +98 -0
  361. package/dist/core/tools/hashline-engine/diff-preview.js.map +1 -0
  362. package/dist/core/tools/hashline-engine/format.d.ts +71 -0
  363. package/dist/core/tools/hashline-engine/format.d.ts.map +1 -0
  364. package/dist/core/tools/hashline-engine/format.js +178 -0
  365. package/dist/core/tools/hashline-engine/format.js.map +1 -0
  366. package/dist/core/tools/hashline-engine/fs.d.ts +81 -0
  367. package/dist/core/tools/hashline-engine/fs.d.ts.map +1 -0
  368. package/dist/core/tools/hashline-engine/fs.js +143 -0
  369. package/dist/core/tools/hashline-engine/fs.js.map +1 -0
  370. package/dist/core/tools/hashline-engine/index.d.ts +18 -0
  371. package/dist/core/tools/hashline-engine/index.d.ts.map +1 -0
  372. package/dist/core/tools/hashline-engine/index.js +20 -0
  373. package/dist/core/tools/hashline-engine/index.js.map +1 -0
  374. package/dist/core/tools/hashline-engine/input.d.ts +101 -0
  375. package/dist/core/tools/hashline-engine/input.d.ts.map +1 -0
  376. package/dist/core/tools/hashline-engine/input.js +398 -0
  377. package/dist/core/tools/hashline-engine/input.js.map +1 -0
  378. package/dist/core/tools/hashline-engine/messages.d.ts +99 -0
  379. package/dist/core/tools/hashline-engine/messages.d.ts.map +1 -0
  380. package/dist/core/tools/hashline-engine/messages.js +144 -0
  381. package/dist/core/tools/hashline-engine/messages.js.map +1 -0
  382. package/dist/core/tools/hashline-engine/mismatch.d.ts +45 -0
  383. package/dist/core/tools/hashline-engine/mismatch.d.ts.map +1 -0
  384. package/dist/core/tools/hashline-engine/mismatch.js +90 -0
  385. package/dist/core/tools/hashline-engine/mismatch.js.map +1 -0
  386. package/dist/core/tools/hashline-engine/normalize.d.ts +21 -0
  387. package/dist/core/tools/hashline-engine/normalize.d.ts.map +1 -0
  388. package/dist/core/tools/hashline-engine/normalize.js +33 -0
  389. package/dist/core/tools/hashline-engine/normalize.js.map +1 -0
  390. package/dist/core/tools/hashline-engine/parser.d.ts +24 -0
  391. package/dist/core/tools/hashline-engine/parser.d.ts.map +1 -0
  392. package/dist/core/tools/hashline-engine/parser.js +381 -0
  393. package/dist/core/tools/hashline-engine/parser.js.map +1 -0
  394. package/dist/core/tools/hashline-engine/patcher.d.ts +118 -0
  395. package/dist/core/tools/hashline-engine/patcher.d.ts.map +1 -0
  396. package/dist/core/tools/hashline-engine/patcher.js +341 -0
  397. package/dist/core/tools/hashline-engine/patcher.js.map +1 -0
  398. package/dist/core/tools/hashline-engine/prefixes.d.ts +43 -0
  399. package/dist/core/tools/hashline-engine/prefixes.d.ts.map +1 -0
  400. package/dist/core/tools/hashline-engine/prefixes.js +135 -0
  401. package/dist/core/tools/hashline-engine/prefixes.js.map +1 -0
  402. package/dist/core/tools/hashline-engine/recovery.d.ts +41 -0
  403. package/dist/core/tools/hashline-engine/recovery.d.ts.map +1 -0
  404. package/dist/core/tools/hashline-engine/recovery.js +168 -0
  405. package/dist/core/tools/hashline-engine/recovery.js.map +1 -0
  406. package/dist/core/tools/hashline-engine/snapshots.d.ts +65 -0
  407. package/dist/core/tools/hashline-engine/snapshots.d.ts.map +1 -0
  408. package/dist/core/tools/hashline-engine/snapshots.js +108 -0
  409. package/dist/core/tools/hashline-engine/snapshots.js.map +1 -0
  410. package/dist/core/tools/hashline-engine/stream.d.ts +3 -0
  411. package/dist/core/tools/hashline-engine/stream.d.ts.map +1 -0
  412. package/dist/core/tools/hashline-engine/stream.js +111 -0
  413. package/dist/core/tools/hashline-engine/stream.js.map +1 -0
  414. package/dist/core/tools/hashline-engine/tokenizer.d.ts +69 -0
  415. package/dist/core/tools/hashline-engine/tokenizer.d.ts.map +1 -0
  416. package/dist/core/tools/hashline-engine/tokenizer.js +430 -0
  417. package/dist/core/tools/hashline-engine/tokenizer.js.map +1 -0
  418. package/dist/core/tools/hashline-engine/types.d.ts +166 -0
  419. package/dist/core/tools/hashline-engine/types.d.ts.map +1 -0
  420. package/dist/core/tools/hashline-engine/types.js +9 -0
  421. package/dist/core/tools/hashline-engine/types.js.map +1 -0
  422. package/dist/core/tools/hashline.d.ts +29 -0
  423. package/dist/core/tools/hashline.d.ts.map +1 -0
  424. package/dist/core/tools/hashline.js +110 -0
  425. package/dist/core/tools/hashline.js.map +1 -0
  426. package/dist/core/tools/index.d.ts +6 -4
  427. package/dist/core/tools/index.d.ts.map +1 -1
  428. package/dist/core/tools/index.js +52 -35
  429. package/dist/core/tools/index.js.map +1 -1
  430. package/dist/core/tools/notebook.d.ts +38 -0
  431. package/dist/core/tools/notebook.d.ts.map +1 -0
  432. package/dist/core/tools/notebook.js +125 -0
  433. package/dist/core/tools/notebook.js.map +1 -0
  434. package/dist/core/tools/read-document-extract.d.ts +9 -0
  435. package/dist/core/tools/read-document-extract.d.ts.map +1 -0
  436. package/dist/core/tools/read-document-extract.js +212 -0
  437. package/dist/core/tools/read-document-extract.js.map +1 -0
  438. package/dist/core/tools/read-selectors.d.ts +24 -0
  439. package/dist/core/tools/read-selectors.d.ts.map +1 -0
  440. package/dist/core/tools/read-selectors.js +277 -0
  441. package/dist/core/tools/read-selectors.js.map +1 -0
  442. package/dist/core/tools/read-url.d.ts +37 -0
  443. package/dist/core/tools/read-url.d.ts.map +1 -0
  444. package/dist/core/tools/read-url.js +39 -0
  445. package/dist/core/tools/read-url.js.map +1 -0
  446. package/dist/core/tools/read.d.ts +11 -11
  447. package/dist/core/tools/read.d.ts.map +1 -1
  448. package/dist/core/tools/read.js +224 -94
  449. package/dist/core/tools/read.js.map +1 -1
  450. package/dist/core/tools/resource-selectors.d.ts +44 -0
  451. package/dist/core/tools/resource-selectors.d.ts.map +1 -0
  452. package/dist/core/tools/resource-selectors.js +808 -0
  453. package/dist/core/tools/resource-selectors.js.map +1 -0
  454. package/dist/core/tools/search-details.d.ts +26 -0
  455. package/dist/core/tools/search-details.d.ts.map +1 -0
  456. package/dist/core/tools/search-details.js +24 -0
  457. package/dist/core/tools/search-details.js.map +1 -0
  458. package/dist/core/tools/search-line-ranges.d.ts +11 -0
  459. package/dist/core/tools/search-line-ranges.d.ts.map +1 -0
  460. package/dist/core/tools/search-line-ranges.js +65 -0
  461. package/dist/core/tools/search-line-ranges.js.map +1 -0
  462. package/dist/core/tools/search-native.d.ts +97 -0
  463. package/dist/core/tools/search-native.d.ts.map +1 -0
  464. package/dist/core/tools/search-native.js +27 -0
  465. package/dist/core/tools/search-native.js.map +1 -0
  466. package/dist/core/tools/search.d.ts +24 -0
  467. package/dist/core/tools/search.d.ts.map +1 -0
  468. package/dist/core/tools/search.js +573 -0
  469. package/dist/core/tools/search.js.map +1 -0
  470. package/dist/core/tools/truncate.d.ts +4 -4
  471. package/dist/core/tools/truncate.d.ts.map +1 -1
  472. package/dist/core/tools/truncate.js +3 -3
  473. package/dist/core/tools/truncate.js.map +1 -1
  474. package/dist/core/tools/url-ip-guards.d.ts +4 -0
  475. package/dist/core/tools/url-ip-guards.d.ts.map +1 -0
  476. package/dist/core/tools/url-ip-guards.js +126 -0
  477. package/dist/core/tools/url-ip-guards.js.map +1 -0
  478. package/dist/core/tools/write.d.ts +12 -2
  479. package/dist/core/tools/write.d.ts.map +1 -1
  480. package/dist/core/tools/write.js +166 -14
  481. package/dist/core/tools/write.js.map +1 -1
  482. package/dist/core/trust-manager.d.ts.map +1 -1
  483. package/dist/core/trust-manager.js +2 -3
  484. package/dist/core/trust-manager.js.map +1 -1
  485. package/dist/index-extensions.d.ts +2 -2
  486. package/dist/index-extensions.d.ts.map +1 -1
  487. package/dist/index-extensions.js +1 -1
  488. package/dist/index-extensions.js.map +1 -1
  489. package/dist/index.d.ts +3 -3
  490. package/dist/index.d.ts.map +1 -1
  491. package/dist/index.js +3 -3
  492. package/dist/index.js.map +1 -1
  493. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +1 -0
  494. package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
  495. package/dist/modes/interactive/components/chat-session-host-runtime.js +12 -0
  496. package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
  497. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts +4 -0
  498. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts.map +1 -0
  499. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js +131 -0
  500. package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js.map +1 -0
  501. package/dist/modes/interactive/components/chat-session-host.d.ts +2 -0
  502. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  503. package/dist/modes/interactive/components/chat-session-host.js +7 -1
  504. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  505. package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
  506. package/dist/modes/interactive/components/chat-transcript.js +15 -4
  507. package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
  508. package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
  509. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  510. package/dist/modes/interactive/components/custom-editor.js +9 -2
  511. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  512. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  514. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  515. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  516. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  517. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  518. package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
  519. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  520. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  521. package/dist/modes/interactive/components/tool-execution.d.ts +3 -0
  522. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/tool-execution.js +26 -0
  524. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  525. package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/tree-selector-content.js +0 -5
  527. package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
  528. package/dist/modes/interactive/interactive-auth-login.d.ts.map +1 -1
  529. package/dist/modes/interactive/interactive-auth-login.js +1 -0
  530. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  531. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  532. package/dist/modes/interactive/interactive-autocomplete.js +80 -2
  533. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  534. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  535. package/dist/modes/interactive/interactive-hotkeys-debug.js +3 -0
  536. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  537. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  538. package/dist/modes/interactive/interactive-input-handling.js +51 -0
  539. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  540. package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
  541. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  542. package/dist/modes/interactive/interactive-mode-base.js +5 -0
  543. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  544. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  545. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  546. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  547. package/dist/modes/interactive/interactive-mode-surface.d.ts +12 -0
  548. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  549. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  550. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  551. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  552. package/dist/modes/interactive/interactive-mode.js +1 -0
  553. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  554. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  555. package/dist/modes/interactive/interactive-model-routing.js +4 -1
  556. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  557. package/dist/modes/interactive/interactive-onboarding.d.ts +11 -0
  558. package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -0
  559. package/dist/modes/interactive/interactive-onboarding.js +220 -0
  560. package/dist/modes/interactive/interactive-onboarding.js.map +1 -0
  561. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  562. package/dist/modes/interactive/interactive-selectors.js +4 -0
  563. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  564. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  565. package/dist/modes/interactive/interactive-session-routing.js +6 -0
  566. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  567. package/dist/modes/interactive/interactive-slash-commands.d.ts.map +1 -1
  568. package/dist/modes/interactive/interactive-slash-commands.js +9 -4
  569. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  570. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  571. package/dist/modes/interactive/interactive-startup.js +28 -0
  572. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  573. package/dist/utils/child-process.d.ts.map +1 -1
  574. package/dist/utils/child-process.js +21 -1
  575. package/dist/utils/child-process.js.map +1 -1
  576. package/dist/utils/markit.d.ts +8 -0
  577. package/dist/utils/markit.d.ts.map +1 -0
  578. package/dist/utils/markit.js +53 -0
  579. package/dist/utils/markit.js.map +1 -0
  580. package/dist/utils/paths.d.ts +2 -1
  581. package/dist/utils/paths.d.ts.map +1 -1
  582. package/dist/utils/paths.js +14 -1
  583. package/dist/utils/paths.js.map +1 -1
  584. package/docs/compaction.md +18 -1
  585. package/docs/containerization.md +1 -1
  586. package/docs/docs.json +1 -0
  587. package/docs/extensions.md +25 -36
  588. package/docs/models.md +1 -1
  589. package/docs/providers.md +2 -1
  590. package/docs/quickstart.md +11 -6
  591. package/docs/sdk.md +5 -5
  592. package/docs/session-format.md +6 -0
  593. package/docs/sessions.md +6 -0
  594. package/docs/settings.md +7 -0
  595. package/docs/subagents.md +3 -2
  596. package/docs/tools.md +49 -0
  597. package/docs/usage.md +3 -3
  598. package/docs/workflows.md +112 -8
  599. package/examples/extensions/subagent/README.md +5 -5
  600. package/examples/extensions/subagent/agents/planner.md +1 -1
  601. package/examples/extensions/subagent/agents/reviewer.md +1 -1
  602. package/examples/extensions/subagent/agents/scout.md +2 -2
  603. package/examples/extensions/subagent/display.ts +3 -3
  604. package/examples/sdk/05-tools.ts +3 -3
  605. package/examples/sdk/README.md +1 -1
  606. package/package.json +5 -3
@@ -21,8 +21,7 @@ import type { ChatMessageRenderOptions, ReadonlyFooterDataProvider } from "@bast
21
21
  import { WorkflowAttachPane } from "./workflow-attach-pane.js";
22
22
  import { WORKFLOW_STATUS_KEY } from "./workflow-status.js";
23
23
  import { deriveGraphThemeFromPiTheme } from "./graph-theme.js";
24
- import { killRun as defaultKillRun } from "../runs/background/status.js";
25
- import { cancellationRegistry } from "../runs/background/cancellation-registry.js";
24
+ import { quitRun as defaultQuitRun } from "../runs/background/quit.js";
26
25
  import { stageControlRegistry as defaultStageControlRegistry } from "../runs/foreground/stage-control-registry.js";
27
26
  import type { StageControlRegistry } from "../runs/foreground/stage-control-registry.js";
28
27
  import type { StageUiBroker } from "../shared/stage-ui-broker.js";
@@ -100,8 +99,8 @@ const FULLSCREEN_OVERLAY_OPTIONS: PiOverlayOptions = {
100
99
  margin: 0,
101
100
  };
102
101
 
103
- const MOUSE_SCROLL_TRACKING_ON = "\x1b[?1000h\x1b[?1006h";
104
- const MOUSE_SCROLL_TRACKING_OFF = "\x1b[?1006l\x1b[?1000l";
102
+ const MOUSE_SCROLL_TRACKING_ON = "\x1b[?1000h\x1b[?1002h\x1b[?1006h";
103
+ const MOUSE_SCROLL_TRACKING_OFF = "\x1b[?1006l\x1b[?1002l\x1b[?1000l";
105
104
  const MAIN_CHAT_INPUT_STATUS_KEY = `${WORKFLOW_STATUS_KEY}:main-chat-input`;
106
105
  const MAIN_CHAT_INPUT_STATUS = "Main chat needs input — exit graph to answer.";
107
106
 
@@ -119,11 +118,10 @@ export interface BuildGraphOverlayAdapterOpts {
119
118
  /** Broker used to route stage-local custom UI into attached stage chats. */
120
119
  stageUiBroker?: StageUiBroker;
121
120
  /**
122
- * Kill hook used by graph-mode `q`. The extension factory supplies this so
123
- * persistence can record a terminal event while retaining the run for
124
- * inspection.
121
+ * Quit hook used by graph-mode `q`. This is intentionally distinct from
122
+ * `/workflow kill`: panel quit leaves durable-progress runs resumable.
125
123
  */
126
- onKillRun?: (runId: string) => void;
124
+ onQuitRun?: (runId: string) => void;
127
125
  /** Optional clock injection for deterministic attach-pane transition tests. */
128
126
  now?: () => number;
129
127
  }
@@ -135,8 +133,8 @@ export function buildGraphOverlayAdapter(
135
133
  ): GraphOverlayPort {
136
134
  const registry = buildOpts.stageControlRegistry ?? defaultStageControlRegistry;
137
135
  const stageUiBroker = buildOpts.stageUiBroker;
138
- const killRun = buildOpts.onKillRun ?? ((id: string): void => {
139
- defaultKillRun(id, { store, cancellation: cancellationRegistry });
136
+ const quitRun = buildOpts.onQuitRun ?? ((id: string): void => {
137
+ defaultQuitRun(id, { store, stageControlRegistry: registry });
140
138
  });
141
139
  let currentView: WorkflowAttachPane | null = null;
142
140
  // pi-tui returns an OverlayHandle via `options.onHandle`. We hold onto
@@ -329,7 +327,7 @@ export function buildGraphOverlayAdapter(
329
327
  uiStatus,
330
328
  onClose: finish,
331
329
  onHide: hideMounted,
332
- onKill: killRun,
330
+ onQuit: quitRun,
333
331
  initialAttachStageId: stageId,
334
332
  piTui: tui,
335
333
  piTheme: theme,
@@ -10,7 +10,10 @@ import {
10
10
  trailingWidgetBorderChar,
11
11
  widgetHintTargetLineIndex,
12
12
  } from "./stage-chat-view-render-helpers.js";
13
- import type { StageChatViewContext } from "./stage-chat-view-types.js";
13
+ import {
14
+ STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL,
15
+ type StageChatViewContext,
16
+ } from "./stage-chat-view-types.js";
14
17
  import type { StageSnapshot } from "../shared/store-types.js";
15
18
  import { truncateToWidth, visibleWidth } from "./text-helpers.js";
16
19
 
@@ -101,10 +104,13 @@ function mergeOrchestratorReturnHintIntoLine(
101
104
  width: number,
102
105
  options: { preserveTrailingBorder?: boolean; rightMargin?: number } = {},
103
106
  ): string {
104
- const plain = "ctrl+d returns to orchestrator panel";
107
+ const copyModeState = ctx.mouseScrollCaptureEnabled ? "off" : "on";
108
+ const plain = `ctrl+d graph · ${STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL} copy mode ${copyModeState}`;
105
109
  const styled =
106
110
  paint("ctrl+d", ctx.theme.text, { bold: true }) +
107
- paint(" returns to orchestrator panel", ctx.theme.textMuted);
111
+ paint(" graph · ", ctx.theme.textMuted) +
112
+ paint(STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL, ctx.theme.text, { bold: true }) +
113
+ paint(` copy mode ${copyModeState}`, ctx.theme.textMuted);
108
114
  const trailingBorder = options.preserveTrailingBorder === true
109
115
  ? trailingWidgetBorderChar(line)
110
116
  : "";
@@ -17,9 +17,9 @@ import { releaseMountedCustomUi } from "./stage-chat-view-custom-ui.js";
17
17
  import {
18
18
  canSubmitPrompt,
19
19
  currentStage,
20
+ isAbortableStreamingSession,
20
21
  isBlocked,
21
22
  isReadOnlyArchive,
22
- isStreaming,
23
23
  promptPageSize,
24
24
  recordCurrentPromptDraft,
25
25
  resolvePromptResponse,
@@ -30,6 +30,11 @@ export function handleStageChatInput(
30
30
  ctx: StageChatViewContext,
31
31
  data: string,
32
32
  ): boolean {
33
+ if (matchesKey(data, Key.ctrl("t"))) {
34
+ ctx.mouseScrollCaptureEnabled = !ctx.mouseScrollCaptureEnabled;
35
+ ctx.requestRender?.();
36
+ return true;
37
+ }
33
38
  if (ctx.mountedCustomUi) {
34
39
  return handleMountedCustomUiInput(ctx, data);
35
40
  }
@@ -54,12 +59,16 @@ export function handleStageChatInput(
54
59
  if (ctx.chatHost.handleScrollInput(data)) return true;
55
60
  if (matchesKey(data, Key.escape)) {
56
61
  if (
57
- isStreaming(ctx) ||
62
+ ctx.chatHost.isCompacting() ||
58
63
  ctx.chatHost.isBashRunning() ||
59
64
  ctx.chatHost.isEditingBashCommand()
60
65
  ) {
61
66
  return ctx.chatHost.handleInput(data);
62
67
  }
68
+ if (isAbortableStreamingSession(ctx)) {
69
+ void ctx.chatHost.interrupt();
70
+ return true;
71
+ }
63
72
  ctx.onClose();
64
73
  return true;
65
74
  }
@@ -0,0 +1,35 @@
1
+ import type { AgentSessionEvent } from "@bastani/atomic";
2
+ import type { StageChatViewContext } from "./stage-chat-view-types.js";
3
+ import { isTerminalStageChatState } from "./stage-chat-view-status.js";
4
+
5
+ export function applyStageChatLiveHandleEvent(
6
+ ctx: StageChatViewContext,
7
+ event: AgentSessionEvent,
8
+ ): void {
9
+ ctx.chatHost.applyAgentEvent(event);
10
+ if (!shouldCleanupAfterLiveEvent(ctx, event)) return;
11
+ const hadAnimationTick = ctx.chatHost.hasAnimationTick();
12
+ ctx.chatHost.clearBusyForTerminalWorkflowStage();
13
+ if (hadAnimationTick !== ctx.chatHost.hasAnimationTick()) ctx.requestRender?.();
14
+ }
15
+
16
+ function shouldCleanupAfterLiveEvent(
17
+ ctx: StageChatViewContext,
18
+ event: AgentSessionEvent,
19
+ ): boolean {
20
+ if (!isToolExecutionLiveEvent(event)) return false;
21
+ if (ctx.chatHost.isStreaming()) return false;
22
+ return isCurrentRunOrStageTerminal(ctx);
23
+ }
24
+
25
+ function isCurrentRunOrStageTerminal(ctx: StageChatViewContext): boolean {
26
+ return (
27
+ isTerminalStageChatState(ctx.lastObservedRunStatus) ||
28
+ isTerminalStageChatState(ctx.lastObservedStageStatus)
29
+ );
30
+ }
31
+
32
+ function isToolExecutionLiveEvent(event: AgentSessionEvent): boolean {
33
+ const type = String((event as { type?: unknown }).type ?? "");
34
+ return type === "tool_execution_start" || type === "tool_execution_update";
35
+ }
@@ -1,10 +1,6 @@
1
- import {
2
- ChatSessionHost,
3
- type ChatSessionHostStyle,
4
- } from "@bastani/atomic";
5
- import { Editor } from "@earendil-works/pi-tui";
6
- import type { EditorComponent } from "@earendil-works/pi-tui";
7
- import type { PendingPrompt, StageSnapshot } from "../shared/store-types.js";
1
+ import { ChatSessionHost, type ChatSessionHostStyle } from "@bastani/atomic";
2
+ import { Editor, type EditorComponent } from "@earendil-works/pi-tui";
3
+ import type { PendingPrompt, RunSnapshot, StageSnapshot } from "../shared/store-types.js";
8
4
  import { stageUiBroker } from "../shared/stage-ui-broker.js";
9
5
  import { resolveStageChatViewportRows } from "./stage-chat-layout.js";
10
6
  import { createPromptCardState } from "./prompt-card.js";
@@ -33,7 +29,13 @@ import {
33
29
  type StageChatViewOpts,
34
30
  } from "./stage-chat-view-types.js";
35
31
  import { noticeRow, noticeSummary } from "./stage-chat-view-transcript.js";
32
+ import { applyStageChatLiveHandleEvent } from "./stage-chat-view-live-events.js";
36
33
  import { hexToAnsi, RESET } from "./color-utils.js";
34
+ import {
35
+ isTerminalOrNonStreamingStageChatStatus,
36
+ isTerminalStageChatState,
37
+ isTerminalStageChatTransition,
38
+ } from "./stage-chat-view-status.js";
37
39
 
38
40
  export function initializeStageChatView(
39
41
  ctx: StageChatViewContext,
@@ -66,6 +68,9 @@ export function initializeStageChatView(
66
68
  ctx.promptScrollOffset = 0;
67
69
  ctx.promptMaxScroll = 0;
68
70
  ctx.localPaused = false;
71
+ ctx.mouseScrollCaptureEnabled = true;
72
+ ctx.lastObservedStageStatus = undefined;
73
+ ctx.lastObservedRunStatus = undefined;
69
74
  ctx.seenNoticeIds = new Set<string>();
70
75
  ctx._unsubscribeStore = null;
71
76
  ctx._unsubscribeHandle = null;
@@ -82,16 +87,18 @@ export function initializeStageChatView(
82
87
  });
83
88
 
84
89
  snapshotMessagesFromHandle(ctx);
85
- const initialStage = currentStage(ctx);
90
+ const initialRun = currentRun(ctx);
91
+ const initialStage = initialRun?.stages.find((s) => s.id === ctx.stageId);
92
+ ctx.lastObservedRunStatus = initialRun?.status;
93
+ ctx.lastObservedStageStatus = initialStage?.status;
86
94
  snapshotMessagesFromSessionFile(ctx, initialStage);
87
95
  absorbStageNotices(ctx, initialStage);
88
96
  syncPromptState(ctx, initialStage?.pendingPrompt);
97
+ if (isTerminalStageChatState(initialRun?.status) || isTerminalStageChatState(initialStage?.status)) ctx.chatHost.clearBusyForTerminalWorkflowStage();
89
98
  ctx._unsubscribeStore = ctx.store.subscribe(() => handleStoreUpdate(ctx));
90
99
 
91
100
  if (ctx.handle) {
92
- ctx._unsubscribeHandle = ctx.handle.subscribe((event) => {
93
- ctx.chatHost.applyAgentEvent(event);
94
- });
101
+ ctx._unsubscribeHandle = ctx.handle.subscribe((event) => applyStageChatLiveHandleEvent(ctx, event));
95
102
  }
96
103
  ctx.chatHost.syncAnimationTick();
97
104
  }
@@ -171,7 +178,7 @@ function createChatHost(
171
178
  isBashRunning: () => liveHandle(ctx)?.agentSession?.isBashRunning === true,
172
179
  requestRender: opts.requestRender,
173
180
  getAgentSession: () => liveHandle(ctx)?.agentSession,
174
- isStreaming: () => liveHandle(ctx)?.isStreaming === true,
181
+ isStreaming: () => isLiveHandleStreaming(ctx),
175
182
  isPaused: () => isPaused(ctx),
176
183
  isDisabled: () => isBlocked(ctx) || !liveHandle(ctx),
177
184
  tui: opts.piTui,
@@ -200,7 +207,10 @@ function chatHostStyle(ctx: StageChatViewContext): ChatSessionHostStyle {
200
207
  }
201
208
 
202
209
  function handleStoreUpdate(ctx: StageChatViewContext): void {
203
- const stage = currentStage(ctx);
210
+ const run = currentRun(ctx);
211
+ const stage = run?.stages.find((s) => s.id === ctx.stageId);
212
+ const currentRunStatus = run?.status;
213
+ const currentStageStatus = stage?.status;
204
214
  let changed = false;
205
215
  if (stage && stage.status === "paused" && !ctx.localPaused) {
206
216
  ctx.localPaused = true;
@@ -215,8 +225,15 @@ function handleStoreUpdate(ctx: StageChatViewContext): void {
215
225
  if (promptChanged && ctx.promptState && canSubmitPrompt(ctx, ctx.promptState.prompt.id)) {
216
226
  ctx.requestFocus?.();
217
227
  }
228
+ if (isTerminalStageChatTransition(ctx.lastObservedStageStatus, currentStageStatus) || isTerminalStageChatTransition(ctx.lastObservedRunStatus, currentRunStatus)) {
229
+ ctx.chatHost.clearBusyForTerminalWorkflowStage();
230
+ changed = true;
231
+ }
232
+ ctx.lastObservedRunStatus = currentRunStatus;
233
+ ctx.lastObservedStageStatus = currentStageStatus;
234
+ const hadAnimationTick = ctx.chatHost.hasAnimationTick();
218
235
  ctx.chatHost.syncAnimationTick();
219
- if (changed) ctx.requestRender?.();
236
+ if (changed || hadAnimationTick !== ctx.chatHost.hasAnimationTick()) ctx.requestRender?.();
220
237
  }
221
238
 
222
239
  function snapshotMessagesFromHandle(ctx: StageChatViewContext): void {
@@ -256,10 +273,12 @@ function absorbStageNotices(
256
273
  return changed;
257
274
  }
258
275
 
276
+ export function currentRun(ctx: StageChatViewContext): RunSnapshot | undefined {
277
+ return ctx.store.snapshot().runs.find((r) => r.id === ctx.runId);
278
+ }
279
+
259
280
  export function currentStage(ctx: StageChatViewContext): StageSnapshot | undefined {
260
- const snap = ctx.store.snapshot();
261
- const run = snap.runs.find((r) => r.id === ctx.runId);
262
- return run?.stages.find((s) => s.id === ctx.stageId);
281
+ return currentRun(ctx)?.stages.find((s) => s.id === ctx.stageId);
263
282
  }
264
283
 
265
284
  export function syncPromptState(
@@ -386,14 +405,29 @@ export function viewLineCount(ctx: StageChatViewContext): number {
386
405
  return resolveStageChatViewportRows(reported, VIEW_LINE_COUNT);
387
406
  }
388
407
 
408
+ export { isTerminalOrNonStreamingStageChatStatus } from "./stage-chat-view-status.js";
409
+
389
410
  export function liveHandle(ctx: StageChatViewContext) {
390
411
  return ctx.handle?.isDisposed === true ? undefined : ctx.handle;
391
412
  }
392
413
 
414
+ export function isLiveHandleStreaming(ctx: StageChatViewContext): boolean {
415
+ const handle = liveHandle(ctx);
416
+ if (!handle) return false;
417
+ if (isTerminalOrNonStreamingStageChatStatus(currentRun(ctx)?.status)) return false;
418
+ if (isTerminalOrNonStreamingStageChatStatus(currentStage(ctx)?.status)) return false;
419
+ if (isTerminalOrNonStreamingStageChatStatus(handle.status)) return false;
420
+ return handle.isStreaming === true;
421
+ }
422
+
393
423
  export function isStreaming(ctx: StageChatViewContext): boolean {
394
424
  return ctx.chatHost.isStreaming();
395
425
  }
396
426
 
427
+ export function isAbortableStreamingSession(ctx: StageChatViewContext): boolean {
428
+ return isLiveHandleStreaming(ctx) || liveHandle(ctx)?.agentSession?.isStreaming === true;
429
+ }
430
+
397
431
  export function isBlocked(ctx: StageChatViewContext): boolean {
398
432
  return currentStage(ctx)?.status === "blocked";
399
433
  }
@@ -0,0 +1,36 @@
1
+ const TERMINAL_OR_NON_STREAMING_STAGE_CHAT_STATUSES = new Set<string>([
2
+ "success",
3
+ "complete",
4
+ "completed",
5
+ "failure",
6
+ "failed",
7
+ "error",
8
+ "cancellation",
9
+ "cancelled",
10
+ "canceled",
11
+ "paused",
12
+ "detached",
13
+ "killed",
14
+ "stopped",
15
+ "no-longer-running",
16
+ "skipped",
17
+ "blocked",
18
+ ]);
19
+
20
+ export function isTerminalOrNonStreamingStageChatStatus(
21
+ status: string | undefined,
22
+ ): boolean {
23
+ return status !== undefined && TERMINAL_OR_NON_STREAMING_STAGE_CHAT_STATUSES.has(status);
24
+ }
25
+
26
+ export function isTerminalStageChatTransition(
27
+ previousStatus: string | undefined,
28
+ currentStatus: string | undefined,
29
+ ): boolean {
30
+ return !isTerminalOrNonStreamingStageChatStatus(previousStatus) &&
31
+ isTerminalOrNonStreamingStageChatStatus(currentStatus);
32
+ }
33
+
34
+ export function isTerminalStageChatState(status: string | undefined): boolean {
35
+ return isTerminalOrNonStreamingStageChatStatus(status);
36
+ }
@@ -11,7 +11,7 @@ import type {
11
11
  MountedStageCustomUi,
12
12
  StageUiBroker,
13
13
  } from "../shared/stage-ui-broker.js";
14
- import type { StageNotice, StageStatus } from "../shared/store-types.js";
14
+ import type { RunStatus, StageNotice, StageStatus } from "../shared/store-types.js";
15
15
  import type { GraphTheme } from "./graph-theme.js";
16
16
  import type { PromptCardState } from "./prompt-card.js";
17
17
 
@@ -19,6 +19,7 @@ export const VIEW_LINE_COUNT = 32;
19
19
  export const PROMPT_SCROLL_STEP_ROWS = 4;
20
20
  export const HEADER_ROWS = 1;
21
21
  export const SEP_ROWS = 1;
22
+ export const STAGE_CHAT_MOUSE_SCROLL_TOGGLE_LABEL = "ctrl+t";
22
23
 
23
24
  export function isReadOnlyArchiveStatus(status: StageStatus): boolean {
24
25
  return status === "completed" || status === "failed" || status === "skipped";
@@ -144,6 +145,9 @@ export interface StageChatViewContext {
144
145
  promptScrollOffset: number;
145
146
  promptMaxScroll: number;
146
147
  localPaused: boolean;
148
+ mouseScrollCaptureEnabled: boolean;
149
+ lastObservedStageStatus: StageStatus | undefined;
150
+ lastObservedRunStatus: RunStatus | undefined;
147
151
  seenNoticeIds: Set<string>;
148
152
  _unsubscribeStore: (() => void) | null;
149
153
  _unsubscribeHandle: (() => void) | null;
@@ -95,6 +95,7 @@ export class StageChatView implements Component, Focusable {
95
95
  private promptScrollOffset!: StageChatViewContext["promptScrollOffset"];
96
96
  private promptMaxScroll!: StageChatViewContext["promptMaxScroll"];
97
97
  private localPaused!: StageChatViewContext["localPaused"];
98
+ private mouseScrollCaptureEnabled!: StageChatViewContext["mouseScrollCaptureEnabled"];
98
99
  private seenNoticeIds!: StageChatViewContext["seenNoticeIds"];
99
100
  private _unsubscribeStore!: StageChatViewContext["_unsubscribeStore"];
100
101
  private _unsubscribeHandle!: StageChatViewContext["_unsubscribeHandle"];
@@ -177,7 +178,7 @@ export class StageChatView implements Component, Focusable {
177
178
  }
178
179
 
179
180
  wantsMouseScrollTracking(): boolean {
180
- return true;
181
+ return this.mouseScrollCaptureEnabled;
181
182
  }
182
183
 
183
184
  handleInput(data: string): boolean {
@@ -220,6 +221,7 @@ export class StageChatView implements Component, Focusable {
220
221
  void this.promptEditorSubmitFromEnter;
221
222
  void this.promptScrollOffset;
222
223
  void this.promptMaxScroll;
224
+ void this.mouseScrollCaptureEnabled;
223
225
  void this.seenNoticeIds;
224
226
  void this._unsubscribeStore;
225
227
  void this._unsubscribeHandle;
@@ -56,6 +56,10 @@ export interface RenderStatusListOpts {
56
56
  width?: number;
57
57
  }
58
58
 
59
+ function isQuitRun(run: RunSnapshot): boolean {
60
+ return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
61
+ }
62
+
59
63
  /**
60
64
  * Render a list of run snapshots as the canonical rounded `BACKGROUND`
61
65
  * surface: one panel plus one card per run.
@@ -157,6 +161,7 @@ function renderRunEntry(
157
161
 
158
162
  function runAccent(run: RunSnapshot, theme?: GraphTheme): string {
159
163
  if (!theme) return "#000000";
164
+ if (isQuitRun(run)) return theme.warning;
160
165
  switch (run.status) {
161
166
  case "completed": return theme.success;
162
167
  case "running": return theme.warning;
@@ -172,6 +177,7 @@ function runAccent(run: RunSnapshot, theme?: GraphTheme): string {
172
177
  }
173
178
 
174
179
  function runTrailing(run: RunSnapshot, theme?: GraphTheme): { text: string; fg?: string } | undefined {
180
+ if (isQuitRun(run)) return { text: "○ quit", fg: theme?.warning };
175
181
  switch (run.status) {
176
182
  case "completed": return { text: "✓ completed", fg: theme?.success };
177
183
  case "running": return { text: "● running", fg: theme?.warning };
@@ -205,6 +211,7 @@ function runCardMeta(run: RunSnapshot, now: number): string {
205
211
  ? fmtDuration(elapsedRunMs(run, now))
206
212
  : undefined;
207
213
 
214
+ if (isQuitRun(run)) return "resumable via /workflow resume";
208
215
  if (run.status === "running") {
209
216
  if (isChain) parts.push(`${done}/${total}`);
210
217
  const labels = runningStageLabels(run);
@@ -315,15 +322,17 @@ function effectiveWidth(width?: number): number {
315
322
  interface Counts {
316
323
  active: number;
317
324
  paused: number;
325
+ quit: number;
318
326
  completed: number;
319
327
  failed: number;
320
328
  pending: number;
321
329
  }
322
330
 
323
331
  function countBuckets(runs: readonly RunSnapshot[]): Counts {
324
- const c: Counts = { active: 0, paused: 0, completed: 0, failed: 0, pending: 0 };
332
+ const c: Counts = { active: 0, paused: 0, quit: 0, completed: 0, failed: 0, pending: 0 };
325
333
  for (const r of runs) {
326
- if (r.endedAt === undefined) {
334
+ if (isQuitRun(r)) c.quit++;
335
+ else if (r.endedAt === undefined) {
327
336
  if (r.status === "pending") c.pending++;
328
337
  else if (r.status === "paused") c.paused++;
329
338
  else if (r.status === "running") c.active++;
@@ -343,6 +352,7 @@ function themedBadges(c: Counts, theme: GraphTheme): FlatBandBadge[] {
343
352
  // Keep the word label: the pause glyph is less familiar than the other
344
353
  // status glyphs, so this intentional asymmetry improves scanability.
345
354
  if (c.paused > 0) out.push({ text: `❚❚ ${c.paused} paused`, fg: theme.warning });
355
+ if (c.quit > 0) out.push({ text: `${c.quit} quit`, fg: theme.warning });
346
356
  if (c.pending > 0) out.push({ text: `○ ${c.pending}`, fg: theme.dim });
347
357
  if (c.failed > 0) out.push({ text: `⊘ ${c.failed}`, fg: theme.error });
348
358
  return out;
@@ -355,6 +365,7 @@ function plainBadges(c: Counts): FlatBandBadge[] {
355
365
  // Keep the word label: the pause glyph is less familiar than the other
356
366
  // status glyphs, so this intentional asymmetry improves scanability.
357
367
  if (c.paused > 0) out.push({ text: `❚❚ ${c.paused} paused` });
368
+ if (c.quit > 0) out.push({ text: `${c.quit} quit` });
358
369
  if (c.pending > 0) out.push({ text: `○ ${c.pending}` });
359
370
  if (c.failed > 0) out.push({ text: `⊘ ${c.failed}` });
360
371
  return out;
@@ -381,6 +392,7 @@ function emptyStateLine(theme?: GraphTheme): string {
381
392
  }
382
393
 
383
394
  function statusIconForRun(run: RunSnapshot): string {
395
+ if (isQuitRun(run)) return "○";
384
396
  switch (run.status) {
385
397
  case "completed": return "✓";
386
398
  case "skipped": return "⊘";
@@ -73,9 +73,14 @@ function recentlyEnded(run: RunSnapshot, now: number): boolean {
73
73
  return run.endedAt !== undefined && now - run.endedAt <= RECENT_ENDED_WINDOW_MS;
74
74
  }
75
75
 
76
+ function isQuitRun(run: RunSnapshot): boolean {
77
+ return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
78
+ }
79
+
76
80
  interface RunCounts {
77
81
  active: number;
78
82
  paused: number;
83
+ quit: number;
79
84
  done: number;
80
85
  failed: number;
81
86
  /** Runs with a pending HIL prompt — surfaced as a separate badge so the
@@ -106,9 +111,10 @@ function countRuns(
106
111
  runs: readonly RunSnapshot[],
107
112
  allRuns: readonly RunSnapshot[] = runs,
108
113
  ): RunCounts {
109
- const counts: RunCounts = { active: 0, paused: 0, done: 0, failed: 0, awaiting: 0 };
114
+ const counts: RunCounts = { active: 0, paused: 0, quit: 0, done: 0, failed: 0, awaiting: 0 };
110
115
  for (const r of runs) {
111
- if (r.endedAt === undefined && r.status === "paused") counts.paused++;
116
+ if (isQuitRun(r)) counts.quit++;
117
+ else if (r.endedAt === undefined && r.status === "paused") counts.paused++;
112
118
  else if (r.endedAt === undefined) counts.active++;
113
119
  else if (r.status === "completed" || r.status === "skipped" || r.status === "cancelled" || r.status === "blocked") counts.done++;
114
120
  else if (r.status === "failed" || r.status === "killed") counts.failed++;
@@ -165,6 +171,7 @@ function shortId(run: RunSnapshot): string {
165
171
  }
166
172
 
167
173
  function statusGlyph(run: RunSnapshot): string {
174
+ if (isQuitRun(run)) return "○";
168
175
  switch (run.status) {
169
176
  case "running":
170
177
  return "●";
@@ -188,6 +195,7 @@ function statusGlyph(run: RunSnapshot): string {
188
195
  }
189
196
 
190
197
  function statusFg(run: RunSnapshot, theme: GraphTheme): string {
198
+ if (isQuitRun(run)) return theme.warning;
191
199
  switch (run.status) {
192
200
  case "running":
193
201
  case "paused":
@@ -237,6 +245,7 @@ function metaLine(run: RunSnapshot, now: number): string {
237
245
  if (run.endedAt !== undefined) {
238
246
  return elapsedLabel(run, now);
239
247
  }
248
+ if (isQuitRun(run)) return "quit · resumable via /workflow resume";
240
249
  const parts: string[] = [modeLabel(run)];
241
250
  const prog = progressLabel(run);
242
251
  if (prog) parts.push(prog);
@@ -257,6 +266,9 @@ function countBadges(counts: RunCounts, theme: GraphTheme): FlatBandBadge[] {
257
266
  if (counts.paused > 0) {
258
267
  badges.push({ text: `❚❚ ${counts.paused} paused`, fg: theme.warning });
259
268
  }
269
+ if (counts.quit > 0) {
270
+ badges.push({ text: `${counts.quit} quit`, fg: theme.warning });
271
+ }
260
272
  // Awaiting input is shown in Sky per DESIGN.md status semantics: a live
261
273
  // human-in-the-loop request that requires attention. Mirror the graph node's
262
274
  // question-mark status glyph, then keep ↵ as the attach/respond action hint.
@@ -332,16 +344,18 @@ function themedCollapsed(
332
344
  const dim = hexToAnsi(theme.dim);
333
345
  const muted = hexToAnsi(theme.textMuted);
334
346
  const warning = hexToAnsi(theme.warning);
335
- const total = counts.active + counts.paused + counts.done + counts.failed;
347
+ const total = counts.active + counts.paused + counts.quit + counts.done + counts.failed;
336
348
  const active = counts.active;
337
349
  const paused = counts.paused > 0 ? `${dim} · ${RESET}${warning}${counts.paused} ❚❚${RESET}` : "";
338
- return ` ${mauve}▾${RESET} ${muted}${total} background${RESET}${dim} · ${RESET}${warning}${active} ●${RESET}${paused}`;
350
+ const quit = counts.quit > 0 ? `${dim} · ${RESET}${warning}${counts.quit} quit${RESET}` : "";
351
+ return ` ${mauve}▾${RESET} ${muted}${total} background${RESET}${dim} · ${RESET}${warning}${active} ●${RESET}${paused}${quit}`;
339
352
  }
340
353
 
341
354
  function plainCollapsed(counts: RunCounts): string {
342
- const total = counts.active + counts.paused + counts.done + counts.failed;
355
+ const total = counts.active + counts.paused + counts.quit + counts.done + counts.failed;
343
356
  const paused = counts.paused > 0 ? ` · ${counts.paused} ❚❚` : "";
344
- return ` ▾ ${total} background · ${counts.active} ●${paused}`;
357
+ const quit = counts.quit > 0 ? ` · ${counts.quit} quit` : "";
358
+ return ` ▾ ${total} background · ${counts.active} ●${paused}${quit}`;
345
359
  }
346
360
 
347
361
  // ---------------------------------------------------------------------------
@@ -372,7 +386,8 @@ export function buildThemedWidgetLines(
372
386
  // visually persists for a beat before dropping off.
373
387
  const visibleCounts: RunCounts = {
374
388
  active: display.filter((r) => r.endedAt === undefined && r.status !== "paused").length,
375
- paused: display.filter((r) => r.endedAt === undefined && r.status === "paused").length,
389
+ paused: display.filter((r) => r.endedAt === undefined && r.status === "paused" && !isQuitRun(r)).length,
390
+ quit: display.filter(isQuitRun).length,
376
391
  done: display.filter((r) => r.endedAt !== undefined && (r.status === "completed" || r.status === "skipped" || r.status === "cancelled" || r.status === "blocked")).length,
377
392
  failed: display.filter((r) => r.endedAt !== undefined && (r.status === "failed" || r.status === "killed")).length,
378
393
  awaiting: counts.awaiting,
@@ -386,7 +401,7 @@ export function buildThemedWidgetLines(
386
401
  return [themed ? themedCollapsed(visibleCounts, graphTheme) : plainCollapsed(visibleCounts)];
387
402
  }
388
403
 
389
- const total = counts.active + counts.paused + counts.done + counts.failed;
404
+ const total = counts.active + counts.paused + counts.quit + counts.done + counts.failed;
390
405
  const subtitle = `${total} run${total === 1 ? "" : "s"}`;
391
406
 
392
407
  const badgeList = countBadges(visibleCounts, graphTheme);
@@ -29,8 +29,8 @@ export interface WorkflowAttachPaneOpts {
29
29
  onClose: () => void;
30
30
  /** Called when the user requests the host to hide the popup. */
31
31
  onHide?: () => void;
32
- /** Called when the user kills the active run (q in graph mode). */
33
- onKill?: (runId: string) => void;
32
+ /** Called when the user quits/detaches the active run (q in graph mode). */
33
+ onQuit?: (runId: string) => void;
34
34
  /** Called when the user resolves a HIL prompt via the graph view. */
35
35
  onPromptResolve?: (runId: string, promptId: string, response: unknown) => void;
36
36
  /** Live pi-tui host objects used by attached stage chat to reuse coding-agent editor UI. */
@@ -73,8 +73,9 @@ export interface WorkflowAttachPaneOpts {
73
73
  requestFocus?: () => void;
74
74
  /**
75
75
  * Host hook for terminal mouse reporting. Graph mode uses wheel input
76
- * for canvas scrolling; stage-chat mode uses it for transcript history
77
- * scrolling and drops non-wheel mouse bytes before they reach the editor.
76
+ * for canvas scrolling. Stage-chat mode captures wheel input by default so
77
+ * transcript/prompt scrolling stays inside the active workflow chat; ctrl+t
78
+ * toggles copy mode, which disables capture for terminal text selection.
78
79
  */
79
80
  setMouseScrollTracking?: (enabled: boolean) => void;
80
81
  /** Optional clock injection for deterministic transition-quarantine tests. */
@@ -19,7 +19,6 @@
19
19
  * - src/tui/stage-chat-view.ts (chat mode Component)
20
20
  * - src/runs/foreground/stage-control-registry.ts (live handles)
21
21
  */
22
-
23
22
  import type { Component, EditorComponent, EditorTheme, TUI } from "@earendil-works/pi-tui";
24
23
  import type { ChatMessageRenderOptions, ReadonlyFooterDataProvider } from "@bastani/atomic";
25
24
  import type { Store } from "../shared/store.js";
@@ -39,7 +38,6 @@ import type { StageUiBroker } from "../shared/stage-ui-broker.js";
39
38
  import type { StageSnapshot, StoreSnapshot } from "../shared/store-types.js";
40
39
  import { expandWorkflowGraph } from "../shared/expanded-workflow-graph.js";
41
40
  import { WORKFLOW_STATUS_KEY } from "./workflow-status.js";
42
-
43
41
  /**
44
42
  * Surface used to write Pi's footer/status tag while the attach pane is
45
43
  * mounted. Passing `undefined` clears the slot — required on dispose so
@@ -50,7 +48,6 @@ import { WORKFLOW_STATUS_KEY } from "./workflow-status.js";
50
48
  */
51
49
  import type { AttachUiStatusSurface, WorkflowAttachPaneMode, WorkflowAttachPaneOpts } from "./workflow-attach-pane-types.js";
52
50
  const ENTER_TRANSITION_QUARANTINE_MS = 200;
53
-
54
51
  export class WorkflowAttachPane implements Component {
55
52
  private store: Store;
56
53
  private theme: GraphTheme;
@@ -60,7 +57,7 @@ export class WorkflowAttachPane implements Component {
60
57
  private uiStatus: AttachUiStatusSurface | undefined;
61
58
  private onClose: () => void;
62
59
  private onHide?: () => void;
63
- private onKill?: (runId: string) => void;
60
+ private onQuit?: (runId: string) => void;
64
61
  private onPromptResolve?: (runId: string, promptId: string, response: unknown) => void;
65
62
  private getViewportRows?: () => number | undefined;
66
63
  private hostRequestRender?: () => void;
@@ -73,7 +70,6 @@ export class WorkflowAttachPane implements Component {
73
70
  private getChatRenderSettings?: () => Partial<Omit<ChatMessageRenderOptions, "ui" | "cwd">> | undefined;
74
71
  private footerData?: ReadonlyFooterDataProvider;
75
72
  private now: () => number;
76
-
77
73
  private mode: WorkflowAttachPaneMode = "graph";
78
74
  private visible = true;
79
75
  private graphView: GraphView;
@@ -97,7 +93,7 @@ export class WorkflowAttachPane implements Component {
97
93
  this.uiStatus = opts.uiStatus;
98
94
  this.onClose = opts.onClose;
99
95
  this.onHide = opts.onHide;
100
- this.onKill = opts.onKill;
96
+ this.onQuit = opts.onQuit;
101
97
  this.onPromptResolve = opts.onPromptResolve;
102
98
  this.getViewportRows = opts.getViewportRows;
103
99
  this.hostRequestRender = opts.requestRender;
@@ -130,7 +126,7 @@ export class WorkflowAttachPane implements Component {
130
126
  graphTheme: this.theme,
131
127
  onClose: this.onClose,
132
128
  onHide: this.onHide,
133
- onKill: this.onKill,
129
+ onQuit: this.onQuit,
134
130
  onPromptResolve: this.onPromptResolve,
135
131
  onStageAttach: (runId, stageId) => this._attachToStage(runId, stageId, {
136
132
  suppressInitialPromptSubmit: true,
@@ -366,7 +362,11 @@ export class WorkflowAttachPane implements Component {
366
362
  if (!this.visible) return false;
367
363
  if (this.mode === "stage-chat" && this.chatView) {
368
364
  if (this._shouldQuarantineStagePromptEnter(data)) return true;
369
- return this.chatView.handleInput(data);
365
+ const beforeMouseTracking = this.chatView.wantsMouseScrollTracking();
366
+ const handled = this.chatView.handleInput(data);
367
+ const afterMouseTracking = this.chatView?.wantsMouseScrollTracking();
368
+ if (afterMouseTracking !== undefined && afterMouseTracking !== beforeMouseTracking) this._syncMouseScrollTracking();
369
+ return handled;
370
370
  }
371
371
  if (this._shouldQuarantineGraphEnter(data)) return true;
372
372
  return this.graphView.handleInput(data);