@bastani/atomic 0.9.5-alpha.7 → 0.9.5-alpha.9

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 (317) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/dist/builtin/cursor/package.json +2 -2
  3. package/dist/builtin/intercom/CHANGELOG.md +17 -0
  4. package/dist/builtin/intercom/README.md +27 -21
  5. package/dist/builtin/intercom/broker/broker.ts +3 -6
  6. package/dist/builtin/intercom/broker/paths.ts +42 -5
  7. package/dist/builtin/intercom/broker/spawn.ts +78 -10
  8. package/dist/builtin/intercom/config.ts +6 -3
  9. package/dist/builtin/intercom/contact-supervisor-tool.ts +6 -4
  10. package/dist/builtin/intercom/index-heavy.ts +1 -1
  11. package/dist/builtin/intercom/index.ts +162 -130
  12. package/dist/builtin/intercom/intercom-tool.ts +9 -3
  13. package/dist/builtin/intercom/package.json +10 -1
  14. package/dist/builtin/intercom/result-renderers.ts +1 -1
  15. package/dist/builtin/intercom/ui/compose.ts +2 -2
  16. package/dist/builtin/intercom/ui/inline-message.ts +2 -2
  17. package/dist/builtin/intercom/ui/session-list.ts +2 -2
  18. package/dist/builtin/mcp/CHANGELOG.md +11 -0
  19. package/dist/builtin/mcp/README.md +6 -6
  20. package/dist/builtin/mcp/direct-tools.ts +41 -23
  21. package/dist/builtin/mcp/index.ts +31 -4
  22. package/dist/builtin/mcp/init.ts +4 -43
  23. package/dist/builtin/mcp/metadata-hydration.ts +37 -0
  24. package/dist/builtin/mcp/package.json +1 -1
  25. package/dist/builtin/mcp/proxy-info-modes.ts +67 -14
  26. package/dist/builtin/mcp/startup-warmup.ts +98 -0
  27. package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
  28. package/dist/builtin/subagents/CHANGELOG.md +18 -0
  29. package/dist/builtin/subagents/package.json +1 -1
  30. package/dist/builtin/subagents/src/extension/index.ts +14 -25
  31. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
  32. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +23 -18
  33. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +20 -10
  34. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +13 -3
  35. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +10 -2
  36. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +28 -1
  37. package/dist/builtin/subagents/src/tui/render-event-formatting.ts +15 -48
  38. package/dist/builtin/subagents/src/tui/render-layout.ts +9 -0
  39. package/dist/builtin/subagents/src/tui/render-widget-graph.ts +27 -25
  40. package/dist/builtin/subagents/src/tui/render-widget.ts +72 -66
  41. package/dist/builtin/subagents/src/tui/render.ts +1 -1
  42. package/dist/builtin/web-access/package.json +1 -1
  43. package/dist/builtin/workflows/CHANGELOG.md +29 -0
  44. package/dist/builtin/workflows/README.md +4 -2
  45. package/dist/builtin/workflows/builtin/goal-artifacts.ts +3 -1
  46. package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -2
  47. package/dist/builtin/workflows/builtin/goal-reducer.ts +21 -0
  48. package/dist/builtin/workflows/builtin/goal-review.ts +60 -6
  49. package/dist/builtin/workflows/builtin/goal-runner.ts +71 -22
  50. package/dist/builtin/workflows/builtin/goal-types.ts +7 -1
  51. package/dist/builtin/workflows/builtin/ralph-core.ts +52 -4
  52. package/dist/builtin/workflows/builtin/ralph-review-gate.ts +10 -3
  53. package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +23 -2
  54. package/dist/builtin/workflows/builtin/ralph-runner.ts +38 -16
  55. package/dist/builtin/workflows/builtin/review-convergence.ts +111 -0
  56. package/dist/builtin/workflows/package.json +1 -1
  57. package/dist/builtin/workflows/skills/create-spec/SKILL.md +2 -0
  58. package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
  59. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
  60. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
  61. package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
  62. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
  63. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
  64. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
  65. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
  66. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
  67. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  68. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
  69. package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
  70. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
  71. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
  72. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
  73. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
  74. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
  75. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
  76. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
  77. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
  78. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
  79. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
  80. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
  81. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
  82. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  83. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
  84. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
  85. package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
  86. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
  87. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
  88. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
  89. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
  90. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
  91. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
  92. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
  93. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
  94. package/dist/builtin/workflows/src/durable/backend.ts +12 -0
  95. package/dist/builtin/workflows/src/durable/child-primitive.ts +12 -8
  96. package/dist/builtin/workflows/src/durable/dbos-backend.ts +63 -2
  97. package/dist/builtin/workflows/src/durable/dbos-envelope.ts +28 -0
  98. package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
  99. package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
  100. package/dist/builtin/workflows/src/durable/stage-primitive.ts +165 -27
  101. package/dist/builtin/workflows/src/durable/types.ts +30 -1
  102. package/dist/builtin/workflows/src/engine/primitives/task.ts +1 -0
  103. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
  104. package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
  105. package/dist/builtin/workflows/src/engine/run.ts +32 -32
  106. package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
  107. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  108. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
  109. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
  110. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
  111. package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
  112. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
  113. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
  114. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
  115. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +2 -0
  116. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
  117. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
  118. package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
  119. package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
  120. package/dist/builtin/workflows/src/runs/foreground/executor-continuation.ts +13 -3
  121. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
  122. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +2 -1
  123. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +4 -3
  124. package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +18 -19
  125. package/dist/builtin/workflows/src/runs/foreground/stage-runner-unresolved-overflow.ts +38 -0
  126. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
  127. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
  128. package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
  129. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +18 -1
  130. package/dist/builtin/workflows/src/shared/persistence-restore.ts +23 -5
  131. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
  132. package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
  133. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
  134. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
  135. package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
  136. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
  137. package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
  138. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
  139. package/dist/bun/internal-intercom-broker.d.ts +6 -0
  140. package/dist/bun/internal-intercom-broker.d.ts.map +1 -0
  141. package/dist/bun/internal-intercom-broker.js +39 -0
  142. package/dist/bun/internal-intercom-broker.js.map +1 -0
  143. package/dist/bun/split-loader.d.ts.map +1 -1
  144. package/dist/bun/split-loader.js +21 -8
  145. package/dist/bun/split-loader.js.map +1 -1
  146. package/dist/core/agent-session-auto-compaction.d.ts +21 -2
  147. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  148. package/dist/core/agent-session-auto-compaction.js +163 -11
  149. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  150. package/dist/core/agent-session-events.d.ts.map +1 -1
  151. package/dist/core/agent-session-events.js +10 -1
  152. package/dist/core/agent-session-events.js.map +1 -1
  153. package/dist/core/agent-session-methods.d.ts +12 -3
  154. package/dist/core/agent-session-methods.d.ts.map +1 -1
  155. package/dist/core/agent-session-methods.js.map +1 -1
  156. package/dist/core/agent-session-models.d.ts +2 -2
  157. package/dist/core/agent-session-models.d.ts.map +1 -1
  158. package/dist/core/agent-session-models.js.map +1 -1
  159. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  160. package/dist/core/agent-session-prompt.js +1 -0
  161. package/dist/core/agent-session-prompt.js.map +1 -1
  162. package/dist/core/agent-session-retry.d.ts +2 -0
  163. package/dist/core/agent-session-retry.d.ts.map +1 -1
  164. package/dist/core/agent-session-retry.js +152 -4
  165. package/dist/core/agent-session-retry.js.map +1 -1
  166. package/dist/core/agent-session-services.d.ts +1 -0
  167. package/dist/core/agent-session-services.d.ts.map +1 -1
  168. package/dist/core/agent-session-services.js +1 -0
  169. package/dist/core/agent-session-services.js.map +1 -1
  170. package/dist/core/agent-session-types.d.ts +15 -1
  171. package/dist/core/agent-session-types.d.ts.map +1 -1
  172. package/dist/core/agent-session-types.js.map +1 -1
  173. package/dist/core/agent-session.d.ts +6 -0
  174. package/dist/core/agent-session.d.ts.map +1 -1
  175. package/dist/core/agent-session.js +6 -0
  176. package/dist/core/agent-session.js.map +1 -1
  177. package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
  178. package/dist/core/compaction/context-compaction-runner.js +36 -20
  179. package/dist/core/compaction/context-compaction-runner.js.map +1 -1
  180. package/dist/core/copilot-anthropic-sse-repair.d.ts +23 -0
  181. package/dist/core/copilot-anthropic-sse-repair.d.ts.map +1 -0
  182. package/dist/core/copilot-anthropic-sse-repair.js +340 -0
  183. package/dist/core/copilot-anthropic-sse-repair.js.map +1 -0
  184. package/dist/core/copilot-gemini-reasoning.d.ts +16 -8
  185. package/dist/core/copilot-gemini-reasoning.d.ts.map +1 -1
  186. package/dist/core/copilot-gemini-reasoning.js +27 -22
  187. package/dist/core/copilot-gemini-reasoning.js.map +1 -1
  188. package/dist/core/copilot-hosts.d.ts +12 -0
  189. package/dist/core/copilot-hosts.d.ts.map +1 -0
  190. package/dist/core/copilot-hosts.js +33 -0
  191. package/dist/core/copilot-hosts.js.map +1 -0
  192. package/dist/core/extensions/agent-events.d.ts +1 -1
  193. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  194. package/dist/core/extensions/agent-events.js.map +1 -1
  195. package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
  196. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  197. package/dist/core/extensions/loader-virtual-modules.js +2 -1
  198. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  199. package/dist/core/footer-data-provider.d.ts +6 -0
  200. package/dist/core/footer-data-provider.d.ts.map +1 -1
  201. package/dist/core/footer-data-provider.js +72 -29
  202. package/dist/core/footer-data-provider.js.map +1 -1
  203. package/dist/core/http-dispatcher.d.ts.map +1 -1
  204. package/dist/core/http-dispatcher.js +5 -5
  205. package/dist/core/http-dispatcher.js.map +1 -1
  206. package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
  207. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  208. package/dist/core/openai-responses-payload-sanitizer.js +24 -9
  209. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  210. package/dist/core/sdk-types.d.ts +2 -0
  211. package/dist/core/sdk-types.d.ts.map +1 -1
  212. package/dist/core/sdk-types.js.map +1 -1
  213. package/dist/core/sdk.d.ts.map +1 -1
  214. package/dist/core/sdk.js +1 -0
  215. package/dist/core/sdk.js.map +1 -1
  216. package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
  217. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  218. package/dist/core/settings-manager-basic-accessors.js +6 -0
  219. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  220. package/dist/core/settings-types.d.ts +1 -0
  221. package/dist/core/settings-types.d.ts.map +1 -1
  222. package/dist/core/settings-types.js.map +1 -1
  223. package/dist/core/slash-commands.d.ts +2 -0
  224. package/dist/core/slash-commands.d.ts.map +1 -1
  225. package/dist/core/slash-commands.js +141 -0
  226. package/dist/core/slash-commands.js.map +1 -1
  227. package/dist/index-extensions.d.ts +1 -1
  228. package/dist/index-extensions.d.ts.map +1 -1
  229. package/dist/index-extensions.js.map +1 -1
  230. package/dist/index.d.ts +1 -0
  231. package/dist/index.d.ts.map +1 -1
  232. package/dist/index.js +1 -0
  233. package/dist/index.js.map +1 -1
  234. package/dist/main-deferred-startup.d.ts +12 -0
  235. package/dist/main-deferred-startup.d.ts.map +1 -1
  236. package/dist/main-deferred-startup.js +23 -2
  237. package/dist/main-deferred-startup.js.map +1 -1
  238. package/dist/main-early-input.d.ts +41 -0
  239. package/dist/main-early-input.d.ts.map +1 -0
  240. package/dist/main-early-input.js +154 -0
  241. package/dist/main-early-input.js.map +1 -0
  242. package/dist/main.d.ts +0 -6
  243. package/dist/main.d.ts.map +1 -1
  244. package/dist/main.js +20 -14
  245. package/dist/main.js.map +1 -1
  246. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  247. package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
  248. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  249. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  250. package/dist/modes/interactive/components/chat-session-host-events.js +15 -0
  251. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  252. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  253. package/dist/modes/interactive/interactive-agent-events.js +25 -0
  254. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  255. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  256. package/dist/modes/interactive/interactive-autocomplete.js +21 -9
  257. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  258. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  259. package/dist/modes/interactive/interactive-deferred-startup.js +41 -28
  260. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  261. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  262. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
  263. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  264. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  265. package/dist/modes/interactive/interactive-input-handling.js +318 -185
  266. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  267. package/dist/modes/interactive/interactive-mode-base.d.ts +12 -0
  268. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  269. package/dist/modes/interactive/interactive-mode-base.js +39 -0
  270. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  271. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  272. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  273. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  274. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  275. package/dist/modes/interactive/interactive-mode-surface.d.ts +6 -2
  276. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  277. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  278. package/dist/modes/interactive/interactive-mode-types.d.ts +3 -0
  279. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  280. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  281. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  282. package/dist/modes/interactive/interactive-model-routing.js +3 -1
  283. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  284. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  285. package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
  286. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  287. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  288. package/dist/modes/interactive/interactive-render-chat.js +36 -10
  289. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  290. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  291. package/dist/modes/interactive/interactive-session-routing.js +5 -1
  292. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  293. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  294. package/dist/modes/interactive/interactive-startup.js +26 -22
  295. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  296. package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
  297. package/dist/modes/interactive/theme/global-theme.js +26 -2
  298. package/dist/modes/interactive/theme/global-theme.js.map +1 -1
  299. package/dist/utils/fs-watch.d.ts +24 -1
  300. package/dist/utils/fs-watch.d.ts.map +1 -1
  301. package/dist/utils/fs-watch.js +60 -5
  302. package/dist/utils/fs-watch.js.map +1 -1
  303. package/docs/compaction.md +8 -0
  304. package/docs/development.md +4 -0
  305. package/docs/extensions.md +5 -0
  306. package/docs/json.md +3 -1
  307. package/docs/providers.md +1 -0
  308. package/docs/quickstart.md +1 -1
  309. package/docs/rpc.md +3 -1
  310. package/docs/settings.md +27 -1
  311. package/docs/subagents.md +4 -0
  312. package/docs/terminal-setup.md +4 -0
  313. package/docs/usage.md +2 -2
  314. package/docs/windows.md +4 -0
  315. package/docs/workflows.md +21 -9
  316. package/npm-shrinkwrap.json +513 -23
  317. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-process-lifecycle.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-process-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEzF,MAAM,2BAA2B,GAAG,GAAG,CAAC;AACxC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC,mBAAmB,CAAC,SAAS,CAAC,WAAW,GAAG;IACxC,0EAA0E;IAC1E,yEAAyE;IACzE,iEAAiE;IACjE,IAAI,IAAI,CAAC,wBAAwB,EAAE,EAAE,CAAC;QACpC,sEAAsE;QACtE,6BAA6B;QAC7B,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,GAAG,GAAG,IAAI,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;IAC5B,CAAC;AACH,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,wBAAwB,GAAG;IACrD,4EAA4E;IAC5E,8DAA8D;IAC9D,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,6BAA6B,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,WAAW,GAAG;IACxC,8DAA8D;IAC9D,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;AACvB,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,QAAQ,GAAG,KAAK,WAAqC,OAAkC;IACjH,IAAI,IAAI,CAAC,cAAc;QAAE,OAAO;IAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,wEAAwE;IACxE,qEAAqE;IAErE,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,CAAC;QACvC,wEAAwE;QACxE,oEAAoE;QACpE,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;QAC7F,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wEAAwE;IACxE,oEAAoE;IACpE,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,CAAC;IACvC,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;IAE7F,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,aAAa,IAAI,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,qBAAqB,GAAG;IAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAChC,2BAA2B,EAAE,CAAC;IAC9B,mEAAmE;IACnE,oEAAoE;IACpE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,aAAa,GAAG,UAAoC,KAAY;IAC1F,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,IAAI,CAAC;QACH,2BAA2B,EAAE,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,sBAAsB,GAAG,KAAK;IACxD,IAAI,CAAC,IAAI,CAAC,iBAAiB;QAAE,OAAO;IACpC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,sBAAsB,GAAG;IACnD,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAEhC,MAAM,OAAO,GAAqB,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,2BAA2B,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC;QACF,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC,CAAC;IACF,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAE5E,MAAM,oBAAoB,GAAG,CAAC,KAAY,EAAE,EAAE;QAC5C,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACjD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CACnC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAClD,CAAC;IACF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CACnC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAClD,CAAC;IAEF,sEAAsE;IACtE,wEAAwE;IACxE,yDAAyD;IACzD,MAAM,wBAAwB,GAAG,CAAC,KAAY,EAAE,EAAE,CAChD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,CAAC,eAAe,CAAC,mBAAmB,EAAE,wBAAwB,CAAC,CAAC;IACvE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE,CACnC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,wBAAwB,CAAC,CAC3D,CAAC;AACJ,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,wBAAwB,GAAG;IACrD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACjD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC;AAClC,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,WAAW,GAAG;IACxC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,mDAAmD,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IAExD,mEAAmE;IACnE,mEAAmE;IACnE,MAAM,YAAY,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAEnC,6CAA6C;IAC7C,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;QAC3B,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAChC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,iDAAiD;QACjD,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAEf,qEAAqE;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAChC,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,cAAc,GAAG,KAAK;IAChD,MAAM,IAAI,GAAG,CACX,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CACzD,CAAC,IAAI,EAAE,CAAC;IACT,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,yEAAyE;IACzE,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAChD,CAAC;QACD,OAAO;IACT,CAAC;IAED,oEAAoE;IACpE,iGAAiG;IACjG,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACpC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAC1B,CAAC;IACD,yEAAyE;SACpE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,aAAa,GAAG;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACtD,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,UAAU,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,UAAU,CACb,YAAY,QAAQ,kBAAkB,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,CAC1E,CAAC;IACJ,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { chalk, killTrackedDetachedChildren } from \"./interactive-mode-deps.ts\";\nimport { formatResumeCommand, isDeadTerminalError } from \"./interactive-mode-helpers.ts\";\n\nconst SHUTDOWN_INPUT_DRAIN_MAX_MS = 250;\nconst SHUTDOWN_INPUT_DRAIN_IDLE_MS = 50;\n\nInteractiveModeBase.prototype.handleCtrlC = function(this: InteractiveModeBase): void {\n // When the agent is doing work, Ctrl+C interrupts it (matching Escape and\n // common CLI muscle memory) instead of clearing/exiting the editor. Only\n // fall back to the clear / double-press-exit behavior when idle.\n if (this.interruptActiveOperation()) {\n // Reset the double-press window so a follow-up Ctrl+C after the abort\n // does not immediately exit.\n this.lastSigintTime = 0;\n return;\n }\n const now = Date.now();\n if (now - this.lastSigintTime < 500) {\n void this.shutdown();\n } else {\n this.clearEditor();\n this.lastSigintTime = now;\n }\n };\n\nInteractiveModeBase.prototype.interruptActiveOperation = function(this: InteractiveModeBase): boolean {\n // Mirror the Escape interrupt paths so Ctrl+C aborts whichever operation is\n // currently running. Returns true when something was aborted.\n if (this.session.isStreaming) {\n this.restoreQueuedMessagesToEditor({ abort: true });\n return true;\n }\n if (this.session.isBashRunning) {\n this.session.abortBash();\n return true;\n }\n if (this.session.isCompacting) {\n this.session.abortCompaction();\n return true;\n }\n if (this.session.isRetrying) {\n this.session.abortRetry();\n return true;\n }\n return false;\n };\n\nInteractiveModeBase.prototype.handleCtrlD = function(this: InteractiveModeBase): void {\n // Only called when editor is empty (enforced by CustomEditor)\n void this.shutdown();\n };\n\nInteractiveModeBase.prototype.shutdown = async function(this: InteractiveModeBase, options?: { fromSignal?: boolean }): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n // Keep signal handlers registered until terminal cleanup has completed.\n // `signal-exit` checks the listener list during the same SIGTERM/SIGHUP\n // dispatch and re-sends the signal if only its own listeners remain.\n\n if (options?.fromSignal) {\n await this.runtimeHost.dispose();\n this.themeController.disableAutoSync();\n // Drain any in-flight Kitty key release events briefly before stopping.\n // Keep this bounded so Ctrl+C exits do not feel stalled on Windows.\n await this.ui.terminal.drainInput(SHUTDOWN_INPUT_DRAIN_MAX_MS, SHUTDOWN_INPUT_DRAIN_IDLE_MS);\n this.stop();\n process.exit(0);\n }\n\n // Drain any in-flight Kitty key release events briefly before stopping.\n // Keep this bounded so Ctrl+C exits do not feel stalled on Windows.\n this.themeController.disableAutoSync();\n await this.ui.terminal.drainInput(SHUTDOWN_INPUT_DRAIN_MAX_MS, SHUTDOWN_INPUT_DRAIN_IDLE_MS);\n\n this.stop();\n await this.runtimeHost.dispose();\n const resumeCommand = formatResumeCommand(this.sessionManager);\n if (resumeCommand) {\n process.stdout.write(`${chalk.dim(\"To resume this session:\")} ${resumeCommand}\\n`);\n }\n process.exit(0);\n };\n\nInteractiveModeBase.prototype.emergencyTerminalExit = function(this: InteractiveModeBase): never {\n this.isShuttingDown = true;\n this.unregisterSignalHandlers();\n killTrackedDetachedChildren();\n // The terminal is gone. Do not run normal shutdown because TUI and\n // extension cleanup can write restore sequences and re-trigger EIO.\n process.exit(129);\n };\n\nInteractiveModeBase.prototype.uncaughtCrash = function(this: InteractiveModeBase, error: Error): never {\n if (this.isShuttingDown) {\n process.exit(1);\n }\n this.isShuttingDown = true;\n try {\n this.unregisterSignalHandlers();\n } catch {}\n try {\n killTrackedDetachedChildren();\n } catch {}\n try {\n this.ui.stop();\n } catch {}\n console.error(\"pi exiting due to uncaughtException:\");\n console.error(error);\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.checkShutdownRequested = async function(this: InteractiveModeBase): Promise<void> {\n if (!this.shutdownRequested) return;\n await this.shutdown();\n };\n\nInteractiveModeBase.prototype.registerSignalHandlers = function(this: InteractiveModeBase): void {\n this.unregisterSignalHandlers();\n\n const signals: NodeJS.Signals[] = [\"SIGTERM\"];\n if (process.platform !== \"win32\") {\n signals.push(\"SIGHUP\");\n }\n\n for (const signal of signals) {\n const handler = () => {\n killTrackedDetachedChildren();\n void this.shutdown({ fromSignal: true });\n };\n process.prependListener(signal, handler);\n this.signalCleanupHandlers.push(() => process.off(signal, handler));\n }\n\n const sigintHandler = () => {\n this.handleCtrlC();\n };\n process.prependListener(\"SIGINT\", sigintHandler);\n this.signalCleanupHandlers.push(() => process.off(\"SIGINT\", sigintHandler));\n\n const terminalErrorHandler = (error: Error) => {\n if (isDeadTerminalError(error)) {\n this.emergencyTerminalExit();\n }\n throw error;\n };\n process.stdout.on(\"error\", terminalErrorHandler);\n process.stderr.on(\"error\", terminalErrorHandler);\n this.signalCleanupHandlers.push(() =>\n process.stdout.off(\"error\", terminalErrorHandler),\n );\n this.signalCleanupHandlers.push(() =>\n process.stderr.off(\"error\", terminalErrorHandler),\n );\n\n // Restore the terminal before the process dies on any uncaught throw.\n // Without this, an unhandled exception from extension code (or anywhere\n // in pi) leaves the terminal in raw mode with no cursor.\n const uncaughtExceptionHandler = (error: Error) =>\n this.uncaughtCrash(error);\n process.prependListener(\"uncaughtException\", uncaughtExceptionHandler);\n this.signalCleanupHandlers.push(() =>\n process.off(\"uncaughtException\", uncaughtExceptionHandler),\n );\n };\n\nInteractiveModeBase.prototype.unregisterSignalHandlers = function(this: InteractiveModeBase): void {\n for (const cleanup of this.signalCleanupHandlers) {\n cleanup();\n }\n this.signalCleanupHandlers = [];\n };\n\nInteractiveModeBase.prototype.handleCtrlZ = function(this: InteractiveModeBase): void {\n if (process.platform === \"win32\") {\n this.showStatus(\"Suspend to background is not supported on Windows\");\n return;\n }\n\n // Keep the event loop alive while suspended. Without this, stopping the TUI\n // can leave Node with no ref'ed handles, causing the process to exit on fg\n // before the SIGCONT handler gets a chance to restore the terminal.\n const suspendKeepAlive = setInterval(() => {}, 2 ** 30);\n\n // Ignore SIGINT while suspended so Ctrl+C in the terminal does not\n // kill the backgrounded process. The handler is removed on resume.\n const ignoreSigint = () => {};\n process.on(\"SIGINT\", ignoreSigint);\n\n // Set up handler to restore TUI when resumed\n process.once(\"SIGCONT\", () => {\n clearInterval(suspendKeepAlive);\n process.removeListener(\"SIGINT\", ignoreSigint);\n this.ui.start();\n this.ui.requestRender(true);\n });\n\n try {\n // Stop the TUI (restore terminal to normal mode)\n this.ui.stop();\n\n // Send SIGTSTP to process group (pid=0 means all processes in group)\n process.kill(0, \"SIGTSTP\");\n } catch (error) {\n clearInterval(suspendKeepAlive);\n process.removeListener(\"SIGINT\", ignoreSigint);\n throw error;\n }\n };\n\nInteractiveModeBase.prototype.handleFollowUp = async function(this: InteractiveModeBase): Promise<void> {\n const text = (\n this.editor.getExpandedText?.() ?? this.editor.getText()\n ).trim();\n if (!text) return;\n\n // Queue input during compaction (extension commands execute immediately)\n if (this.session.isCompacting) {\n if (this.isExtensionCommand(text)) {\n this.editor.addToHistory?.(text);\n this.editor.setText(\"\");\n await this.session.prompt(text);\n } else {\n this.queueCompactionMessage(text, \"followUp\");\n }\n return;\n }\n\n // Alt+Enter queues a follow-up message (waits until agent finishes)\n // This handles extension commands (execute immediately), prompt template expansion, and queueing\n if (this.session.isStreaming) {\n this.editor.addToHistory?.(text);\n this.editor.setText(\"\");\n await this.session.prompt(text, { streamingBehavior: \"followUp\" });\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n }\n // If not streaming, Alt+Enter acts like regular Enter (trigger onSubmit)\n else if (this.editor.onSubmit) {\n this.editor.setText(\"\");\n this.editor.onSubmit(text);\n }\n };\n\nInteractiveModeBase.prototype.handleDequeue = function(this: InteractiveModeBase): void {\n const restored = this.restoreQueuedMessagesToEditor();\n if (restored === 0) {\n this.showStatus(\"No queued messages to restore\");\n } else {\n this.showStatus(\n `Restored ${restored} queued message${restored > 1 ? \"s\" : \"\"} to editor`,\n );\n }\n };\n"]}
1
+ {"version":3,"file":"interactive-process-lifecycle.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-process-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { chalk, killTrackedDetachedChildren } from \"./interactive-mode-deps.ts\";\nimport { formatResumeCommand, isDeadTerminalError } from \"./interactive-mode-helpers.ts\";\n\nconst SHUTDOWN_INPUT_DRAIN_MAX_MS = 250;\nconst SHUTDOWN_INPUT_DRAIN_IDLE_MS = 50;\n\nInteractiveModeBase.prototype.handleCtrlC = function(this: InteractiveModeBase): void {\n // When the agent is doing work, Ctrl+C interrupts it (matching Escape and\n // common CLI muscle memory) instead of clearing/exiting the editor. Only\n // fall back to the clear / double-press-exit behavior when idle.\n if (this.interruptActiveOperation()) {\n // Reset the double-press window so a follow-up Ctrl+C after the abort\n // does not immediately exit.\n this.lastSigintTime = 0;\n return;\n }\n const now = Date.now();\n if (now - this.lastSigintTime < 500) {\n void this.shutdown();\n } else {\n this.clearEditor();\n this.lastSigintTime = now;\n }\n };\n\nInteractiveModeBase.prototype.interruptActiveOperation = function(this: InteractiveModeBase): boolean {\n // Mirror the Escape interrupt paths so Ctrl+C aborts whichever operation is\n // currently running. Returns true when something was aborted.\n if (this.session.isStreaming) {\n this.restoreQueuedMessagesToEditor({ abort: true });\n return true;\n }\n if (this.session.isBashRunning) {\n this.session.abortBash();\n return true;\n }\n if (this.session.isCompacting) {\n this.session.abortCompaction();\n return true;\n }\n if (this.session.isRetrying) {\n this.session.abortRetry();\n return true;\n }\n return false;\n };\n\nInteractiveModeBase.prototype.handleCtrlD = function(this: InteractiveModeBase): void {\n // Only called when editor is empty (enforced by CustomEditor)\n void this.shutdown();\n };\n\nInteractiveModeBase.prototype.shutdown = async function(this: InteractiveModeBase, options?: { fromSignal?: boolean }): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n // Keep signal handlers registered until terminal cleanup has completed.\n // `signal-exit` checks the listener list during the same SIGTERM/SIGHUP\n // dispatch and re-sends the signal if only its own listeners remain.\n\n if (options?.fromSignal) {\n await this.runtimeHost.dispose();\n this.themeController.disableAutoSync();\n // Drain any in-flight Kitty key release events briefly before stopping.\n // Keep this bounded so Ctrl+C exits do not feel stalled on Windows.\n await this.ui.terminal.drainInput(SHUTDOWN_INPUT_DRAIN_MAX_MS, SHUTDOWN_INPUT_DRAIN_IDLE_MS);\n this.stop();\n process.exit(0);\n }\n\n // Drain any in-flight Kitty key release events briefly before stopping.\n // Keep this bounded so Ctrl+C exits do not feel stalled on Windows.\n this.themeController.disableAutoSync();\n await this.ui.terminal.drainInput(SHUTDOWN_INPUT_DRAIN_MAX_MS, SHUTDOWN_INPUT_DRAIN_IDLE_MS);\n\n this.stop();\n await this.runtimeHost.dispose();\n const resumeCommand = formatResumeCommand(this.sessionManager);\n if (resumeCommand) {\n process.stdout.write(`${chalk.dim(\"To resume this session:\")} ${resumeCommand}\\n`);\n }\n process.exit(0);\n };\n\nInteractiveModeBase.prototype.emergencyTerminalExit = function(this: InteractiveModeBase): never {\n this.isShuttingDown = true;\n this.unregisterSignalHandlers();\n killTrackedDetachedChildren();\n // The terminal is gone. Do not run normal shutdown because TUI and\n // extension cleanup can write restore sequences and re-trigger EIO.\n process.exit(129);\n };\n\nInteractiveModeBase.prototype.uncaughtCrash = function(this: InteractiveModeBase, error: Error): never {\n if (this.isShuttingDown) {\n process.exit(1);\n }\n this.isShuttingDown = true;\n try {\n this.unregisterSignalHandlers();\n } catch {}\n try {\n killTrackedDetachedChildren();\n } catch {}\n try {\n this.ui.stop();\n } catch {}\n console.error(\"pi exiting due to uncaughtException:\");\n console.error(error);\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.checkShutdownRequested = async function(this: InteractiveModeBase): Promise<void> {\n if (!this.shutdownRequested) return;\n await this.shutdown();\n };\n\nInteractiveModeBase.prototype.registerSignalHandlers = function(this: InteractiveModeBase): void {\n this.unregisterSignalHandlers();\n\n const signals: NodeJS.Signals[] = [\"SIGTERM\"];\n if (process.platform !== \"win32\") {\n signals.push(\"SIGHUP\");\n }\n\n for (const signal of signals) {\n const handler = () => {\n killTrackedDetachedChildren();\n void this.shutdown({ fromSignal: true });\n };\n process.prependListener(signal, handler);\n this.signalCleanupHandlers.push(() => process.off(signal, handler));\n }\n\n const sigintHandler = () => {\n this.handleCtrlC();\n };\n process.prependListener(\"SIGINT\", sigintHandler);\n this.signalCleanupHandlers.push(() => process.off(\"SIGINT\", sigintHandler));\n\n const terminalErrorHandler = (error: Error) => {\n if (isDeadTerminalError(error)) {\n this.emergencyTerminalExit();\n }\n throw error;\n };\n process.stdout.on(\"error\", terminalErrorHandler);\n process.stderr.on(\"error\", terminalErrorHandler);\n this.signalCleanupHandlers.push(() =>\n process.stdout.off(\"error\", terminalErrorHandler),\n );\n this.signalCleanupHandlers.push(() =>\n process.stderr.off(\"error\", terminalErrorHandler),\n );\n\n // Restore the terminal before the process dies on any uncaught throw.\n // Without this, an unhandled exception from extension code (or anywhere\n // in pi) leaves the terminal in raw mode with no cursor.\n const uncaughtExceptionHandler = (error: Error) =>\n this.uncaughtCrash(error);\n process.prependListener(\"uncaughtException\", uncaughtExceptionHandler);\n this.signalCleanupHandlers.push(() =>\n process.off(\"uncaughtException\", uncaughtExceptionHandler),\n );\n };\n\nInteractiveModeBase.prototype.unregisterSignalHandlers = function(this: InteractiveModeBase): void {\n for (const cleanup of this.signalCleanupHandlers) {\n cleanup();\n }\n this.signalCleanupHandlers = [];\n };\n\nInteractiveModeBase.prototype.handleCtrlZ = function(this: InteractiveModeBase): void {\n if (process.platform === \"win32\") {\n this.showStatus(\"Suspend to background is not supported on Windows\");\n return;\n }\n\n // Keep the event loop alive while suspended. Without this, stopping the TUI\n // can leave Node with no ref'ed handles, causing the process to exit on fg\n // before the SIGCONT handler gets a chance to restore the terminal.\n const suspendKeepAlive = setInterval(() => {}, 2 ** 30);\n\n // Ignore SIGINT while suspended so Ctrl+C in the terminal does not\n // kill the backgrounded process. The handler is removed on resume.\n const ignoreSigint = () => {};\n process.on(\"SIGINT\", ignoreSigint);\n\n // Set up handler to restore TUI when resumed\n process.once(\"SIGCONT\", () => {\n clearInterval(suspendKeepAlive);\n process.removeListener(\"SIGINT\", ignoreSigint);\n this.ui.start();\n this.ui.requestRender(true);\n });\n\n try {\n // Stop the TUI (restore terminal to normal mode)\n this.ui.stop();\n\n // Send SIGTSTP to process group (pid=0 means all processes in group)\n process.kill(0, \"SIGTSTP\");\n } catch (error) {\n clearInterval(suspendKeepAlive);\n process.removeListener(\"SIGINT\", ignoreSigint);\n throw error;\n }\n };\n\nInteractiveModeBase.prototype.handleFollowUp = async function(this: InteractiveModeBase): Promise<void> {\n const text = (\n this.editor.getExpandedText?.() ?? this.editor.getText()\n ).trim();\n if (!text) return;\n\n // Queue input during compaction (extension commands execute immediately)\n if (this.session.isCompacting) {\n if (this.isExtensionCommand(text)) {\n this.editor.addToHistory?.(text);\n this.editor.setText(\"\");\n await this.session.prompt(text);\n } else {\n this.queueCompactionMessage(text, \"followUp\");\n }\n return;\n }\n\n // Alt+Enter queues a follow-up message (waits until agent finishes)\n // This handles extension commands (execute immediately), prompt template expansion, and queueing\n if (this.session.isStreaming) {\n this.editor.addToHistory?.(text);\n this.editor.setText(\"\");\n await this.session.prompt(text, { streamingBehavior: \"followUp\" });\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n }\n // If not streaming, Alt+Enter acts like regular Enter (trigger onSubmit)\n else if (this.editor.onSubmit) {\n this.editor.setText(\"\");\n this.editor.onSubmit(text);\n }\n };\n\nInteractiveModeBase.prototype.handleDequeue = function(this: InteractiveModeBase): void {\n const restored = this.restoreQueuedMessagesToEditor();\n if (restored === 0) {\n this.showStatus(\"No queued messages to restore\");\n }\n };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-render-chat.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-render-chat.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentMessage, type Component, type ContextCompactionResult, type SessionContext, type TruncationResult, type ChatMessageEntry, type ChatMessageRenderOptions, Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.showStatus = function(this: InteractiveModeBase, message: string): void {\n const children = this.chatContainer.children;\n const last =\n children.length > 0 ? children[children.length - 1] : undefined;\n const secondLast =\n children.length > 1 ? children[children.length - 2] : undefined;\n\n if (\n last &&\n secondLast &&\n last === this.lastStatusText &&\n secondLast === this.lastStatusSpacer\n ) {\n this.lastStatusText.setText(theme.fg(\"dim\", message));\n this.ui.requestRender();\n return;\n }\n\n const spacer = new Spacer(1);\n const text = new Text(theme.fg(\"dim\", message), 1, 0);\n this.chatContainer.addChild(spacer);\n this.chatContainer.addChild(text);\n this.lastStatusSpacer = spacer;\n this.lastStatusText = text;\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.renderDeferredUserInput = function(this: InteractiveModeBase, text: string): void {\n this.deferredRenderedUserInputs.push(text);\n const startIndex = this.chatContainer.children.length;\n this.addMessageToChat({ role: \"user\", content: text } as AgentMessage);\n const renderedComponents = this.chatContainer.children.slice(startIndex);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text) ?? [];\n trackedComponents.push(renderedComponents);\n this.deferredRenderedUserInputComponents.set(text, trackedComponents);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.consumeDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): boolean {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index === -1) return false;\n this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n return true;\n };\n\nInteractiveModeBase.prototype.discardDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): void {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index !== -1) this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n const componentsToRemove = trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n if (!componentsToRemove) return;\n for (const component of componentsToRemove) {\n this.chatContainer.removeChild(component);\n }\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.chatMessageRenderOptions = function(this: InteractiveModeBase): ChatMessageRenderOptions {\n return {\n ui: this.ui,\n cwd: this.sessionManager.getCwd(),\n markdownTheme: this.getMarkdownThemeWithSettings(),\n hideThinkingBlock: this.hideThinkingBlock,\n hiddenThinkingLabel: this.hiddenThinkingLabel,\n toolOutputExpanded: this.toolOutputExpanded,\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n outputPad: this.outputPad,\n getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),\n getCustomMessageRenderer: (customType) =>\n this.session.extensionRunner.getMessageRenderer(customType),\n };\n };\n\nInteractiveModeBase.prototype.addRenderedChatEntry = function(this: InteractiveModeBase, entry: ChatMessageEntry): Component {\n const component = renderChatMessageEntry(entry, this.chatMessageRenderOptions());\n addChatTranscriptEntry(this.chatContainer, component, entry.role);\n return component;\n };\n\nInteractiveModeBase.prototype.addContextCompactionSummaryToChat = function(this: InteractiveModeBase, result: ContextCompactionResult): void {\n this.chatContainer.addChild(new Spacer(1));\n const component = new ContextCompactionSummaryMessageComponent(\n result,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n };\n\nInteractiveModeBase.prototype.addMessageToChat = function(this: InteractiveModeBase, message: AgentMessage, options?: { populateHistory?: boolean }): void {\n switch (message.role) {\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n message.command,\n this.ui,\n message.excludeFromContext,\n );\n if (message.output) {\n component.appendOutput(message.output);\n }\n component.setComplete(\n message.exitCode,\n message.cancelled,\n message.truncated\n ? ({ truncated: true } as TruncationResult)\n : undefined,\n message.fullOutputPath,\n );\n this.chatContainer.addChild(component);\n break;\n }\n case \"custom\": {\n if (message.display) {\n const renderer = this.session.extensionRunner.getMessageRenderer(\n message.customType,\n );\n const component = new CustomMessageComponent(\n message,\n renderer,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n }\n break;\n }\n case \"branchSummary\": {\n this.chatContainer.addChild(new Spacer(1));\n const component = new BranchSummaryMessageComponent(\n message,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n break;\n }\n case \"user\": {\n const textContent = this.getUserMessageText(message);\n if (textContent) {\n if (this.chatContainer.children.length > 0) {\n this.chatContainer.addChild(new Spacer(1));\n }\n const skillBlock = parseSkillBlock(textContent);\n if (skillBlock) {\n // Render skill block (collapsible)\n const component = new SkillInvocationMessageComponent(\n skillBlock,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n // Render user message separately if present\n if (skillBlock.userMessage) {\n const userComponent = new UserMessageComponent(\n skillBlock.userMessage,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n } else {\n const userComponent = new UserMessageComponent(\n textContent,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n if (options?.populateHistory) {\n this.editor.addToHistory?.(textContent);\n }\n }\n break;\n }\n case \"assistant\": {\n const assistantComponent = new AssistantMessageComponent(\n message,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n this.outputPad,\n );\n this.chatContainer.addChild(assistantComponent);\n break;\n }\n case \"toolResult\": {\n // Tool results are rendered inline with tool calls, handled separately\n break;\n }\n default:\n break;\n }\n };\n\nInteractiveModeBase.prototype.renderSessionContext = function(this: InteractiveModeBase, sessionContext: SessionContext, options: { updateFooter?: boolean; populateHistory?: boolean } = {}): void {\n this.pendingTools.clear();\n const pendingDeferredInputs = [...this.deferredRenderedUserInputs];\n this.deferredRenderedUserInputs = [];\n this.deferredRenderedUserInputComponents.clear();\n\n if (options.updateFooter) {\n this.footer.invalidate();\n this.updateEditorBorderColor();\n }\n\n const entries = chatEntriesFromAgentMessages(sessionContext.messages);\n for (const entry of entries) {\n const component = this.addRenderedChatEntry(entry);\n if (\n entry.kind === \"tool\" &&\n entry.isPartial !== false &&\n component instanceof ToolExecutionComponent\n ) {\n this.pendingTools.set(entry.toolCallId, component);\n }\n if (options.populateHistory && entry.kind === \"user\") {\n this.editor.addToHistory?.(entry.text);\n }\n }\n\n for (const input of pendingDeferredInputs) {\n this.renderDeferredUserInput(input);\n }\n\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.attachStartupNoticesContainer = function(this: InteractiveModeBase, options: { resetDetached?: boolean } = {}): void {\n const isAttached = this.chatContainer.children.includes(this.startupNoticesContainer);\n if (isAttached) return;\n if (options.resetDetached) {\n this.startupNoticesContainer.clear();\n }\n this.chatContainer.addChild(this.startupNoticesContainer);\n };\n\nInteractiveModeBase.prototype.renderInitialMessages = function(this: InteractiveModeBase): void {\n this.attachStartupNoticesContainer({ resetDetached: true });\n // Get aligned messages and entries from session context\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context, {\n updateFooter: true,\n populateHistory: true,\n });\n\n // Show compaction info if session was compacted\n const allEntries = this.sessionManager.getEntries();\n const compactionCount = allEntries.filter(\n (e) => e.type === \"compaction\",\n ).length;\n if (compactionCount > 0) {\n const times =\n compactionCount === 1 ? \"1 time\" : `${compactionCount} times`;\n this.showStatus(`Session compacted ${times}`);\n }\n };\n\nInteractiveModeBase.prototype.getUserInput = async function(this: InteractiveModeBase): Promise<string> {\n const queuedInput = this.pendingUserInputs.shift();\n if (queuedInput !== undefined) {\n return queuedInput;\n }\n\n return new Promise((resolve) => {\n this.onInputCallback = (text: string) => {\n this.onInputCallback = undefined;\n resolve(text);\n };\n });\n };\n\nInteractiveModeBase.prototype.rebuildChatFromMessages = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.attachStartupNoticesContainer();\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context);\n };\n"]}
1
+ {"version":3,"file":"interactive-render-chat.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-render-chat.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentMessage, type Component, type ContextCompactionResult, type SessionContext, type TruncationResult, type ChatMessageEntry, type ChatMessageRenderOptions, Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, recordTimeSinceReset, theme } from \"./interactive-mode-deps.ts\";\nimport { yieldToEventLoop } from \"../../utils/event-loop.ts\";\n\nInteractiveModeBase.prototype.showStatus = function(this: InteractiveModeBase, message: string): void {\n const children = this.chatContainer.children;\n const last =\n children.length > 0 ? children[children.length - 1] : undefined;\n const secondLast =\n children.length > 1 ? children[children.length - 2] : undefined;\n\n if (\n last &&\n secondLast &&\n last === this.lastStatusText &&\n secondLast === this.lastStatusSpacer\n ) {\n this.lastStatusText.setText(theme.fg(\"dim\", message));\n this.ui.requestRender();\n return;\n }\n\n const spacer = new Spacer(1);\n const text = new Text(theme.fg(\"dim\", message), 1, 0);\n this.chatContainer.addChild(spacer);\n this.chatContainer.addChild(text);\n this.lastStatusSpacer = spacer;\n this.lastStatusText = text;\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.renderDeferredUserInput = function(this: InteractiveModeBase, text: string): void {\n this.deferredRenderedUserInputs.push(text);\n const startIndex = this.chatContainer.children.length;\n this.addMessageToChat({ role: \"user\", content: text } as AgentMessage);\n const renderedComponents = this.chatContainer.children.slice(startIndex);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text) ?? [];\n trackedComponents.push(renderedComponents);\n this.deferredRenderedUserInputComponents.set(text, trackedComponents);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.consumeDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): boolean {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index === -1) return false;\n this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n return true;\n };\n\nInteractiveModeBase.prototype.discardDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): void {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index !== -1) this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n const componentsToRemove = trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n if (!componentsToRemove) return;\n for (const component of componentsToRemove) {\n this.chatContainer.removeChild(component);\n }\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.chatMessageRenderOptions = function(this: InteractiveModeBase): ChatMessageRenderOptions {\n return {\n ui: this.ui,\n cwd: this.sessionManager.getCwd(),\n markdownTheme: this.getMarkdownThemeWithSettings(),\n hideThinkingBlock: this.hideThinkingBlock,\n hiddenThinkingLabel: this.hiddenThinkingLabel,\n toolOutputExpanded: this.toolOutputExpanded,\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n outputPad: this.outputPad,\n getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),\n getCustomMessageRenderer: (customType) =>\n this.session.extensionRunner.getMessageRenderer(customType),\n };\n };\n\nInteractiveModeBase.prototype.addRenderedChatEntry = function(this: InteractiveModeBase, entry: ChatMessageEntry): Component {\n const component = renderChatMessageEntry(entry, this.chatMessageRenderOptions());\n addChatTranscriptEntry(this.chatContainer, component, entry.role);\n return component;\n };\n\nInteractiveModeBase.prototype.addContextCompactionSummaryToChat = function(this: InteractiveModeBase, result: ContextCompactionResult): void {\n this.chatContainer.addChild(new Spacer(1));\n const component = new ContextCompactionSummaryMessageComponent(\n result,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n };\n\nInteractiveModeBase.prototype.addMessageToChat = function(this: InteractiveModeBase, message: AgentMessage, options?: { populateHistory?: boolean }): void {\n switch (message.role) {\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n message.command,\n this.ui,\n message.excludeFromContext,\n );\n if (message.output) {\n component.appendOutput(message.output);\n }\n component.setComplete(\n message.exitCode,\n message.cancelled,\n message.truncated\n ? ({ truncated: true } as TruncationResult)\n : undefined,\n message.fullOutputPath,\n );\n this.chatContainer.addChild(component);\n break;\n }\n case \"custom\": {\n if (message.display) {\n const renderer = this.session.extensionRunner.getMessageRenderer(\n message.customType,\n );\n const component = new CustomMessageComponent(\n message,\n renderer,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n }\n break;\n }\n case \"branchSummary\": {\n this.chatContainer.addChild(new Spacer(1));\n const component = new BranchSummaryMessageComponent(\n message,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n break;\n }\n case \"user\": {\n const textContent = this.getUserMessageText(message);\n if (textContent) {\n if (this.chatContainer.children.length > 0) {\n this.chatContainer.addChild(new Spacer(1));\n }\n const skillBlock = parseSkillBlock(textContent);\n if (skillBlock) {\n // Render skill block (collapsible)\n const component = new SkillInvocationMessageComponent(\n skillBlock,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n // Render user message separately if present\n if (skillBlock.userMessage) {\n const userComponent = new UserMessageComponent(\n skillBlock.userMessage,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n } else {\n const userComponent = new UserMessageComponent(\n textContent,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n if (options?.populateHistory) {\n this.editor.addToHistory?.(textContent);\n }\n }\n break;\n }\n case \"assistant\": {\n const assistantComponent = new AssistantMessageComponent(\n message,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n this.outputPad,\n );\n this.chatContainer.addChild(assistantComponent);\n break;\n }\n case \"toolResult\": {\n // Tool results are rendered inline with tool calls, handled separately\n break;\n }\n default:\n break;\n }\n };\n\nInteractiveModeBase.prototype.renderSessionContext = function(this: InteractiveModeBase, sessionContext: SessionContext, options: { updateFooter?: boolean; populateHistory?: boolean } = {}): void {\n this.pendingTools.clear();\n const pendingDeferredInputs = [...this.deferredRenderedUserInputs];\n this.deferredRenderedUserInputs = [];\n this.deferredRenderedUserInputComponents.clear();\n\n if (options.updateFooter) {\n this.footer.invalidate();\n this.updateEditorBorderColor();\n }\n\n const entries = chatEntriesFromAgentMessages(sessionContext.messages);\n for (const entry of entries) {\n const component = this.addRenderedChatEntry(entry);\n if (\n entry.kind === \"tool\" &&\n entry.isPartial !== false &&\n component instanceof ToolExecutionComponent\n ) {\n this.pendingTools.set(entry.toolCallId, component);\n }\n if (options.populateHistory && entry.kind === \"user\") {\n this.editor.addToHistory?.(entry.text);\n }\n }\n\n for (const input of pendingDeferredInputs) {\n this.renderDeferredUserInput(input);\n }\n\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.attachStartupNoticesContainer = function(this: InteractiveModeBase, options: { resetDetached?: boolean } = {}): void {\n const isAttached = this.chatContainer.children.includes(this.startupNoticesContainer);\n if (isAttached) return;\n if (options.resetDetached) {\n this.startupNoticesContainer.clear();\n }\n this.chatContainer.addChild(this.startupNoticesContainer);\n };\n\nInteractiveModeBase.prototype.renderInitialMessages = function(this: InteractiveModeBase): void {\n this.attachStartupNoticesContainer({ resetDetached: true });\n // Get aligned messages and entries from session context\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context, {\n updateFooter: true,\n populateHistory: true,\n });\n\n // Show compaction info if session was compacted\n const allEntries = this.sessionManager.getEntries();\n const compactionCount = allEntries.filter(\n (e) => e.type === \"compaction\",\n ).length;\n if (compactionCount > 0) {\n const times =\n compactionCount === 1 ? \"1 time\" : `${compactionCount} times`;\n this.showStatus(`Session compacted ${times}`);\n }\n };\n\nInteractiveModeBase.prototype.getUserInput = async function(this: InteractiveModeBase): Promise<string> {\n for (let attempt = 0; !this.startupCookedInputRecovered && attempt < 10; attempt += 1) {\n await yieldToEventLoop();\n if (this.recoverCookedStartupInput?.()) break;\n }\n while (true) {\n const queuedInput = this.pendingUserInputs.shift();\n if (queuedInput !== undefined) {\n return queuedInput;\n }\n\n if (this.startupReplayActiveInput) {\n await this.drainStartupReplayCommands();\n continue;\n }\n\n return new Promise((resolve) => {\n this.onInputCallback = (text: string) => {\n this.onInputCallback = undefined;\n resolve(text);\n };\n if (!this.inputHandlerReadyRecorded) {\n this.inputHandlerReadyRecorded = true;\n recordTimeSinceReset(\"interactive-input-handler-ready\");\n void (async () => {\n await yieldToEventLoop();\n this.footerDataProvider.startGitWatcher();\n if (this.deferredStartupPending) {\n await this.ensureDeferredStartupComplete();\n }\n })().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Deferred input-readiness startup task failed: ${message}`);\n });\n }\n });\n }\n };\n\nInteractiveModeBase.prototype.rebuildChatFromMessages = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.attachStartupNoticesContainer();\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context);\n };\n"]}
@@ -1,5 +1,6 @@
1
1
  import { InteractiveModeBase } from "./interactive-mode-base.js";
2
- import { Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, theme } from "./interactive-mode-deps.js";
2
+ import { Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, recordTimeSinceReset, theme } from "./interactive-mode-deps.js";
3
+ import { yieldToEventLoop } from "../../utils/event-loop.js";
3
4
  InteractiveModeBase.prototype.showStatus = function (message) {
4
5
  const children = this.chatContainer.children;
5
6
  const last = children.length > 0 ? children[children.length - 1] : undefined;
@@ -208,16 +209,41 @@ InteractiveModeBase.prototype.renderInitialMessages = function () {
208
209
  }
209
210
  };
210
211
  InteractiveModeBase.prototype.getUserInput = async function () {
211
- const queuedInput = this.pendingUserInputs.shift();
212
- if (queuedInput !== undefined) {
213
- return queuedInput;
212
+ for (let attempt = 0; !this.startupCookedInputRecovered && attempt < 10; attempt += 1) {
213
+ await yieldToEventLoop();
214
+ if (this.recoverCookedStartupInput?.())
215
+ break;
216
+ }
217
+ while (true) {
218
+ const queuedInput = this.pendingUserInputs.shift();
219
+ if (queuedInput !== undefined) {
220
+ return queuedInput;
221
+ }
222
+ if (this.startupReplayActiveInput) {
223
+ await this.drainStartupReplayCommands();
224
+ continue;
225
+ }
226
+ return new Promise((resolve) => {
227
+ this.onInputCallback = (text) => {
228
+ this.onInputCallback = undefined;
229
+ resolve(text);
230
+ };
231
+ if (!this.inputHandlerReadyRecorded) {
232
+ this.inputHandlerReadyRecorded = true;
233
+ recordTimeSinceReset("interactive-input-handler-ready");
234
+ void (async () => {
235
+ await yieldToEventLoop();
236
+ this.footerDataProvider.startGitWatcher();
237
+ if (this.deferredStartupPending) {
238
+ await this.ensureDeferredStartupComplete();
239
+ }
240
+ })().catch((error) => {
241
+ const message = error instanceof Error ? error.message : String(error);
242
+ console.error(`Deferred input-readiness startup task failed: ${message}`);
243
+ });
244
+ }
245
+ });
214
246
  }
215
- return new Promise((resolve) => {
216
- this.onInputCallback = (text) => {
217
- this.onInputCallback = undefined;
218
- resolve(text);
219
- };
220
- });
221
247
  };
222
248
  InteractiveModeBase.prototype.rebuildChatFromMessages = function () {
223
249
  this.chatContainer.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-render-chat.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-render-chat.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentMessage, type Component, type ContextCompactionResult, type SessionContext, type TruncationResult, type ChatMessageEntry, type ChatMessageRenderOptions, Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.showStatus = function(this: InteractiveModeBase, message: string): void {\n const children = this.chatContainer.children;\n const last =\n children.length > 0 ? children[children.length - 1] : undefined;\n const secondLast =\n children.length > 1 ? children[children.length - 2] : undefined;\n\n if (\n last &&\n secondLast &&\n last === this.lastStatusText &&\n secondLast === this.lastStatusSpacer\n ) {\n this.lastStatusText.setText(theme.fg(\"dim\", message));\n this.ui.requestRender();\n return;\n }\n\n const spacer = new Spacer(1);\n const text = new Text(theme.fg(\"dim\", message), 1, 0);\n this.chatContainer.addChild(spacer);\n this.chatContainer.addChild(text);\n this.lastStatusSpacer = spacer;\n this.lastStatusText = text;\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.renderDeferredUserInput = function(this: InteractiveModeBase, text: string): void {\n this.deferredRenderedUserInputs.push(text);\n const startIndex = this.chatContainer.children.length;\n this.addMessageToChat({ role: \"user\", content: text } as AgentMessage);\n const renderedComponents = this.chatContainer.children.slice(startIndex);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text) ?? [];\n trackedComponents.push(renderedComponents);\n this.deferredRenderedUserInputComponents.set(text, trackedComponents);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.consumeDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): boolean {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index === -1) return false;\n this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n return true;\n };\n\nInteractiveModeBase.prototype.discardDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): void {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index !== -1) this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n const componentsToRemove = trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n if (!componentsToRemove) return;\n for (const component of componentsToRemove) {\n this.chatContainer.removeChild(component);\n }\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.chatMessageRenderOptions = function(this: InteractiveModeBase): ChatMessageRenderOptions {\n return {\n ui: this.ui,\n cwd: this.sessionManager.getCwd(),\n markdownTheme: this.getMarkdownThemeWithSettings(),\n hideThinkingBlock: this.hideThinkingBlock,\n hiddenThinkingLabel: this.hiddenThinkingLabel,\n toolOutputExpanded: this.toolOutputExpanded,\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n outputPad: this.outputPad,\n getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),\n getCustomMessageRenderer: (customType) =>\n this.session.extensionRunner.getMessageRenderer(customType),\n };\n };\n\nInteractiveModeBase.prototype.addRenderedChatEntry = function(this: InteractiveModeBase, entry: ChatMessageEntry): Component {\n const component = renderChatMessageEntry(entry, this.chatMessageRenderOptions());\n addChatTranscriptEntry(this.chatContainer, component, entry.role);\n return component;\n };\n\nInteractiveModeBase.prototype.addContextCompactionSummaryToChat = function(this: InteractiveModeBase, result: ContextCompactionResult): void {\n this.chatContainer.addChild(new Spacer(1));\n const component = new ContextCompactionSummaryMessageComponent(\n result,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n };\n\nInteractiveModeBase.prototype.addMessageToChat = function(this: InteractiveModeBase, message: AgentMessage, options?: { populateHistory?: boolean }): void {\n switch (message.role) {\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n message.command,\n this.ui,\n message.excludeFromContext,\n );\n if (message.output) {\n component.appendOutput(message.output);\n }\n component.setComplete(\n message.exitCode,\n message.cancelled,\n message.truncated\n ? ({ truncated: true } as TruncationResult)\n : undefined,\n message.fullOutputPath,\n );\n this.chatContainer.addChild(component);\n break;\n }\n case \"custom\": {\n if (message.display) {\n const renderer = this.session.extensionRunner.getMessageRenderer(\n message.customType,\n );\n const component = new CustomMessageComponent(\n message,\n renderer,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n }\n break;\n }\n case \"branchSummary\": {\n this.chatContainer.addChild(new Spacer(1));\n const component = new BranchSummaryMessageComponent(\n message,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n break;\n }\n case \"user\": {\n const textContent = this.getUserMessageText(message);\n if (textContent) {\n if (this.chatContainer.children.length > 0) {\n this.chatContainer.addChild(new Spacer(1));\n }\n const skillBlock = parseSkillBlock(textContent);\n if (skillBlock) {\n // Render skill block (collapsible)\n const component = new SkillInvocationMessageComponent(\n skillBlock,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n // Render user message separately if present\n if (skillBlock.userMessage) {\n const userComponent = new UserMessageComponent(\n skillBlock.userMessage,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n } else {\n const userComponent = new UserMessageComponent(\n textContent,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n if (options?.populateHistory) {\n this.editor.addToHistory?.(textContent);\n }\n }\n break;\n }\n case \"assistant\": {\n const assistantComponent = new AssistantMessageComponent(\n message,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n this.outputPad,\n );\n this.chatContainer.addChild(assistantComponent);\n break;\n }\n case \"toolResult\": {\n // Tool results are rendered inline with tool calls, handled separately\n break;\n }\n default:\n break;\n }\n };\n\nInteractiveModeBase.prototype.renderSessionContext = function(this: InteractiveModeBase, sessionContext: SessionContext, options: { updateFooter?: boolean; populateHistory?: boolean } = {}): void {\n this.pendingTools.clear();\n const pendingDeferredInputs = [...this.deferredRenderedUserInputs];\n this.deferredRenderedUserInputs = [];\n this.deferredRenderedUserInputComponents.clear();\n\n if (options.updateFooter) {\n this.footer.invalidate();\n this.updateEditorBorderColor();\n }\n\n const entries = chatEntriesFromAgentMessages(sessionContext.messages);\n for (const entry of entries) {\n const component = this.addRenderedChatEntry(entry);\n if (\n entry.kind === \"tool\" &&\n entry.isPartial !== false &&\n component instanceof ToolExecutionComponent\n ) {\n this.pendingTools.set(entry.toolCallId, component);\n }\n if (options.populateHistory && entry.kind === \"user\") {\n this.editor.addToHistory?.(entry.text);\n }\n }\n\n for (const input of pendingDeferredInputs) {\n this.renderDeferredUserInput(input);\n }\n\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.attachStartupNoticesContainer = function(this: InteractiveModeBase, options: { resetDetached?: boolean } = {}): void {\n const isAttached = this.chatContainer.children.includes(this.startupNoticesContainer);\n if (isAttached) return;\n if (options.resetDetached) {\n this.startupNoticesContainer.clear();\n }\n this.chatContainer.addChild(this.startupNoticesContainer);\n };\n\nInteractiveModeBase.prototype.renderInitialMessages = function(this: InteractiveModeBase): void {\n this.attachStartupNoticesContainer({ resetDetached: true });\n // Get aligned messages and entries from session context\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context, {\n updateFooter: true,\n populateHistory: true,\n });\n\n // Show compaction info if session was compacted\n const allEntries = this.sessionManager.getEntries();\n const compactionCount = allEntries.filter(\n (e) => e.type === \"compaction\",\n ).length;\n if (compactionCount > 0) {\n const times =\n compactionCount === 1 ? \"1 time\" : `${compactionCount} times`;\n this.showStatus(`Session compacted ${times}`);\n }\n };\n\nInteractiveModeBase.prototype.getUserInput = async function(this: InteractiveModeBase): Promise<string> {\n const queuedInput = this.pendingUserInputs.shift();\n if (queuedInput !== undefined) {\n return queuedInput;\n }\n\n return new Promise((resolve) => {\n this.onInputCallback = (text: string) => {\n this.onInputCallback = undefined;\n resolve(text);\n };\n });\n };\n\nInteractiveModeBase.prototype.rebuildChatFromMessages = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.attachStartupNoticesContainer();\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context);\n };\n"]}
1
+ {"version":3,"file":"interactive-render-chat.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-render-chat.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentMessage, type Component, type ContextCompactionResult, type SessionContext, type TruncationResult, type ChatMessageEntry, type ChatMessageRenderOptions, Spacer, Text, parseSkillBlock, AssistantMessageComponent, BashExecutionComponent, BranchSummaryMessageComponent, chatEntriesFromAgentMessages, renderChatMessageEntry, addChatTranscriptEntry, ContextCompactionSummaryMessageComponent, CustomMessageComponent, SkillInvocationMessageComponent, ToolExecutionComponent, UserMessageComponent, recordTimeSinceReset, theme } from \"./interactive-mode-deps.ts\";\nimport { yieldToEventLoop } from \"../../utils/event-loop.ts\";\n\nInteractiveModeBase.prototype.showStatus = function(this: InteractiveModeBase, message: string): void {\n const children = this.chatContainer.children;\n const last =\n children.length > 0 ? children[children.length - 1] : undefined;\n const secondLast =\n children.length > 1 ? children[children.length - 2] : undefined;\n\n if (\n last &&\n secondLast &&\n last === this.lastStatusText &&\n secondLast === this.lastStatusSpacer\n ) {\n this.lastStatusText.setText(theme.fg(\"dim\", message));\n this.ui.requestRender();\n return;\n }\n\n const spacer = new Spacer(1);\n const text = new Text(theme.fg(\"dim\", message), 1, 0);\n this.chatContainer.addChild(spacer);\n this.chatContainer.addChild(text);\n this.lastStatusSpacer = spacer;\n this.lastStatusText = text;\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.renderDeferredUserInput = function(this: InteractiveModeBase, text: string): void {\n this.deferredRenderedUserInputs.push(text);\n const startIndex = this.chatContainer.children.length;\n this.addMessageToChat({ role: \"user\", content: text } as AgentMessage);\n const renderedComponents = this.chatContainer.children.slice(startIndex);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text) ?? [];\n trackedComponents.push(renderedComponents);\n this.deferredRenderedUserInputComponents.set(text, trackedComponents);\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.consumeDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): boolean {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index === -1) return false;\n this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n return true;\n };\n\nInteractiveModeBase.prototype.discardDeferredRenderedUserInput = function(this: InteractiveModeBase, text: string): void {\n const index = this.deferredRenderedUserInputs.indexOf(text);\n if (index !== -1) this.deferredRenderedUserInputs.splice(index, 1);\n const trackedComponents = this.deferredRenderedUserInputComponents.get(text);\n const componentsToRemove = trackedComponents?.shift();\n if (trackedComponents && trackedComponents.length === 0) {\n this.deferredRenderedUserInputComponents.delete(text);\n }\n if (!componentsToRemove) return;\n for (const component of componentsToRemove) {\n this.chatContainer.removeChild(component);\n }\n this.updatePendingMessagesDisplay();\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.chatMessageRenderOptions = function(this: InteractiveModeBase): ChatMessageRenderOptions {\n return {\n ui: this.ui,\n cwd: this.sessionManager.getCwd(),\n markdownTheme: this.getMarkdownThemeWithSettings(),\n hideThinkingBlock: this.hideThinkingBlock,\n hiddenThinkingLabel: this.hiddenThinkingLabel,\n toolOutputExpanded: this.toolOutputExpanded,\n showImages: this.settingsManager.getShowImages(),\n imageWidthCells: this.settingsManager.getImageWidthCells(),\n outputPad: this.outputPad,\n getToolDefinition: (toolName) => this.getRegisteredToolDefinition(toolName),\n getCustomMessageRenderer: (customType) =>\n this.session.extensionRunner.getMessageRenderer(customType),\n };\n };\n\nInteractiveModeBase.prototype.addRenderedChatEntry = function(this: InteractiveModeBase, entry: ChatMessageEntry): Component {\n const component = renderChatMessageEntry(entry, this.chatMessageRenderOptions());\n addChatTranscriptEntry(this.chatContainer, component, entry.role);\n return component;\n };\n\nInteractiveModeBase.prototype.addContextCompactionSummaryToChat = function(this: InteractiveModeBase, result: ContextCompactionResult): void {\n this.chatContainer.addChild(new Spacer(1));\n const component = new ContextCompactionSummaryMessageComponent(\n result,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n };\n\nInteractiveModeBase.prototype.addMessageToChat = function(this: InteractiveModeBase, message: AgentMessage, options?: { populateHistory?: boolean }): void {\n switch (message.role) {\n case \"bashExecution\": {\n const component = new BashExecutionComponent(\n message.command,\n this.ui,\n message.excludeFromContext,\n );\n if (message.output) {\n component.appendOutput(message.output);\n }\n component.setComplete(\n message.exitCode,\n message.cancelled,\n message.truncated\n ? ({ truncated: true } as TruncationResult)\n : undefined,\n message.fullOutputPath,\n );\n this.chatContainer.addChild(component);\n break;\n }\n case \"custom\": {\n if (message.display) {\n const renderer = this.session.extensionRunner.getMessageRenderer(\n message.customType,\n );\n const component = new CustomMessageComponent(\n message,\n renderer,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n }\n break;\n }\n case \"branchSummary\": {\n this.chatContainer.addChild(new Spacer(1));\n const component = new BranchSummaryMessageComponent(\n message,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n break;\n }\n case \"user\": {\n const textContent = this.getUserMessageText(message);\n if (textContent) {\n if (this.chatContainer.children.length > 0) {\n this.chatContainer.addChild(new Spacer(1));\n }\n const skillBlock = parseSkillBlock(textContent);\n if (skillBlock) {\n // Render skill block (collapsible)\n const component = new SkillInvocationMessageComponent(\n skillBlock,\n this.getMarkdownThemeWithSettings(),\n );\n component.setExpanded(this.toolOutputExpanded);\n this.chatContainer.addChild(component);\n // Render user message separately if present\n if (skillBlock.userMessage) {\n const userComponent = new UserMessageComponent(\n skillBlock.userMessage,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n } else {\n const userComponent = new UserMessageComponent(\n textContent,\n this.getMarkdownThemeWithSettings(),\n this.outputPad,\n );\n this.chatContainer.addChild(userComponent);\n }\n if (options?.populateHistory) {\n this.editor.addToHistory?.(textContent);\n }\n }\n break;\n }\n case \"assistant\": {\n const assistantComponent = new AssistantMessageComponent(\n message,\n this.hideThinkingBlock,\n this.getMarkdownThemeWithSettings(),\n this.hiddenThinkingLabel,\n this.outputPad,\n );\n this.chatContainer.addChild(assistantComponent);\n break;\n }\n case \"toolResult\": {\n // Tool results are rendered inline with tool calls, handled separately\n break;\n }\n default:\n break;\n }\n };\n\nInteractiveModeBase.prototype.renderSessionContext = function(this: InteractiveModeBase, sessionContext: SessionContext, options: { updateFooter?: boolean; populateHistory?: boolean } = {}): void {\n this.pendingTools.clear();\n const pendingDeferredInputs = [...this.deferredRenderedUserInputs];\n this.deferredRenderedUserInputs = [];\n this.deferredRenderedUserInputComponents.clear();\n\n if (options.updateFooter) {\n this.footer.invalidate();\n this.updateEditorBorderColor();\n }\n\n const entries = chatEntriesFromAgentMessages(sessionContext.messages);\n for (const entry of entries) {\n const component = this.addRenderedChatEntry(entry);\n if (\n entry.kind === \"tool\" &&\n entry.isPartial !== false &&\n component instanceof ToolExecutionComponent\n ) {\n this.pendingTools.set(entry.toolCallId, component);\n }\n if (options.populateHistory && entry.kind === \"user\") {\n this.editor.addToHistory?.(entry.text);\n }\n }\n\n for (const input of pendingDeferredInputs) {\n this.renderDeferredUserInput(input);\n }\n\n this.ui.requestRender();\n };\n\nInteractiveModeBase.prototype.attachStartupNoticesContainer = function(this: InteractiveModeBase, options: { resetDetached?: boolean } = {}): void {\n const isAttached = this.chatContainer.children.includes(this.startupNoticesContainer);\n if (isAttached) return;\n if (options.resetDetached) {\n this.startupNoticesContainer.clear();\n }\n this.chatContainer.addChild(this.startupNoticesContainer);\n };\n\nInteractiveModeBase.prototype.renderInitialMessages = function(this: InteractiveModeBase): void {\n this.attachStartupNoticesContainer({ resetDetached: true });\n // Get aligned messages and entries from session context\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context, {\n updateFooter: true,\n populateHistory: true,\n });\n\n // Show compaction info if session was compacted\n const allEntries = this.sessionManager.getEntries();\n const compactionCount = allEntries.filter(\n (e) => e.type === \"compaction\",\n ).length;\n if (compactionCount > 0) {\n const times =\n compactionCount === 1 ? \"1 time\" : `${compactionCount} times`;\n this.showStatus(`Session compacted ${times}`);\n }\n };\n\nInteractiveModeBase.prototype.getUserInput = async function(this: InteractiveModeBase): Promise<string> {\n for (let attempt = 0; !this.startupCookedInputRecovered && attempt < 10; attempt += 1) {\n await yieldToEventLoop();\n if (this.recoverCookedStartupInput?.()) break;\n }\n while (true) {\n const queuedInput = this.pendingUserInputs.shift();\n if (queuedInput !== undefined) {\n return queuedInput;\n }\n\n if (this.startupReplayActiveInput) {\n await this.drainStartupReplayCommands();\n continue;\n }\n\n return new Promise((resolve) => {\n this.onInputCallback = (text: string) => {\n this.onInputCallback = undefined;\n resolve(text);\n };\n if (!this.inputHandlerReadyRecorded) {\n this.inputHandlerReadyRecorded = true;\n recordTimeSinceReset(\"interactive-input-handler-ready\");\n void (async () => {\n await yieldToEventLoop();\n this.footerDataProvider.startGitWatcher();\n if (this.deferredStartupPending) {\n await this.ensureDeferredStartupComplete();\n }\n })().catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Deferred input-readiness startup task failed: ${message}`);\n });\n }\n });\n }\n };\n\nInteractiveModeBase.prototype.rebuildChatFromMessages = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.attachStartupNoticesContainer();\n const context = this.sessionManager.buildSessionContext();\n this.renderSessionContext(context);\n };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-routing.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-routing.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type ExtensionCommandContext, Loader, Spacer, APP_NAME, MissingSessionCwdError, SessionManager, keyText, SessionSelectorComponent, TreeSelectorComponent, TrustSelectorComponent, hasTrustRequiringProjectResources, ProjectTrustStore, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.handleCloneCommand = async function(this: InteractiveModeBase): Promise<void> {\n const leafId = this.sessionManager.getLeafId();\n if (!leafId) {\n this.showStatus(\"Nothing to clone yet\");\n return;\n }\n\n try {\n const result = await this.runtimeHost.fork(leafId, { position: \"at\" });\n if (result.cancelled) {\n this.ui.requestRender();\n return;\n }\n\n this.renderCurrentSessionState();\n this.editor.setText(\"\");\n this.showStatus(\"Cloned to new session\");\n } catch (error: unknown) {\n this.showError(error instanceof Error ? error.message : String(error));\n }\n };\n\nInteractiveModeBase.prototype.maybeSaveImplicitProjectTrustAfterReload = function(this: InteractiveModeBase): boolean {\n const cwd = this.sessionManager.getCwd();\n if (this.autoTrustOnReloadCwd !== cwd) {\n return false;\n }\n if (!this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(cwd)) {\n return false;\n }\n\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n try {\n if (trustStore.get(cwd) !== null) {\n this.autoTrustOnReloadCwd = undefined;\n return false;\n }\n trustStore.set(cwd, true);\n this.autoTrustOnReloadCwd = undefined;\n return true;\n } catch (error) {\n this.showWarning(\n `Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n };\n\nInteractiveModeBase.prototype.showTrustSelector = function(this: InteractiveModeBase): void {\n const cwd = this.sessionManager.getCwd();\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n const savedDecision = trustStore.getEntry(cwd);\n this.showSelector((done) => {\n const selector = new TrustSelectorComponent({\n cwd,\n savedDecision,\n projectTrusted: this.settingsManager.isProjectTrusted(),\n onSelect: (selection) => {\n trustStore.setMany(selection.updates);\n done();\n this.showStatus(\n `Saved trust decision: ${selection.trusted ? \"trusted\" : \"untrusted\"}. Restart ${APP_NAME} for this to take effect.`,\n );\n },\n onCancel: () => {\n done();\n this.ui.requestRender();\n },\n });\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showTreeSelector = function(this: InteractiveModeBase, initialSelectedId?: string): void {\n const tree = this.sessionManager.getTree();\n const realLeafId = this.sessionManager.getLeafId();\n const initialFilterMode = this.settingsManager.getTreeFilterMode();\n\n if (tree.length === 0) {\n this.showStatus(\"No entries in session\");\n return;\n }\n\n this.showSelector((done) => {\n const selector = new TreeSelectorComponent(\n tree,\n realLeafId,\n this.ui.terminal.rows,\n async (entryId) => {\n // Selecting the current leaf is a no-op (already there)\n if (entryId === realLeafId) {\n done();\n this.showStatus(\"Already at this point\");\n return;\n }\n\n // Ask about summarization\n done(); // Close selector first\n\n // Loop until user makes a complete choice or cancels to tree\n let wantsSummary = false;\n let customInstructions: string | undefined;\n\n // Check if we should skip the prompt (user preference to always default to no summary)\n if (!this.settingsManager.getBranchSummarySkipPrompt()) {\n while (true) {\n const summaryChoice = await this.showExtensionSelector(\n \"Summarize branch?\",\n [\"No summary\", \"Summarize\", \"Summarize with custom prompt\"],\n );\n\n if (summaryChoice === undefined) {\n // User pressed escape - re-show tree selector with same selection\n this.showTreeSelector(entryId);\n return;\n }\n\n wantsSummary = summaryChoice !== \"No summary\";\n\n if (summaryChoice === \"Summarize with custom prompt\") {\n customInstructions = await this.showExtensionEditor(\n \"Custom summarization instructions\",\n );\n if (customInstructions === undefined) {\n // User cancelled - loop back to summary selector\n continue;\n }\n }\n\n // User made a complete choice\n break;\n }\n }\n\n // Set up escape handler and loader if summarizing\n let summaryLoader: Loader | undefined;\n const originalOnEscape = this.defaultEditor.onEscape;\n\n if (wantsSummary) {\n this.defaultEditor.onEscape = () => {\n this.session.abortBranchSummary();\n };\n this.chatContainer.addChild(new Spacer(1));\n summaryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Summarizing branch... (${keyText(\"app.interrupt\")} Cancel)`,\n );\n this.statusContainer.addChild(summaryLoader);\n this.ui.requestRender();\n }\n\n try {\n const result = await this.session.navigateTree(entryId, {\n summarize: wantsSummary,\n customInstructions,\n });\n\n if (result.aborted) {\n // Summarization aborted - re-show tree selector with same selection\n this.showStatus(\"Branch summarization cancelled\");\n this.showTreeSelector(entryId);\n return;\n }\n if (result.cancelled) {\n this.showStatus(\"Navigation cancelled\");\n return;\n }\n\n // Update UI\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n } catch (error) {\n this.showError(\n error instanceof Error ? error.message : String(error),\n );\n } finally {\n if (summaryLoader) {\n summaryLoader.stop();\n this.statusContainer.clear();\n }\n this.defaultEditor.onEscape = originalOnEscape;\n }\n },\n () => {\n done();\n this.ui.requestRender();\n },\n (entryId, label) => {\n this.sessionManager.appendLabelChange(entryId, label);\n this.ui.requestRender();\n },\n initialSelectedId,\n initialFilterMode,\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showSessionSelector = function(this: InteractiveModeBase): void {\n this.showSelector((done) => {\n const selector = new SessionSelectorComponent(\n (onProgress) =>\n SessionManager.list(\n this.sessionManager.getCwd(),\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n (onProgress) =>\n this.sessionManager.usesDefaultSessionDir()\n ? SessionManager.listAll(onProgress)\n : SessionManager.listAll(\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n async (sessionPath) => {\n done();\n await this.handleResumeSession(sessionPath);\n },\n () => {\n done();\n this.ui.requestRender();\n },\n () => {\n void this.shutdown();\n },\n () => this.ui.requestRender(),\n {\n renameSession: async (\n sessionFilePath: string,\n nextName: string | undefined,\n ) => {\n const next = (nextName ?? \"\").trim();\n if (!next) return;\n const mgr = SessionManager.open(sessionFilePath);\n mgr.appendSessionInfo(next);\n },\n showRenameHint: true,\n keybindings: this.keybindings,\n },\n\n this.sessionManager.getSessionFile(),\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.handleResumeSession = async function(this: InteractiveModeBase, sessionPath: string, options?: Parameters<ExtensionCommandContext[\"switchSession\"]>[1]): Promise<{ cancelled: boolean }> {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.switchSession(sessionPath, {\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session\");\n return result;\n } catch (error: unknown) {\n if (error instanceof MissingSessionCwdError) {\n const selectedCwd = await this.promptForMissingSessionCwd(error);\n if (!selectedCwd) {\n this.showStatus(\"Resume cancelled\");\n return { cancelled: true };\n }\n const result = await this.runtimeHost.switchSession(sessionPath, {\n cwdOverride: selectedCwd,\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session in current cwd\");\n return result;\n }\n return this.handleFatalRuntimeError(\"Failed to resume session\", error);\n }\n };\n"]}
1
+ {"version":3,"file":"interactive-session-routing.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-routing.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type ExtensionCommandContext, Loader, Spacer, APP_NAME, MissingSessionCwdError, SessionManager, keyText, SessionSelectorComponent, TreeSelectorComponent, TrustSelectorComponent, hasTrustRequiringProjectResources, ProjectTrustStore, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.handleCloneCommand = async function(this: InteractiveModeBase): Promise<void> {\n await this.ensureDeferredStartupComplete();\n const leafId = this.sessionManager.getLeafId();\n if (!leafId) {\n this.showStatus(\"Nothing to clone yet\");\n return;\n }\n\n try {\n const result = await this.runtimeHost.fork(leafId, { position: \"at\" });\n if (result.cancelled) {\n this.ui.requestRender();\n return;\n }\n\n this.renderCurrentSessionState();\n this.editor.setText(\"\");\n this.showStatus(\"Cloned to new session\");\n } catch (error: unknown) {\n this.showError(error instanceof Error ? error.message : String(error));\n }\n };\n\nInteractiveModeBase.prototype.maybeSaveImplicitProjectTrustAfterReload = function(this: InteractiveModeBase): boolean {\n const cwd = this.sessionManager.getCwd();\n if (this.autoTrustOnReloadCwd !== cwd) {\n return false;\n }\n if (!this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(cwd)) {\n return false;\n }\n\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n try {\n if (trustStore.get(cwd) !== null) {\n this.autoTrustOnReloadCwd = undefined;\n return false;\n }\n trustStore.set(cwd, true);\n this.autoTrustOnReloadCwd = undefined;\n return true;\n } catch (error) {\n this.showWarning(\n `Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n };\n\nInteractiveModeBase.prototype.showTrustSelector = function(this: InteractiveModeBase): void {\n const cwd = this.sessionManager.getCwd();\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n const savedDecision = trustStore.getEntry(cwd);\n this.showSelector((done) => {\n const selector = new TrustSelectorComponent({\n cwd,\n savedDecision,\n projectTrusted: this.settingsManager.isProjectTrusted(),\n onSelect: (selection) => {\n trustStore.setMany(selection.updates);\n done();\n this.showStatus(\n `Saved trust decision: ${selection.trusted ? \"trusted\" : \"untrusted\"}. Restart ${APP_NAME} for this to take effect.`,\n );\n },\n onCancel: () => {\n done();\n this.ui.requestRender();\n },\n });\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showTreeSelector = async function(this: InteractiveModeBase, initialSelectedId?: string): Promise<void> {\n await this.ensureDeferredStartupComplete();\n const tree = this.sessionManager.getTree();\n const realLeafId = this.sessionManager.getLeafId();\n const initialFilterMode = this.settingsManager.getTreeFilterMode();\n\n if (tree.length === 0) {\n this.showStatus(\"No entries in session\");\n return;\n }\n\n this.showSelector((done) => {\n const selector = new TreeSelectorComponent(\n tree,\n realLeafId,\n this.ui.terminal.rows,\n async (entryId) => {\n // Selecting the current leaf is a no-op (already there)\n if (entryId === realLeafId) {\n done();\n this.showStatus(\"Already at this point\");\n return;\n }\n\n // Ask about summarization\n done(); // Close selector first\n\n // Loop until user makes a complete choice or cancels to tree\n let wantsSummary = false;\n let customInstructions: string | undefined;\n\n // Check if we should skip the prompt (user preference to always default to no summary)\n if (!this.settingsManager.getBranchSummarySkipPrompt()) {\n while (true) {\n const summaryChoice = await this.showExtensionSelector(\n \"Summarize branch?\",\n [\"No summary\", \"Summarize\", \"Summarize with custom prompt\"],\n );\n\n if (summaryChoice === undefined) {\n // User pressed escape - re-show tree selector with same selection\n this.showTreeSelector(entryId);\n return;\n }\n\n wantsSummary = summaryChoice !== \"No summary\";\n\n if (summaryChoice === \"Summarize with custom prompt\") {\n customInstructions = await this.showExtensionEditor(\n \"Custom summarization instructions\",\n );\n if (customInstructions === undefined) {\n // User cancelled - loop back to summary selector\n continue;\n }\n }\n\n // User made a complete choice\n break;\n }\n }\n\n // Set up escape handler and loader if summarizing\n let summaryLoader: Loader | undefined;\n const originalOnEscape = this.defaultEditor.onEscape;\n\n if (wantsSummary) {\n this.defaultEditor.onEscape = () => {\n this.session.abortBranchSummary();\n };\n this.chatContainer.addChild(new Spacer(1));\n summaryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Summarizing branch... (${keyText(\"app.interrupt\")} Cancel)`,\n );\n this.statusContainer.addChild(summaryLoader);\n this.ui.requestRender();\n }\n\n try {\n await this.ensureDeferredStartupComplete();\n const result = await this.session.navigateTree(entryId, {\n summarize: wantsSummary,\n customInstructions,\n });\n\n if (result.aborted) {\n // Summarization aborted - re-show tree selector with same selection\n this.showStatus(\"Branch summarization cancelled\");\n this.showTreeSelector(entryId);\n return;\n }\n if (result.cancelled) {\n this.showStatus(\"Navigation cancelled\");\n return;\n }\n\n // Update UI\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n } catch (error) {\n this.showError(\n error instanceof Error ? error.message : String(error),\n );\n } finally {\n if (summaryLoader) {\n summaryLoader.stop();\n this.statusContainer.clear();\n }\n this.defaultEditor.onEscape = originalOnEscape;\n }\n },\n () => {\n done();\n this.ui.requestRender();\n },\n (entryId, label) => {\n this.sessionManager.appendLabelChange(entryId, label);\n this.ui.requestRender();\n },\n initialSelectedId,\n initialFilterMode,\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showSessionSelector = function(this: InteractiveModeBase): void {\n this.showSelector((done) => {\n const selector = new SessionSelectorComponent(\n (onProgress) =>\n SessionManager.list(\n this.sessionManager.getCwd(),\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n (onProgress) =>\n this.sessionManager.usesDefaultSessionDir()\n ? SessionManager.listAll(onProgress)\n : SessionManager.listAll(\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n async (sessionPath) => {\n done();\n await this.handleResumeSession(sessionPath);\n },\n () => {\n done();\n this.ui.requestRender();\n },\n () => {\n void this.shutdown();\n },\n () => this.ui.requestRender(),\n {\n renameSession: async (\n sessionFilePath: string,\n nextName: string | undefined,\n ) => {\n const next = (nextName ?? \"\").trim();\n if (!next) return;\n const mgr = SessionManager.open(sessionFilePath);\n mgr.appendSessionInfo(next);\n },\n showRenameHint: true,\n keybindings: this.keybindings,\n },\n\n this.sessionManager.getSessionFile(),\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.handleResumeSession = async function(this: InteractiveModeBase, sessionPath: string, options?: Parameters<ExtensionCommandContext[\"switchSession\"]>[1]): Promise<{ cancelled: boolean }> {\n await this.ensureDeferredStartupComplete();\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.switchSession(sessionPath, {\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session\");\n return result;\n } catch (error: unknown) {\n if (error instanceof MissingSessionCwdError) {\n const selectedCwd = await this.promptForMissingSessionCwd(error);\n if (!selectedCwd) {\n this.showStatus(\"Resume cancelled\");\n return { cancelled: true };\n }\n const result = await this.runtimeHost.switchSession(sessionPath, {\n cwdOverride: selectedCwd,\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session in current cwd\");\n return result;\n }\n return this.handleFatalRuntimeError(\"Failed to resume session\", error);\n }\n };\n"]}
@@ -1,6 +1,7 @@
1
1
  import { InteractiveModeBase } from "./interactive-mode-base.js";
2
2
  import { Loader, Spacer, APP_NAME, MissingSessionCwdError, SessionManager, keyText, SessionSelectorComponent, TreeSelectorComponent, TrustSelectorComponent, hasTrustRequiringProjectResources, ProjectTrustStore, theme } from "./interactive-mode-deps.js";
3
3
  InteractiveModeBase.prototype.handleCloneCommand = async function () {
4
+ await this.ensureDeferredStartupComplete();
4
5
  const leafId = this.sessionManager.getLeafId();
5
6
  if (!leafId) {
6
7
  this.showStatus("Nothing to clone yet");
@@ -65,7 +66,8 @@ InteractiveModeBase.prototype.showTrustSelector = function () {
65
66
  return { component: selector, focus: selector };
66
67
  });
67
68
  };
68
- InteractiveModeBase.prototype.showTreeSelector = function (initialSelectedId) {
69
+ InteractiveModeBase.prototype.showTreeSelector = async function (initialSelectedId) {
70
+ await this.ensureDeferredStartupComplete();
69
71
  const tree = this.sessionManager.getTree();
70
72
  const realLeafId = this.sessionManager.getLeafId();
71
73
  const initialFilterMode = this.settingsManager.getTreeFilterMode();
@@ -120,6 +122,7 @@ InteractiveModeBase.prototype.showTreeSelector = function (initialSelectedId) {
120
122
  this.ui.requestRender();
121
123
  }
122
124
  try {
125
+ await this.ensureDeferredStartupComplete();
123
126
  const result = await this.session.navigateTree(entryId, {
124
127
  summarize: wantsSummary,
125
128
  customInstructions,
@@ -190,6 +193,7 @@ InteractiveModeBase.prototype.showSessionSelector = function () {
190
193
  });
191
194
  };
192
195
  InteractiveModeBase.prototype.handleResumeSession = async function (sessionPath, options) {
196
+ await this.ensureDeferredStartupComplete();
193
197
  if (this.loadingAnimation) {
194
198
  this.loadingAnimation.stop();
195
199
  this.loadingAnimation = undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-routing.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-routing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAgC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,EAAE,cAAc,EAAE,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,iCAAiC,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAE3R,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,GAAG,KAAK;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;IAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;QACxC,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,wCAAwC,GAAG;IACrE,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;IACzC,IAAI,IAAI,CAAC,oBAAoB,KAAK,GAAG,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,IAAI,CAAC,iCAAiC,CAAC,GAAG,CAAC,EAAE,CAAC;QACxF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,WAAW,CACd,8CAA8C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACvG,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,iBAAiB,GAAG;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC7E,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,IAAI,sBAAsB,CAAC;YAC1C,GAAG;YACH,aAAa;YACb,cAAc,EAAE,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE;YACvD,QAAQ,EAAE,CAAC,SAAS,EAAE,EAAE;gBACtB,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBACtC,IAAI,EAAE,CAAC;gBACP,IAAI,CAAC,UAAU,CACb,yBAAyB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,aAAa,QAAQ,2BAA2B,CACrH,CAAC;YACJ,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACb,IAAI,EAAE,CAAC;gBACP,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;SACF,CAAC,CAAC;QACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,gBAAgB,GAAG,UAAoC,iBAA0B;IAC3G,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;IACnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC;IAEnE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,IAAI,qBAAqB,CACxC,IAAI,EACJ,UAAU,EACV,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EACrB,KAAK,EAAE,OAAO,EAAE,EAAE;YAChB,wDAAwD;YACxD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC3B,IAAI,EAAE,CAAC;gBACP,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,0BAA0B;YAC1B,IAAI,EAAE,CAAC,CAAC,uBAAuB;YAE/B,6DAA6D;YAC7D,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,IAAI,kBAAsC,CAAC;YAE3C,uFAAuF;YACvF,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,0BAA0B,EAAE,EAAE,CAAC;gBACvD,OAAO,IAAI,EAAE,CAAC;oBACZ,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,qBAAqB,CACpD,mBAAmB,EACnB,CAAC,YAAY,EAAE,WAAW,EAAE,8BAA8B,CAAC,CAC5D,CAAC;oBAEF,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;wBAChC,kEAAkE;wBAClE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;wBAC/B,OAAO;oBACT,CAAC;oBAED,YAAY,GAAG,aAAa,KAAK,YAAY,CAAC;oBAE9C,IAAI,aAAa,KAAK,8BAA8B,EAAE,CAAC;wBACrD,kBAAkB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CACjD,mCAAmC,CACpC,CAAC;wBACF,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;4BACrC,iDAAiD;4BACjD,SAAS;wBACX,CAAC;oBACH,CAAC;oBAED,8BAA8B;oBAC9B,MAAM;gBACR,CAAC;YACH,CAAC;YAED,kDAAkD;YAClD,IAAI,aAAiC,CAAC;YACtC,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;YAErD,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,GAAG,EAAE;oBACjC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBACpC,CAAC,CAAC;gBACF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3C,aAAa,GAAG,IAAI,MAAM,CACxB,IAAI,CAAC,EAAE,EACP,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EACxC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EACjC,0BAA0B,OAAO,CAAC,eAAe,CAAC,UAAU,CAC7D,CAAC;gBACF,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;gBAC7C,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE;oBACtD,SAAS,EAAE,YAAY;oBACvB,kBAAkB;iBACnB,CAAC,CAAC;gBAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,oEAAoE;oBACpE,IAAI,CAAC,UAAU,CAAC,gCAAgC,CAAC,CAAC;oBAClD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBACD,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;oBACrB,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;oBACxC,OAAO;gBACT,CAAC;gBAED,YAAY;gBACZ,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC7B,IAAI,MAAM,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;oBACvD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBACzC,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,6BAA6B,CAAC,CAAC;gBAC/C,KAAK,IAAI,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,SAAS,CACZ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,IAAI,aAAa,EAAE,CAAC;oBAClB,aAAa,CAAC,IAAI,EAAE,CAAC;oBACrB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;gBAC/B,CAAC;gBACD,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,gBAAgB,CAAC;YACjD,CAAC;QACH,CAAC,EACD,GAAG,EAAE;YACH,IAAI,EAAE,CAAC;YACP,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC,EACD,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACjB,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACtD,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC,EACD,iBAAiB,EACjB,iBAAiB,CAClB,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,mBAAmB,GAAG;IAChD,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,IAAI,wBAAwB,CAC3C,CAAC,UAAU,EAAE,EAAE,CACb,cAAc,CAAC,IAAI,CACjB,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAC5B,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,EACnC,UAAU,CACX,EACH,CAAC,UAAU,EAAE,EAAE,CACb,IAAI,CAAC,cAAc,CAAC,qBAAqB,EAAE;YACzC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;YACpC,CAAC,CAAC,cAAc,CAAC,OAAO,CACpB,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,EACnC,UAAU,CACX,EACP,KAAK,EAAE,WAAW,EAAE,EAAE;YACpB,IAAI,EAAE,CAAC;YACP,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAC9C,CAAC,EACD,GAAG,EAAE;YACH,IAAI,EAAE,CAAC;YACP,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC,EACD,GAAG,EAAE;YACH,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACvB,CAAC,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,EAC7B;YACE,aAAa,EAAE,KAAK,EAClB,eAAuB,EACvB,QAA4B,EAC5B,EAAE;gBACF,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACrC,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAClB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBACjD,GAAG,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YACD,cAAc,EAAE,IAAI;YACpB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,EAED,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,CACrC,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEJ,mBAAmB,CAAC,SAAS,CAAC,mBAAmB,GAAG,KAAK,WAAqC,WAAmB,EAAE,OAAiE;IAChL,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,WAAW,EAAE;YAC/D,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,0BAA0B,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC;SACzE,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;YAC5C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;gBACpC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC7B,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,WAAW,EAAE;gBAC/D,WAAW,EAAE,WAAW;gBACxB,WAAW,EAAE,OAAO,EAAE,WAAW;gBACjC,0BAA0B,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC;aACzE,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,gCAAgC,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,uBAAuB,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type ExtensionCommandContext, Loader, Spacer, APP_NAME, MissingSessionCwdError, SessionManager, keyText, SessionSelectorComponent, TreeSelectorComponent, TrustSelectorComponent, hasTrustRequiringProjectResources, ProjectTrustStore, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.handleCloneCommand = async function(this: InteractiveModeBase): Promise<void> {\n const leafId = this.sessionManager.getLeafId();\n if (!leafId) {\n this.showStatus(\"Nothing to clone yet\");\n return;\n }\n\n try {\n const result = await this.runtimeHost.fork(leafId, { position: \"at\" });\n if (result.cancelled) {\n this.ui.requestRender();\n return;\n }\n\n this.renderCurrentSessionState();\n this.editor.setText(\"\");\n this.showStatus(\"Cloned to new session\");\n } catch (error: unknown) {\n this.showError(error instanceof Error ? error.message : String(error));\n }\n };\n\nInteractiveModeBase.prototype.maybeSaveImplicitProjectTrustAfterReload = function(this: InteractiveModeBase): boolean {\n const cwd = this.sessionManager.getCwd();\n if (this.autoTrustOnReloadCwd !== cwd) {\n return false;\n }\n if (!this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(cwd)) {\n return false;\n }\n\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n try {\n if (trustStore.get(cwd) !== null) {\n this.autoTrustOnReloadCwd = undefined;\n return false;\n }\n trustStore.set(cwd, true);\n this.autoTrustOnReloadCwd = undefined;\n return true;\n } catch (error) {\n this.showWarning(\n `Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n };\n\nInteractiveModeBase.prototype.showTrustSelector = function(this: InteractiveModeBase): void {\n const cwd = this.sessionManager.getCwd();\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n const savedDecision = trustStore.getEntry(cwd);\n this.showSelector((done) => {\n const selector = new TrustSelectorComponent({\n cwd,\n savedDecision,\n projectTrusted: this.settingsManager.isProjectTrusted(),\n onSelect: (selection) => {\n trustStore.setMany(selection.updates);\n done();\n this.showStatus(\n `Saved trust decision: ${selection.trusted ? \"trusted\" : \"untrusted\"}. Restart ${APP_NAME} for this to take effect.`,\n );\n },\n onCancel: () => {\n done();\n this.ui.requestRender();\n },\n });\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showTreeSelector = function(this: InteractiveModeBase, initialSelectedId?: string): void {\n const tree = this.sessionManager.getTree();\n const realLeafId = this.sessionManager.getLeafId();\n const initialFilterMode = this.settingsManager.getTreeFilterMode();\n\n if (tree.length === 0) {\n this.showStatus(\"No entries in session\");\n return;\n }\n\n this.showSelector((done) => {\n const selector = new TreeSelectorComponent(\n tree,\n realLeafId,\n this.ui.terminal.rows,\n async (entryId) => {\n // Selecting the current leaf is a no-op (already there)\n if (entryId === realLeafId) {\n done();\n this.showStatus(\"Already at this point\");\n return;\n }\n\n // Ask about summarization\n done(); // Close selector first\n\n // Loop until user makes a complete choice or cancels to tree\n let wantsSummary = false;\n let customInstructions: string | undefined;\n\n // Check if we should skip the prompt (user preference to always default to no summary)\n if (!this.settingsManager.getBranchSummarySkipPrompt()) {\n while (true) {\n const summaryChoice = await this.showExtensionSelector(\n \"Summarize branch?\",\n [\"No summary\", \"Summarize\", \"Summarize with custom prompt\"],\n );\n\n if (summaryChoice === undefined) {\n // User pressed escape - re-show tree selector with same selection\n this.showTreeSelector(entryId);\n return;\n }\n\n wantsSummary = summaryChoice !== \"No summary\";\n\n if (summaryChoice === \"Summarize with custom prompt\") {\n customInstructions = await this.showExtensionEditor(\n \"Custom summarization instructions\",\n );\n if (customInstructions === undefined) {\n // User cancelled - loop back to summary selector\n continue;\n }\n }\n\n // User made a complete choice\n break;\n }\n }\n\n // Set up escape handler and loader if summarizing\n let summaryLoader: Loader | undefined;\n const originalOnEscape = this.defaultEditor.onEscape;\n\n if (wantsSummary) {\n this.defaultEditor.onEscape = () => {\n this.session.abortBranchSummary();\n };\n this.chatContainer.addChild(new Spacer(1));\n summaryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Summarizing branch... (${keyText(\"app.interrupt\")} Cancel)`,\n );\n this.statusContainer.addChild(summaryLoader);\n this.ui.requestRender();\n }\n\n try {\n const result = await this.session.navigateTree(entryId, {\n summarize: wantsSummary,\n customInstructions,\n });\n\n if (result.aborted) {\n // Summarization aborted - re-show tree selector with same selection\n this.showStatus(\"Branch summarization cancelled\");\n this.showTreeSelector(entryId);\n return;\n }\n if (result.cancelled) {\n this.showStatus(\"Navigation cancelled\");\n return;\n }\n\n // Update UI\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n } catch (error) {\n this.showError(\n error instanceof Error ? error.message : String(error),\n );\n } finally {\n if (summaryLoader) {\n summaryLoader.stop();\n this.statusContainer.clear();\n }\n this.defaultEditor.onEscape = originalOnEscape;\n }\n },\n () => {\n done();\n this.ui.requestRender();\n },\n (entryId, label) => {\n this.sessionManager.appendLabelChange(entryId, label);\n this.ui.requestRender();\n },\n initialSelectedId,\n initialFilterMode,\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showSessionSelector = function(this: InteractiveModeBase): void {\n this.showSelector((done) => {\n const selector = new SessionSelectorComponent(\n (onProgress) =>\n SessionManager.list(\n this.sessionManager.getCwd(),\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n (onProgress) =>\n this.sessionManager.usesDefaultSessionDir()\n ? SessionManager.listAll(onProgress)\n : SessionManager.listAll(\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n async (sessionPath) => {\n done();\n await this.handleResumeSession(sessionPath);\n },\n () => {\n done();\n this.ui.requestRender();\n },\n () => {\n void this.shutdown();\n },\n () => this.ui.requestRender(),\n {\n renameSession: async (\n sessionFilePath: string,\n nextName: string | undefined,\n ) => {\n const next = (nextName ?? \"\").trim();\n if (!next) return;\n const mgr = SessionManager.open(sessionFilePath);\n mgr.appendSessionInfo(next);\n },\n showRenameHint: true,\n keybindings: this.keybindings,\n },\n\n this.sessionManager.getSessionFile(),\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.handleResumeSession = async function(this: InteractiveModeBase, sessionPath: string, options?: Parameters<ExtensionCommandContext[\"switchSession\"]>[1]): Promise<{ cancelled: boolean }> {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.switchSession(sessionPath, {\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session\");\n return result;\n } catch (error: unknown) {\n if (error instanceof MissingSessionCwdError) {\n const selectedCwd = await this.promptForMissingSessionCwd(error);\n if (!selectedCwd) {\n this.showStatus(\"Resume cancelled\");\n return { cancelled: true };\n }\n const result = await this.runtimeHost.switchSession(sessionPath, {\n cwdOverride: selectedCwd,\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session in current cwd\");\n return result;\n }\n return this.handleFatalRuntimeError(\"Failed to resume session\", error);\n }\n };\n"]}
1
+ {"version":3,"file":"interactive-session-routing.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type ExtensionCommandContext, Loader, Spacer, APP_NAME, MissingSessionCwdError, SessionManager, keyText, SessionSelectorComponent, TreeSelectorComponent, TrustSelectorComponent, hasTrustRequiringProjectResources, ProjectTrustStore, theme } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.handleCloneCommand = async function(this: InteractiveModeBase): Promise<void> {\n await this.ensureDeferredStartupComplete();\n const leafId = this.sessionManager.getLeafId();\n if (!leafId) {\n this.showStatus(\"Nothing to clone yet\");\n return;\n }\n\n try {\n const result = await this.runtimeHost.fork(leafId, { position: \"at\" });\n if (result.cancelled) {\n this.ui.requestRender();\n return;\n }\n\n this.renderCurrentSessionState();\n this.editor.setText(\"\");\n this.showStatus(\"Cloned to new session\");\n } catch (error: unknown) {\n this.showError(error instanceof Error ? error.message : String(error));\n }\n };\n\nInteractiveModeBase.prototype.maybeSaveImplicitProjectTrustAfterReload = function(this: InteractiveModeBase): boolean {\n const cwd = this.sessionManager.getCwd();\n if (this.autoTrustOnReloadCwd !== cwd) {\n return false;\n }\n if (!this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(cwd)) {\n return false;\n }\n\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n try {\n if (trustStore.get(cwd) !== null) {\n this.autoTrustOnReloadCwd = undefined;\n return false;\n }\n trustStore.set(cwd, true);\n this.autoTrustOnReloadCwd = undefined;\n return true;\n } catch (error) {\n this.showWarning(\n `Could not save project trust after reload: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n };\n\nInteractiveModeBase.prototype.showTrustSelector = function(this: InteractiveModeBase): void {\n const cwd = this.sessionManager.getCwd();\n const trustStore = new ProjectTrustStore(this.runtimeHost.services.agentDir);\n const savedDecision = trustStore.getEntry(cwd);\n this.showSelector((done) => {\n const selector = new TrustSelectorComponent({\n cwd,\n savedDecision,\n projectTrusted: this.settingsManager.isProjectTrusted(),\n onSelect: (selection) => {\n trustStore.setMany(selection.updates);\n done();\n this.showStatus(\n `Saved trust decision: ${selection.trusted ? \"trusted\" : \"untrusted\"}. Restart ${APP_NAME} for this to take effect.`,\n );\n },\n onCancel: () => {\n done();\n this.ui.requestRender();\n },\n });\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showTreeSelector = async function(this: InteractiveModeBase, initialSelectedId?: string): Promise<void> {\n await this.ensureDeferredStartupComplete();\n const tree = this.sessionManager.getTree();\n const realLeafId = this.sessionManager.getLeafId();\n const initialFilterMode = this.settingsManager.getTreeFilterMode();\n\n if (tree.length === 0) {\n this.showStatus(\"No entries in session\");\n return;\n }\n\n this.showSelector((done) => {\n const selector = new TreeSelectorComponent(\n tree,\n realLeafId,\n this.ui.terminal.rows,\n async (entryId) => {\n // Selecting the current leaf is a no-op (already there)\n if (entryId === realLeafId) {\n done();\n this.showStatus(\"Already at this point\");\n return;\n }\n\n // Ask about summarization\n done(); // Close selector first\n\n // Loop until user makes a complete choice or cancels to tree\n let wantsSummary = false;\n let customInstructions: string | undefined;\n\n // Check if we should skip the prompt (user preference to always default to no summary)\n if (!this.settingsManager.getBranchSummarySkipPrompt()) {\n while (true) {\n const summaryChoice = await this.showExtensionSelector(\n \"Summarize branch?\",\n [\"No summary\", \"Summarize\", \"Summarize with custom prompt\"],\n );\n\n if (summaryChoice === undefined) {\n // User pressed escape - re-show tree selector with same selection\n this.showTreeSelector(entryId);\n return;\n }\n\n wantsSummary = summaryChoice !== \"No summary\";\n\n if (summaryChoice === \"Summarize with custom prompt\") {\n customInstructions = await this.showExtensionEditor(\n \"Custom summarization instructions\",\n );\n if (customInstructions === undefined) {\n // User cancelled - loop back to summary selector\n continue;\n }\n }\n\n // User made a complete choice\n break;\n }\n }\n\n // Set up escape handler and loader if summarizing\n let summaryLoader: Loader | undefined;\n const originalOnEscape = this.defaultEditor.onEscape;\n\n if (wantsSummary) {\n this.defaultEditor.onEscape = () => {\n this.session.abortBranchSummary();\n };\n this.chatContainer.addChild(new Spacer(1));\n summaryLoader = new Loader(\n this.ui,\n (spinner) => theme.fg(\"accent\", spinner),\n (text) => theme.fg(\"muted\", text),\n `Summarizing branch... (${keyText(\"app.interrupt\")} Cancel)`,\n );\n this.statusContainer.addChild(summaryLoader);\n this.ui.requestRender();\n }\n\n try {\n await this.ensureDeferredStartupComplete();\n const result = await this.session.navigateTree(entryId, {\n summarize: wantsSummary,\n customInstructions,\n });\n\n if (result.aborted) {\n // Summarization aborted - re-show tree selector with same selection\n this.showStatus(\"Branch summarization cancelled\");\n this.showTreeSelector(entryId);\n return;\n }\n if (result.cancelled) {\n this.showStatus(\"Navigation cancelled\");\n return;\n }\n\n // Update UI\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n } catch (error) {\n this.showError(\n error instanceof Error ? error.message : String(error),\n );\n } finally {\n if (summaryLoader) {\n summaryLoader.stop();\n this.statusContainer.clear();\n }\n this.defaultEditor.onEscape = originalOnEscape;\n }\n },\n () => {\n done();\n this.ui.requestRender();\n },\n (entryId, label) => {\n this.sessionManager.appendLabelChange(entryId, label);\n this.ui.requestRender();\n },\n initialSelectedId,\n initialFilterMode,\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.showSessionSelector = function(this: InteractiveModeBase): void {\n this.showSelector((done) => {\n const selector = new SessionSelectorComponent(\n (onProgress) =>\n SessionManager.list(\n this.sessionManager.getCwd(),\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n (onProgress) =>\n this.sessionManager.usesDefaultSessionDir()\n ? SessionManager.listAll(onProgress)\n : SessionManager.listAll(\n this.sessionManager.getSessionDir(),\n onProgress,\n ),\n async (sessionPath) => {\n done();\n await this.handleResumeSession(sessionPath);\n },\n () => {\n done();\n this.ui.requestRender();\n },\n () => {\n void this.shutdown();\n },\n () => this.ui.requestRender(),\n {\n renameSession: async (\n sessionFilePath: string,\n nextName: string | undefined,\n ) => {\n const next = (nextName ?? \"\").trim();\n if (!next) return;\n const mgr = SessionManager.open(sessionFilePath);\n mgr.appendSessionInfo(next);\n },\n showRenameHint: true,\n keybindings: this.keybindings,\n },\n\n this.sessionManager.getSessionFile(),\n );\n return { component: selector, focus: selector };\n });\n };\n\nInteractiveModeBase.prototype.handleResumeSession = async function(this: InteractiveModeBase, sessionPath: string, options?: Parameters<ExtensionCommandContext[\"switchSession\"]>[1]): Promise<{ cancelled: boolean }> {\n await this.ensureDeferredStartupComplete();\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.switchSession(sessionPath, {\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session\");\n return result;\n } catch (error: unknown) {\n if (error instanceof MissingSessionCwdError) {\n const selectedCwd = await this.promptForMissingSessionCwd(error);\n if (!selectedCwd) {\n this.showStatus(\"Resume cancelled\");\n return { cancelled: true };\n }\n const result = await this.runtimeHost.switchSession(sessionPath, {\n cwdOverride: selectedCwd,\n withSession: options?.withSession,\n projectTrustContextFactory: (cwd) => this.createProjectTrustContext(cwd),\n });\n if (result.cancelled) {\n return result;\n }\n this.renderCurrentSessionState();\n if (this.firstRunNoticeVisible) {\n this.clearFirstRunOnboardingUi();\n }\n this.showStatus(\"Resumed session in current cwd\");\n return result;\n }\n return this.handleFatalRuntimeError(\"Failed to resume session\", error);\n }\n };\n"]}