@bastani/atomic 0.9.5-alpha.8 → 0.9.5

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 (530) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  4. package/dist/builtin/cursor/package.json +3 -3
  5. package/dist/builtin/cursor/src/model-mapper.ts +6 -3
  6. package/dist/builtin/intercom/CHANGELOG.md +37 -0
  7. package/dist/builtin/intercom/README.md +4 -2
  8. package/dist/builtin/intercom/broker/broker.ts +6 -114
  9. package/dist/builtin/intercom/broker/client.ts +29 -54
  10. package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
  11. package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
  12. package/dist/builtin/intercom/broker/send-handler.ts +106 -0
  13. package/dist/builtin/intercom/broker/send-signature.ts +37 -0
  14. package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
  15. package/dist/builtin/intercom/index-heavy.ts +49 -53
  16. package/dist/builtin/intercom/index.ts +278 -262
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
  18. package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
  19. package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
  20. package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
  21. package/dist/builtin/intercom/lifecycle.ts +37 -20
  22. package/dist/builtin/intercom/package.json +3 -6
  23. package/dist/builtin/intercom/reply-routing.ts +17 -0
  24. package/dist/builtin/intercom/subagent-relay.ts +58 -12
  25. package/dist/builtin/intercom/types.ts +3 -3
  26. package/dist/builtin/mcp/CHANGELOG.md +38 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +10 -6
  29. package/dist/builtin/mcp/apps-cancellation.ts +32 -0
  30. package/dist/builtin/mcp/call-tool-result.ts +9 -0
  31. package/dist/builtin/mcp/caller-wait.ts +50 -0
  32. package/dist/builtin/mcp/command-registration.ts +82 -0
  33. package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
  34. package/dist/builtin/mcp/direct-tools.ts +40 -255
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +274 -239
  37. package/dist/builtin/mcp/init.ts +96 -126
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
  39. package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
  40. package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
  41. package/dist/builtin/mcp/metadata-hydration.ts +52 -0
  42. package/dist/builtin/mcp/package.json +3 -3
  43. package/dist/builtin/mcp/proxy-auth.ts +4 -4
  44. package/dist/builtin/mcp/proxy-call.ts +111 -40
  45. package/dist/builtin/mcp/proxy-connect.ts +35 -15
  46. package/dist/builtin/mcp/proxy-info-modes.ts +106 -23
  47. package/dist/builtin/mcp/proxy-modes.ts +3 -3
  48. package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
  49. package/dist/builtin/mcp/startup-warmup.ts +98 -0
  50. package/dist/builtin/mcp/state-lease.ts +12 -0
  51. package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
  52. package/dist/builtin/mcp/ui-server.ts +8 -8
  53. package/dist/builtin/mcp/ui-session.ts +9 -18
  54. package/dist/builtin/subagents/CHANGELOG.md +78 -0
  55. package/dist/builtin/subagents/README.md +30 -29
  56. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  61. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  62. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  63. package/dist/builtin/subagents/agents/debugger.md +2 -2
  64. package/dist/builtin/subagents/agents/worker.md +2 -2
  65. package/dist/builtin/subagents/package.json +5 -5
  66. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  67. package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
  68. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  69. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  70. package/dist/builtin/subagents/src/extension/index.ts +289 -320
  71. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
  72. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  73. package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
  74. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  75. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  76. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  77. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  78. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +26 -20
  79. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  80. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  81. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  82. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  83. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  84. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  85. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  86. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  87. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  88. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  89. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  90. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  91. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  92. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +177 -233
  93. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  94. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  95. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +29 -15
  96. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  100. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  101. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  102. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  103. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  104. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +63 -46
  105. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  106. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  107. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  116. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  117. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  118. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  119. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  120. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +55 -12
  121. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  122. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  123. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  124. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  125. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  126. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  127. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  128. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  129. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  130. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  131. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  132. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  133. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  134. package/dist/builtin/subagents/src/tui/render-widget.ts +157 -89
  135. package/dist/builtin/web-access/CHANGELOG.md +28 -0
  136. package/dist/builtin/web-access/README.md +4 -0
  137. package/dist/builtin/web-access/content-tools.ts +8 -3
  138. package/dist/builtin/web-access/index-heavy.ts +1 -1
  139. package/dist/builtin/web-access/index.ts +190 -46
  140. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  141. package/dist/builtin/web-access/package.json +2 -2
  142. package/dist/builtin/web-access/result-renderers.ts +1 -1
  143. package/dist/builtin/web-access/summary-review.ts +1 -1
  144. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  145. package/dist/builtin/web-access/web-search-return.ts +7 -0
  146. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  147. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  148. package/dist/builtin/workflows/CHANGELOG.md +86 -0
  149. package/dist/builtin/workflows/README.md +5 -5
  150. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  151. package/dist/builtin/workflows/builtin/goal-runner.ts +86 -27
  152. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  153. package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
  154. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  155. package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
  156. package/dist/builtin/workflows/package.json +2 -2
  157. package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
  158. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
  159. package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
  160. package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
  161. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
  162. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
  163. package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
  164. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
  165. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
  166. package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
  167. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
  168. package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
  169. package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
  170. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
  171. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
  172. package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
  173. package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
  174. package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
  175. package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
  176. package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
  177. package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
  178. package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
  179. package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
  180. package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
  181. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
  182. package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
  183. package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
  184. package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
  185. package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
  186. package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
  187. package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
  188. package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
  189. package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
  190. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
  191. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
  192. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
  193. package/dist/builtin/workflows/src/durable/backend.ts +12 -0
  194. package/dist/builtin/workflows/src/durable/dbos-backend.ts +17 -1
  195. package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
  196. package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
  197. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  198. package/dist/builtin/workflows/src/durable/types.ts +16 -0
  199. package/dist/builtin/workflows/src/engine/primitives/task.ts +3 -1
  200. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
  201. package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
  202. package/dist/builtin/workflows/src/engine/run.ts +20 -19
  203. package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
  204. package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
  205. package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
  206. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
  207. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
  208. package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
  209. package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
  210. package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
  211. package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
  212. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
  213. package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
  214. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  215. package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
  216. package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
  217. package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
  218. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
  219. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -1
  220. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +3 -2
  221. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  222. package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
  223. package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
  224. package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
  225. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  226. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  227. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  228. package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
  229. package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
  230. package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
  231. package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
  232. package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
  233. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  234. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  235. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  236. package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
  237. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
  238. package/dist/cli/args.d.ts.map +1 -1
  239. package/dist/cli/args.js +2 -2
  240. package/dist/cli/args.js.map +1 -1
  241. package/dist/core/agent-session-auto-compaction.d.ts +23 -3
  242. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  243. package/dist/core/agent-session-auto-compaction.js +129 -17
  244. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  245. package/dist/core/agent-session-events.d.ts.map +1 -1
  246. package/dist/core/agent-session-events.js +9 -1
  247. package/dist/core/agent-session-events.js.map +1 -1
  248. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  249. package/dist/core/agent-session-message-queue.js +1 -1
  250. package/dist/core/agent-session-message-queue.js.map +1 -1
  251. package/dist/core/agent-session-methods.d.ts +6 -3
  252. package/dist/core/agent-session-methods.d.ts.map +1 -1
  253. package/dist/core/agent-session-methods.js.map +1 -1
  254. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  255. package/dist/core/agent-session-prompt.js +2 -2
  256. package/dist/core/agent-session-prompt.js.map +1 -1
  257. package/dist/core/agent-session-retry.d.ts.map +1 -1
  258. package/dist/core/agent-session-retry.js +1 -1
  259. package/dist/core/agent-session-retry.js.map +1 -1
  260. package/dist/core/agent-session-services.d.ts.map +1 -1
  261. package/dist/core/agent-session-services.js +3 -2
  262. package/dist/core/agent-session-services.js.map +1 -1
  263. package/dist/core/agent-session-types.d.ts.map +1 -1
  264. package/dist/core/agent-session-types.js +1 -1
  265. package/dist/core/agent-session-types.js.map +1 -1
  266. package/dist/core/agent-session.d.ts +4 -2
  267. package/dist/core/agent-session.d.ts.map +1 -1
  268. package/dist/core/agent-session.js +4 -2
  269. package/dist/core/agent-session.js.map +1 -1
  270. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  271. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  272. package/dist/core/anthropic-thinking-guard.js +42 -32
  273. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  274. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  275. package/dist/core/atomic-guide-command.js +15 -15
  276. package/dist/core/atomic-guide-command.js.map +1 -1
  277. package/dist/core/auth-storage.d.ts.map +1 -1
  278. package/dist/core/auth-storage.js +14 -9
  279. package/dist/core/auth-storage.js.map +1 -1
  280. package/dist/core/compaction/compaction.d.ts +2 -0
  281. package/dist/core/compaction/compaction.d.ts.map +1 -1
  282. package/dist/core/compaction/compaction.js +79 -46
  283. package/dist/core/compaction/compaction.js.map +1 -1
  284. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  285. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  286. package/dist/core/compaction/context-assistant-turns.js +87 -0
  287. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  288. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  289. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  290. package/dist/core/compaction/context-compaction-critical.js +2 -2
  291. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  292. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  293. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  294. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  295. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  296. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  297. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  298. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  299. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  300. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  301. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  302. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  303. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  304. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  305. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  306. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  307. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  308. package/dist/core/compaction/context-deletion-application.js +17 -15
  309. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  310. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  311. package/dist/core/compaction/context-deletion-store.js +1 -1
  312. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  313. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  314. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  315. package/dist/core/compaction/context-deletion-targets.js +36 -31
  316. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  317. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  318. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  319. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  320. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  321. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  322. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  323. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  324. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  325. package/dist/core/copilot-model-synthesis.js +3 -1
  326. package/dist/core/copilot-model-synthesis.js.map +1 -1
  327. package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
  328. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  329. package/dist/core/extensions/loader-virtual-modules.js +2 -1
  330. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  331. package/dist/core/extensions/provider-types.d.ts +2 -7
  332. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  333. package/dist/core/extensions/provider-types.js.map +1 -1
  334. package/dist/core/footer-data-provider.d.ts +6 -0
  335. package/dist/core/footer-data-provider.d.ts.map +1 -1
  336. package/dist/core/footer-data-provider.js +72 -29
  337. package/dist/core/footer-data-provider.js.map +1 -1
  338. package/dist/core/messages.d.ts +9 -0
  339. package/dist/core/messages.d.ts.map +1 -1
  340. package/dist/core/messages.js +100 -18
  341. package/dist/core/messages.js.map +1 -1
  342. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  343. package/dist/core/model-registry-builtins.js +5 -0
  344. package/dist/core/model-registry-builtins.js.map +1 -1
  345. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  346. package/dist/core/model-registry-custom-loader.js +49 -8
  347. package/dist/core/model-registry-custom-loader.js.map +1 -1
  348. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  349. package/dist/core/model-registry-dynamic.js +11 -5
  350. package/dist/core/model-registry-dynamic.js.map +1 -1
  351. package/dist/core/model-registry-loader.d.ts.map +1 -1
  352. package/dist/core/model-registry-loader.js +8 -0
  353. package/dist/core/model-registry-loader.js.map +1 -1
  354. package/dist/core/model-registry-schemas.d.ts +93 -8
  355. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  356. package/dist/core/model-registry-schemas.js +24 -12
  357. package/dist/core/model-registry-schemas.js.map +1 -1
  358. package/dist/core/model-registry-types.d.ts +7 -6
  359. package/dist/core/model-registry-types.d.ts.map +1 -1
  360. package/dist/core/model-registry-types.js.map +1 -1
  361. package/dist/core/model-registry.d.ts +5 -0
  362. package/dist/core/model-registry.d.ts.map +1 -1
  363. package/dist/core/model-registry.js +23 -0
  364. package/dist/core/model-registry.js.map +1 -1
  365. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  366. package/dist/core/model-resolver-cli.js +33 -5
  367. package/dist/core/model-resolver-cli.js.map +1 -1
  368. package/dist/core/model-resolver-initial.d.ts +6 -1
  369. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  370. package/dist/core/model-resolver-initial.js +12 -7
  371. package/dist/core/model-resolver-initial.js.map +1 -1
  372. package/dist/core/model-resolver.d.ts +1 -1
  373. package/dist/core/model-resolver.d.ts.map +1 -1
  374. package/dist/core/model-resolver.js +1 -1
  375. package/dist/core/model-resolver.js.map +1 -1
  376. package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
  377. package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
  378. package/dist/core/openai-responses-payload-sanitizer.js +24 -9
  379. package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
  380. package/dist/core/resource-loader-context-files.d.ts +1 -0
  381. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  382. package/dist/core/resource-loader-context-files.js +13 -10
  383. package/dist/core/resource-loader-context-files.js.map +1 -1
  384. package/dist/core/sdk.d.ts.map +1 -1
  385. package/dist/core/sdk.js +2 -2
  386. package/dist/core/sdk.js.map +1 -1
  387. package/dist/core/session-entry-normalization.d.ts +7 -0
  388. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  389. package/dist/core/session-entry-normalization.js +14 -0
  390. package/dist/core/session-entry-normalization.js.map +1 -0
  391. package/dist/core/session-manager-core.d.ts.map +1 -1
  392. package/dist/core/session-manager-core.js +1 -0
  393. package/dist/core/session-manager-core.js.map +1 -1
  394. package/dist/core/session-manager-history.d.ts +2 -2
  395. package/dist/core/session-manager-history.d.ts.map +1 -1
  396. package/dist/core/session-manager-history.js +127 -108
  397. package/dist/core/session-manager-history.js.map +1 -1
  398. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  399. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  400. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  401. package/dist/core/settings-types.d.ts +1 -1
  402. package/dist/core/settings-types.d.ts.map +1 -1
  403. package/dist/core/settings-types.js.map +1 -1
  404. package/dist/core/slash-commands.d.ts +2 -0
  405. package/dist/core/slash-commands.d.ts.map +1 -1
  406. package/dist/core/slash-commands.js +141 -0
  407. package/dist/core/slash-commands.js.map +1 -1
  408. package/dist/core/tools/bash.d.ts.map +1 -1
  409. package/dist/core/tools/bash.js +11 -8
  410. package/dist/core/tools/bash.js.map +1 -1
  411. package/dist/index.d.ts +1 -0
  412. package/dist/index.d.ts.map +1 -1
  413. package/dist/index.js +1 -0
  414. package/dist/index.js.map +1 -1
  415. package/dist/main-deferred-startup.d.ts.map +1 -1
  416. package/dist/main-deferred-startup.js +2 -2
  417. package/dist/main-deferred-startup.js.map +1 -1
  418. package/dist/main-early-input.d.ts.map +1 -1
  419. package/dist/main-early-input.js +7 -0
  420. package/dist/main-early-input.js.map +1 -1
  421. package/dist/main-session.d.ts.map +1 -1
  422. package/dist/main-session.js +1 -0
  423. package/dist/main-session.js.map +1 -1
  424. package/dist/main.d.ts.map +1 -1
  425. package/dist/main.js +1 -1
  426. package/dist/main.js.map +1 -1
  427. package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
  428. package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
  429. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  430. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  431. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  432. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  433. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  434. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  435. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  436. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  437. package/dist/modes/interactive/interactive-agent-events.js +3 -1
  438. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  439. package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  440. package/dist/modes/interactive/interactive-autocomplete.js +21 -9
  441. package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  442. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  443. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  444. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  445. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  446. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  447. package/dist/modes/interactive/interactive-deferred-startup.js +43 -30
  448. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  449. package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
  450. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
  451. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  452. package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
  453. package/dist/modes/interactive/interactive-input-handling.js +41 -6
  454. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  455. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  456. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  457. package/dist/modes/interactive/interactive-mode-base.js +3 -0
  458. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  459. package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
  460. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  461. package/dist/modes/interactive/interactive-mode-deps.js +2 -2
  462. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  463. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
  464. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  465. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  466. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  467. package/dist/modes/interactive/interactive-model-routing.js +11 -4
  468. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  469. package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
  470. package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
  471. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  472. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  473. package/dist/modes/interactive/interactive-render-chat.js +15 -1
  474. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  475. package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
  476. package/dist/modes/interactive/interactive-session-routing.js +5 -1
  477. package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
  478. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-startup.js +20 -21
  480. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  481. package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
  482. package/dist/modes/interactive/theme/global-theme.js +26 -2
  483. package/dist/modes/interactive/theme/global-theme.js.map +1 -1
  484. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  485. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  486. package/dist/modes/interactive/theme/theme-class.js +2 -0
  487. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  488. package/dist/utils/clipboard-image.d.ts.map +1 -1
  489. package/dist/utils/clipboard-image.js +3 -0
  490. package/dist/utils/clipboard-image.js.map +1 -1
  491. package/dist/utils/fs-watch.d.ts +24 -1
  492. package/dist/utils/fs-watch.d.ts.map +1 -1
  493. package/dist/utils/fs-watch.js +60 -5
  494. package/dist/utils/fs-watch.js.map +1 -1
  495. package/docs/changelog.mdx +19 -0
  496. package/docs/compaction.md +60 -49
  497. package/docs/custom-provider.md +18 -5
  498. package/docs/development.md +4 -0
  499. package/docs/extensions.md +11 -2
  500. package/docs/json.md +1 -1
  501. package/docs/models.md +69 -10
  502. package/docs/providers.md +1 -1
  503. package/docs/quickstart.md +12 -8
  504. package/docs/rpc.md +2 -2
  505. package/docs/sdk.md +1 -1
  506. package/docs/settings.md +4 -4
  507. package/docs/subagents.md +40 -5
  508. package/docs/tools.md +1 -1
  509. package/docs/usage.md +4 -2
  510. package/docs/windows.md +4 -0
  511. package/docs/workflows.md +33 -48
  512. package/examples/extensions/preset.ts +2 -2
  513. package/examples/extensions/subagent/README.md +2 -2
  514. package/examples/extensions/subagent/index.ts +1 -2
  515. package/examples/extensions/subagent/schemas.ts +4 -1
  516. package/examples/sdk/12-full-control.ts +1 -1
  517. package/npm-shrinkwrap.json +48 -51
  518. package/package.json +7 -7
  519. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  520. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  521. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  522. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  523. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  524. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  525. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  526. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  527. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  528. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  529. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  530. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -7,28 +7,28 @@ import { APP_NAME, getEnvValue } from "@bastani/atomic";
7
7
  import { type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@bastani/atomic";
8
8
  import { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from "@earendil-works/pi-tui";
9
9
  import { discoverAgents } from "../agents/agents.ts";
10
- import { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from "../shared/artifacts.ts";
10
+ import { getArtifactsDir } from "../shared/artifacts.ts";
11
11
  import { resolveCurrentSessionId } from "../shared/session-identity.ts";
12
- import { cleanupOldChainDirs } from "../shared/settings.ts";
13
12
  import { advanceResultPulseFrame, renderLiveSubagentResult, renderSubagentResult, stopResultAnimations, stopWidgetAnimation, type SubagentResultRenderState } from "../tui/render.ts";
14
13
  import { SubagentParams } from "./schemas.ts";
15
14
  import { createSubagentExecutor, type SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
16
15
  import { createAsyncJobTracker } from "../runs/background/async-job-tracker.ts";
17
- import { createResultWatcher } from "../runs/background/result-watcher.ts";
18
16
  import { registerSlashCommands } from "../slash/slash-commands.ts";
19
17
  import { registerPromptTemplateDelegationBridge } from "../slash/prompt-template-bridge.ts";
20
18
  import { registerSlashSubagentBridge } from "../slash/slash-bridge.ts";
21
19
  import { clearSlashSnapshots, getSlashRenderableSnapshot, resolveSlashMessageDetails, restoreSlashFinalSnapshots, type SlashMessageDetails } from "../slash/slash-live-state.ts";
22
- import { inspectSubagentStatus } from "../runs/background/run-status.ts";
23
20
  import registerSubagentNotify, { type SubagentNotifyDetails } from "../runs/background/notify.ts";
24
- import { cleanupOldNestedRuntimeDirs } from "../runs/shared/nested-events.ts";
25
21
  import { SUBAGENT_CHILD_ENV, SUBAGENT_FANOUT_CHILD_ENV } from "../runs/shared/pi-args.ts";
26
22
  import registerFanoutChildSubagentExtension from "./fanout-child.ts";
27
23
  import { formatDuration, shortenPath } from "../shared/formatters.ts";
28
24
  import { loadConfig } from "./config.ts";
29
25
  import { DEFAULT_PROMPT_GUIDANCE } from "./prompt-guidance.ts";
30
- import { type Details, type SubagentState, ASYNC_DIR, DEFAULT_ARTIFACT_CONFIG, RESULTS_DIR, SLASH_RESULT_TYPE, SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_CONTROL_EVENT, WIDGET_KEY } from "../shared/types.ts";
26
+ import { SUBAGENT_TOOL_DESCRIPTION } from "./tool-description.ts";
27
+ export { SUBAGENT_TOOL_DESCRIPTION } from "./tool-description.ts";
28
+ import { type Details, type SubagentState, ASYNC_DIR, DEFAULT_ARTIFACT_CONFIG, RESULTS_DIR, SLASH_RESULT_TYPE, SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_CONTROL_EVENT } from "../shared/types.ts";
31
29
  import { clearPendingForegroundControlNotices, formatSubagentControlNotice, handleSubagentControlNotice, SUBAGENT_CONTROL_MESSAGE_TYPE, type SubagentControlMessageDetails } from "./control-notices.ts";
30
+ import { createSubagentStartupMaintenance } from "./startup-maintenance.ts";
31
+ import { beginApiLifecycle, getApiScopedSet } from "./api-lifecycle.ts";
32
32
  export { loadConfig } from "./config.ts";
33
33
  function getSubagentSessionRoot(parentSessionFile: string | null): string {
34
34
  if (parentSessionFile) {
@@ -62,9 +62,6 @@ function isSlashResultRunning(result: { details?: Details }): boolean {
62
62
  function isSlashResultError(result: { details?: Details }): boolean {
63
63
  return result.details?.results.some((entry) => entry.exitCode !== 0 && entry.progress?.status !== "running") || false;
64
64
  }
65
- function isStaleExtensionContextError(error: unknown): boolean {
66
- return error instanceof Error && error.message.includes("Extension context no longer active");
67
- }
68
65
  type SubagentToolRenderState = SubagentResultRenderState;
69
66
  function rebuildSlashResultContainer(
70
67
  container: Container,
@@ -83,13 +80,14 @@ function createSlashResultComponent(
83
80
  details: SlashMessageDetails,
84
81
  options: { expanded: boolean },
85
82
  theme: ExtensionContext["ui"]["theme"],
83
+ owner: ExtensionAPI,
86
84
  ): Container {
87
85
  const container = new Container();
88
86
  let lastVersion = -1;
89
87
  let lastSnapshotNow = 0;
90
88
  let pulseFrame = 0;
91
89
  container.render = (width: number): string[] => {
92
- const snapshot = getSlashRenderableSnapshot(details);
90
+ const snapshot = getSlashRenderableSnapshot(details, owner);
93
91
  if (snapshot.version !== lastVersion) {
94
92
  lastVersion = snapshot.version;
95
93
  lastSnapshotNow = Date.now();
@@ -155,338 +153,309 @@ class SubagentControlNoticeComponent implements Component {
155
153
  return lines;
156
154
  }
157
155
  }
156
+
158
157
  export default function registerSubagentExtension(pi: ExtensionAPI): void {
159
158
  if (getEnvValue(SUBAGENT_CHILD_ENV) === "1") {
160
159
  if (getEnvValue(SUBAGENT_FANOUT_CHILD_ENV) === "1") registerFanoutChildSubagentExtension(pi);
161
160
  return;
162
161
  }
163
- const globalStore = globalThis as Record<string, unknown>;
164
- const runtimeCleanupStoreKey = "__piSubagentRuntimeCleanup";
165
- const previousRuntimeCleanup = globalStore[runtimeCleanupStoreKey];
166
- if (typeof previousRuntimeCleanup === "function") {
167
- try {
168
- previousRuntimeCleanup();
169
- } catch {
170
- }
171
- }
172
- ensureAccessibleDir(RESULTS_DIR);
173
- ensureAccessibleDir(ASYNC_DIR);
174
- cleanupOldChainDirs();
175
- const config = loadConfig();
176
- const asyncByDefault = config.asyncByDefault === true;
177
- const tempArtifactsDir = getArtifactsDir(null);
178
- cleanupAllArtifactDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);
179
- cleanupOldNestedRuntimeDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);
180
- const state: SubagentState = {
181
- baseCwd: "",
182
- currentSessionId: null,
183
- asyncJobs: new Map(),
184
- subagentInProgress: false,
185
- foregroundRuns: new Map(),
186
- foregroundControls: new Map(),
187
- lastForegroundControlId: null,
188
- pendingForegroundControlNotices: new Map(),
189
- cleanupTimers: new Map(),
190
- lastUiContext: null,
191
- poller: null,
192
- completionSeen: new Map(),
193
- watcher: null,
194
- watcherRestartTimer: null,
195
- resultFileCoalescer: {
196
- schedule: () => false,
197
- clear: () => {},
198
- },
199
- };
200
- const { startResultWatcher, primeExistingResults, stopResultWatcher } = createResultWatcher(
201
- pi,
202
- state,
203
- RESULTS_DIR,
204
- 10 * 60 * 1000,
205
- );
206
- startResultWatcher();
207
- primeExistingResults();
208
- const runtimeCleanup = () => {
209
- stopResultWatcher();
210
- stopWidgetAnimation();
211
- stopResultAnimations();
212
- clearPendingForegroundControlNotices(state);
213
- if (state.poller) {
214
- clearInterval(state.poller);
215
- state.poller = null;
216
- }
217
- };
218
- globalStore[runtimeCleanupStoreKey] = runtimeCleanup;
219
- const { ensurePoller, handleStarted, handleComplete, resetJobs, hydrateActiveJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR);
220
- const executor = createSubagentExecutor({
221
- pi,
222
- state,
223
- config,
224
- asyncByDefault,
225
- tempArtifactsDir,
226
- getSubagentSessionRoot,
227
- expandTilde,
228
- discoverAgents,
229
- });
230
- pi.registerMessageRenderer<SlashMessageDetails>(SLASH_RESULT_TYPE, (message, options, theme) => {
231
- const details = resolveSlashMessageDetails(message.details);
232
- if (!details) return undefined;
233
- return createSlashResultComponent(details, options, theme);
234
- });
235
- pi.registerMessageRenderer<SubagentNotifyDetails>("subagent-notify", (message, options, theme) => {
236
- const content = typeof message.content === "string" ? message.content : "";
237
- const details = (message.details as SubagentNotifyDetails | undefined) ?? parseSubagentNotifyContent(content);
238
- if (!details) return new Text(content, 0, 0);
239
- const icon = details.status === "completed"
240
- ? theme.fg("success", "✓")
241
- : details.status === "paused"
242
- ? theme.fg("warning", "■")
243
- : theme.fg("error", "✗");
244
- const parts: string[] = [];
245
- if (details.taskInfo) parts.push(details.taskInfo);
246
- if (details.durationMs !== undefined) parts.push(formatDuration(details.durationMs));
247
- let text = `${icon} ${theme.bold(details.agent)} ${theme.fg("dim", details.status)}`;
248
- if (parts.length > 0) text += ` ${theme.fg("dim", "·")} ${parts.map((part) => theme.fg("dim", part)).join(` ${theme.fg("dim", "·")} `)}`;
249
- const trimmedPreview = details.resultPreview.trim();
250
- const previewLines = options.expanded
251
- ? trimmedPreview.split("\n").filter((line) => line.trim())
252
- : [trimmedPreview.split("\n", 1)[0] ?? ""].filter((line) => line.trim());
253
- for (const line of previewLines.length > 0 ? previewLines : ["(no output)"]) {
254
- text += `\n ${theme.fg("dim", `⎿ ${line}`)}`;
255
- }
256
- if (!options.expanded && trimmedPreview.includes("\n")) {
257
- text += `\n ${theme.fg("dim", "ctrl+o full notification")}`;
258
- }
259
- if (details.sessionLabel && details.sessionValue) {
260
- text += `\n ${theme.fg("muted", `${details.sessionLabel}: ${shortenPath(details.sessionValue)}`)}`;
261
- }
262
- return new Text(text, 0, 0);
263
- });
264
- pi.registerMessageRenderer<SubagentControlMessageDetails>(SUBAGENT_CONTROL_MESSAGE_TYPE, (message, _options, theme) => {
265
- const details = message.details as SubagentControlMessageDetails | undefined;
266
- if (!details?.event) return undefined;
267
- const content = typeof message.content === "string" ? message.content : undefined;
268
- return new SubagentControlNoticeComponent({ ...details, noticeText: formatSubagentControlNotice(details, content) }, theme);
269
- });
270
- const executeSubagentCollapsed = (id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((result: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => {
271
- if (ctx.hasUI) {
272
- state.lastUiContext = ctx;
273
- ctx.ui.setToolsExpanded(false);
274
- }
275
- return executor.execute(id, params, signal, onUpdate, ctx);
276
- };
277
- const slashBridge = registerSlashSubagentBridge({
278
- events: pi.events,
279
- getContext: () => state.lastUiContext,
280
- execute: (id, params, signal, onUpdate, ctx) =>
281
- executeSubagentCollapsed(id, params, signal, onUpdate, ctx),
282
- });
283
- const promptTemplateBridge = registerPromptTemplateDelegationBridge({
284
- events: pi.events,
285
- getContext: () => state.lastUiContext,
286
- execute: async (requestId, request, signal, ctx, onUpdate) => {
287
- if (request.tasks && request.tasks.length > 0) {
162
+ const lifecycle = beginApiLifecycle(pi);
163
+ const registrationFailureCleanups: Array<() => void> = [];
164
+ let runtimeCleanupInstalled = false;
165
+ try {
166
+ ensureAccessibleDir(RESULTS_DIR);
167
+ ensureAccessibleDir(ASYNC_DIR);
168
+ const config = loadConfig();
169
+ const asyncByDefault = config.asyncByDefault === true;
170
+ const tempArtifactsDir = getArtifactsDir(null);
171
+ const state: SubagentState = {
172
+ baseCwd: "",
173
+ currentSessionId: null,
174
+ asyncJobs: new Map(),
175
+ subagentInProgress: false,
176
+ foregroundRuns: new Map(),
177
+ foregroundControls: new Map(),
178
+ lastForegroundControlId: null,
179
+ pendingForegroundControlNotices: new Map(),
180
+ cleanupTimers: new Map(),
181
+ lastUiContext: null,
182
+ poller: null,
183
+ completionSeen: new Map(),
184
+ watcher: null,
185
+ watcherRestartTimer: null,
186
+ resultFileCoalescer: {
187
+ schedule: () => false,
188
+ clear: () => {},
189
+ },
190
+ };
191
+ const maintenance = createSubagentStartupMaintenance(pi, state, {
192
+ resultsDir: RESULTS_DIR,
193
+ artifactCleanupDays: DEFAULT_ARTIFACT_CONFIG.cleanupDays,
194
+ resultTtlMs: 10 * 60 * 1000,
195
+ });
196
+ maintenance.scheduleStartupCleanup();
197
+ registrationFailureCleanups.push(() => maintenance.stop());
198
+ maintenance.startResultWatcherDeferred();
199
+ maintenance.primeExistingResultsDeferred();
200
+ const { ensurePoller, handleStarted, handleComplete, resetJobs, hydrateActiveJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR);
201
+ const executor = createSubagentExecutor({
202
+ pi,
203
+ state,
204
+ config,
205
+ asyncByDefault,
206
+ tempArtifactsDir,
207
+ getSubagentSessionRoot,
208
+ expandTilde,
209
+ discoverAgents,
210
+ });
211
+ pi.registerMessageRenderer<SlashMessageDetails>(SLASH_RESULT_TYPE, (message, options, theme) => {
212
+ const details = resolveSlashMessageDetails(message.details);
213
+ if (!details) return undefined;
214
+ return createSlashResultComponent(details, options, theme, pi);
215
+ });
216
+ pi.registerMessageRenderer<SubagentNotifyDetails>("subagent-notify", (message, options, theme) => {
217
+ const content = typeof message.content === "string" ? message.content : "";
218
+ const details = (message.details as SubagentNotifyDetails | undefined) ?? parseSubagentNotifyContent(content);
219
+ if (!details) return new Text(content, 0, 0);
220
+ const icon = details.status === "completed"
221
+ ? theme.fg("success", "✓")
222
+ : details.status === "paused"
223
+ ? theme.fg("warning", "■")
224
+ : theme.fg("error", "✗");
225
+ const parts: string[] = [];
226
+ if (details.taskInfo) parts.push(details.taskInfo);
227
+ if (details.durationMs !== undefined) parts.push(formatDuration(details.durationMs));
228
+ let text = `${icon} ${theme.bold(details.agent)} ${theme.fg("dim", details.status)}`;
229
+ if (parts.length > 0) text += ` ${theme.fg("dim", "·")} ${parts.map((part) => theme.fg("dim", part)).join(` ${theme.fg("dim", "·")} `)}`;
230
+ const trimmedPreview = details.resultPreview.trim();
231
+ const previewLines = options.expanded
232
+ ? trimmedPreview.split("\n").filter((line) => line.trim())
233
+ : [trimmedPreview.split("\n", 1)[0] ?? ""].filter((line) => line.trim());
234
+ for (const line of previewLines.length > 0 ? previewLines : ["(no output)"]) {
235
+ text += `\n ${theme.fg("dim", `⎿ ${line}`)}`;
236
+ }
237
+ if (!options.expanded && trimmedPreview.includes("\n")) {
238
+ text += `\n ${theme.fg("dim", "ctrl+o full notification")}`;
239
+ }
240
+ if (details.sessionLabel && details.sessionValue) {
241
+ text += `\n ${theme.fg("muted", `${details.sessionLabel}: ${shortenPath(details.sessionValue)}`)}`;
242
+ }
243
+ return new Text(text, 0, 0);
244
+ });
245
+ pi.registerMessageRenderer<SubagentControlMessageDetails>(SUBAGENT_CONTROL_MESSAGE_TYPE, (message, _options, theme) => {
246
+ const details = message.details as SubagentControlMessageDetails | undefined;
247
+ if (!details?.event) return undefined;
248
+ const content = typeof message.content === "string" ? message.content : undefined;
249
+ return new SubagentControlNoticeComponent({ ...details, noticeText: formatSubagentControlNotice(details, content) }, theme);
250
+ });
251
+ const executeSubagentCollapsed = (id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((result: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => {
252
+ if (ctx.hasUI) {
253
+ state.lastUiContext = ctx;
254
+ ctx.ui.setToolsExpanded(false);
255
+ }
256
+ return executor.execute(id, params, signal, onUpdate, ctx);
257
+ };
258
+ const slashBridge = registerSlashSubagentBridge({
259
+ events: pi.events,
260
+ getContext: () => state.lastUiContext,
261
+ execute: (id, params, signal, onUpdate, ctx) =>
262
+ executeSubagentCollapsed(id, params, signal, onUpdate, ctx),
263
+ });
264
+ registrationFailureCleanups.push(() => {
265
+ slashBridge.cancelAll();
266
+ slashBridge.dispose();
267
+ });
268
+ const promptTemplateBridge = registerPromptTemplateDelegationBridge({
269
+ events: pi.events,
270
+ getContext: () => state.lastUiContext,
271
+ execute: async (requestId, request, signal, ctx, onUpdate) => {
272
+ if (request.tasks && request.tasks.length > 0) {
273
+ return executeSubagentCollapsed(
274
+ requestId,
275
+ {
276
+ tasks: request.tasks,
277
+ context: request.context,
278
+ cwd: request.cwd,
279
+ worktree: request.worktree,
280
+ async: false,
281
+ },
282
+ signal,
283
+ onUpdate,
284
+ ctx,
285
+ );
286
+ }
288
287
  return executeSubagentCollapsed(
289
288
  requestId,
290
289
  {
291
- tasks: request.tasks,
290
+ agent: request.agent,
291
+ task: request.task,
292
292
  context: request.context,
293
293
  cwd: request.cwd,
294
- worktree: request.worktree,
294
+ model: request.model,
295
295
  async: false,
296
- clarify: false,
297
296
  },
298
297
  signal,
299
298
  onUpdate,
300
299
  ctx,
301
300
  );
302
- }
303
- return executeSubagentCollapsed(
304
- requestId,
305
- {
306
- agent: request.agent,
307
- task: request.task,
308
- context: request.context,
309
- cwd: request.cwd,
310
- model: request.model,
311
- async: false,
312
- clarify: false,
313
- },
314
- signal,
315
- onUpdate,
316
- ctx,
317
- );
318
- },
319
- });
320
- function effectiveParallelTaskCount(tasks: Array<{ count?: unknown }> | undefined): number {
321
- if (!tasks || tasks.length === 0) return 0;
322
- return tasks.reduce((total, task) => {
323
- const count = typeof task.count === "number" && Number.isInteger(task.count) && task.count >= 1 ? task.count : 1;
324
- return total + count;
325
- }, 0);
326
- }
327
- const tool: ToolDefinition<typeof SubagentParams, Details, SubagentToolRenderState> = {
328
- name: "subagent",
329
- label: "Subagent",
330
- description: `Delegate to subagents or manage agent definitions.
331
- EXECUTION (use exactly ONE mode):
332
- • Before executing, use { action: "list" } to inspect configured agents/chains. Only execute agents listed as executable/non-disabled.
333
- SINGLE: { agent, task? } - one task; omit task for self-contained agents
334
- CHAIN: { chain: [{agent:"agent-a"}, {parallel:[{agent:"agent-b",count:3}]}] } - sequential pipeline with optional parallel fan-out
335
- PARALLEL: { tasks: [{agent,task,count?,output?,reads?,progress?}, ...], concurrency?: number, worktree?: true } - concurrent execution (worktree: isolate each task in a git worktree)
336
- Optional context: { context: "fresh" | "fork" } (default: if any requested agent has defaultContext: "fork", the whole invocation uses fork; otherwise "fresh"; inspect agent defaults via { action: "list" })
337
- CHAIN TEMPLATE VARIABLES (use in task strings):
338
- {task} - The original task/request from the user
339
- • {previous} - Text response from the previous step (empty for first step)
340
- • {chain_dir} - Shared directory for chain files (e.g., <tmpdir>/${APP_NAME}-subagents-<scope>/chain-runs/abc123/)
341
- Example: { chain: [{agent:"agent-a", task:"Analyze {task}"}, {agent:"agent-b", task:"Plan based on {previous}"}] }
342
- MANAGEMENT (use action field, omit agent/task/chain/tasks):
343
- { action: "list" } - discover executable agents/chains
344
- { action: "get", agent: "name" } - full detail; packaged agents use dotted runtime names like "package.agent"
345
- • { action: "create", config: { name: "custom-agent", package: "code-analysis", systemPrompt, systemPromptMode, inheritProjectContext, inheritSkills, defaultContext, ... } }
346
- • { action: "update", agent: "code-analysis.custom-agent", config: { package: "analysis", ... } } - merge
347
- • { action: "delete", agent: "code-analysis.custom-agent" }
348
- • Use chainName for chain operations; packaged chains also use dotted runtime names
349
- CONTROL:
350
- • { action: "status", id: "..." } - inspect an async/background run by id or prefix
351
- • { action: "interrupt", id?: "..." } - soft-interrupt the current child turn and leave the run paused
352
- • { action: "resume", id: "...", message: "...", index?: 0 } - follow up with a live async child or revive a completed async/foreground child from its session
353
- DIAGNOSTICS:
354
- • { action: "doctor" } - read-only report for runtime paths, discovery, sessions, and intercom`,
355
- parameters: SubagentParams,
356
- promptGuidelines: DEFAULT_PROMPT_GUIDANCE,
357
- execute(id, params, signal, onUpdate, ctx) {
358
- return executeSubagentCollapsed(id, params, signal, onUpdate, ctx);
359
- },
360
- renderCall(args, theme) {
361
- if (args.action) {
362
- const target = args.agent || args.chainName || "";
363
- return new Text(
364
- `${theme.fg("toolTitle", theme.bold("subagent "))}${args.action}${target ? ` ${theme.fg("accent", target)}` : ""}`,
365
- 0, 0,
366
- );
367
- }
368
- const isParallel = (args.tasks?.length ?? 0) > 0;
369
- const parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);
370
- const asyncLabel = args.async === true && args.clarify !== true && !isParallel ? theme.fg("warning", " [async]") : "";
371
- if (args.chain?.length)
372
- return new Text(
373
- `${theme.fg("toolTitle", theme.bold("subagent "))}chain (${args.chain.length})${asyncLabel}`,
374
- 0,
375
- 0,
376
- );
377
- if (isParallel)
301
+ },
302
+ });
303
+ registrationFailureCleanups.push(() => {
304
+ promptTemplateBridge.cancelAll();
305
+ promptTemplateBridge.dispose();
306
+ });
307
+ function effectiveParallelTaskCount(tasks: Array<{ count?: unknown }> | undefined): number {
308
+ if (!tasks || tasks.length === 0) return 0;
309
+ return tasks.reduce((total, task) => {
310
+ const count = typeof task.count === "number" && Number.isInteger(task.count) && task.count >= 1 ? task.count : 1;
311
+ return total + count;
312
+ }, 0);
313
+ }
314
+ const tool: ToolDefinition<typeof SubagentParams, Details, SubagentToolRenderState> = {
315
+ name: "subagent",
316
+ label: "Subagent",
317
+ description: SUBAGENT_TOOL_DESCRIPTION,
318
+ parameters: SubagentParams,
319
+ promptGuidelines: DEFAULT_PROMPT_GUIDANCE,
320
+ execute(id, params, signal, onUpdate, ctx) {
321
+ const executionSignal = signal ?? ctx.signal ?? new AbortController().signal;
322
+ return executeSubagentCollapsed(id, params as SubagentParamsLike, executionSignal, onUpdate, ctx);
323
+ },
324
+ renderCall(args, theme) {
325
+ if (args.action) {
326
+ const target = args.agent || args.chainName || "";
327
+ return new Text(
328
+ `${theme.fg("toolTitle", theme.bold("subagent "))}${args.action}${target ? ` ${theme.fg("accent", target)}` : ""}`,
329
+ 0, 0,
330
+ );
331
+ }
332
+ const isParallel = (args.tasks?.length ?? 0) > 0;
333
+ const parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);
334
+ const asyncLabel = args.async === true ? theme.fg("warning", " [async]") : "";
335
+ if (args.chain?.length)
336
+ return new Text(
337
+ `${theme.fg("toolTitle", theme.bold("subagent "))}chain (${args.chain.length})${asyncLabel}`,
338
+ 0,
339
+ 0,
340
+ );
341
+ if (isParallel)
342
+ return new Text(
343
+ `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})${asyncLabel}`,
344
+ 0,
345
+ 0,
346
+ );
378
347
  return new Text(
379
- `${theme.fg("toolTitle", theme.bold("subagent "))}parallel (${parallelCount})`,
348
+ `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}${asyncLabel}`,
380
349
  0,
381
350
  0,
382
351
  );
383
- return new Text(
384
- `${theme.fg("toolTitle", theme.bold("subagent "))}${theme.fg("accent", args.agent || "?")}${asyncLabel}`,
385
- 0,
386
- 0,
387
- );
388
- },
389
- renderResult(result, options, theme, context) {
390
- return renderLiveSubagentResult(result, options, theme, context);
391
- },
392
- };
393
- pi.registerTool(tool);
394
- registerSlashCommands(pi, state);
395
- const eventUnsubscribeStoreKey = "__piSubagentEventUnsubscribes";
396
- const controlNoticeSeenStoreKey = "__piSubagentVisibleControlNotices";
397
- const previousEventUnsubscribes = globalStore[eventUnsubscribeStoreKey];
398
- if (Array.isArray(previousEventUnsubscribes)) {
399
- for (const unsubscribe of previousEventUnsubscribes) {
400
- if (typeof unsubscribe !== "function") continue;
401
- try {
402
- unsubscribe();
403
- } catch {
404
- }
352
+ },
353
+ renderResult(result, options, theme, context) {
354
+ return renderLiveSubagentResult(result, options, theme, context);
355
+ },
356
+ };
357
+ pi.registerTool(tool);
358
+ registerSlashCommands(pi, state);
359
+ const notifyCleanup = registerSubagentNotify(pi);
360
+ registrationFailureCleanups.push(notifyCleanup);
361
+ const visibleControlNotices = getApiScopedSet(pi, "__piSubagentVisibleControlNoticesByApi");
362
+ const startedEventHandler = (payload: unknown) => {
363
+ if (lifecycle.isCurrent()) handleStarted(payload);
364
+ };
365
+ const completeEventHandler = (payload: unknown) => {
366
+ if (lifecycle.isCurrent()) handleComplete(payload);
367
+ };
368
+ const controlEventHandler = (payload: unknown) => {
369
+ if (!lifecycle.isCurrent()) return;
370
+ handleSubagentControlNotice({
371
+ pi,
372
+ state,
373
+ visibleControlNotices,
374
+ details: payload as SubagentControlMessageDetails,
375
+ });
376
+ };
377
+ const eventUnsubscribes: Array<() => void> = [];
378
+ for (const [event, handler] of [
379
+ [SUBAGENT_ASYNC_STARTED_EVENT, startedEventHandler],
380
+ [SUBAGENT_ASYNC_COMPLETE_EVENT, completeEventHandler],
381
+ [SUBAGENT_CONTROL_EVENT, controlEventHandler],
382
+ ] as const) {
383
+ const unsubscribe = pi.events.on(event, handler);
384
+ eventUnsubscribes.push(unsubscribe);
385
+ registrationFailureCleanups.push(unsubscribe);
405
386
  }
406
- }
407
- registerSubagentNotify(pi);
408
- const existingVisibleControlNotices = globalStore[controlNoticeSeenStoreKey];
409
- const visibleControlNotices = existingVisibleControlNotices instanceof Set ? existingVisibleControlNotices as Set<string> : new Set<string>();
410
- globalStore[controlNoticeSeenStoreKey] = visibleControlNotices;
411
- const controlEventHandler = (payload: unknown) => {
412
- handleSubagentControlNotice({
413
- pi,
414
- state,
415
- visibleControlNotices,
416
- details: payload as SubagentControlMessageDetails,
417
- });
418
- };
419
- const eventUnsubscribes = [
420
- pi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, handleStarted),
421
- pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),
422
- pi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler),
423
- ];
424
- globalStore[eventUnsubscribeStoreKey] = eventUnsubscribes;
425
- pi.on("tool_result", (event, ctx) => {
426
- if (event.toolName !== "subagent") return;
427
- if (!ctx.hasUI) return;
428
- state.lastUiContext = ctx;
429
- hydrateActiveJobs(ctx);
430
- if (state.asyncJobs.size > 0) ensurePoller();
431
- });
432
- const cleanupSessionArtifacts = (ctx: ExtensionContext) => {
433
- try {
434
- const sessionFile = ctx.sessionManager.getSessionFile();
435
- if (sessionFile) {
436
- cleanupOldArtifacts(getArtifactsDir(sessionFile), DEFAULT_ARTIFACT_CONFIG.cleanupDays);
437
- }
438
- } catch {
439
- }
440
- };
441
- const resetSessionState = (ctx: ExtensionContext) => {
442
- state.baseCwd = ctx.cwd;
443
- state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
444
- state.lastUiContext = ctx;
445
- cleanupSessionArtifacts(ctx);
446
- clearPendingForegroundControlNotices(state);
447
- resetJobs(ctx);
448
- hydrateActiveJobs(ctx);
449
- restoreSlashFinalSnapshots(ctx.sessionManager.getEntries());
450
- primeExistingResults();
451
- };
452
- pi.on("session_start", (_event, ctx) => {
453
- resetSessionState(ctx);
454
- });
455
- pi.on("session_shutdown", () => {
456
- for (const unsubscribe of eventUnsubscribes) {
457
- try {
458
- unsubscribe();
459
- } catch {
387
+ let cleaned = false;
388
+ const runtimeCleanup = () => {
389
+ if (cleaned) return;
390
+ cleaned = true;
391
+ const cleanupSteps: Array<() => void> = [
392
+ ...eventUnsubscribes,
393
+ notifyCleanup,
394
+ () => maintenance.stop(),
395
+ () => stopWidgetAnimation(undefined, pi),
396
+ () => stopResultAnimations(),
397
+ () => {
398
+ if (state.poller) clearInterval(state.poller);
399
+ state.poller = null;
400
+ },
401
+ () => clearPendingForegroundControlNotices(state),
402
+ ...Array.from(state.cleanupTimers.values(), (timer) => () => clearTimeout(timer)),
403
+ () => state.cleanupTimers.clear(),
404
+ () => state.asyncJobs.clear(),
405
+ () => clearSlashSnapshots(pi),
406
+ () => slashBridge.cancelAll(),
407
+ () => slashBridge.dispose(),
408
+ () => promptTemplateBridge.cancelAll(),
409
+ () => promptTemplateBridge.dispose(),
410
+ ];
411
+ for (const cleanup of cleanupSteps) {
412
+ try {
413
+ cleanup();
414
+ } catch {
415
+ // Cleanup is exhaustive and best effort so later owned resources release.
416
+ }
460
417
  }
461
- }
462
- if (globalStore[eventUnsubscribeStoreKey] === eventUnsubscribes) {
463
- delete globalStore[eventUnsubscribeStoreKey];
464
- }
465
- stopResultWatcher();
466
- stopWidgetAnimation();
467
- stopResultAnimations();
468
- if (state.poller) clearInterval(state.poller);
469
- state.poller = null;
470
- clearPendingForegroundControlNotices(state);
471
- for (const timer of state.cleanupTimers.values()) {
472
- clearTimeout(timer);
473
- }
474
- state.cleanupTimers.clear();
475
- state.asyncJobs.clear();
476
- clearSlashSnapshots();
477
- slashBridge.cancelAll();
478
- slashBridge.dispose();
479
- promptTemplateBridge.cancelAll();
480
- promptTemplateBridge.dispose();
481
- if (globalStore[runtimeCleanupStoreKey] === runtimeCleanup) {
482
- delete globalStore[runtimeCleanupStoreKey];
483
- }
484
- try {
485
- if (state.lastUiContext?.hasUI) {
486
- state.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);
418
+ };
419
+ lifecycle.setCleanup(runtimeCleanup);
420
+ runtimeCleanupInstalled = true;
421
+ pi.on("tool_result", (event, ctx) => {
422
+ if (!lifecycle.isCurrent() || event.toolName !== "subagent") return;
423
+ if (!ctx.hasUI) return;
424
+ state.lastUiContext = ctx;
425
+ hydrateActiveJobs(ctx);
426
+ if (state.asyncJobs.size > 0) ensurePoller();
427
+ });
428
+ const cleanupSessionArtifacts = (ctx: ExtensionContext) => {
429
+ maintenance.cleanupSessionArtifactsDeferred(ctx);
430
+ };
431
+ const resetSessionState = (ctx: ExtensionContext) => {
432
+ state.baseCwd = ctx.cwd;
433
+ state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
434
+ state.lastUiContext = ctx;
435
+ cleanupSessionArtifacts(ctx);
436
+ clearPendingForegroundControlNotices(state);
437
+ resetJobs(ctx);
438
+ hydrateActiveJobs(ctx);
439
+ restoreSlashFinalSnapshots(ctx.sessionManager.getEntries(), pi);
440
+ maintenance.primeExistingResultsDeferred();
441
+ };
442
+ pi.on("session_start", (_event, ctx) => {
443
+ if (lifecycle.isCurrent()) resetSessionState(ctx);
444
+ });
445
+ pi.on("session_shutdown", () => {
446
+ lifecycle.dispose();
447
+ });
448
+ } catch (error) {
449
+ if (!runtimeCleanupInstalled) {
450
+ for (const cleanup of registrationFailureCleanups.reverse()) {
451
+ try {
452
+ cleanup();
453
+ } catch {
454
+ // Continue releasing partial-registration resources.
455
+ }
487
456
  }
488
- } catch (error) {
489
- if (!isStaleExtensionContextError(error)) throw error;
490
457
  }
491
- });
458
+ lifecycle.dispose();
459
+ throw error;
460
+ }
492
461
  }