@bastani/atomic 0.9.5-alpha.9 → 0.9.6-alpha.1

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 (377) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.md +2 -2
  3. package/dist/builtin/cursor/CHANGELOG.md +18 -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 +43 -0
  7. package/dist/builtin/intercom/README.md +5 -3
  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 +40 -61
  16. package/dist/builtin/intercom/index.ts +222 -267
  17. package/dist/builtin/intercom/lazy-heavy-proxy.ts +108 -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 +36 -34
  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 +33 -0
  27. package/dist/builtin/mcp/OAUTH.md +1 -0
  28. package/dist/builtin/mcp/README.md +4 -0
  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 +6 -239
  35. package/dist/builtin/mcp/host-html-template.ts +4 -2
  36. package/dist/builtin/mcp/index.ts +258 -250
  37. package/dist/builtin/mcp/init.ts +96 -87
  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 +21 -6
  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 +49 -19
  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/state-lease.ts +12 -0
  50. package/dist/builtin/mcp/ui-server.ts +8 -8
  51. package/dist/builtin/mcp/ui-session.ts +9 -18
  52. package/dist/builtin/subagents/CHANGELOG.md +73 -0
  53. package/dist/builtin/subagents/README.md +30 -29
  54. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  55. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  56. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  57. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  58. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  59. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  60. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  61. package/dist/builtin/subagents/agents/debugger.md +2 -2
  62. package/dist/builtin/subagents/agents/worker.md +2 -2
  63. package/dist/builtin/subagents/package.json +5 -5
  64. package/dist/builtin/subagents/prompts/review-loop.md +1 -1
  65. package/dist/builtin/subagents/skills/subagent/SKILL.md +38 -37
  66. package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
  67. package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
  68. package/dist/builtin/subagents/src/extension/index.ts +287 -307
  69. package/dist/builtin/subagents/src/extension/prompt-guidance.ts +6 -10
  70. package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
  71. package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
  72. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
  73. package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
  74. package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
  75. package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +3 -2
  76. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
  77. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
  78. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
  79. package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
  80. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
  81. package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
  82. package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
  83. package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
  84. package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
  85. package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
  86. package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
  87. package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
  88. package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
  89. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +172 -238
  90. package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
  91. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
  92. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +17 -13
  93. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
  94. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  95. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  96. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  97. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
  98. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
  99. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
  100. package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
  101. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +53 -44
  102. package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
  103. package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
  104. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
  105. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
  106. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
  107. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
  108. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
  109. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  110. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
  111. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
  113. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
  114. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
  115. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
  116. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
  117. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +27 -11
  118. package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
  119. package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
  120. package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
  121. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
  122. package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
  123. package/dist/builtin/subagents/src/shared/settings.ts +20 -10
  124. package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
  125. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  126. package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
  127. package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
  128. package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
  129. package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
  130. package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
  131. package/dist/builtin/subagents/src/tui/render-widget.ts +128 -89
  132. package/dist/builtin/web-access/CHANGELOG.md +34 -0
  133. package/dist/builtin/web-access/README.md +4 -0
  134. package/dist/builtin/web-access/content-tools.ts +8 -3
  135. package/dist/builtin/web-access/index-heavy.ts +1 -1
  136. package/dist/builtin/web-access/index.ts +190 -46
  137. package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
  138. package/dist/builtin/web-access/package.json +2 -2
  139. package/dist/builtin/web-access/result-renderers.ts +1 -1
  140. package/dist/builtin/web-access/summary-review.ts +1 -1
  141. package/dist/builtin/web-access/web-search-activity.ts +1 -1
  142. package/dist/builtin/web-access/web-search-return.ts +7 -0
  143. package/dist/builtin/web-access/web-search-summary.ts +1 -1
  144. package/dist/builtin/web-access/web-search-tool.ts +4 -2
  145. package/dist/builtin/workflows/CHANGELOG.md +76 -0
  146. package/dist/builtin/workflows/README.md +5 -5
  147. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
  148. package/dist/builtin/workflows/builtin/goal-runner.ts +47 -26
  149. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
  150. package/dist/builtin/workflows/builtin/ralph-core.ts +6 -6
  151. package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
  152. package/dist/builtin/workflows/builtin/ralph-runner.ts +0 -11
  153. package/dist/builtin/workflows/package.json +2 -2
  154. package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
  155. package/dist/builtin/workflows/src/engine/primitives/task.ts +2 -1
  156. package/dist/builtin/workflows/src/extension/workflow-prompts.ts +23 -22
  157. package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
  158. package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -2
  159. package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
  160. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
  161. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
  162. package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
  163. package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
  164. package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
  165. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
  166. package/dist/cli/args.d.ts.map +1 -1
  167. package/dist/cli/args.js +2 -2
  168. package/dist/cli/args.js.map +1 -1
  169. package/dist/core/agent-session-events.d.ts.map +1 -1
  170. package/dist/core/agent-session-events.js +2 -1
  171. package/dist/core/agent-session-events.js.map +1 -1
  172. package/dist/core/agent-session-message-queue.d.ts.map +1 -1
  173. package/dist/core/agent-session-message-queue.js +1 -1
  174. package/dist/core/agent-session-message-queue.js.map +1 -1
  175. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  176. package/dist/core/agent-session-prompt.js +1 -1
  177. package/dist/core/agent-session-prompt.js.map +1 -1
  178. package/dist/core/agent-session-retry.d.ts.map +1 -1
  179. package/dist/core/agent-session-retry.js +1 -1
  180. package/dist/core/agent-session-retry.js.map +1 -1
  181. package/dist/core/agent-session-services.d.ts.map +1 -1
  182. package/dist/core/agent-session-services.js +3 -2
  183. package/dist/core/agent-session-services.js.map +1 -1
  184. package/dist/core/agent-session-types.d.ts.map +1 -1
  185. package/dist/core/agent-session-types.js +1 -1
  186. package/dist/core/agent-session-types.js.map +1 -1
  187. package/dist/core/anthropic-thinking-guard.d.ts +5 -5
  188. package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
  189. package/dist/core/anthropic-thinking-guard.js +42 -32
  190. package/dist/core/anthropic-thinking-guard.js.map +1 -1
  191. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  192. package/dist/core/atomic-guide-command.js +15 -15
  193. package/dist/core/atomic-guide-command.js.map +1 -1
  194. package/dist/core/auth-storage.d.ts.map +1 -1
  195. package/dist/core/auth-storage.js +14 -9
  196. package/dist/core/auth-storage.js.map +1 -1
  197. package/dist/core/compaction/compaction.d.ts +2 -0
  198. package/dist/core/compaction/compaction.d.ts.map +1 -1
  199. package/dist/core/compaction/compaction.js +79 -46
  200. package/dist/core/compaction/compaction.js.map +1 -1
  201. package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
  202. package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
  203. package/dist/core/compaction/context-assistant-turns.js +87 -0
  204. package/dist/core/compaction/context-assistant-turns.js.map +1 -0
  205. package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
  206. package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
  207. package/dist/core/compaction/context-compaction-critical.js +2 -2
  208. package/dist/core/compaction/context-compaction-critical.js.map +1 -1
  209. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
  210. package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
  211. package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
  212. package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
  213. package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
  214. package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
  215. package/dist/core/compaction/context-compaction-eviction.js +196 -146
  216. package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
  217. package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
  218. package/dist/core/compaction/context-compaction-prompt.js +1 -1
  219. package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
  220. package/dist/core/compaction/context-compaction-types.d.ts +2 -0
  221. package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
  222. package/dist/core/compaction/context-compaction-types.js.map +1 -1
  223. package/dist/core/compaction/context-deletion-application.d.ts +5 -4
  224. package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
  225. package/dist/core/compaction/context-deletion-application.js +17 -15
  226. package/dist/core/compaction/context-deletion-application.js.map +1 -1
  227. package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
  228. package/dist/core/compaction/context-deletion-store.js +1 -1
  229. package/dist/core/compaction/context-deletion-store.js.map +1 -1
  230. package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
  231. package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
  232. package/dist/core/compaction/context-deletion-targets.js +36 -31
  233. package/dist/core/compaction/context-deletion-targets.js.map +1 -1
  234. package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
  235. package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
  236. package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
  237. package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
  238. package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
  239. package/dist/core/compaction/context-transcript-analysis.js +33 -37
  240. package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
  241. package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
  242. package/dist/core/copilot-model-synthesis.js +3 -1
  243. package/dist/core/copilot-model-synthesis.js.map +1 -1
  244. package/dist/core/extensions/provider-types.d.ts +2 -7
  245. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  246. package/dist/core/extensions/provider-types.js.map +1 -1
  247. package/dist/core/messages.d.ts +9 -0
  248. package/dist/core/messages.d.ts.map +1 -1
  249. package/dist/core/messages.js +100 -18
  250. package/dist/core/messages.js.map +1 -1
  251. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  252. package/dist/core/model-registry-builtins.js +5 -0
  253. package/dist/core/model-registry-builtins.js.map +1 -1
  254. package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
  255. package/dist/core/model-registry-custom-loader.js +49 -8
  256. package/dist/core/model-registry-custom-loader.js.map +1 -1
  257. package/dist/core/model-registry-dynamic.d.ts.map +1 -1
  258. package/dist/core/model-registry-dynamic.js +11 -5
  259. package/dist/core/model-registry-dynamic.js.map +1 -1
  260. package/dist/core/model-registry-loader.d.ts.map +1 -1
  261. package/dist/core/model-registry-loader.js +8 -0
  262. package/dist/core/model-registry-loader.js.map +1 -1
  263. package/dist/core/model-registry-schemas.d.ts +93 -8
  264. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  265. package/dist/core/model-registry-schemas.js +24 -12
  266. package/dist/core/model-registry-schemas.js.map +1 -1
  267. package/dist/core/model-registry-types.d.ts +7 -6
  268. package/dist/core/model-registry-types.d.ts.map +1 -1
  269. package/dist/core/model-registry-types.js.map +1 -1
  270. package/dist/core/model-registry.d.ts +5 -0
  271. package/dist/core/model-registry.d.ts.map +1 -1
  272. package/dist/core/model-registry.js +23 -0
  273. package/dist/core/model-registry.js.map +1 -1
  274. package/dist/core/model-resolver-cli.d.ts.map +1 -1
  275. package/dist/core/model-resolver-cli.js +33 -5
  276. package/dist/core/model-resolver-cli.js.map +1 -1
  277. package/dist/core/model-resolver-initial.d.ts +6 -1
  278. package/dist/core/model-resolver-initial.d.ts.map +1 -1
  279. package/dist/core/model-resolver-initial.js +12 -7
  280. package/dist/core/model-resolver-initial.js.map +1 -1
  281. package/dist/core/model-resolver.d.ts +1 -1
  282. package/dist/core/model-resolver.d.ts.map +1 -1
  283. package/dist/core/model-resolver.js +1 -1
  284. package/dist/core/model-resolver.js.map +1 -1
  285. package/dist/core/resource-loader-context-files.d.ts +1 -0
  286. package/dist/core/resource-loader-context-files.d.ts.map +1 -1
  287. package/dist/core/resource-loader-context-files.js +13 -10
  288. package/dist/core/resource-loader-context-files.js.map +1 -1
  289. package/dist/core/sdk.d.ts.map +1 -1
  290. package/dist/core/sdk.js +2 -2
  291. package/dist/core/sdk.js.map +1 -1
  292. package/dist/core/session-entry-normalization.d.ts +7 -0
  293. package/dist/core/session-entry-normalization.d.ts.map +1 -0
  294. package/dist/core/session-entry-normalization.js +14 -0
  295. package/dist/core/session-entry-normalization.js.map +1 -0
  296. package/dist/core/session-manager-core.d.ts.map +1 -1
  297. package/dist/core/session-manager-core.js +1 -0
  298. package/dist/core/session-manager-core.js.map +1 -1
  299. package/dist/core/session-manager-history.d.ts +2 -2
  300. package/dist/core/session-manager-history.d.ts.map +1 -1
  301. package/dist/core/session-manager-history.js +127 -108
  302. package/dist/core/session-manager-history.js.map +1 -1
  303. package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
  304. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  305. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  306. package/dist/core/settings-types.d.ts +1 -1
  307. package/dist/core/settings-types.d.ts.map +1 -1
  308. package/dist/core/settings-types.js.map +1 -1
  309. package/dist/core/tools/bash.d.ts.map +1 -1
  310. package/dist/core/tools/bash.js +11 -8
  311. package/dist/core/tools/bash.js.map +1 -1
  312. package/dist/main-session.d.ts.map +1 -1
  313. package/dist/main-session.js +1 -0
  314. package/dist/main-session.js.map +1 -1
  315. package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/settings-selector-options.js +3 -1
  317. package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
  318. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  320. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  321. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  322. package/dist/modes/interactive/interactive-agent-events.js +2 -1
  323. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  324. package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
  325. package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
  326. package/dist/modes/interactive/interactive-child-ordering.js +26 -0
  327. package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
  328. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  329. package/dist/modes/interactive/interactive-deferred-startup.js +2 -2
  330. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  331. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  332. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  333. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  334. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  335. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  336. package/dist/modes/interactive/interactive-model-routing.js +8 -3
  337. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  338. package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
  339. package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
  340. package/dist/modes/interactive/theme/theme-class.js +2 -0
  341. package/dist/modes/interactive/theme/theme-class.js.map +1 -1
  342. package/dist/utils/clipboard-image.d.ts.map +1 -1
  343. package/dist/utils/clipboard-image.js +3 -0
  344. package/dist/utils/clipboard-image.js.map +1 -1
  345. package/docs/changelog.mdx +19 -0
  346. package/docs/compaction.md +55 -48
  347. package/docs/custom-provider.md +18 -5
  348. package/docs/extensions.md +7 -3
  349. package/docs/models.md +69 -10
  350. package/docs/providers.md +1 -1
  351. package/docs/quickstart.md +9 -7
  352. package/docs/rpc.md +2 -2
  353. package/docs/sdk.md +1 -1
  354. package/docs/settings.md +3 -3
  355. package/docs/subagents.md +36 -5
  356. package/docs/tools.md +1 -1
  357. package/docs/usage.md +4 -2
  358. package/docs/workflows.md +27 -44
  359. package/examples/extensions/preset.ts +2 -2
  360. package/examples/extensions/subagent/README.md +2 -2
  361. package/examples/extensions/subagent/index.ts +1 -2
  362. package/examples/extensions/subagent/schemas.ts +4 -1
  363. package/examples/sdk/12-full-control.ts +1 -1
  364. package/npm-shrinkwrap.json +48 -51
  365. package/package.json +7 -7
  366. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
  367. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
  368. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
  369. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
  370. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
  371. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
  372. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
  373. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
  374. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
  375. package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
  376. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
  377. package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
@@ -1,202 +1,56 @@
1
- import type { AgentEndEvent, AgentStartEvent, ExtensionAPI, ExtensionCommandContext, ExtensionContext, ExtensionHandler, MessageRenderer, ModelSelectEvent, RegisteredCommand, SessionShutdownEvent, SessionStartEvent, ToolDefinition, ToolExecutionEndEvent, ToolExecutionStartEvent, TurnEndEvent, TurnStartEvent } from "@bastani/atomic";
1
+ import { APP_NAME, getEnvValue, type ExtensionAPI, type ExtensionContext, type SessionStartEvent, type ToolDefinition } from "@bastani/atomic";
2
2
  import { Text } from "@earendil-works/pi-tui";
3
3
  import { Type } from "typebox";
4
4
  import { renderIntercomToolResult } from "./result-renderers.js";
5
-
6
- type CapturedCommand = Omit<RegisteredCommand, "name" | "sourceInfo">;
7
- type CapturedShortcut = Parameters<ExtensionAPI["registerShortcut"]>[1];
8
- type EventHandler = Parameters<ExtensionAPI["events"]["on"]>[1];
9
- type EventPayload = Parameters<EventHandler>[0];
10
- type ToolRenderResultArgs = Parameters<NonNullable<ToolDefinition["renderResult"]>>;
11
-
12
- type ForwardedEventMap = {
13
- session_start: SessionStartEvent;
14
- session_shutdown: SessionShutdownEvent;
15
- turn_start: TurnStartEvent;
16
- turn_end: TurnEndEvent;
17
- agent_start: AgentStartEvent;
18
- agent_end: AgentEndEvent;
19
- tool_execution_start: ToolExecutionStartEvent;
20
- tool_execution_end: ToolExecutionEndEvent;
21
- model_select: ModelSelectEvent;
22
- };
23
-
24
- type LazyLifecycleEvent = keyof ForwardedEventMap;
25
- type ForwardedHandler<K extends LazyLifecycleEvent> = ExtensionHandler<ForwardedEventMap[K]>;
26
- type ForwardedHandlerMap = { [K in LazyLifecycleEvent]: ForwardedHandler<K>[] };
27
- type AnyForwardedHandler = { [K in LazyLifecycleEvent]: ForwardedHandler<K> }[LazyLifecycleEvent];
28
-
29
- type CapturedHeavy = {
30
- tools: Map<string, ToolDefinition>;
31
- commands: Map<string, CapturedCommand>;
32
- handlers: ForwardedHandlerMap;
33
- shortcuts: Map<string, CapturedShortcut>;
34
- eventHandlers: Map<string, EventHandler[]>;
35
- };
36
-
37
- type LifecycleSnapshot<K extends LazyLifecycleEvent> = {
5
+ import { executeHeavyTool, runHeavyCommand, type HeavyHandle } from "./lazy-tool-execution.js";
6
+ import { assertCurrentLifecycleLease, createLifecycleLease, retainSettledLifecycleCleanup, retireLifecycleLease, SerializedLifecycleForwarder, type LifecycleLease } from "./lifecycle-lease.js";
7
+ import { rejectLazyResultRelay } from "./lazy-subagent-ack.js";
8
+ import {
9
+ createForwardedHandlerMap,
10
+ createHeavyProxy,
11
+ dispatchEventHandlers,
12
+ dispatchHandlers,
13
+ type CapturedHeavy,
14
+ type ForwardedEventMap,
15
+ type ToolRenderResultArgs,
16
+ } from "./lazy-heavy-proxy.js";
17
+
18
+ type LifecycleSnapshot<K extends keyof ForwardedEventMap> = {
38
19
  event: ForwardedEventMap[K];
39
20
  ctx: ExtensionContext;
40
21
  };
41
-
42
- type SessionSnapshot = LifecycleSnapshot<"session_start"> & {
43
- generation: number;
44
- };
45
-
22
+ type ShutdownSnapshot = LifecycleSnapshot<"session_shutdown"> & { generation: number };
23
+ type IntercomLease = LifecycleLease<ShutdownSnapshot>;
24
+ type SessionSnapshot = LifecycleSnapshot<"session_start"> & { generation: number; lease: IntercomLease };
25
+ type IntercomHeavyHandle = HeavyHandle<CapturedHeavy>;
26
+ type HeavyAttempt = { lease: IntercomLease; promise: Promise<IntercomHeavyHandle> };
27
+ type ReplayAttempt = { lease: IntercomLease; heavy: CapturedHeavy; promise: Promise<void> };
46
28
  type ActiveLifecycleState = {
47
29
  turnStart: LifecycleSnapshot<"turn_start"> | null;
48
30
  agentStart: LifecycleSnapshot<"agent_start"> | null;
49
31
  activeTools: Map<string, LifecycleSnapshot<"tool_execution_start">>;
50
32
  modelSelect: LifecycleSnapshot<"model_select"> | null;
51
33
  };
52
- const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
53
- const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
54
-
55
- function hasSubagentIntercomEnv(): boolean {
56
- return Object.keys(process.env).some((key) => key.endsWith("_SUBAGENT_ORCHESTRATOR_TARGET"));
57
- }
58
-
59
- function createSyntheticSessionStartEvent(): SessionStartEvent {
60
- return { type: "session_start", reason: "startup" };
61
- }
62
-
63
- function createForwardedHandlerMap(): ForwardedHandlerMap {
64
- return {
65
- session_start: [],
66
- session_shutdown: [],
67
- turn_start: [],
68
- turn_end: [],
69
- agent_start: [],
70
- agent_end: [],
71
- tool_execution_start: [],
72
- tool_execution_end: [],
73
- model_select: [],
74
- };
75
- }
76
-
77
- function addHandler<K extends LazyLifecycleEvent>(captured: CapturedHeavy, event: K, handler: ForwardedHandler<K>): void {
78
- captured.handlers[event].push(handler);
34
+ interface LightweightIntercomOptions {
35
+ importHeavy?: () => Promise<{ default: (pi: ExtensionAPI) => void | Promise<void> }>;
79
36
  }
80
37
 
81
- function captureForwardedHandler(captured: CapturedHeavy, event: "session_start", handler: ForwardedHandler<"session_start">): void;
82
- function captureForwardedHandler(captured: CapturedHeavy, event: "session_shutdown", handler: ForwardedHandler<"session_shutdown">): void;
83
- function captureForwardedHandler(captured: CapturedHeavy, event: "turn_start", handler: ForwardedHandler<"turn_start">): void;
84
- function captureForwardedHandler(captured: CapturedHeavy, event: "turn_end", handler: ForwardedHandler<"turn_end">): void;
85
- function captureForwardedHandler(captured: CapturedHeavy, event: "agent_start", handler: ForwardedHandler<"agent_start">): void;
86
- function captureForwardedHandler(captured: CapturedHeavy, event: "agent_end", handler: ForwardedHandler<"agent_end">): void;
87
- function captureForwardedHandler(captured: CapturedHeavy, event: "tool_execution_start", handler: ForwardedHandler<"tool_execution_start">): void;
88
- function captureForwardedHandler(captured: CapturedHeavy, event: "tool_execution_end", handler: ForwardedHandler<"tool_execution_end">): void;
89
- function captureForwardedHandler(captured: CapturedHeavy, event: "model_select", handler: ForwardedHandler<"model_select">): void;
90
- function captureForwardedHandler(captured: CapturedHeavy, event: LazyLifecycleEvent, handler: AnyForwardedHandler): void;
91
- function captureForwardedHandler(captured: CapturedHeavy, event: LazyLifecycleEvent, handler: AnyForwardedHandler): void {
92
- switch (event) {
93
- case "session_start":
94
- addHandler(captured, event, handler as ForwardedHandler<"session_start">);
95
- return;
96
- case "session_shutdown":
97
- addHandler(captured, event, handler as ForwardedHandler<"session_shutdown">);
98
- return;
99
- case "turn_start":
100
- addHandler(captured, event, handler as ForwardedHandler<"turn_start">);
101
- return;
102
- case "turn_end":
103
- addHandler(captured, event, handler as ForwardedHandler<"turn_end">);
104
- return;
105
- case "agent_start":
106
- addHandler(captured, event, handler as ForwardedHandler<"agent_start">);
107
- return;
108
- case "agent_end":
109
- addHandler(captured, event, handler as ForwardedHandler<"agent_end">);
110
- return;
111
- case "tool_execution_start":
112
- addHandler(captured, event, handler as ForwardedHandler<"tool_execution_start">);
113
- return;
114
- case "tool_execution_end":
115
- addHandler(captured, event, handler as ForwardedHandler<"tool_execution_end">);
116
- return;
117
- case "model_select":
118
- addHandler(captured, event, handler as ForwardedHandler<"model_select">);
119
- }
120
- }
121
-
122
- function addEventHandler(captured: CapturedHeavy, event: string, handler: EventHandler): void {
123
- const handlers = captured.eventHandlers.get(event) ?? [];
124
- handlers.push(handler);
125
- captured.eventHandlers.set(event, handlers);
126
- }
127
-
128
- async function dispatchHandlers<K extends LazyLifecycleEvent>(captured: CapturedHeavy, eventName: K, event: ForwardedEventMap[K], ctx: ExtensionContext): Promise<void> {
129
- for (const handler of captured.handlers[eventName]) {
130
- await handler(event, ctx);
131
- }
132
- }
38
+ const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
39
+ const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
133
40
 
134
- async function dispatchEventHandlers(captured: CapturedHeavy, eventName: string, payload: EventPayload): Promise<void> {
135
- for (const handler of captured.eventHandlers.get(eventName) ?? []) {
136
- await handler(payload);
137
- }
138
- }
41
+ const SUBAGENT_ENV_PREFIX = `${APP_NAME.toUpperCase()}_SUBAGENT_`;
139
42
 
140
- function createHeavyProxy(pi: ExtensionAPI, captured: CapturedHeavy): ExtensionAPI {
141
- return new Proxy(pi, {
142
- get(target, prop, receiver) {
143
- if (prop === "registerTool") {
144
- return (tool: ToolDefinition) => captured.tools.set(tool.name, tool);
145
- }
146
- if (prop === "registerCommand") {
147
- return (name: string, options: CapturedCommand) => captured.commands.set(name, options);
148
- }
149
- if (prop === "on") {
150
- return (event: LazyLifecycleEvent, handler: AnyForwardedHandler) => {
151
- captureForwardedHandler(captured, event, handler);
152
- };
153
- }
154
- if (prop === "registerShortcut") {
155
- return (shortcut: string, options: CapturedShortcut) => {
156
- captured.shortcuts.set(shortcut, options);
157
- };
158
- }
159
- if (prop === "registerMessageRenderer") {
160
- return (customType: string, renderer: MessageRenderer) => pi.registerMessageRenderer(customType, renderer);
161
- }
162
- if (prop === "events") {
163
- return new Proxy(pi.events, {
164
- get(eventTarget, eventProp, eventReceiver) {
165
- if (eventProp === "on") {
166
- return (event: string, handler: EventHandler) => {
167
- addEventHandler(captured, event, handler);
168
- return () => {
169
- const handlers = captured.eventHandlers.get(event) ?? [];
170
- captured.eventHandlers.set(event, handlers.filter((candidate) => candidate !== handler));
171
- };
172
- };
173
- }
174
- return Reflect.get(eventTarget, eventProp, eventReceiver);
175
- },
176
- });
177
- }
178
- return Reflect.get(target, prop, receiver);
179
- },
180
- }) as ExtensionAPI;
43
+ function readSubagentEnv(name: string): string | undefined {
44
+ const value = getEnvValue(`${SUBAGENT_ENV_PREFIX}${name}`)?.trim();
45
+ return value || undefined;
181
46
  }
182
47
 
183
- async function executeHeavyTool(
184
- loadHeavy: (ctx?: ExtensionContext) => Promise<CapturedHeavy>,
185
- name: string,
186
- args: Parameters<NonNullable<ToolDefinition["execute"]>>,
187
- ): Promise<Awaited<ReturnType<NonNullable<ToolDefinition["execute"]>>>> {
188
- const ctx = args[4];
189
- const heavy = await loadHeavy(ctx);
190
- const tool = heavy.tools.get(name);
191
- if (!tool?.execute) throw new Error(`Intercom tool implementation not found: ${name}`);
192
- return await tool.execute(...args) as Awaited<ReturnType<NonNullable<ToolDefinition["execute"]>>>;
48
+ function hasSubagentIntercomEnv(): boolean {
49
+ return readSubagentEnv("ORCHESTRATOR_TARGET") !== undefined;
193
50
  }
194
51
 
195
- async function runHeavyCommand(loadHeavy: (ctx?: ExtensionContext) => Promise<CapturedHeavy>, args: string | undefined, ctx: ExtensionCommandContext): Promise<void> {
196
- const heavy = await loadHeavy(ctx);
197
- const command = heavy.commands.get("intercom");
198
- if (!command) throw new Error("Intercom command implementation not found");
199
- await command.handler(args ?? "", ctx);
52
+ function createSyntheticSessionStartEvent(): SessionStartEvent {
53
+ return { type: "session_start", reason: "startup" };
200
54
  }
201
55
 
202
56
  function renderHeavyToolResult(loadedHeavy: CapturedHeavy | null, name: string, args: ToolRenderResultArgs): ReturnType<NonNullable<ToolDefinition["renderResult"]>> {
@@ -204,159 +58,261 @@ function renderHeavyToolResult(loadedHeavy: CapturedHeavy | null, name: string,
204
58
  if (renderer) return renderer(...args);
205
59
  return renderIntercomToolResult(name, args);
206
60
  }
207
-
208
- export default function intercom(pi: ExtensionAPI) {
209
- let heavyPromise: Promise<CapturedHeavy> | null = null;
210
- let loadedHeavy: CapturedHeavy | null = null;
61
+ export default function intercom(pi: ExtensionAPI, options: LightweightIntercomOptions = {}) {
62
+ const delegatedSessionName = readSubagentEnv("INTERCOM_SESSION_NAME");
63
+ let heavyAttempt: HeavyAttempt | null = null;
64
+ let loadedHeavy: IntercomHeavyHandle | null = null;
211
65
  let sessionSnapshot: SessionSnapshot | null = null;
212
66
  let lifecycleGeneration = 0;
67
+ let nextLeaseId = 1;
68
+ let activeLease = createLifecycleLease<ShutdownSnapshot>(nextLeaseId++);
213
69
  let replayedGeneration = 0;
70
+ let replayAttempt: ReplayAttempt | null = null;
71
+ const lifecycleForward = new SerializedLifecycleForwarder();
72
+ const invalidatedMessage = "Intercom initialization was invalidated by session shutdown";
214
73
  const activeLifecycle: ActiveLifecycleState = {
215
74
  turnStart: null,
216
75
  agentStart: null,
217
76
  activeTools: new Map(),
218
77
  modelSelect: null,
219
78
  };
220
-
221
- async function replaySessionStart(heavy: CapturedHeavy): Promise<void> {
222
- if (!sessionSnapshot || replayedGeneration === sessionSnapshot.generation) return;
223
- replayedGeneration = sessionSnapshot.generation;
224
- await dispatchHandlers(heavy, "session_start", sessionSnapshot.event, sessionSnapshot.ctx);
225
- if (activeLifecycle.turnStart) {
226
- await dispatchHandlers(heavy, "turn_start", activeLifecycle.turnStart.event, activeLifecycle.turnStart.ctx);
227
- }
228
- if (activeLifecycle.modelSelect) {
229
- await dispatchHandlers(heavy, "model_select", activeLifecycle.modelSelect.event, activeLifecycle.modelSelect.ctx);
230
- }
231
- if (activeLifecycle.agentStart) {
232
- await dispatchHandlers(heavy, "agent_start", activeLifecycle.agentStart.event, activeLifecycle.agentStart.ctx);
233
- }
234
- for (const activeTool of activeLifecycle.activeTools.values()) {
235
- await dispatchHandlers(heavy, "tool_execution_start", activeTool.event, activeTool.ctx);
79
+ function assertLease(lease: IntercomLease): void {
80
+ assertCurrentLifecycleLease(activeLease, lease, invalidatedMessage);
81
+ }
82
+ function createHandle(heavy: CapturedHeavy, lease: IntercomLease): IntercomHeavyHandle {
83
+ return { heavy, assertCurrent: () => assertLease(lease) };
84
+ }
85
+ async function waitForPriorCleanup(lease: IntercomLease): Promise<void> {
86
+ await lease.priorCleanup;
87
+ assertLease(lease);
88
+ }
89
+ function isReplaySnapshotCurrent(snapshot: SessionSnapshot, lease: IntercomLease): boolean {
90
+ assertLease(lease);
91
+ return sessionSnapshot === snapshot;
92
+ }
93
+ async function replaySessionStart(heavy: CapturedHeavy, lease: IntercomLease, onReplay?: (ctx: ExtensionContext) => void): Promise<void> {
94
+ for (;;) {
95
+ assertLease(lease);
96
+ const snapshot = sessionSnapshot;
97
+ if (!snapshot || snapshot.lease !== lease || replayedGeneration === snapshot.generation) return;
98
+ const active = {
99
+ turnStart: activeLifecycle.turnStart,
100
+ modelSelect: activeLifecycle.modelSelect,
101
+ agentStart: activeLifecycle.agentStart,
102
+ activeTools: [...activeLifecycle.activeTools.values()],
103
+ };
104
+ onReplay?.(snapshot.ctx);
105
+ await dispatchHandlers(heavy, "session_start", snapshot.event, snapshot.ctx);
106
+ if (!isReplaySnapshotCurrent(snapshot, lease)) continue;
107
+ if (active.turnStart) await dispatchHandlers(heavy, "turn_start", active.turnStart.event, active.turnStart.ctx);
108
+ if (!isReplaySnapshotCurrent(snapshot, lease)) continue;
109
+ if (active.modelSelect) await dispatchHandlers(heavy, "model_select", active.modelSelect.event, active.modelSelect.ctx);
110
+ if (!isReplaySnapshotCurrent(snapshot, lease)) continue;
111
+ if (active.agentStart) await dispatchHandlers(heavy, "agent_start", active.agentStart.event, active.agentStart.ctx);
112
+ if (!isReplaySnapshotCurrent(snapshot, lease)) continue;
113
+ for (const activeTool of active.activeTools) {
114
+ await dispatchHandlers(heavy, "tool_execution_start", activeTool.event, activeTool.ctx);
115
+ if (!isReplaySnapshotCurrent(snapshot, lease)) break;
116
+ }
117
+ if (!isReplaySnapshotCurrent(snapshot, lease)) continue;
118
+ replayedGeneration = snapshot.generation;
119
+ return;
236
120
  }
237
121
  }
238
-
239
- async function loadHeavy(ctx?: ExtensionContext): Promise<CapturedHeavy> {
240
- if (!heavyPromise) {
241
- heavyPromise = (async () => {
242
- const captured: CapturedHeavy = {
243
- tools: new Map(),
244
- commands: new Map(),
245
- handlers: createForwardedHandlerMap(),
246
- shortcuts: new Map(),
247
- eventHandlers: new Map(),
248
- };
249
- const mod = await import("./index-heavy.js");
122
+ async function ensureSessionStartReplayed(heavy: CapturedHeavy, lease: IntercomLease, onReplay?: (ctx: ExtensionContext) => void): Promise<void> {
123
+ await waitForPriorCleanup(lease);
124
+ const snapshot = sessionSnapshot;
125
+ if (!snapshot || snapshot.lease !== lease || replayedGeneration === snapshot.generation) return;
126
+ const existing = replayAttempt;
127
+ if (existing?.lease === lease && existing.heavy === heavy) return existing.promise;
128
+ let promise: Promise<void>;
129
+ promise = lifecycleForward.enqueue(() => replaySessionStart(heavy, lease, onReplay)).finally(() => {
130
+ if (replayAttempt?.promise === promise) replayAttempt = null;
131
+ });
132
+ replayAttempt = { lease, heavy, promise };
133
+ await promise;
134
+ }
135
+ async function loadHeavy(ctx?: ExtensionContext): Promise<IntercomHeavyHandle> {
136
+ const lease = activeLease;
137
+ if (lease.retired) throw new Error("Intercom initialization unavailable: no active session");
138
+ await waitForPriorCleanup(lease);
139
+ const existing = heavyAttempt;
140
+ if (existing?.lease === lease) {
141
+ const handle = await existing.promise;
142
+ assertLease(lease);
143
+ if (!sessionSnapshot && ctx) {
144
+ sessionSnapshot = { event: createSyntheticSessionStartEvent(), ctx, generation: ++lifecycleGeneration, lease };
145
+ }
146
+ await ensureSessionStartReplayed(handle.heavy, lease);
147
+ assertLease(lease);
148
+ return handle;
149
+ }
150
+ let promise: Promise<IntercomHeavyHandle>;
151
+ promise = (async (): Promise<IntercomHeavyHandle> => {
152
+ const captured: CapturedHeavy = {
153
+ tools: new Map(), commands: new Map(), handlers: createForwardedHandlerMap(),
154
+ shortcuts: new Map(), eventHandlers: new Map(),
155
+ };
156
+ let replayCtx: ExtensionContext | null = null;
157
+ let cleaned = false;
158
+ const cleanupCandidate = async (): Promise<void> => {
159
+ const shutdown = lease.shutdown;
160
+ const cleanupCtx = shutdown?.ctx ?? replayCtx;
161
+ if (!cleanupCtx || cleaned) return;
162
+ cleaned = true;
163
+ const event = shutdown?.event ?? { type: "session_shutdown", reason: "quit" };
164
+ try {
165
+ await dispatchHandlers(captured, "session_shutdown", event, cleanupCtx);
166
+ } catch (cleanupError) {
167
+ console.error("Intercom failed to clean rejected lazy candidate:", cleanupError);
168
+ }
169
+ };
170
+ try {
171
+ const mod = await (options.importHeavy?.() ?? import("./index-heavy.js"));
172
+ assertLease(lease);
250
173
  await mod.default(createHeavyProxy(pi, captured));
251
- loadedHeavy = captured;
174
+ assertLease(lease);
252
175
  if (!sessionSnapshot && ctx) {
253
- sessionSnapshot = { event: createSyntheticSessionStartEvent(), ctx, generation: ++lifecycleGeneration };
176
+ sessionSnapshot = { event: createSyntheticSessionStartEvent(), ctx, generation: ++lifecycleGeneration, lease };
254
177
  }
255
- await replaySessionStart(captured);
256
- return captured;
257
- })();
258
- }
259
- const heavy = await heavyPromise;
260
- if (!sessionSnapshot && ctx) {
261
- sessionSnapshot = { event: createSyntheticSessionStartEvent(), ctx, generation: ++lifecycleGeneration };
262
- await replaySessionStart(heavy);
263
- }
264
- return heavy;
178
+ await ensureSessionStartReplayed(captured, lease, (replayContext) => { replayCtx = replayContext; });
179
+ assertLease(lease);
180
+ const handle = createHandle(captured, lease);
181
+ loadedHeavy = handle;
182
+ return handle;
183
+ } catch (error) {
184
+ await cleanupCandidate();
185
+ throw error;
186
+ }
187
+ })();
188
+ heavyAttempt = { lease, promise };
189
+ void promise.then(
190
+ () => undefined,
191
+ (error: unknown) => {
192
+ if (heavyAttempt?.promise === promise) heavyAttempt = null;
193
+ const message = error instanceof Error ? error.message : String(error);
194
+ console.error(`Intercom heavy initialization failed; a later call will retry: ${message}`, error);
195
+ },
196
+ );
197
+ return promise;
265
198
  }
266
-
267
199
  pi.on("session_start", async (event, ctx) => {
268
- const generation = ++lifecycleGeneration;
269
- sessionSnapshot = { event, ctx, generation };
270
- if (loadedHeavy) {
271
- replayedGeneration = generation;
272
- await dispatchHandlers(loadedHeavy, "session_start", event, ctx);
200
+ if (delegatedSessionName && typeof pi.setSessionName === "function") pi.setSessionName(delegatedSessionName);
201
+ if (activeLease.retired) activeLease = createLifecycleLease<ShutdownSnapshot>(nextLeaseId++, activeLease.cleanupBarrier);
202
+ const lease = activeLease;
203
+ await waitForPriorCleanup(lease);
204
+ if (sessionSnapshot) {
205
+ activeLifecycle.turnStart = null;
206
+ activeLifecycle.agentStart = null;
207
+ activeLifecycle.activeTools.clear();
208
+ activeLifecycle.modelSelect = null;
273
209
  }
210
+ const generation = ++lifecycleGeneration;
211
+ sessionSnapshot = { event, ctx, generation, lease };
212
+ if (loadedHeavy) await ensureSessionStartReplayed(loadedHeavy.heavy, lease);
274
213
  });
275
-
276
214
  pi.on("session_shutdown", async (event, ctx) => {
277
- ++lifecycleGeneration;
215
+ const lease = activeLease;
216
+ const generation = ++lifecycleGeneration;
217
+ retireLifecycleLease(lease, { event, ctx, generation });
218
+ const retiredHeavy = loadedHeavy?.heavy ?? null;
219
+ const retiredAttempt = heavyAttempt?.lease === lease ? heavyAttempt.promise : null;
220
+ const retiredReplay = replayAttempt?.lease === lease ? replayAttempt.promise : null;
221
+ sessionSnapshot = null;
222
+ heavyAttempt = null;
223
+ loadedHeavy = null;
224
+ replayAttempt = null;
225
+ replayedGeneration = generation;
278
226
  activeLifecycle.turnStart = null;
279
227
  activeLifecycle.agentStart = null;
280
228
  activeLifecycle.activeTools.clear();
281
229
  activeLifecycle.modelSelect = null;
282
- if (loadedHeavy) {
283
- await dispatchHandlers(loadedHeavy, "session_shutdown", event, ctx);
230
+ const publishedCleanup = retiredHeavy
231
+ ? lifecycleForward.enqueue(() => dispatchHandlers(retiredHeavy, "session_shutdown", event, ctx))
232
+ : Promise.resolve();
233
+ const retainedCleanup = retainSettledLifecycleCleanup(lease, [publishedCleanup, retiredAttempt, retiredReplay, lifecycleForward.settled]);
234
+ try {
235
+ await publishedCleanup;
236
+ } finally {
237
+ await retainedCleanup;
284
238
  }
285
- sessionSnapshot = null;
286
- replayedGeneration = lifecycleGeneration;
287
239
  });
288
-
289
240
  pi.on("turn_start", async (event, ctx) => {
241
+ if (activeLease.retired) return;
290
242
  activeLifecycle.turnStart = { event, ctx };
291
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "turn_start", event, ctx);
243
+ const heavy = loadedHeavy?.heavy;
244
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "turn_start", event, ctx));
292
245
  });
293
-
294
246
  pi.on("turn_end", async (event, ctx) => {
247
+ if (activeLease.retired) return;
295
248
  activeLifecycle.turnStart = null;
296
249
  activeLifecycle.agentStart = null;
297
250
  activeLifecycle.activeTools.clear();
298
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "turn_end", event, ctx);
251
+ const heavy = loadedHeavy?.heavy;
252
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "turn_end", event, ctx));
299
253
  });
300
-
301
254
  pi.on("agent_start", async (event, ctx) => {
255
+ if (activeLease.retired) return;
302
256
  activeLifecycle.agentStart = { event, ctx };
303
257
  activeLifecycle.activeTools.clear();
304
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "agent_start", event, ctx);
258
+ const heavy = loadedHeavy?.heavy;
259
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "agent_start", event, ctx));
305
260
  });
306
-
307
261
  pi.on("agent_end", async (event, ctx) => {
262
+ if (activeLease.retired) return;
308
263
  activeLifecycle.agentStart = null;
309
264
  activeLifecycle.activeTools.clear();
310
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "agent_end", event, ctx);
265
+ const heavy = loadedHeavy?.heavy;
266
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "agent_end", event, ctx));
311
267
  });
312
-
313
268
  pi.on("tool_execution_start", async (event, ctx) => {
269
+ if (activeLease.retired) return;
314
270
  activeLifecycle.activeTools.set(event.toolCallId, { event, ctx });
315
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "tool_execution_start", event, ctx);
271
+ const heavy = loadedHeavy?.heavy;
272
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "tool_execution_start", event, ctx));
316
273
  });
317
-
318
274
  pi.on("tool_execution_end", async (event, ctx) => {
275
+ if (activeLease.retired) return;
319
276
  activeLifecycle.activeTools.delete(event.toolCallId);
320
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "tool_execution_end", event, ctx);
277
+ const heavy = loadedHeavy?.heavy;
278
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "tool_execution_end", event, ctx));
321
279
  });
322
-
323
280
  pi.on("model_select", async (event, ctx) => {
281
+ if (activeLease.retired) return;
324
282
  activeLifecycle.modelSelect = { event, ctx };
325
- if (loadedHeavy) await dispatchHandlers(loadedHeavy, "model_select", event, ctx);
283
+ const heavy = loadedHeavy?.heavy;
284
+ if (heavy) await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "model_select", event, ctx));
326
285
  });
327
-
328
286
  pi.registerShortcut("alt+m", {
329
287
  description: "Open session intercom overlay",
330
288
  handler: async (ctx) => {
331
- const heavy = await loadHeavy(ctx);
332
- const handler = heavy.shortcuts.get("alt+m")?.handler;
289
+ const handle = await loadHeavy(ctx);
290
+ handle.assertCurrent();
291
+ const handler = handle.heavy.shortcuts.get("alt+m")?.handler;
333
292
  if (!handler) throw new Error("Intercom shortcut implementation not found: alt+m");
334
293
  await handler(ctx);
294
+ handle.assertCurrent();
335
295
  },
336
296
  });
337
-
338
297
  for (const eventName of [SUBAGENT_CONTROL_INTERCOM_EVENT, SUBAGENT_RESULT_INTERCOM_EVENT] as const) {
339
298
  pi.events.on(eventName, (payload) => {
340
- void loadHeavy().then((heavy) => dispatchEventHandlers(heavy, eventName, payload)).catch((error) => {
299
+ void loadHeavy().then(async (handle) => {
300
+ handle.assertCurrent();
301
+ await dispatchEventHandlers(handle.heavy, eventName, payload);
302
+ handle.assertCurrent();
303
+ }).catch((error) => {
304
+ rejectLazyResultRelay(pi, eventName, payload, error);
341
305
  console.error(`Intercom event relay failed (${eventName}):`, error);
342
306
  });
343
307
  });
344
308
  }
345
-
346
- if (hasSubagentIntercomEnv()) {
347
- pi.on("session_start", (_event, ctx) => {
348
- void loadHeavy(ctx).catch((error) => {
349
- console.error("Intercom initialization failed:", error);
350
- });
351
- });
352
- }
353
-
309
+ // Heavy Intercom state stays unloaded until the model or user invokes an
310
+ // Intercom tool, command, shortcut, or relay that needs it.
354
311
  pi.registerTool({
355
312
  name: "intercom",
356
313
  label: "Intercom",
357
314
  description: `Send a message to another local agent session running on this machine.
358
315
  Use this to communicate findings, request help, or coordinate work with other sessions.
359
-
360
316
  Usage:
361
317
  intercom({ action: "list" }) → List active sessions
362
318
  intercom({ action: "send", to: "session-name", message: "..." }) → Send message
@@ -378,14 +334,13 @@ Usage:
378
334
  replyTo: Type.Optional(Type.String({ description: "Message ID to reply to (for threading or responding to an 'ask')" })),
379
335
  }),
380
336
  execute: (...args) => executeHeavyTool(loadHeavy, "intercom", args),
381
- renderResult: (...args) => renderHeavyToolResult(loadedHeavy, "intercom", args),
337
+ renderResult: (...args) => renderHeavyToolResult(loadedHeavy?.heavy ?? null, "intercom", args),
382
338
  renderCall(args, theme) {
383
339
  const input = args as { action?: string; to?: string; message?: string };
384
340
  const target = input.to ? ` ${input.to}` : "";
385
341
  return new Text(theme.fg("toolTitle", theme.bold(`intercom ${input.action ?? ""}`)) + theme.fg("accent", target), 0, 0);
386
342
  },
387
343
  });
388
-
389
344
  if (hasSubagentIntercomEnv()) {
390
345
  pi.registerTool({
391
346
  name: "contact_supervisor",
@@ -419,7 +374,7 @@ Usage:
419
374
  }, { description: "Structured interview request for reason='interview_request'" })),
420
375
  }),
421
376
  execute: (...args) => executeHeavyTool(loadHeavy, "contact_supervisor", args),
422
- renderResult: (...args) => renderHeavyToolResult(loadedHeavy, "contact_supervisor", args),
377
+ renderResult: (...args) => renderHeavyToolResult(loadedHeavy?.heavy ?? null, "contact_supervisor", args),
423
378
  renderCall(args, theme) {
424
379
  const input = args as { reason?: string; message?: string; interview?: { title?: string } };
425
380
  const reason = input.reason ?? "contact";