@ponythewhite/base-context 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/NOTICE +0 -5
  3. package/README.md +44 -27
  4. package/dist/NOTICE +0 -5
  5. package/dist/base-context-runtime/pyproject.toml +1 -1
  6. package/dist/base-context-runtime/src/rlm/__init__.py +7 -5
  7. package/dist/base-context-runtime/test/test_subagent_registry.py +28 -1
  8. package/dist/base-context-runtime/uv.lock +1 -1
  9. package/dist/build-info.json +1 -1
  10. package/dist/bundle/amazon-bedrock.js +21 -0
  11. package/dist/bundle/{anthropic-YY4S534V.js → anthropic-UV5GZDGU.js} +5 -5
  12. package/dist/bundle/{azure-openai-responses-JRP6MIM3.js → azure-openai-responses-WSNPXLYC.js} +6 -6
  13. package/dist/bundle/{bundled-modules-P5HARVZA.js → bundled-modules-PWOGKUQQ.js} +71 -16
  14. package/dist/bundle/chunk-27QCJ2AZ.js +2578 -0
  15. package/dist/bundle/{chunk-BYVP7LWV.js → chunk-44PEHPOG.js} +1916 -4689
  16. package/dist/bundle/{chunk-MZHTNNVA.js → chunk-4GXPNXOJ.js} +8 -0
  17. package/dist/bundle/{chunk-SC5KG5R4.js → chunk-DGNX7HQ3.js} +1 -7
  18. package/dist/bundle/{chunk-A53O363M.js → chunk-GRJFXLBM.js} +0 -1
  19. package/dist/bundle/chunk-HKINIBP4.js +29 -0
  20. package/dist/bundle/{chunk-73DCPU3D.js → chunk-IADCPVEI.js} +1019 -3427
  21. package/dist/bundle/{chunk-UDSW6FNG.js → chunk-KTNETTHI.js} +1 -1
  22. package/dist/bundle/{chunk-U7AUVG3B.js → chunk-VSIYFWYI.js} +24 -6
  23. package/dist/bundle/{chunk-IW77OXFS.js → chunk-W46VZFI6.js} +0 -2099
  24. package/dist/bundle/{cli-main-O4X7GFGY.js → cli-main-4DS7Y3PI.js} +8 -6
  25. package/dist/bundle/cli.js +2 -2
  26. package/dist/bundle/{google-AUTVGDGZ.js → google-T32FMD4G.js} +6 -6
  27. package/dist/bundle/{google-vertex-Q75D7RKS.js → google-vertex-56KP6I3B.js} +3 -3
  28. package/dist/bundle/{main-XKOW2BV6.js → main-SV7JLVEB.js} +7 -5
  29. package/dist/bundle/{mistral-7ESB7QUD.js → mistral-WGBMYIVU.js} +5 -5
  30. package/dist/bundle/{openai-codex-responses-LV3QRPN4.js → openai-codex-responses-PIV2RQ3G.js} +6 -6
  31. package/dist/bundle/{openai-completions-OJECLPXJ.js → openai-completions-64C3JPR4.js} +11 -22
  32. package/dist/bundle/{openai-responses-FN6HZMBC.js → openai-responses-UI7RSTDV.js} +6 -6
  33. package/dist/cli/args.d.ts.map +1 -1
  34. package/dist/cli/args.js +108 -59
  35. package/dist/cli/args.js.map +1 -1
  36. package/dist/cli/daemon-ps.d.ts +4 -3
  37. package/dist/cli/daemon-ps.d.ts.map +1 -1
  38. package/dist/cli/daemon-ps.js +6 -1
  39. package/dist/cli/daemon-ps.js.map +1 -1
  40. package/dist/cli/product-doctor.d.ts +0 -1
  41. package/dist/cli/product-doctor.d.ts.map +1 -1
  42. package/dist/cli/product-doctor.js +6 -3
  43. package/dist/cli/product-doctor.js.map +1 -1
  44. package/dist/config.d.ts +0 -3
  45. package/dist/config.d.ts.map +1 -1
  46. package/dist/config.js +0 -8
  47. package/dist/config.js.map +1 -1
  48. package/dist/core/agent-session-config.d.ts +1 -2
  49. package/dist/core/agent-session-config.d.ts.map +1 -1
  50. package/dist/core/agent-session-config.js +0 -3
  51. package/dist/core/agent-session-config.js.map +1 -1
  52. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  53. package/dist/core/agent-session-runtime.js +5 -4
  54. package/dist/core/agent-session-runtime.js.map +1 -1
  55. package/dist/core/agent-session-services.d.ts +5 -3
  56. package/dist/core/agent-session-services.d.ts.map +1 -1
  57. package/dist/core/agent-session-services.js +2 -27
  58. package/dist/core/agent-session-services.js.map +1 -1
  59. package/dist/core/agent-session.d.ts +10 -6
  60. package/dist/core/agent-session.d.ts.map +1 -1
  61. package/dist/core/agent-session.js +107 -107
  62. package/dist/core/agent-session.js.map +1 -1
  63. package/dist/core/auth-storage.d.ts +8 -35
  64. package/dist/core/auth-storage.d.ts.map +1 -1
  65. package/dist/core/auth-storage.js +33 -243
  66. package/dist/core/auth-storage.js.map +1 -1
  67. package/dist/core/cron-jobs.d.ts.map +1 -1
  68. package/dist/core/cron-jobs.js +7 -1
  69. package/dist/core/cron-jobs.js.map +1 -1
  70. package/dist/core/inference-coordinator.d.ts +6 -1
  71. package/dist/core/inference-coordinator.d.ts.map +1 -1
  72. package/dist/core/inference-coordinator.js +18 -2
  73. package/dist/core/inference-coordinator.js.map +1 -1
  74. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  75. package/dist/core/kernel/bootstrap.js +2 -2
  76. package/dist/core/kernel/bootstrap.js.map +1 -1
  77. package/dist/core/kernel/repl-manager.d.ts +2 -0
  78. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  79. package/dist/core/kernel/repl-manager.js +44 -1
  80. package/dist/core/kernel/repl-manager.js.map +1 -1
  81. package/dist/core/logging.d.ts +4 -3
  82. package/dist/core/logging.d.ts.map +1 -1
  83. package/dist/core/logging.js +6 -6
  84. package/dist/core/logging.js.map +1 -1
  85. package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
  86. package/dist/core/mcp/mcp-manager.js +3 -3
  87. package/dist/core/mcp/mcp-manager.js.map +1 -1
  88. package/dist/core/model-registry.d.ts +1 -16
  89. package/dist/core/model-registry.d.ts.map +1 -1
  90. package/dist/core/model-registry.js +88 -196
  91. package/dist/core/model-registry.js.map +1 -1
  92. package/dist/core/model-resolver.d.ts +2 -19
  93. package/dist/core/model-resolver.d.ts.map +1 -1
  94. package/dist/core/model-resolver.js +36 -266
  95. package/dist/core/model-resolver.js.map +1 -1
  96. package/dist/core/provider-contracts.d.ts +5 -6
  97. package/dist/core/provider-contracts.d.ts.map +1 -1
  98. package/dist/core/provider-contracts.js +25 -36
  99. package/dist/core/provider-contracts.js.map +1 -1
  100. package/dist/core/provider-display-names.d.ts.map +1 -1
  101. package/dist/core/provider-display-names.js +0 -2
  102. package/dist/core/provider-display-names.js.map +1 -1
  103. package/dist/core/rlm-max-subagents.d.ts +32 -0
  104. package/dist/core/rlm-max-subagents.d.ts.map +1 -0
  105. package/dist/core/rlm-max-subagents.js +50 -0
  106. package/dist/core/rlm-max-subagents.js.map +1 -0
  107. package/dist/core/rlm-runtime.d.ts +3 -3
  108. package/dist/core/rlm-runtime.d.ts.map +1 -1
  109. package/dist/core/rlm-runtime.js.map +1 -1
  110. package/dist/core/sdk.d.ts +4 -3
  111. package/dist/core/sdk.d.ts.map +1 -1
  112. package/dist/core/sdk.js +27 -14
  113. package/dist/core/sdk.js.map +1 -1
  114. package/dist/core/settings-manager.d.ts +3 -16
  115. package/dist/core/settings-manager.d.ts.map +1 -1
  116. package/dist/core/settings-manager.js +12 -44
  117. package/dist/core/settings-manager.js.map +1 -1
  118. package/dist/core/slash-commands.d.ts.map +1 -1
  119. package/dist/core/slash-commands.js +6 -6
  120. package/dist/core/slash-commands.js.map +1 -1
  121. package/dist/index.d.ts +1 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js.map +1 -1
  124. package/dist/installer.mjs +2 -3
  125. package/dist/main.d.ts.map +1 -1
  126. package/dist/main.js +39 -34
  127. package/dist/main.js.map +1 -1
  128. package/dist/modes/acp/acp-mode.d.ts.map +1 -1
  129. package/dist/modes/acp/acp-mode.js +1 -1
  130. package/dist/modes/acp/acp-mode.js.map +1 -1
  131. package/dist/modes/agent-connection/daemon-agent-connection.d.ts +6 -2
  132. package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
  133. package/dist/modes/agent-connection/daemon-agent-connection.js +13 -2
  134. package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
  135. package/dist/modes/agent-connection/in-process-agent-connection.d.ts +2 -0
  136. package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
  137. package/dist/modes/agent-connection/in-process-agent-connection.js +6 -0
  138. package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
  139. package/dist/modes/agent-connection/types.d.ts +3 -0
  140. package/dist/modes/agent-connection/types.d.ts.map +1 -1
  141. package/dist/modes/agent-connection/types.js.map +1 -1
  142. package/dist/modes/agents-view/agents-view-mode.d.ts.map +1 -1
  143. package/dist/modes/agents-view/agents-view-mode.js +2 -19
  144. package/dist/modes/agents-view/agents-view-mode.js.map +1 -1
  145. package/dist/modes/daemon/daemon-mode.d.ts +5 -0
  146. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  147. package/dist/modes/daemon/daemon-mode.js +107 -12
  148. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  149. package/dist/modes/daemon/daemon-protocol.d.ts +194 -165
  150. package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
  151. package/dist/modes/daemon/daemon-protocol.js +16 -11
  152. package/dist/modes/daemon/daemon-protocol.js.map +1 -1
  153. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts +19 -0
  154. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts.map +1 -0
  155. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js +74 -0
  156. package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js.map +1 -0
  157. package/dist/modes/daemon/daemon-rlm-capacity.d.ts +19 -0
  158. package/dist/modes/daemon/daemon-rlm-capacity.d.ts.map +1 -0
  159. package/dist/modes/daemon/daemon-rlm-capacity.js +85 -0
  160. package/dist/modes/daemon/daemon-rlm-capacity.js.map +1 -0
  161. package/dist/modes/daemon/daemon-session-summarizer.d.ts +2 -3
  162. package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
  163. package/dist/modes/daemon/daemon-session-summarizer.js +32 -23
  164. package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
  165. package/dist/modes/daemon/daemon-state-root.d.ts +15 -0
  166. package/dist/modes/daemon/daemon-state-root.d.ts.map +1 -0
  167. package/dist/modes/daemon/daemon-state-root.js +40 -0
  168. package/dist/modes/daemon/daemon-state-root.js.map +1 -0
  169. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts +2 -0
  170. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
  171. package/dist/modes/daemon/daemon-supervisor-ownership.js +27 -0
  172. package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
  173. package/dist/modes/daemon/daemon-supervisor.d.ts +10 -1
  174. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  175. package/dist/modes/daemon/daemon-supervisor.js +213 -20
  176. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  177. package/dist/modes/daemon/daemon-worker-protocol.d.ts +28 -1
  178. package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
  179. package/dist/modes/daemon/daemon-worker-protocol.js +16 -2
  180. package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
  181. package/dist/modes/daemon/saved-session-catalog.d.ts.map +1 -1
  182. package/dist/modes/daemon/saved-session-catalog.js +2 -0
  183. package/dist/modes/daemon/saved-session-catalog.js.map +1 -1
  184. package/dist/modes/interactive/auth-flows.d.ts +0 -6
  185. package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
  186. package/dist/modes/interactive/auth-flows.js +6 -126
  187. package/dist/modes/interactive/auth-flows.js.map +1 -1
  188. package/dist/modes/interactive/components/configuration-menu.d.ts +3 -0
  189. package/dist/modes/interactive/components/configuration-menu.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/configuration-menu.js +13 -2
  191. package/dist/modes/interactive/components/configuration-menu.js.map +1 -1
  192. package/dist/modes/interactive/components/footer.d.ts +1 -1
  193. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/footer.js +2 -2
  195. package/dist/modes/interactive/components/footer.js.map +1 -1
  196. package/dist/modes/interactive/components/index.d.ts +0 -1
  197. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/index.js +0 -1
  199. package/dist/modes/interactive/components/index.js.map +1 -1
  200. package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
  201. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/login-dialog.js +3 -40
  203. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  204. package/dist/modes/interactive/components/model-selector.d.ts +2 -0
  205. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  206. package/dist/modes/interactive/components/model-selector.js +13 -2
  207. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  208. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  209. package/dist/modes/interactive/components/oauth-selector.js +2 -11
  210. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  211. package/dist/modes/interactive/feature-hints.d.ts.map +1 -1
  212. package/dist/modes/interactive/feature-hints.js +0 -4
  213. package/dist/modes/interactive/feature-hints.js.map +1 -1
  214. package/dist/modes/interactive/interactive-mode.d.ts +3 -12
  215. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  216. package/dist/modes/interactive/interactive-mode.js +81 -507
  217. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  218. package/dist/modes/interactive/onboarding.d.ts +0 -3
  219. package/dist/modes/interactive/onboarding.d.ts.map +1 -1
  220. package/dist/modes/interactive/onboarding.js +0 -17
  221. package/dist/modes/interactive/onboarding.js.map +1 -1
  222. package/dist/modes/rpc/rpc-client.d.ts +4 -1
  223. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  224. package/dist/modes/rpc/rpc-client.js +82 -42
  225. package/dist/modes/rpc/rpc-client.js.map +1 -1
  226. package/dist/node/amazon-bedrock.d.ts +2 -0
  227. package/dist/node/amazon-bedrock.d.ts.map +1 -0
  228. package/dist/node/amazon-bedrock.js +6 -0
  229. package/dist/node/amazon-bedrock.js.map +1 -0
  230. package/dist/product-identity.d.ts +0 -1
  231. package/dist/product-identity.d.ts.map +1 -1
  232. package/dist/product-identity.js +0 -1
  233. package/dist/product-identity.js.map +1 -1
  234. package/docs/development.md +1 -1
  235. package/docs/fork-philosophy.md +4 -8
  236. package/docs/installation.md +83 -62
  237. package/docs/providers.md +23 -25
  238. package/docs/quickstart.md +19 -10
  239. package/docs/rlm-runtime.md +13 -5
  240. package/docs/rpc.md +4 -4
  241. package/docs/sdk.md +20 -11
  242. package/docs/sessions.md +0 -1
  243. package/docs/settings.md +9 -42
  244. package/docs/skills.md +0 -1
  245. package/docs/upstream-0.9.5.md +171 -0
  246. package/docs/usage.md +14 -10
  247. package/package.json +4 -4
  248. package/dist/core/agent-traces.d.ts +0 -149
  249. package/dist/core/agent-traces.d.ts.map +0 -1
  250. package/dist/core/agent-traces.js +0 -904
  251. package/dist/core/agent-traces.js.map +0 -1
  252. package/dist/core/prime-inference-auth.d.ts +0 -70
  253. package/dist/core/prime-inference-auth.d.ts.map +0 -1
  254. package/dist/core/prime-inference-auth.js +0 -352
  255. package/dist/core/prime-inference-auth.js.map +0 -1
  256. package/dist/core/prime-inference-model-selection.d.ts +0 -16
  257. package/dist/core/prime-inference-model-selection.d.ts.map +0 -1
  258. package/dist/core/prime-inference-model-selection.js +0 -16
  259. package/dist/core/prime-inference-model-selection.js.map +0 -1
  260. package/dist/core/prime-inference-models.d.ts +0 -6
  261. package/dist/core/prime-inference-models.d.ts.map +0 -1
  262. package/dist/core/prime-inference-models.js +0 -62
  263. package/dist/core/prime-inference-models.js.map +0 -1
  264. package/dist/core/telemetry.d.ts +0 -95
  265. package/dist/core/telemetry.d.ts.map +0 -1
  266. package/dist/core/telemetry.js +0 -637
  267. package/dist/core/telemetry.js.map +0 -1
  268. package/dist/modes/interactive/components/prime-onboarding-splash.d.ts +0 -39
  269. package/dist/modes/interactive/components/prime-onboarding-splash.d.ts.map +0 -1
  270. package/dist/modes/interactive/components/prime-onboarding-splash.js +0 -286
  271. package/dist/modes/interactive/components/prime-onboarding-splash.js.map +0 -1
  272. package/dist/modes/interactive/components/prime-team-selector.d.ts +0 -30
  273. package/dist/modes/interactive/components/prime-team-selector.d.ts.map +0 -1
  274. package/dist/modes/interactive/components/prime-team-selector.js +0 -166
  275. package/dist/modes/interactive/components/prime-team-selector.js.map +0 -1
  276. package/dist/skills/prime-intellect/SKILL.md +0 -87
  277. package/dist/skills/prime-intellect/references/compute.md +0 -45
  278. package/dist/skills/prime-intellect/references/environments.md +0 -73
  279. package/dist/skills/prime-intellect/references/inference.md +0 -47
  280. package/dist/skills/prime-intellect/references/sandboxes.md +0 -75
  281. package/skills/prime-intellect/SKILL.md +0 -87
  282. package/skills/prime-intellect/references/compute.md +0 -45
  283. package/skills/prime-intellect/references/environments.md +0 -73
  284. package/skills/prime-intellect/references/inference.md +0 -47
  285. package/skills/prime-intellect/references/sandboxes.md +0 -75
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-agent-connection.d.ts","sourceRoot":"","sources":["../../../src/modes/agent-connection/daemon-agent-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentMessage, ThinkingLevel } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, ServiceTier, Transport } from \"@ponythewhite/base-context-ai\";\nimport { appendRotatingLog, getAgentLogPath, getDaemonLogPath } from \"../../config.js\";\nimport type { AgentSessionMessageReceipt, AgentSessionMessageSafetyStatus } from \"../../core/agent-messages.js\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntimeConfig } from \"../../core/agent-session-config.js\";\nimport type { AgentAutonomousStatus } from \"../../core/autonomous.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\nimport type { CompactionResult } from \"../../core/compaction/index.js\";\nimport type { ContextTreeNode } from \"../../core/context-tree.js\";\nimport type {\n\tAgentCronJob,\n\tAgentHeartbeatDeliveryMode,\n\tAgentHeartbeatManagementAction,\n\tAgentHeartbeatUpdateAction,\n} from \"../../core/cron-jobs.js\";\nimport type { AcpMcpServerConfig } from \"../../core/mcp/acp-mcp-types.js\";\nimport type { RefinementResult } from \"../../core/refinement/index.js\";\nimport type { DeleteSessionFileResult } from \"../../core/session-file-actions.js\";\nimport { SessionAlreadyActiveError } from \"../../core/session-lease.js\";\nimport type { SessionStats } from \"../../core/session-stats.js\";\nimport { AgentsViewRosterStore, STALE_ROSTER_DAEMON_MESSAGE } from \"../agents-view/roster-store.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonTransportClient,\n\tgetDaemonSocketCloseReason,\n} from \"../daemon/daemon-client.js\";\nimport { deserializeDaemonError } from \"../daemon/daemon-errors.js\";\nimport {\n\tcollectDaemonClientEnv,\n\tcollectDaemonLaunchEnv,\n\ttype DaemonAttachResult,\n\ttype DaemonCommand,\n\ttype DaemonEventCursor,\n\ttype DaemonOutbound,\n\ttype DaemonReplayInfo,\n\ttype DaemonSessionClosedReason,\n\ttype DaemonSessionSnapshot,\n\tisUnknownDaemonCommandError,\n} from \"../daemon/daemon-protocol.js\";\nimport {\n\tcreateDaemonSessionTransport,\n\tDaemonControlPlaneTransportError,\n\tDaemonDirectTransportClosedError,\n\tDaemonRoutedClient,\n} from \"../daemon/daemon-routed-client.js\";\nimport type { SessionSummary } from \"../daemon/daemon-session-list.js\";\nimport { listDaemonHeartbeats } from \"../daemon/heartbeat-catalog.js\";\nimport {\n\tdeleteDaemonSavedSession,\n\tlistDaemonSavedSessions,\n\trenameDaemonSavedSession,\n} from \"../daemon/saved-session-catalog.js\";\nimport type {\n\tAgentConnection,\n\tAgentConnectionBeforeSessionInvalidateListener,\n\tAgentConnectionEvent,\n\tAgentConnectionEventListener,\n\tAgentConnectionExecuteBashOptions,\n\tAgentConnectionExtensionUiResponse,\n\tAgentConnectionForkOptions,\n\tAgentConnectionHeadlessCompletionOptions,\n\tAgentConnectionHeartbeat,\n\tAgentConnectionModel,\n\tAgentConnectionModelCatalog,\n\tAgentConnectionModelCycleResult,\n\tAgentConnectionNavigateTreeOptions,\n\tAgentConnectionNavigateTreeResult,\n\tAgentConnectionNewSessionOptions,\n\tAgentConnectionPromptOptions,\n\tAgentConnectionQueuedMessageLane,\n\tAgentConnectionQueuedMessageMutation,\n\tAgentConnectionQueuedMessageMutationStatus,\n\tAgentConnectionQueueMode,\n\tAgentConnectionQueueState,\n\tAgentConnectionResourceSnapshot,\n\tAgentConnectionRlmChildAgentSnapshot,\n\tAgentConnectionSavedSessionInfo,\n\tAgentConnectionSavedSessionScope,\n\tAgentConnectionScopedModel,\n\tAgentConnectionSessionContext,\n\tAgentConnectionSessionHeader,\n\tAgentConnectionSessionInputPause,\n\tAgentConnectionSessionListCallbacks,\n\tAgentConnectionSessionTreeFlatNode,\n\tAgentConnectionSessionTreeNode,\n\tAgentConnectionSessionWatcher,\n\tAgentConnectionSideQuestionEvent,\n\tAgentConnectionSideQuestionTurn,\n\tAgentConnectionSlashCommand,\n\tAgentConnectionSnapshot,\n\tAgentConnectionState,\n\tAgentConnectionSwitchSessionOptions,\n\tAgentConnectionToolDefinition,\n\tAgentConnectionUserMessage,\n} from \"./types.js\";\nimport { AgentConnectionPromptAdmissionError } from \"./types.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonSnapshotBegin = Extract<DaemonOutbound, { type: \"session_snapshot_begin\" }>;\n\ninterface DaemonSnapshotAssembly {\n\tbegin?: DaemonSnapshotBegin;\n\tchunks: Map<number, AgentMessage[]>;\n\tpromise: Promise<DaemonSessionSnapshot>;\n\tresolve: (snapshot: DaemonSessionSnapshot) => void;\n\treject: (error: Error) => void;\n\ttimeout: ReturnType<typeof setTimeout>;\n}\n\nexport const DAEMON_REFINE_REQUEST_TIMEOUT_MS = 10 * 60 * 1000;\nconst DAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS = 24 * 60 * 60 * 1000;\nexport const DAEMON_RECONNECT_TIMEOUT_MS = 60_000;\nexport const DAEMON_SNAPSHOT_TIMEOUT_MS = 30_000;\nconst MAX_IGNORED_SNAPSHOT_IDS = 128;\nconst UPDATE_RECONNECT_TIMEOUT_MS = 120000;\nconst UPDATE_RECONNECT_RETRY_MS = 100;\nconst MAX_COMPLETED_SNAPSHOTS = 128;\nconst OWNED_SESSION_DISPOSE_RECONNECT_WAIT_MS = 10_000;\nconst updateTransportReconnects = new WeakMap<DaemonTransportClient, Promise<void>>();\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatErrorSentence(error: unknown): string {\n\tconst message = (error instanceof Error ? error.message : String(error)).trim();\n\tif (!message) {\n\t\treturn \"Unknown daemon error.\";\n\t}\n\treturn /[.!?]$/.test(message) ? message : `${message}.`;\n}\n\nfunction reconnectDaemonTransportAfterUpdate(client: DaemonTransportClient): Promise<void> {\n\tconst existing = updateTransportReconnects.get(client);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\tconst reconnectPromise = Promise.resolve()\n\t\t.then(async () => {\n\t\t\tclient.disconnectForReconnect(\"update\");\n\t\t\tconst deadline = Date.now() + UPDATE_RECONNECT_TIMEOUT_MS;\n\t\t\tlet lastError: unknown;\n\t\t\twhile (Date.now() < deadline) {\n\t\t\t\ttry {\n\t\t\t\t\tawait client.reconnect(1000);\n\t\t\t\t\treturn;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlastError = error;\n\t\t\t\t}\n\t\t\t\tawait delay(UPDATE_RECONNECT_RETRY_MS);\n\t\t\t}\n\t\t\tthrow lastError ?? new Error(\"the updated daemon did not become available\");\n\t\t})\n\t\t.finally(() => {\n\t\t\tif (updateTransportReconnects.get(client) === reconnectPromise) {\n\t\t\t\tupdateTransportReconnects.delete(client);\n\t\t\t}\n\t\t});\n\tupdateTransportReconnects.set(client, reconnectPromise);\n\treturn reconnectPromise;\n}\n\nexport interface DaemonAgentConnectionOptions {\n\tcloseClientOnDispose?: boolean;\n\t/** Secondary watchers pass false to stay on the shared control-plane socket. */\n\tdirectTransport?: boolean;\n\t/** Restart/probe the detached supervisor after a transient socket loss. */\n\trecoverDaemon?: () => Promise<void>;\n\t/** Bound supervisor recovery before surfacing a fatal connection error. */\n\treconnectTimeoutMs?: number;\n\t/** Bound an incomplete streamed snapshot before failing the attach or resync. */\n\tsnapshotTimeoutMs?: number;\n\t/**\n\t * Send this client's allowlisted env (herdr pane identity) with attach so\n\t * an env-less session (e.g. cron-created) adopts it. Set only by the\n\t * primary interactive connection — the daemon adopts-if-absent, never\n\t * rebinds, so watchers must not send env at all.\n\t */\n\tsendClientEnv?: boolean;\n\t/** Advertise support for interactive extension dialogs. */\n\tsupportsExtensionUi?: boolean;\n\t/** Dispose the connection by stopping its hidden worker instead of detaching. */\n\townedSession?: boolean;\n\t/** Fresh runtime context used only if the owned worker must be relaunched. */\n\townedSessionRecoveryConfig?: AgentSessionRuntimeConfig;\n\t/** Require the target worker to have been created with telemetry disabled. */\n\ttelemetryDisabled?: true;\n}\n\n/**\n * AgentConnection adapter for the local daemon JSONL socket transport.\n *\n * InteractiveMode depends only on AgentConnection; local socket ownership and\n * daemon command details stay inside this adapter.\n */\nexport function buildSessionTreeFromFlatNodes(\n\tflatNodes: readonly AgentConnectionSessionTreeFlatNode[],\n): AgentConnectionSessionTreeNode[] {\n\tconst byId = new Map<string, AgentConnectionSessionTreeNode>();\n\tconst roots: AgentConnectionSessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) {\n\t\tbyId.set(flatNode.entry.id, { ...flatNode, children: [] });\n\t}\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = byId.get(entry.id)!;\n\t\tconst parent = entry.parentId === null || entry.parentId === entry.id ? undefined : byId.get(entry.parentId);\n\t\tif (parent) parent.children.push(node);\n\t\telse roots.push(node);\n\t}\n\t// Match SessionManager.getTree() ordering without recursively walking deep\n\t// chains: every node is already indexed, so sort each sibling array directly.\n\tfor (const node of byId.values()) {\n\t\tnode.children.sort(\n\t\t\t(left, right) => new Date(left.entry.timestamp).getTime() - new Date(right.entry.timestamp).getTime(),\n\t\t);\n\t}\n\treturn roots;\n}\n\nexport class DaemonAgentConnection implements AgentConnection {\n\tprivate readonly listeners = new Set<AgentConnectionEventListener>();\n\tprivate readonly unsubscribeDaemonMessages: () => void;\n\tprivate readonly unsubscribeDaemonClose: () => void;\n\tprivate readonly clientId = `daemon-agent-connection:${randomUUID()}`;\n\tprivate readonly sessionInputPauses = new Map<string, Promise<AgentConnectionSessionInputPause>>();\n\tprivate sessionInputPauseGeneration = 0;\n\tprivate ownedSessionPromotionTail = Promise.resolve();\n\tprivate lastEventCursor: DaemonEventCursor | undefined;\n\tprivate readonly retiredEventGenerations = new Set<string>();\n\tprivate lastEventSequence: number | undefined;\n\tprivate childRosterSequence: number | undefined;\n\tprivate latestSnapshot: AgentConnectionSnapshot | undefined;\n\tprivate latestSnapshotIsFresh = false;\n\tprivate attachedSessionId: string | undefined;\n\tprivate attachedSessionFile: string | undefined;\n\tprivate daemonLogPath: string | undefined;\n\tprivate updateRestartPending = false;\n\tprivate updateReconnectFailed = false;\n\tprivate terminalCloseEmitted = false;\n\tprivate updateReconnectPromise?: Promise<void>;\n\tprivate readonly activeSideQuestionIds = new Set<string>();\n\tprivate readonly snapshotAssemblies = new Map<string, DaemonSnapshotAssembly>();\n\tprivate readonly completedSnapshots = new Map<string, DaemonSessionSnapshot>();\n\tprivate readonly pendingReattachActiveSessionIds = new Set<string>();\n\tprivate readonly snapshotRecoveryPromises = new Map<string, Promise<void>>();\n\tprivate readonly ignoredSnapshotIds = new Set<string>();\n\tprivate rosterStore: AgentsViewRosterStore | undefined;\n\tprivate reconnectPromise?: Promise<void>;\n\tprivate initialAttachPending = false;\n\tprivate initialControlPlaneClose?: Error;\n\tprivate readonly definitiveRequestErrors = new WeakSet<Error>();\n\tprivate disposing = false;\n\tprivate disposed = false;\n\n\tconstructor(\n\t\tprivate readonly client: DaemonTransportClient,\n\t\tprivate activeSessionId: string,\n\t\tprivate readonly options: DaemonAgentConnectionOptions = {},\n\t) {\n\t\tif (options.recoverDaemon) {\n\t\t\tthis.client.enableRequestRecovery();\n\t\t}\n\t\tthis.unsubscribeDaemonMessages = this.client.onMessage((message) => {\n\t\t\tvoid this.handleDaemonMessage(message).catch((error: unknown) => {\n\t\t\t\ttry {\n\t\t\t\t\tappendRotatingLog(\n\t\t\t\t\t\tgetAgentLogPath(),\n\t\t\t\t\t\t`[${new Date().toISOString()}] daemon-message: ignored ${message.type} failure: ${String(error)}`,\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// Logging failure must not turn an isolated message error into a connection failure.\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\tthis.captureDaemonLogPath();\n\t\tthis.unsubscribeDaemonClose = this.client.onClose((error) => this.handleTransportClose(error));\n\t}\n\n\tprivate handleTransportClose(error: Error): void {\n\t\tconst directSessionSurvives =\n\t\t\tthis.client instanceof DaemonRoutedClient &&\n\t\t\tthis.client.hasDirectTransport &&\n\t\t\t!(error instanceof DaemonDirectTransportClosedError);\n\t\tconst invalidatedInputPause = !directSessionSurvives && this.sessionInputPauses.size > 0;\n\t\tif (!directSessionSurvives) {\n\t\t\tthis.sessionInputPauses.clear();\n\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\tthis.rejectSnapshotAssemblies(error);\n\t\t}\n\t\tif (this.initialAttachPending) {\n\t\t\t// attach() owns failure handling until the initial attach settles.\n\t\t\tif (directSessionSurvives) this.initialControlPlaneClose = error;\n\t\t\treturn;\n\t\t}\n\t\tif (this.disposed || this.terminalCloseEmitted) {\n\t\t\treturn;\n\t\t}\n\t\t// A lost direct link invalidates the fence (holders learn via the generation bump) yet the session falls back.\n\t\tif (invalidatedInputPause && !(error instanceof DaemonDirectTransportClosedError)) {\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tvoid this.emit({\n\t\t\t\ttype: \"closed\",\n\t\t\t\terror: \"Daemon connection closed while session input was paused; the fence was invalidated.\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// An authoritative shutdown/update reason outranks the surviving direct link.\n\t\tconst closeReason = getDaemonSocketCloseReason(error);\n\t\tif (closeReason === \"shutdown\") {\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tvoid this.emit({ type: \"closed\", error: this.formatDaemonSessionClosedError(\"shutdown\") });\n\t\t\treturn;\n\t\t}\n\t\tif ((this.updateRestartPending || closeReason === \"update\") && !this.updateReconnectFailed) {\n\t\t\tthis.updateRestartPending = true;\n\t\t\tvoid this.reconnectAfterUpdate();\n\t\t\treturn;\n\t\t}\n\t\t// A direct-transport loss is never itself a session loss: fall back through a supervisor re-attach.\n\t\tif (directSessionSurvives || error instanceof DaemonDirectTransportClosedError || this.options.recoverDaemon) {\n\t\t\tvoid this.reconnect(error);\n\t\t\treturn;\n\t\t}\n\t\tthis.terminalCloseEmitted = true;\n\t\tvoid this.emit({ type: \"closed\", error: this.formatDaemonConnectionClosedError(error) });\n\t}\n\n\tstatic async attach(\n\t\tclient: DaemonTransportClient,\n\t\tactiveSessionId: string,\n\t\toptions?: DaemonAgentConnectionOptions,\n\t): Promise<DaemonAgentConnection> {\n\t\tconst transport = await createDaemonSessionTransport(\n\t\t\tclient,\n\t\t\tactiveSessionId,\n\t\t\toptions?.ownedSession === true || options?.directTransport === false,\n\t\t);\n\t\tconst connection = new DaemonAgentConnection(transport, activeSessionId, options);\n\t\tconnection.initialAttachPending = true;\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait connection.attach();\n\t\t\t} catch (error) {\n\t\t\t\tif (!(transport instanceof DaemonRoutedClient)) throw error;\n\t\t\t\ttransport.fallbackToSupervisor();\n\t\t\t\ttry {\n\t\t\t\t\t// This retry owns its failure; a parked request would pend the attach forever.\n\t\t\t\t\tawait connection.attach({ recoverable: false });\n\t\t\t\t} catch (retryError) {\n\t\t\t\t\t// A control-plane close saved during the window is the authoritative cause.\n\t\t\t\t\tthrow connection.initialControlPlaneClose ?? retryError;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconnection.initialAttachPending = false;\n\t\t\tconst initialControlPlaneClose = connection.initialControlPlaneClose;\n\t\t\tconnection.initialControlPlaneClose = undefined;\n\t\t\tif (initialControlPlaneClose) {\n\t\t\t\t// No listeners exist yet: a terminal close rejects the attach; the rest replays through the one handler.\n\t\t\t\tif (getDaemonSocketCloseReason(initialControlPlaneClose) === \"shutdown\") {\n\t\t\t\t\tthrow initialControlPlaneClose;\n\t\t\t\t}\n\t\t\t\tconnection.handleTransportClose(initialControlPlaneClose);\n\t\t\t}\n\t\t\treturn connection;\n\t\t} catch (error) {\n\t\t\tconnection.initialAttachPending = false;\n\t\t\tawait connection.dispose();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync attach(options?: { recoverable?: boolean }): Promise<void> {\n\t\tconst supportsExtensionUi = this.options.supportsExtensionUi !== false;\n\t\tconst result = await this.requestData<SessionSummary | DaemonAttachResult>(\n\t\t\t{\n\t\t\t\ttype: \"attach\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tsupportsExtensionUi,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tcapabilities: [\n\t\t\t\t\t\"attach_snapshot\",\n\t\t\t\t\t\"event_sequence\",\n\t\t\t\t\t...(supportsExtensionUi ? ([\"extension_ui\"] as const) : []),\n\t\t\t\t\t\"slim_attach\",\n\t\t\t\t\t\"chunked_snapshot\",\n\t\t\t\t\t...(this.options.ownedSession ? ([\"client_owned_sessions\"] as const) : []),\n\t\t\t\t],\n\t\t\t\tenv: this.options.sendClientEnv ? collectDaemonClientEnv() : undefined,\n\t\t\t\tlaunchEnv: this.options.ownedSession ? collectDaemonLaunchEnv() : undefined,\n\t\t\t\t...(this.options.ownedSession &&\n\t\t\t\tthis.options.ownedSessionRecoveryConfig &&\n\t\t\t\tthis.client.supportsServerCapability(\"owned_session_recovery_context\")\n\t\t\t\t\t? { recoveryConfig: this.options.ownedSessionRecoveryConfig }\n\t\t\t\t\t: {}),\n\t\t\t\ttelemetryDisabled: this.options.telemetryDisabled,\n\t\t\t\tresumeCursor:\n\t\t\t\t\tthis.lastEventCursor === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\t\t\t\t...this.lastEventCursor,\n\t\t\t\t\t\t\t},\n\t\t\t},\n\t\t\tundefined,\n\t\t\toptions,\n\t\t);\n\t\tthis.activeSessionId = getAttachActiveSessionId(result);\n\t\tconst summary = \"snapshot\" in result ? result.snapshot.summary : result;\n\t\tthis.attachedSessionId = summary.sessionId;\n\t\tthis.attachedSessionFile =\n\t\t\tsummary.sessionFile ?? (\"snapshot\" in result ? result.snapshot.state.sessionFile : undefined);\n\t\tthis.captureDaemonLogPath();\n\t\tthis.updateReconnectFailed = false;\n\t\tthis.terminalCloseEmitted = false;\n\t\tconst attachCursor = getAttachLastEventCursor(result);\n\t\tif (attachCursor) {\n\t\t\tthis.observeEventCursor(attachCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, getAttachLastEventSequence(result));\n\t\tif (\"snapshot\" in result) {\n\t\t\tconst snapshot = result.snapshotStream\n\t\t\t\t? await this.waitForSnapshot(result.snapshotStream.id)\n\t\t\t\t: result.snapshot;\n\t\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot, result.replay);\n\t\t\tif (Array.isArray(snapshot.children)) this.childRosterSequence = snapshot.lastEventSequence;\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tthis.latestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tthis.latestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t} else {\n\t\t\tthis.latestSnapshot = undefined;\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t}\n\t\t// The roster bar is an accessory: its subscribe failure must never fail an\n\t\t// otherwise-recovered session. The bar degrades; the next reconnect or rebind\n\t\t// re-attaches through this same seam.\n\t\tif (this.rosterStore) await this.rosterStore.attach(this.client).catch(() => undefined);\n\t}\n\n\tasync subscribeAgentRoster(\n\t\tlistener: () => void,\n\t): Promise<{ summaries(): SessionSummary[]; dispose(): Promise<void> }> {\n\t\tthis.rosterStore ??= new AgentsViewRosterStore();\n\t\tconst store = this.rosterStore;\n\t\tif (!(await store.attach(this.client))) {\n\t\t\tthrow new Error(STALE_ROSTER_DAEMON_MESSAGE);\n\t\t}\n\t\tconst unsubscribe = store.onUpdate(listener);\n\t\treturn {\n\t\t\tsummaries: () => store.summaries(),\n\t\t\tdispose: async () => unsubscribe(),\n\t\t};\n\t}\n\n\tsubscribe(listener: AgentConnectionEventListener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tonBeforeSessionInvalidate(_listener: AgentConnectionBeforeSessionInvalidateListener): () => void {\n\t\treturn () => {};\n\t}\n\n\tasync getState(): Promise<AgentConnectionState> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot.state;\n\t\t}\n\t\treturn this.requestData<AgentConnectionState>({\n\t\t\ttype: \"get_connection_state\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getInitialSnapshot(options?: { recoverable?: boolean }): Promise<AgentConnectionSnapshot> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot;\n\t\t}\n\t\t// The session tree is intentionally not fetched here: it is large on long\n\t\t// sessions and only needed when the user opens the tree/branch selector.\n\t\t// getSessionTree() fetches it lazily via get_session_tree on first use.\n\t\tconst snapshotCursor = this.lastEventCursor;\n\t\tconst snapshotSequence = this.lastEventSequence;\n\t\tconst [state, messagesData, sessionContextData] = await Promise.all([\n\t\t\tthis.requestData<AgentConnectionState>(\n\t\t\t\t{ type: \"get_connection_state\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t\tthis.requestData<{ messages: AgentMessage[] }>(\n\t\t\t\t{ type: \"get_messages\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t\tthis.requestData<{ context: AgentConnectionSessionContext }>(\n\t\t\t\t{ type: \"get_session_context\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t]);\n\t\tconst children = this.latestSnapshot?.children;\n\t\tconst streamingMessage = this.latestSnapshot?.streamingMessage;\n\t\tthis.latestSnapshot = {\n\t\t\tstate,\n\t\t\tmessages: messagesData.messages,\n\t\t\tsessionContext: sessionContextData.context,\n\t\t\t...(children ? { children } : {}),\n\t\t\t...(streamingMessage ? { streamingMessage } : {}),\n\t\t};\n\t\tif (snapshotSequence !== undefined) {\n\t\t\tthis.latestSnapshot.lastEventSequence = snapshotSequence;\n\t\t}\n\t\tif (snapshotCursor) {\n\t\t\tthis.latestSnapshot.lastEventCursor = snapshotCursor;\n\t\t}\n\t\tthis.latestSnapshotIsFresh =\n\t\t\tsnapshotSequence === this.lastEventSequence &&\n\t\t\tsnapshotCursor?.generation === this.lastEventCursor?.generation &&\n\t\t\tsnapshotCursor?.sequence === this.lastEventCursor?.sequence;\n\t\treturn this.latestSnapshot;\n\t}\n\n\tasync getRlmChildSnapshots(): Promise<AgentConnectionRlmChildAgentSnapshot[]> {\n\t\tif (!this.client.supportsServerCapability(\"authoritative_child_roster\")) {\n\t\t\tthrow new DaemonCapabilityUnavailableError(\"get_rlm_children\", \"authoritative_child_roster\");\n\t\t}\n\t\tconst data = await this.requestData<{\n\t\t\tchildren: AgentConnectionRlmChildAgentSnapshot[];\n\t\t\teventSequence: number;\n\t\t}>({ type: \"get_rlm_children\", activeSessionId: this.activeSessionId });\n\t\tif (!Array.isArray(data.children) || !Number.isInteger(data.eventSequence)) {\n\t\t\tthrow new Error(\"Daemon returned an invalid child roster\");\n\t\t}\n\t\tif ((this.childRosterSequence ?? -1) > data.eventSequence) {\n\t\t\treturn this.latestSnapshot?.children ?? data.children;\n\t\t}\n\t\tthis.childRosterSequence = data.eventSequence;\n\t\tif (this.latestSnapshot) {\n\t\t\tthis.latestSnapshot = { ...this.latestSnapshot, children: data.children };\n\t\t}\n\t\treturn data.children;\n\t}\n\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot.messages;\n\t\t}\n\t\tconst data = await this.requestData<{ messages: AgentMessage[] }>({\n\t\t\ttype: \"get_messages\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.messages;\n\t}\n\n\tasync getSessionHeader(): Promise<AgentConnectionSessionHeader | undefined> {\n\t\tconst data = await this.requestData<{ header?: AgentConnectionSessionHeader | null }>({\n\t\t\ttype: \"get_session_header\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.header ?? undefined;\n\t}\n\n\tasync getCommands(): Promise<AgentConnectionSlashCommand[]> {\n\t\tconst data = await this.requestData<{ commands: AgentConnectionSlashCommand[] }>({\n\t\t\ttype: \"get_commands\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.commands;\n\t}\n\n\tasync getResourceSnapshot(): Promise<AgentConnectionResourceSnapshot> {\n\t\treturn this.requestData<AgentConnectionResourceSnapshot>({\n\t\t\ttype: \"get_resource_snapshot\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tsupportsAcpMcpServers(): boolean {\n\t\treturn this.client.supportsServerCapability(\"acp_mcp_servers\");\n\t}\n\n\tasync replaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): Promise<void> {\n\t\tif (!this.supportsAcpMcpServers()) {\n\t\t\tthrow new DaemonCapabilityUnavailableError(\"replace_acp_mcp_servers\", \"acp_mcp_servers\");\n\t\t}\n\t\tawait this.requestOk({\n\t\t\ttype: \"replace_acp_mcp_servers\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\townerId,\n\t\t\tservers: [...servers],\n\t\t});\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, _serverNames: readonly string[]): Promise<void> {\n\t\tawait this.replaceAcpMcpServers([], ownerId);\n\t}\n\n\tasync getAvailableModels(): Promise<AgentConnectionModel[]> {\n\t\tconst data = await this.requestData<{ models: AgentConnectionModel[] }>({\n\t\t\ttype: \"get_available_models\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.models;\n\t}\n\n\tasync getModelCatalog(): Promise<AgentConnectionModelCatalog> {\n\t\tif (!this.client.supportsServerCapability(\"model_catalog\")) {\n\t\t\tconst models = await this.getAvailableModels();\n\t\t\treturn {\n\t\t\t\tmodels,\n\t\t\t\tconfiguredProviders: [...new Set(models.map((model) => model.provider))],\n\t\t\t};\n\t\t}\n\t\treturn this.requestData<AgentConnectionModelCatalog>({\n\t\t\ttype: \"get_model_catalog\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\treturn this.requestData<SessionStats>({\n\t\t\ttype: \"get_session_stats\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getContextTree(): Promise<ContextTreeNode> {\n\t\treturn this.requestData<ContextTreeNode>({\n\t\t\ttype: \"get_context_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getSessionContext(): Promise<AgentConnectionSessionContext> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot?.sessionContext) {\n\t\t\treturn this.latestSnapshot.sessionContext;\n\t\t}\n\t\tconst data = await this.requestData<{ context: AgentConnectionSessionContext }>({\n\t\t\ttype: \"get_session_context\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.context;\n\t}\n\n\tasync getSessionTree(): Promise<{ tree: AgentConnectionSessionTreeNode[]; leafId: string | null }> {\n\t\tconst data = await this.requestData<{\n\t\t\tflatNodes: AgentConnectionSessionTreeFlatNode[];\n\t\t\tleafId: string | null;\n\t\t}>({\n\t\t\ttype: \"get_session_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn { tree: buildSessionTreeFromFlatNodes(data.flatNodes), leafId: data.leafId };\n\t}\n\n\tasync listSavedSessions(\n\t\tscope: AgentConnectionSavedSessionScope,\n\t\tcallbacks?: AgentConnectionSessionListCallbacks,\n\t): Promise<AgentConnectionSavedSessionInfo[]> {\n\t\treturn listDaemonSavedSessions(this.client, { activeSessionId: this.activeSessionId }, scope, callbacks);\n\t}\n\n\tasync getQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.requestData<AgentConnectionQueueState>({\n\t\t\ttype: \"get_queue\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync mutateQueuedMessage(\n\t\tlane: AgentConnectionQueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: AgentConnectionQueuedMessageMutation,\n\t): Promise<AgentConnectionQueuedMessageMutationStatus> {\n\t\tif (!this.client.supportsServerCapability(\"queue_message_mutation\")) return \"unsupported\";\n\t\tconst data = await this.requestData<{ status: AgentConnectionQueuedMessageMutationStatus }>({\n\t\t\ttype: \"mutate_queued_message\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tlane,\n\t\t\tindex,\n\t\t\texpectedText,\n\t\t\tmutation,\n\t\t});\n\t\treturn data.status;\n\t}\n\n\tasync clearQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.requestData<AgentConnectionQueueState>({\n\t\t\ttype: \"clear_queue\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync abortAndClearQueue(): Promise<AgentConnectionQueueState> {\n\t\ttry {\n\t\t\treturn await this.requestData<AgentConnectionQueueState>({\n\t\t\t\ttype: \"abort_and_clear_queue\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"abort_and_clear_queue\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync acquireSessionInputPause(leaseKey: string): Promise<AgentConnectionSessionInputPause> {\n\t\tif (this.terminalCloseEmitted) throw new Error(\"Daemon connection is closed; cannot acquire an input pause.\");\n\t\tconst activeSessionId = this.activeSessionId;\n\t\tconst generation = this.sessionInputPauseGeneration;\n\t\tconst acquisitionKey = JSON.stringify([activeSessionId, leaseKey]);\n\t\tconst existing = this.sessionInputPauses.get(acquisitionKey);\n\t\tif (existing) return existing;\n\t\tconst acquisition = (async (): Promise<AgentConnectionSessionInputPause> => {\n\t\t\tconst { pauseId } = await this.requestData<{ pauseId: string }>({\n\t\t\t\ttype: \"acquire_session_input_pause\",\n\t\t\t\tactiveSessionId,\n\t\t\t\tleaseKey,\n\t\t\t});\n\t\t\tif (generation !== this.sessionInputPauseGeneration || this.terminalCloseEmitted) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.requestData({\n\t\t\t\t\t\ttype: \"release_session_input_pause\",\n\t\t\t\t\t\tactiveSessionId,\n\t\t\t\t\t\tpauseId,\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tthis.client.close();\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"Session input pause acquisition was invalidated by a daemon reconnect.\");\n\t\t\t}\n\t\t\tlet released = false;\n\t\t\treturn {\n\t\t\t\trelease: async () => {\n\t\t\t\t\tif (released) return;\n\t\t\t\t\tif (generation !== this.sessionInputPauseGeneration) {\n\t\t\t\t\t\tthrow new Error(\"Session input pause was invalidated by a daemon reconnect.\");\n\t\t\t\t\t}\n\t\t\t\t\tawait this.requestData({\n\t\t\t\t\t\ttype: \"release_session_input_pause\",\n\t\t\t\t\t\tactiveSessionId,\n\t\t\t\t\t\tpauseId,\n\t\t\t\t\t});\n\t\t\t\t\treleased = true;\n\t\t\t\t\tif (this.sessionInputPauses.get(acquisitionKey) === acquisition) {\n\t\t\t\t\t\tthis.sessionInputPauses.delete(acquisitionKey);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t})();\n\t\tthis.sessionInputPauses.set(acquisitionKey, acquisition);\n\t\ttry {\n\t\t\treturn await acquisition;\n\t\t} catch (error) {\n\t\t\tif (this.sessionInputPauses.get(acquisitionKey) === acquisition)\n\t\t\t\tthis.sessionInputPauses.delete(acquisitionKey);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync listCronJobs(options: { includeInactive?: boolean } = {}): Promise<AgentCronJob[]> {\n\t\tconst data = await this.requestData<{ jobs: AgentCronJob[] }>({\n\t\t\ttype: \"cron_list\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tincludeInactive: options.includeInactive,\n\t\t});\n\t\treturn data.jobs;\n\t}\n\n\tasync listHeartbeats(): Promise<AgentConnectionHeartbeat[]> {\n\t\treturn listDaemonHeartbeats(this.client, this.options.ownedSession ? this.activeSessionId : undefined);\n\t}\n\n\tasync manageHeartbeat(\n\t\tactiveSessionId: string,\n\t\tjobId: string,\n\t\taction: AgentHeartbeatManagementAction,\n\t): Promise<AgentCronJob> {\n\t\tif (!this.client.supportsServerCapability(\"heartbeat_management\")) {\n\t\t\tthrow new Error(\"Heartbeat management requires a newer Base Context daemon.\");\n\t\t}\n\t\ttry {\n\t\t\tconst data = await this.requestData<{ heartbeat: AgentCronJob }>({\n\t\t\t\ttype: \"heartbeat_manage\",\n\t\t\t\tactiveSessionId,\n\t\t\t\tjobId,\n\t\t\t\taction,\n\t\t\t});\n\t\t\treturn data.heartbeat;\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"heartbeat_manage\")) {\n\t\t\t\tthrow new Error(\"Heartbeat management requires a newer Base Context daemon.\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync addCronJob(schedule: string, prompt: string): Promise<AgentCronJob> {\n\t\treturn this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tconst data = await this.requestData<{ job: AgentCronJob }>({\n\t\t\t\ttype: \"cron_add\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tschedule,\n\t\t\t\tprompt,\n\t\t\t\tpromoteOwnedSession,\n\t\t\t});\n\t\t\treturn data.job;\n\t\t});\n\t}\n\n\tasync cancelCronJob(jobId: string): Promise<AgentCronJob> {\n\t\tconst data = await this.requestData<{ job: AgentCronJob }>({\n\t\t\ttype: \"cron_cancel\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tjobId,\n\t\t});\n\t\treturn data.job;\n\t}\n\n\tasync getHeartbeat(): Promise<AgentCronJob | undefined> {\n\t\tconst data = await this.requestData<{ heartbeat?: AgentCronJob | null }>({\n\t\t\ttype: \"heartbeat_get\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.heartbeat ?? undefined;\n\t}\n\n\tasync setHeartbeat(\n\t\tschedule: string,\n\t\tinstruction: string,\n\t\tdeliveryMode?: AgentHeartbeatDeliveryMode,\n\t): Promise<AgentCronJob> {\n\t\treturn this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tconst data = await this.requestData<{ heartbeat: AgentCronJob }>({\n\t\t\t\ttype: \"heartbeat_set\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tschedule,\n\t\t\t\tprompt: instruction,\n\t\t\t\t...(deliveryMode ? { deliveryMode } : {}),\n\t\t\t\tpromoteOwnedSession,\n\t\t\t});\n\t\t\treturn data.heartbeat;\n\t\t});\n\t}\n\n\tasync updateHeartbeat(action: AgentHeartbeatUpdateAction): Promise<AgentCronJob | undefined> {\n\t\tconst data = await this.requestData<{ heartbeat?: AgentCronJob | null }>({\n\t\t\ttype: \"heartbeat_update\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\taction,\n\t\t});\n\t\treturn data.heartbeat ?? undefined;\n\t}\n\n\tasync sendAgentMessage(targetActiveSessionId: string, message: string): Promise<AgentSessionMessageReceipt> {\n\t\treturn this.requestData<AgentSessionMessageReceipt>({\n\t\t\ttype: \"send_message\",\n\t\t\ttargetActiveSessionId,\n\t\t\tmessage,\n\t\t\tfromActiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getAgentMessageStatus(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_status\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync pauseAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_pause\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync resumeAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_resume\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync clearAgentMessages(): Promise<number> {\n\t\treturn this.requestData<number>({\n\t\t\ttype: \"agent_messages_clear\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getUserMessagesForForking(): Promise<AgentConnectionUserMessage[]> {\n\t\tconst data = await this.requestData<{ messages: AgentConnectionUserMessage[] }>({\n\t\t\ttype: \"get_user_messages_for_forking\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.messages;\n\t}\n\n\tasync getLastAssistantText(): Promise<string | undefined> {\n\t\tconst data = await this.requestData<{ text?: string | null }>({\n\t\t\ttype: \"get_last_assistant_text\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.text ?? undefined;\n\t}\n\n\tasync getSystemPrompt(): Promise<string> {\n\t\tconst data = await this.requestData<{ systemPrompt: string }>({\n\t\t\ttype: \"get_system_prompt\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.systemPrompt;\n\t}\n\n\tasync getToolDefinition(name: string): Promise<AgentConnectionToolDefinition | undefined> {\n\t\tconst data = await this.requestData<{ toolDefinition?: AgentConnectionToolDefinition }>({\n\t\t\ttype: \"get_tool_definition\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tname,\n\t\t});\n\t\treturn data.toolDefinition;\n\t}\n\n\tasync setSessionEntryLabel(entryId: string, label: string | undefined): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"set_session_entry_label\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tentryId,\n\t\t\tlabel,\n\t\t});\n\t}\n\n\tasync respondToExtensionUiRequest(requestId: string, response: AgentConnectionExtensionUiResponse): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"extension_ui_response\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\trequestId,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync prompt(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.promptWithAdmissionCancellation(\"prompt\", message, options);\n\t}\n\n\tasync promptAndWait(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.promptWithAdmissionCancellation(\"prompt_and_wait\", message, options);\n\t}\n\n\tprivate async promptWithAdmissionCancellation(\n\t\ttype: \"prompt\" | \"prompt_and_wait\",\n\t\tmessage: string,\n\t\toptions?: AgentConnectionPromptOptions,\n\t): Promise<void> {\n\t\tconst signal = options?.signal;\n\t\tif (signal?.aborted) {\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\"Prompt admission was cancelled.\", \"cancelled\");\n\t\t}\n\t\tif (!signal) {\n\t\t\tawait this.requestData<unknown>(\n\t\t\t\t{\n\t\t\t\t\ttype,\n\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\tmessage,\n\t\t\t\t\timages: options?.images,\n\t\t\t\t\tstreamingBehavior: options?.streamingBehavior,\n\t\t\t\t\tqueueIfBusy: options?.queueIfBusy,\n\t\t\t\t\tsource: options?.source,\n\t\t\t\t},\n\t\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst admissionId = `prompt-admission:${randomUUID()}`;\n\t\tlet resolveAbort = () => {};\n\t\tconst aborted = new Promise<\"abort\">((resolve) => {\n\t\t\tresolveAbort = () => resolve(\"abort\");\n\t\t});\n\t\tconst onAbort = () => resolveAbort();\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t// Close the listener-registration race before issuing the first request.\n\t\tif (signal.aborted) {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\"Prompt admission was cancelled.\", \"cancelled\");\n\t\t}\n\t\tconst command = {\n\t\t\ttype,\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tmessage,\n\t\t\timages: options.images,\n\t\t\tstreamingBehavior: options.streamingBehavior,\n\t\t\tqueueIfBusy: options.queueIfBusy,\n\t\t\tsource: options.source,\n\t\t\tadmissionId,\n\t\t} as Extract<DaemonCommandBody, { type: typeof type }>;\n\t\tlet promptError: unknown;\n\t\tconst promptRequest = this.requestData<unknown>(command, DAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS).catch(\n\t\t\t(error: unknown) => {\n\t\t\t\tpromptError =\n\t\t\t\t\terror instanceof DaemonCapabilityUnavailableError && !error.afterReconnect\n\t\t\t\t\t\t? new AgentConnectionPromptAdmissionError(error.message, \"unsupported\", { cause: error })\n\t\t\t\t\t\t: error;\n\t\t\t\treturn \"failed\" as const;\n\t\t\t},\n\t\t);\n\t\ttry {\n\t\t\tconst first = await Promise.race([promptRequest.then(() => \"settled\" as const), aborted]);\n\t\t\tif (first === \"settled\" && promptError === undefined) return;\n\t\t\tif (first === \"settled\" && promptError instanceof AgentConnectionPromptAdmissionError) throw promptError;\n\t\t\tif (\n\t\t\t\tfirst === \"settled\" &&\n\t\t\t\t!signal.aborted &&\n\t\t\t\tpromptError instanceof Error &&\n\t\t\t\tthis.definitiveRequestErrors.has(promptError)\n\t\t\t) {\n\t\t\t\tthrow promptError;\n\t\t\t}\n\t\t\tlet status: \"cancelled\" | \"owned\" | \"unknown\" = \"unknown\";\n\t\t\ttry {\n\t\t\t\tconst result = await this.requestData<{ status: \"cancelled\" | \"owned\" | \"unknown\" }>({\n\t\t\t\t\ttype: \"cancel_prompt_admission\",\n\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\tadmissionId,\n\t\t\t\t\t...(this.client.supportsServerCapability(\"owned_prompt_cancellation\") ? { cancelOwned: true } : {}),\n\t\t\t\t});\n\t\t\t\tstatus = result.status;\n\t\t\t} catch {\n\t\t\t\t// Timeout/transport is indistinguishable from accepted ownership.\n\t\t\t}\n\t\t\tawait promptRequest;\n\t\t\tif (promptError instanceof AgentConnectionPromptAdmissionError) throw promptError;\n\t\t\tconst definitiveFailure = promptError instanceof Error && this.definitiveRequestErrors.has(promptError);\n\t\t\tif (promptError === undefined || (status === \"owned\" && type === \"prompt\" && !definitiveFailure)) return;\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\n\t\t\t\tpromptError instanceof Error ? promptError.message : \"Prompt admission did not complete.\",\n\t\t\t\tstatus,\n\t\t\t\tpromptError === undefined ? undefined : { cause: promptError },\n\t\t\t);\n\t\t} finally {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t}\n\t}\n\n\tasync startSideQuestion(\n\t\tid: string,\n\t\tquestion: string,\n\t\tpreviousTurns?: AgentConnectionSideQuestionTurn[],\n\t): Promise<void> {\n\t\tif (previousTurns?.length && !this.client.supportsServerCapability(\"side_question_transcript\")) {\n\t\t\t// An older daemon would silently ignore previousTurns and answer the\n\t\t\t// follow-up without the side-conversation context; fail loudly instead.\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without side-conversation follow-ups; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\tthis.activeSideQuestionIds.add(id);\n\t\ttry {\n\t\t\tawait this.requestOk({\n\t\t\t\ttype: \"start_side_question\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tsideQuestionId: id,\n\t\t\t\tquestion,\n\t\t\t\tpreviousTurns,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.activeSideQuestionIds.delete(id);\n\t\t\tif (isUnknownDaemonCommandError(error, \"start_side_question\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync abortSideQuestion(id: string): Promise<boolean> {\n\t\tconst data = await this.requestData<{ aborted: boolean }>({\n\t\t\ttype: \"abort_side_question\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tsideQuestionId: id,\n\t\t});\n\t\tthis.activeSideQuestionIds.delete(id);\n\t\treturn data.aborted;\n\t}\n\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.requestOk({ type: \"steer\", activeSessionId: this.activeSessionId, message, images });\n\t}\n\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.requestOk({ type: \"follow_up\", activeSessionId: this.activeSessionId, message, images });\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync cancelRlmChild(childId: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst result = await this.requestData<{ cancelled: boolean }>({\n\t\t\t\ttype: \"cancel_rlm_child\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tchildId,\n\t\t\t});\n\t\t\treturn result.cancelled;\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"cancel_rlm_child\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this.requestData<unknown>(\n\t\t\t{ type: \"wait_for_idle\", activeSessionId: this.activeSessionId },\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync waitForHeadlessCompletion(options?: AgentConnectionHeadlessCompletionOptions): Promise<AgentAutonomousStatus> {\n\t\tif (options?.waitForRlmQuiescence && !this.client.supportsServerCapability(\"rlm_quiescence_barrier\")) {\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without RLM quiescence barriers; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\treturn this.requestData<AgentAutonomousStatus>(\n\t\t\t{\n\t\t\t\ttype: \"wait_for_headless_completion\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t...(options?.waitForRlmQuiescence ? { waitForRlmQuiescence: true } : {}),\n\t\t\t},\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync executeBash(command: string, options?: AgentConnectionExecuteBashOptions): Promise<void> {\n\t\tif (options?.transient && !this.client.supportsServerCapability(\"transient_bash\")) {\n\t\t\t// An older daemon would record the run into the session, leaking the\n\t\t\t// side conversation into the main transcript; fail loudly instead.\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without side-conversation bash; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tawait this.requestOk({\n\t\t\t\ttype: \"execute_bash\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tcommand,\n\t\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t\t\ttransient: options?.transient,\n\t\t\t\trunId: options?.runId,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"execute_bash\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync executeBashAndWait(command: string): Promise<BashResult> {\n\t\treturn this.requestData<BashResult>(\n\t\t\t{\n\t\t\t\ttype: \"execute_bash_and_wait\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tcommand,\n\t\t\t},\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync abortBash(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.requestOk({ type: \"abort_bash\", activeSessionId: this.activeSessionId });\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"abort_bash\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync setModel(provider: string, modelId: string): Promise<AgentConnectionModel> {\n\t\treturn this.requestData<AgentConnectionModel>({\n\t\t\ttype: \"set_model\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t});\n\t}\n\n\tasync cycleModel(direction?: \"forward\" | \"backward\"): Promise<AgentConnectionModelCycleResult | undefined> {\n\t\tconst result = await this.requestData<AgentConnectionModelCycleResult | null>({\n\t\t\ttype: \"cycle_model\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tdirection,\n\t\t});\n\t\treturn result ?? undefined;\n\t}\n\n\tasync setScopedModels(scopedModels: AgentConnectionScopedModel[]): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"set_scoped_models\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tscopedModels,\n\t\t});\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_thinking_level\", activeSessionId: this.activeSessionId, level });\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_service_tier\", activeSessionId: this.activeSessionId, serviceTier });\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\tconst result = await this.requestData<{ level: ThinkingLevel } | null>({\n\t\t\ttype: \"cycle_thinking_level\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn result?.level;\n\t}\n\n\tasync setTransport(transport: Transport): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_transport\", activeSessionId: this.activeSessionId, transport });\n\t}\n\n\tasync setSteeringMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_steering_mode\", activeSessionId: this.activeSessionId, mode });\n\t}\n\n\tasync setFollowUpMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_follow_up_mode\", activeSessionId: this.activeSessionId, mode });\n\t}\n\n\tasync setAutoCompactionEnabled(enabled: boolean): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_auto_compaction\", activeSessionId: this.activeSessionId, enabled });\n\t}\n\n\tasync setAutoRetryEnabled(enabled: boolean): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_auto_retry\", activeSessionId: this.activeSessionId, enabled });\n\t}\n\n\tasync compact(customInstructions?: string): Promise<CompactionResult> {\n\t\treturn this.requestData<CompactionResult>({\n\t\t\ttype: \"compact\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tcustomInstructions,\n\t\t});\n\t}\n\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t): Promise<RefinementResult> {\n\t\tconst command: {\n\t\t\ttype: \"refine\";\n\t\t\tactiveSessionId: string;\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t} = {\n\t\t\ttype: \"refine\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tinstructions: options.instructions,\n\t\t\trollbackId: options.rollbackId,\n\t\t};\n\t\tif (options.global !== undefined) {\n\t\t\tcommand.global = options.global;\n\t\t}\n\t\treturn this.requestData<RefinementResult>(command, DAEMON_REFINE_REQUEST_TIMEOUT_MS);\n\t}\n\n\tasync abortCompaction(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_compaction\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync abortBranchSummary(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_branch_summary\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync abortRetry(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_retry\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tawait this.requestOk({ type: \"reload\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync newSession(options?: AgentConnectionNewSessionOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.requestData<{ cancelled: boolean }>({\n\t\t\ttype: \"new_session\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tparentSession: options?.parentSession,\n\t\t});\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: AgentConnectionSwitchSessionOptions,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst sourceActiveSessionId = this.activeSessionId;\n\t\ttry {\n\t\t\treturn await this.requestData<{ cancelled: boolean }>({\n\t\t\t\ttype: \"switch_session\",\n\t\t\t\tactiveSessionId: sourceActiveSessionId,\n\t\t\t\tsessionPath,\n\t\t\t\tcwdOverride: options?.cwdOverride,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof SessionAlreadyActiveError) || !error.activeSessionId) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (this.options.ownedSession) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error.activeSessionId === sourceActiveSessionId) {\n\t\t\t\treturn { cancelled: false };\n\t\t\t}\n\t\t\treturn this.reattachSession(sourceActiveSessionId, error.activeSessionId);\n\t\t}\n\t}\n\n\tprivate async reattachSession(\n\t\tsourceActiveSessionId: string,\n\t\ttargetActiveSessionId: string,\n\t): Promise<{ cancelled: false }> {\n\t\tconst previousState = {\n\t\t\tlastEventCursor: this.lastEventCursor,\n\t\t\tlastEventSequence: this.lastEventSequence,\n\t\t\tlatestSnapshot: this.latestSnapshot,\n\t\t\tlatestSnapshotIsFresh: this.latestSnapshotIsFresh,\n\t\t\tretiredEventGenerations: new Set(this.retiredEventGenerations),\n\t\t};\n\t\tthis.activeSessionId = targetActiveSessionId;\n\t\tthis.lastEventCursor = undefined;\n\t\tthis.lastEventSequence = undefined;\n\t\tthis.latestSnapshot = undefined;\n\t\tthis.latestSnapshotIsFresh = false;\n\t\tthis.retiredEventGenerations.clear();\n\t\tthis.pendingReattachActiveSessionIds.add(targetActiveSessionId);\n\t\tlet reattached = false;\n\t\ttry {\n\t\t\tconst supportsExtensionUi = this.options.supportsExtensionUi !== false;\n\t\t\tconst result = await this.requestData<DaemonAttachResult>({\n\t\t\t\ttype: \"reattach\",\n\t\t\t\tactiveSessionId: sourceActiveSessionId,\n\t\t\t\ttargetActiveSessionId,\n\t\t\t\tsupportsExtensionUi,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tcapabilities: [\n\t\t\t\t\t\"attach_snapshot\",\n\t\t\t\t\t\"event_sequence\",\n\t\t\t\t\t...(supportsExtensionUi ? ([\"extension_ui\"] as const) : []),\n\t\t\t\t\t\"slim_attach\",\n\t\t\t\t\t\"chunked_snapshot\",\n\t\t\t\t\t...(this.options.ownedSession ? ([\"client_owned_sessions\"] as const) : []),\n\t\t\t\t],\n\t\t\t\tenv: this.options.sendClientEnv ? collectDaemonClientEnv() : undefined,\n\t\t\t\tlaunchEnv: this.options.ownedSession ? collectDaemonLaunchEnv() : undefined,\n\t\t\t\ttelemetryDisabled: this.options.telemetryDisabled,\n\t\t\t});\n\t\t\t// Reattach rebinds the connection (and drops any direct link); pauses on the old session are gone.\n\t\t\tthis.sessionInputPauses.clear();\n\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\treattached = true;\n\t\t\tthis.activeSessionId = result.activeSessionId;\n\t\t\tthis.activeSideQuestionIds.clear();\n\t\t\tif (result.snapshotStream) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.waitForSnapshot(result.snapshotStream.id);\n\t\t\t\t} catch (snapshotError) {\n\t\t\t\t\tawait this.snapshotRecoveryPromises.get(result.snapshotStream.id);\n\t\t\t\t\tif (!this.latestSnapshotIsFresh) {\n\t\t\t\t\t\tthrow snapshotError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.applyReplacementSnapshot(result.snapshot, result.replay);\n\t\t\t\tawait this.emit({\n\t\t\t\t\ttype: \"session_replaced\",\n\t\t\t\t\tstate: result.snapshot.state,\n\t\t\t\t\tmessages: result.snapshot.messages,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { cancelled: false };\n\t\t} catch (error) {\n\t\t\tif (!reattached) {\n\t\t\t\tthis.activeSessionId = sourceActiveSessionId;\n\t\t\t\tthis.lastEventCursor = previousState.lastEventCursor;\n\t\t\t\tthis.lastEventSequence = previousState.lastEventSequence;\n\t\t\t\tthis.latestSnapshot = previousState.latestSnapshot;\n\t\t\t\tthis.latestSnapshotIsFresh = previousState.latestSnapshotIsFresh;\n\t\t\t\tthis.retiredEventGenerations.clear();\n\t\t\t\tfor (const generation of previousState.retiredEventGenerations) {\n\t\t\t\t\tthis.retiredEventGenerations.add(generation);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingReattachActiveSessionIds.delete(targetActiveSessionId);\n\t\t}\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: AgentConnectionForkOptions,\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\treturn this.requestData<{ cancelled: boolean; selectedText?: string }>({\n\t\t\ttype: \"fork\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tentryId,\n\t\t\tposition: options?.position,\n\t\t});\n\t}\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions?: AgentConnectionNavigateTreeOptions,\n\t): Promise<AgentConnectionNavigateTreeResult> {\n\t\treturn this.requestData<AgentConnectionNavigateTreeResult>({\n\t\t\ttype: \"navigate_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\ttargetId,\n\t\t\tsummarize: options?.summarize,\n\t\t\tcustomInstructions: options?.customInstructions,\n\t\t\treplaceInstructions: options?.replaceInstructions,\n\t\t\tlabel: options?.label,\n\t\t});\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\treturn this.requestData<{ cancelled: boolean }>({\n\t\t\ttype: \"import_jsonl\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tinputPath,\n\t\t\tcwdOverride,\n\t\t});\n\t}\n\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\tconst data = await this.requestData<{ path: string }>({\n\t\t\ttype: \"export_html\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\toutputPath,\n\t\t});\n\t\treturn data.path;\n\t}\n\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\tconst data = await this.requestData<{ path: string }>({\n\t\t\ttype: \"export_jsonl\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\toutputPath,\n\t\t});\n\t\treturn data.path;\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_session_name\", activeSessionId: this.activeSessionId, name });\n\t}\n\n\tasync getRlmMaxDepthStatus() {\n\t\treturn this.requestData<{ maxDepth: number; source: \"default\" | \"env\" | \"global\" | \"inherited\" | \"chat\" }>({\n\t\t\ttype: \"get_rlm_max_depth_status\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options?: { global?: boolean }) {\n\t\treturn this.requestData<{\n\t\t\tmaxDepth: number;\n\t\t\tsource: \"default\" | \"env\" | \"global\" | \"inherited\" | \"chat\";\n\t\t\tglobalSaved: boolean;\n\t\t\tglobalError?: string;\n\t\t}>({\n\t\t\ttype: \"set_rlm_max_depth\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tmaxDepth,\n\t\t\tglobal: options?.global,\n\t\t});\n\t}\n\n\tasync renameSavedSession(sessionPath: string, name: string): Promise<void> {\n\t\tawait renameDaemonSavedSession(this.client, { activeSessionId: this.activeSessionId }, sessionPath, name);\n\t}\n\n\tasync deleteSavedSession(sessionPath: string): Promise<DeleteSessionFileResult> {\n\t\treturn deleteDaemonSavedSession(this.client, { activeSessionId: this.activeSessionId }, sessionPath);\n\t}\n\n\tasync watchSession(activeSessionId: string): Promise<AgentConnectionSessionWatcher | undefined> {\n\t\t// A second connection on the shared client; each one filters to its own session id.\n\t\t// attach() rejects for an unknown/exited session — treat that as unreachable.\n\t\tlet connection: DaemonAgentConnection;\n\t\ttry {\n\t\t\tconst watchClient =\n\t\t\t\tthis.client instanceof DaemonRoutedClient ? this.client.controlPlaneTransport : this.client;\n\t\t\tconnection = await DaemonAgentConnection.attach(watchClient, activeSessionId, {\n\t\t\t\tcloseClientOnDispose: false,\n\t\t\t\tdirectTransport: false,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tgetMessages: () => connection.getMessages(),\n\t\t\tgetCommands: () => connection.getCommands(),\n\t\t\tsubscribe: (listener) => connection.subscribe(listener),\n\t\t\tgetToolDefinition: (name) => connection.getToolDefinition(name),\n\t\t\tclose: () => connection.dispose(),\n\t\t};\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this.disposed || this.disposing) {\n\t\t\treturn;\n\t\t}\n\t\tthis.disposing = true;\n\t\tif (this.options.ownedSession && !this.client.isConnected && this.reconnectPromise) {\n\t\t\tawait Promise.race([this.reconnectPromise, delay(OWNED_SESSION_DISPOSE_RECONNECT_WAIT_MS)]).catch(\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t}\n\t\tthis.disposed = true;\n\t\tthis.updateRestartPending = false;\n\t\tawait Promise.allSettled([...this.activeSideQuestionIds].map((id) => this.abortSideQuestion(id)));\n\t\tawait this.rosterStore?.dispose().catch(() => undefined);\n\t\tthis.rosterStore = undefined;\n\t\tthis.unsubscribeDaemonMessages();\n\t\tthis.unsubscribeDaemonClose();\n\t\tif (this.options.ownedSession) {\n\t\t\tawait this.requestOk({ type: \"complete_owned_session\", activeSessionId: this.activeSessionId }).catch(\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.requestOk({ type: \"detach\", activeSessionId: this.activeSessionId }).catch(() => undefined);\n\t\t}\n\t\tif (this.options.closeClientOnDispose) {\n\t\t\tthis.client.close();\n\t\t}\n\t\tthis.rejectSnapshotAssemblies(new Error(\"Daemon connection disposed during snapshot transfer\"));\n\t}\n\n\tasync promoteToResident(): Promise<void> {\n\t\tawait this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tif (!promoteOwnedSession) return;\n\t\t\tawait this.requestOk({ type: \"promote_owned_session\", activeSessionId: this.activeSessionId });\n\t\t});\n\t}\n\n\tprivate withOwnedSessionPromotion<T>(operation: (promoteOwnedSession: boolean) => Promise<T>): Promise<T> {\n\t\tconst run = this.ownedSessionPromotionTail.then(async () => {\n\t\t\tconst promoteOwnedSession = this.options.ownedSession === true;\n\t\t\tconst result = await operation(promoteOwnedSession);\n\t\t\tif (promoteOwnedSession) {\n\t\t\t\tthis.options.ownedSession = false;\n\t\t\t}\n\t\t\treturn result;\n\t\t});\n\t\tthis.ownedSessionPromotionTail = run.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn run;\n\t}\n\n\tprivate async reconnect(cause: Error): Promise<void> {\n\t\tif (this.reconnectPromise) {\n\t\t\treturn this.reconnectPromise;\n\t\t}\n\t\tthis.reconnectPromise = (async () => {\n\t\t\tvoid this.emit({ type: \"connection_status\", status: \"reconnecting\", error: cause.message });\n\t\t\tconst timeoutMs = this.options.reconnectTimeoutMs ?? DAEMON_RECONNECT_TIMEOUT_MS;\n\t\t\tlet deadline: number | undefined;\n\t\t\tlet attempt = 0;\n\t\t\tlet lastError: Error = cause;\n\t\t\twhile (!this.disposed) {\n\t\t\t\t// A held direct link owns session liveness: control-plane recovery retries unbounded,\n\t\t\t\t// and the bounded session-plane deadline arms only once the direct link is gone.\n\t\t\t\tconst directSessionHeld = this.client instanceof DaemonRoutedClient && this.client.hasDirectTransport;\n\t\t\t\tif (directSessionHeld) {\n\t\t\t\t\tdeadline = undefined;\n\t\t\t\t} else {\n\t\t\t\t\tdeadline ??= Date.now() + timeoutMs;\n\t\t\t\t\tif (Date.now() >= deadline) break;\n\t\t\t\t}\n\t\t\t\tlet controlPlaneHandshakeComplete = false;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.options.recoverDaemon?.();\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.client.connect(1000);\n\t\t\t\t\tawait this.client.waitForHello(3000);\n\t\t\t\t\tcontrolPlaneHandshakeComplete = true;\n\t\t\t\t\tif (directSessionHeld) {\n\t\t\t\t\t\t// The roster subscription is a control-plane accessory; its usual rebind seam (attach) is skipped while held.\n\t\t\t\t\t\tif (this.rosterStore) await this.rosterStore.attach(this.client).catch(() => undefined);\n\t\t\t\t\t\t// One check after the last await, against the close handler's own dispatch outputs:\n\t\t\t\t\t\t// terminal closes set terminalCloseEmitted, update closes set updateRestartPending\n\t\t\t\t\t\t// (restoration owns the client), and recoverable closes joined this loop.\n\t\t\t\t\t\tif (this.disposed || this.terminalCloseEmitted || this.updateRestartPending) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (this.client instanceof DaemonRoutedClient && this.client.hasDirectTransport) {\n\t\t\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// The direct link died mid-recovery: rerun as a bounded session-plane reconnect.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// This loop owns the retry: a socket close must reject these instead of parking them behind a hello it can never produce.\n\t\t\t\t\tawait this.attach({ recoverable: false });\n\t\t\t\t\tif (!this.disposed) {\n\t\t\t\t\t\tconst snapshot = await this.getInitialSnapshot({ recoverable: false });\n\t\t\t\t\t\tvoid this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlastError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// A direct-half failure must not tear down a control-plane socket with a completed handshake.\n\t\t\t\t\tconst shouldResetControlPlane =\n\t\t\t\t\t\t!(this.client instanceof DaemonRoutedClient) ||\n\t\t\t\t\t\t!controlPlaneHandshakeComplete ||\n\t\t\t\t\t\terror instanceof DaemonControlPlaneTransportError ||\n\t\t\t\t\t\t!this.client.isControlPlaneReady;\n\t\t\t\t\tif (shouldResetControlPlane) this.client.resetTransportForReconnect();\n\t\t\t\t\tif (deadline !== undefined && deadline - Date.now() <= 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst delayMs = Math.min(\n\t\t\t\t\t\t...(deadline !== undefined ? [deadline - Date.now()] : []),\n\t\t\t\t\t\t2000,\n\t\t\t\t\t\t100 * 2 ** Math.min(attempt, 5),\n\t\t\t\t\t);\n\t\t\t\t\tattempt++;\n\t\t\t\t\tawait new Promise((resolveDelay) => setTimeout(resolveDelay, delayMs));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this.disposed) {\n\t\t\t\tthis.sessionInputPauses.clear();\n\t\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\t\tthis.client.close();\n\t\t\t\tawait this.emit({ type: \"closed\", error: `Daemon reconnection failed: ${lastError.message}` });\n\t\t\t}\n\t\t})().finally(() => {\n\t\t\tthis.reconnectPromise = undefined;\n\t\t});\n\t\treturn this.reconnectPromise;\n\t}\n\n\tprivate async requestOk(command: DaemonCommandBody): Promise<void> {\n\t\tawait this.requestData<unknown>(command);\n\t}\n\n\tprivate async requestData<T>(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs?: number,\n\t\toptions?: Parameters<DaemonTransportClient[\"request\"]>[2],\n\t): Promise<T> {\n\t\tconst response = await this.client.request(command, timeoutMs, options);\n\t\tif (!response.success) {\n\t\t\tconst error = deserializeDaemonError(response);\n\t\t\tthis.definitiveRequestErrors.add(error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (invalidatesCachedSnapshot(command.type)) {\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t}\n\t\treturn response.data as T;\n\t}\n\n\tprivate async handleDaemonMessage(message: DaemonOutbound): Promise<void> {\n\t\tif (message.type === \"heartbeats_changed\") {\n\t\t\tawait this.emit({ type: \"heartbeats_changed\" });\n\t\t\treturn;\n\t\t}\n\t\tif (!this.isMessageForActiveSession(message)) {\n\t\t\treturn;\n\t\t}\n\t\tif (\"snapshotId\" in message && this.ignoredSnapshotIds.has(message.snapshotId)) {\n\t\t\tif (message.type === \"session_snapshot_end\" || message.type === \"session_snapshot_failed\") {\n\t\t\t\tthis.ignoredSnapshotIds.delete(message.snapshotId);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_begin\") {\n\t\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\t\tassembly.begin = message;\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_chunk\") {\n\t\t\tthis.getSnapshotAssembly(message.snapshotId).chunks.set(message.index, message.messages);\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_end\") {\n\t\t\tawait this.completeSnapshotAssembly(message);\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_failed\") {\n\t\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\t\tconst purpose = assembly.begin?.purpose ?? \"attach\";\n\t\t\tconst snapshotError = new Error(message.error);\n\t\t\tconst recoveryPromise =\n\t\t\t\tpurpose === \"replacement\" || purpose === \"resync\"\n\t\t\t\t\t? this.recoverFailedSnapshot(purpose, snapshotError)\n\t\t\t\t\t: undefined;\n\t\t\tif (recoveryPromise) {\n\t\t\t\tthis.snapshotRecoveryPromises.set(message.snapshotId, recoveryPromise);\n\t\t\t}\n\t\t\tthis.rejectSnapshotAssembly(message.snapshotId, assembly, snapshotError);\n\t\t\tthis.ignoreSnapshotId(message.snapshotId);\n\t\t\tif (recoveryPromise) {\n\t\t\t\ttry {\n\t\t\t\t\tawait recoveryPromise;\n\t\t\t\t} finally {\n\t\t\t\t\tthis.snapshotRecoveryPromises.delete(message.snapshotId);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.isStaleSequencedMessage(message)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.observeDaemonEventSequence(message);\n\n\t\tif (message.type === \"session_event\") {\n\t\t\tif (message.event.type !== \"refine_complete\" && message.event.type !== \"refine_failed\") {\n\t\t\t\tthis.observeStreamingMessage(message.event);\n\t\t\t}\n\t\t\tif (message.event.type === \"rlm_child_update\") {\n\t\t\t\tthis.childRosterSequence = maxEventSequence(this.childRosterSequence, getDaemonMessageSequence(message));\n\t\t\t\tthis.observeRlmChildUpdate(message.event.child);\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t\tawait this.emit({ type: \"session_event\", event: message.event });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"side_question_event\") {\n\t\t\tthis.observeSideQuestionEvent(message.event);\n\t\t\tawait this.emit({ type: \"side_question_event\", event: message.event });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_status\") {\n\t\t\t// Keep a cached snapshot's recap current so a later re-attach seeds it.\n\t\t\tif (this.latestSnapshot) {\n\t\t\t\tthis.latestSnapshot = {\n\t\t\t\t\t...this.latestSnapshot,\n\t\t\t\t\tstate: { ...this.latestSnapshot.state, recap: message.recap },\n\t\t\t\t};\n\t\t\t}\n\t\t\tawait this.emit({ type: \"session_status\", recap: message.recap });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_resynced\") {\n\t\t\tthis.attachedSessionId = message.snapshot.state.sessionId;\n\t\t\tthis.attachedSessionFile = message.snapshot.state.sessionFile;\n\t\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(message.snapshot);\n\t\t\tif (Array.isArray(message.snapshot.children)) {\n\t\t\t\tthis.childRosterSequence = message.snapshot.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tthis.latestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tthis.latestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t\tawait this.emit({ type: \"session_resynced\", snapshot: this.latestSnapshot });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_replaced\") {\n\t\t\tthis.attachedSessionId = message.state.sessionId;\n\t\t\tthis.attachedSessionFile = message.state.sessionFile;\n\t\t\tif (message.snapshotFollows) {\n\t\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst latestSnapshot: AgentConnectionSnapshot = {\n\t\t\t\tstate: message.state,\n\t\t\t\tmessages: message.messages,\n\t\t\t};\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tlatestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tlatestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshot = latestSnapshot;\n\t\t\tthis.childRosterSequence = undefined;\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t\tawait this.emit({ type: \"session_replaced\", state: message.state, messages: message.messages });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"extension_ui_request\") {\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"extension_ui_request\",\n\t\t\t\trequest: {\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tmethod: message.method,\n\t\t\t\t\tpayload: message.payload,\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"extension_error\") {\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"extension_error\",\n\t\t\t\textensionPath: message.extensionPath,\n\t\t\t\tevent: message.event,\n\t\t\t\terror: message.error,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_closed\") {\n\t\t\tif (message.reason === \"update\") {\n\t\t\t\tthis.captureDaemonLogPath();\n\t\t\t\tthis.updateRestartPending = true;\n\t\t\t\tvoid this.reconnectAfterUpdate();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tawait this.emit({ type: \"closed\", error: this.formatDaemonSessionClosedError(message.reason) });\n\t\t}\n\t}\n\n\tprivate captureDaemonLogPath(): void {\n\t\tconst socketPath = this.client.hello?.socketPath;\n\t\tif (socketPath) {\n\t\t\tthis.daemonLogPath = getDaemonLogPath(socketPath);\n\t\t}\n\t}\n\n\tprivate formatDaemonSessionClosedError(reason: DaemonSessionClosedReason): string {\n\t\tconst explanation: Record<DaemonSessionClosedReason, string> = {\n\t\t\tkilled:\n\t\t\t\t\"The daemon stopped this agent session. Its transcript remains saved and can be reopened from Agents View.\",\n\t\t\tshutdown:\n\t\t\t\t\"The Base Context daemon shut down while this window was attached. The session transcript remains saved; restart Base Context and reopen it from Agents View.\",\n\t\t\tcompleted:\n\t\t\t\t\"The daemon closed this agent session after it completed. Its transcript remains available from Agents View.\",\n\t\t\treplaced:\n\t\t\t\t\"The daemon replaced this agent session with another session. Reopen the current session from Agents View.\",\n\t\t\tupdate:\n\t\t\t\t\"The Base Context daemon restarted for an update, but this window did not restore automatically. The session transcript remains saved; restart Base Context and reopen it from Agents View.\",\n\t\t};\n\t\treturn `${explanation[reason]} ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatDaemonConnectionClosedError(error: Error): string {\n\t\treturn `Lost connection to the Base Context daemon. Cause: ${formatErrorSentence(error)} The session transcript remains saved; restart Base Context or reopen the session from Agents View. ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatUpdateReconnectError(error: unknown): string {\n\t\treturn `The Base Context daemon restarted for an update, but this window could not reconnect to its restored session before the recovery timeout expired. Last error: ${formatErrorSentence(error)} The session transcript remains saved; restart Base Context and reopen it from Agents View. ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatDaemonDiagnosticContext(): string {\n\t\tconst details: string[] = [];\n\t\tif (this.attachedSessionId) {\n\t\t\tdetails.push(`Session ID: ${this.attachedSessionId}.`);\n\t\t}\n\t\tif (this.attachedSessionFile) {\n\t\t\tdetails.push(`Session file: ${this.attachedSessionFile}.`);\n\t\t}\n\t\tdetails.push(`Diagnostic log: ${this.daemonLogPath ?? getAgentLogPath()}.`);\n\t\treturn details.join(\" \");\n\t}\n\n\tprivate reconnectAfterUpdate(): Promise<void> {\n\t\tif (this.updateReconnectPromise) {\n\t\t\treturn this.updateReconnectPromise;\n\t\t}\n\t\tvoid this.emit({\n\t\t\ttype: \"connection_status\",\n\t\t\tstatus: \"reconnecting\",\n\t\t\terror: \"The Base Context daemon is restarting for an update.\",\n\t\t});\n\t\tconst reconnectPromise = reconnectDaemonTransportAfterUpdate(this.client)\n\t\t\t.then(() => this.restoreConnectionAfterUpdate())\n\t\t\t.then(() => {\n\t\t\t\tif (!this.disposed) {\n\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(async (error: unknown) => {\n\t\t\t\tthis.updateRestartPending = false;\n\t\t\t\tthis.updateReconnectFailed = true;\n\t\t\t\tif (!this.disposed) {\n\t\t\t\t\tthis.terminalCloseEmitted = true;\n\t\t\t\t\tawait this.emit({\n\t\t\t\t\t\ttype: \"closed\",\n\t\t\t\t\t\terror: this.formatUpdateReconnectError(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.updateReconnectPromise === reconnectPromise) {\n\t\t\t\t\tthis.updateReconnectPromise = undefined;\n\t\t\t\t}\n\t\t\t});\n\t\tthis.updateReconnectPromise = reconnectPromise;\n\t\treturn reconnectPromise;\n\t}\n\n\tprivate async restoreConnectionAfterUpdate(): Promise<void> {\n\t\tconst sessionId = this.attachedSessionId;\n\t\tconst sessionFile = this.attachedSessionFile;\n\t\tif (!sessionId && !sessionFile) {\n\t\t\tthrow new Error(\"the previous session identity is unavailable\");\n\t\t}\n\t\tconst deadline = Date.now() + UPDATE_RECONNECT_TIMEOUT_MS;\n\t\tlet lastError: unknown;\n\t\twhile (!this.disposed && Date.now() < deadline) {\n\t\t\ttry {\n\t\t\t\tawait this.client.reconnect(1000);\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// This loop owns the retry: a socket close must reject these instead of parking them behind a hello it can never produce.\n\t\t\t\tconst response = await this.client.request({ type: \"list\" }, 30000, { recoverable: false });\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!response.success) {\n\t\t\t\t\tthrow deserializeDaemonError(response);\n\t\t\t\t}\n\t\t\t\tconst sessions = readSessionSummaries(response.data);\n\t\t\t\tconst restored = sessions.find(\n\t\t\t\t\t(summary) =>\n\t\t\t\t\t\tsummary.activeSessionId !== undefined &&\n\t\t\t\t\t\t((sessionFile !== undefined && summary.sessionFile === sessionFile) ||\n\t\t\t\t\t\t\t(sessionId !== undefined && summary.sessionId === sessionId)),\n\t\t\t\t);\n\t\t\t\tif (restored?.activeSessionId) {\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.activeSessionId = restored.activeSessionId;\n\t\t\t\t\tthis.lastEventSequence = undefined;\n\t\t\t\t\tthis.lastEventCursor = undefined;\n\t\t\t\t\tthis.retiredEventGenerations.clear();\n\t\t\t\t\tawait this.attach({ recoverable: false });\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst snapshot = await this.getInitialSnapshot({ recoverable: false });\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.updateRestartPending = false;\n\t\t\t\t\tvoid this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error;\n\t\t\t}\n\t\t\tawait delay(UPDATE_RECONNECT_RETRY_MS);\n\t\t}\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthrow lastError ?? new Error(\"the restored session did not become available\");\n\t}\n\n\tprivate getSnapshotAssembly(snapshotId: string): DaemonSnapshotAssembly {\n\t\tconst existing = this.snapshotAssemblies.get(snapshotId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\t\tlet resolveSnapshot!: (snapshot: DaemonSessionSnapshot) => void;\n\t\tlet rejectSnapshot!: (error: Error) => void;\n\t\tconst promise = new Promise<DaemonSessionSnapshot>((resolve, reject) => {\n\t\t\tresolveSnapshot = resolve;\n\t\t\trejectSnapshot = reject;\n\t\t});\n\t\tvoid promise.catch(() => undefined);\n\t\tconst timeout = setTimeout(() => {\n\t\t\tconst current = this.snapshotAssemblies.get(snapshotId);\n\t\t\tif (current) {\n\t\t\t\tcurrent.reject(new Error(`Timed out waiting for snapshot ${snapshotId}`));\n\t\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t\t\tthis.ignoreSnapshotId(snapshotId);\n\t\t\t}\n\t\t}, this.options.snapshotTimeoutMs ?? DAEMON_SNAPSHOT_TIMEOUT_MS);\n\t\ttimeout.unref();\n\t\tconst assembly: DaemonSnapshotAssembly = {\n\t\t\tchunks: new Map(),\n\t\t\tpromise,\n\t\t\tresolve: resolveSnapshot,\n\t\t\treject: rejectSnapshot,\n\t\t\ttimeout,\n\t\t};\n\t\tthis.snapshotAssemblies.set(snapshotId, assembly);\n\t\treturn assembly;\n\t}\n\n\tprivate rejectSnapshotAssemblies(error: Error): void {\n\t\tfor (const assembly of this.snapshotAssemblies.values()) {\n\t\t\tclearTimeout(assembly.timeout);\n\t\t\tassembly.reject(error);\n\t\t}\n\t\tthis.snapshotAssemblies.clear();\n\t\tthis.completedSnapshots.clear();\n\t\tthis.snapshotRecoveryPromises.clear();\n\t\tthis.ignoredSnapshotIds.clear();\n\t}\n\n\tprivate ignoreSnapshotId(snapshotId: string): void {\n\t\tthis.ignoredSnapshotIds.add(snapshotId);\n\t\twhile (this.ignoredSnapshotIds.size > MAX_IGNORED_SNAPSHOT_IDS) {\n\t\t\tconst oldest = this.ignoredSnapshotIds.values().next().value;\n\t\t\tif (oldest === undefined) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.ignoredSnapshotIds.delete(oldest);\n\t\t}\n\t}\n\n\tprivate rejectSnapshotAssembly(snapshotId: string, assembly: DaemonSnapshotAssembly, error: Error): void {\n\t\tassembly.reject(error);\n\t\tclearTimeout(assembly.timeout);\n\t\tif (assembly.begin?.purpose && assembly.begin.purpose !== \"attach\") {\n\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t}\n\t}\n\n\tprivate async recoverFailedSnapshot(purpose: \"replacement\" | \"resync\", snapshotError: Error): Promise<void> {\n\t\tthis.latestSnapshotIsFresh = false;\n\t\tif (purpose === \"replacement\") {\n\t\t\tthis.latestSnapshot = undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst snapshot = await this.getInitialSnapshot();\n\t\t\tif (this.disposed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\t\tif (purpose === \"replacement\") {\n\t\t\t\tawait this.emit({ type: \"session_replaced\", state: snapshot.state, messages: snapshot.messages });\n\t\t\t} else {\n\t\t\t\tawait this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t}\n\t\t} catch (recoveryError) {\n\t\t\tif (this.disposed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"closed\",\n\t\t\t\terror: `Failed to recover from a ${purpose} snapshot transfer. Snapshot error: ${formatErrorSentence(snapshotError)} Recovery error: ${formatErrorSentence(recoveryError)} ${this.formatDaemonDiagnosticContext()}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async waitForSnapshot(snapshotId: string): Promise<DaemonSessionSnapshot> {\n\t\tconst completed = this.completedSnapshots.get(snapshotId);\n\t\tif (completed) {\n\t\t\tthis.completedSnapshots.delete(snapshotId);\n\t\t\treturn completed;\n\t\t}\n\t\tconst assembly = this.getSnapshotAssembly(snapshotId);\n\t\ttry {\n\t\t\treturn await assembly.promise;\n\t\t} finally {\n\t\t\tclearTimeout(assembly.timeout);\n\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t\tthis.completedSnapshots.delete(snapshotId);\n\t\t}\n\t}\n\n\tprivate applyReplacementSnapshot(snapshot: DaemonSessionSnapshot, replay?: DaemonReplayInfo): void {\n\t\tif (snapshot.lastEventCursor) {\n\t\t\tthis.observeEventCursor(snapshot.lastEventCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, snapshot.lastEventSequence);\n\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot, replay);\n\t\tthis.childRosterSequence = Array.isArray(snapshot.children) ? snapshot.lastEventSequence : undefined;\n\t\tthis.latestSnapshotIsFresh = true;\n\t}\n\n\tprivate async completeSnapshotAssembly(\n\t\tmessage: Extract<DaemonOutbound, { type: \"session_snapshot_end\" }>,\n\t): Promise<void> {\n\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\tif (!assembly.begin) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(`Snapshot ${message.snapshotId} ended before it began`),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (assembly.chunks.size !== message.chunkCount) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(\n\t\t\t\t\t`Snapshot ${message.snapshotId} ended with ${assembly.chunks.size} of ${message.chunkCount} chunks`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst messages: AgentMessage[] = [];\n\t\tfor (let index = 0; index < message.chunkCount; index++) {\n\t\t\tconst chunk = assembly.chunks.get(index);\n\t\t\tif (!chunk) {\n\t\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\t\tmessage.snapshotId,\n\t\t\t\t\tassembly,\n\t\t\t\t\tnew Error(`Snapshot ${message.snapshotId} is missing chunk ${index}`),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tmessages.push(...chunk);\n\t\t}\n\t\tif (messages.length !== assembly.begin.messageCount) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(\n\t\t\t\t\t`Snapshot ${message.snapshotId} contained ${messages.length} of ${assembly.begin.messageCount} messages`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot: DaemonSessionSnapshot = {\n\t\t\t...assembly.begin.snapshot,\n\t\t\tmessages,\n\t\t\tlastEventSequence: message.lastEventSequence,\n\t\t\tlastEventCursor: message.lastEventCursor,\n\t\t};\n\t\tif (message.lastEventCursor) {\n\t\t\tthis.observeEventCursor(message.lastEventCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, message.lastEventSequence);\n\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot);\n\t\tthis.latestSnapshotIsFresh = true;\n\t\tassembly.resolve(snapshot);\n\t\tconst purpose = assembly.begin.purpose ?? \"attach\";\n\t\tclearTimeout(assembly.timeout);\n\t\tif (purpose !== \"attach\") {\n\t\t\tthis.snapshotAssemblies.delete(message.snapshotId);\n\t\t\tif (this.pendingReattachActiveSessionIds.has(message.activeSessionId)) {\n\t\t\t\tthis.completedSnapshots.set(message.snapshotId, snapshot);\n\t\t\t\twhile (this.completedSnapshots.size > MAX_COMPLETED_SNAPSHOTS) {\n\t\t\t\t\tconst oldest = this.completedSnapshots.keys().next().value;\n\t\t\t\t\tif (oldest === undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tthis.completedSnapshots.delete(oldest);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (purpose === \"replacement\") {\n\t\t\tawait this.emit({ type: \"session_replaced\", state: snapshot.state, messages });\n\t\t} else if (purpose === \"resync\") {\n\t\t\tawait this.emit({ type: \"session_resynced\", snapshot: this.latestSnapshot });\n\t\t}\n\t}\n\n\tprivate observeRlmChildUpdate(child: AgentConnectionRlmChildAgentSnapshot): void {\n\t\tif (!this.latestSnapshot) return;\n\t\tconst children = this.latestSnapshot.children ?? [];\n\t\tconst index = children.findIndex((candidate) => candidate.id === child.id);\n\t\tconst updatedChildren = [...children];\n\t\tif (index === -1) {\n\t\t\tupdatedChildren.push(child);\n\t\t} else {\n\t\t\tupdatedChildren[index] = child;\n\t\t}\n\t\tthis.latestSnapshot = { ...this.latestSnapshot, children: updatedChildren };\n\t}\n\n\tprivate observeStreamingMessage(event: AgentSessionEvent): void {\n\t\tif (!this.latestSnapshot) {\n\t\t\treturn;\n\t\t}\n\t\tif ((event.type === \"message_start\" || event.type === \"message_update\") && event.message.role === \"assistant\") {\n\t\t\tthis.latestSnapshot = { ...this.latestSnapshot, streamingMessage: event.message };\n\t\t\treturn;\n\t\t}\n\t\tif ((event.type === \"message_end\" && event.message.role === \"assistant\") || event.type === \"agent_end\") {\n\t\t\tconst { streamingMessage: _streamingMessage, ...snapshot } = this.latestSnapshot;\n\t\t\tthis.latestSnapshot = snapshot;\n\t\t}\n\t}\n\n\tprivate isMessageForActiveSession(message: DaemonOutbound): boolean {\n\t\tif (!(\"activeSessionId\" in message)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn message.activeSessionId === this.activeSessionId;\n\t}\n\n\tprivate isStaleSequencedMessage(message: DaemonOutbound): boolean {\n\t\tconst cursor = getDaemonMessageCursor(message);\n\t\tif (cursor) {\n\t\t\tif (this.retiredEventGenerations.has(cursor.generation)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn (\n\t\t\t\tthis.lastEventCursor?.generation === cursor.generation && cursor.sequence <= this.lastEventCursor.sequence\n\t\t\t);\n\t\t}\n\t\tconst sequence = getDaemonMessageSequence(message);\n\t\treturn sequence !== undefined && this.lastEventSequence !== undefined && sequence <= this.lastEventSequence;\n\t}\n\n\tprivate observeDaemonEventSequence(message: DaemonOutbound): void {\n\t\tconst cursor = getDaemonMessageCursor(message);\n\t\tif (cursor) {\n\t\t\tthis.observeEventCursor(cursor);\n\t\t\tthis.lastEventSequence = cursor.sequence;\n\t\t\treturn;\n\t\t}\n\t\tconst sequence = getDaemonMessageSequence(message);\n\t\tif (sequence === undefined) {\n\t\t\treturn;\n\t\t}\n\t\tthis.lastEventSequence =\n\t\t\tthis.lastEventSequence === undefined ? sequence : Math.max(this.lastEventSequence, sequence);\n\t\tif (this.lastEventCursor) {\n\t\t\tthis.lastEventCursor = {\n\t\t\t\t...this.lastEventCursor,\n\t\t\t\tsequence: Math.max(this.lastEventCursor.sequence, sequence),\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate observeEventCursor(cursor: DaemonEventCursor): void {\n\t\tconst current = this.lastEventCursor;\n\t\tif (current && current.generation !== cursor.generation) {\n\t\t\tthis.retiredEventGenerations.add(current.generation);\n\t\t}\n\t\tif (!current || current.generation !== cursor.generation || cursor.sequence > current.sequence) {\n\t\t\tthis.lastEventCursor = cursor;\n\t\t}\n\t}\n\n\tprivate async emit(event: AgentConnectionEvent): Promise<void> {\n\t\tconst deliveries: Promise<void>[] = [];\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\ttry {\n\t\t\t\tdeliveries.push(Promise.resolve(listener(event)));\n\t\t\t} catch {\n\t\t\t\t// One attachment must not interrupt delivery or transport recovery for the others.\n\t\t\t}\n\t\t}\n\t\tawait Promise.allSettled(deliveries);\n\t}\n\n\tprivate observeSideQuestionEvent(event: AgentConnectionSideQuestionEvent): void {\n\t\tif (event.status !== \"running\") {\n\t\t\tthis.activeSideQuestionIds.delete(event.id);\n\t\t}\n\t}\n}\n\nfunction readSessionSummaries(value: unknown): SessionSummary[] {\n\tif (!value || typeof value !== \"object\" || !Array.isArray((value as { sessions?: unknown }).sessions)) {\n\t\tthrow new Error(\"Daemon returned an invalid session list response\");\n\t}\n\treturn (value as { sessions: SessionSummary[] }).sessions;\n}\n\nfunction getAttachActiveSessionId(result: SessionSummary | DaemonAttachResult): string {\n\tif (\"snapshot\" in result) {\n\t\treturn result.activeSessionId;\n\t}\n\treturn result.activeSessionId ?? result.id;\n}\n\nfunction getAttachLastEventSequence(result: SessionSummary | DaemonAttachResult): number | undefined {\n\tif (\"lastEventSequence\" in result) {\n\t\treturn result.lastEventSequence;\n\t}\n\treturn undefined;\n}\n\nfunction getAttachLastEventCursor(result: SessionSummary | DaemonAttachResult): DaemonEventCursor | undefined {\n\tif (\"lastEventCursor\" in result) {\n\t\treturn result.lastEventCursor;\n\t}\n\treturn undefined;\n}\n\nfunction maxEventSequence(current: number | undefined, observed: number | undefined): number | undefined {\n\tif (current === undefined) {\n\t\treturn observed;\n\t}\n\tif (observed === undefined) {\n\t\treturn current;\n\t}\n\treturn Math.max(current, observed);\n}\n\nfunction mapDaemonSessionSnapshot(snapshot: DaemonSessionSnapshot, replay?: DaemonReplayInfo): AgentConnectionSnapshot {\n\tconst connectionSnapshot: AgentConnectionSnapshot = {\n\t\tstate: snapshot.state,\n\t\tmessages: snapshot.messages,\n\t\t...(snapshot.summary.streamingMessage ? { streamingMessage: snapshot.summary.streamingMessage } : {}),\n\t\tlastEventSequence: snapshot.lastEventSequence,\n\t\tlastEventCursor: snapshot.lastEventCursor,\n\t};\n\tif (snapshot.sessionContext) {\n\t\tconnectionSnapshot.sessionContext = snapshot.sessionContext;\n\t}\n\tif (snapshot.sessionTree) {\n\t\tconnectionSnapshot.sessionTree = snapshot.sessionTree;\n\t}\n\tif (snapshot.parent) {\n\t\tconnectionSnapshot.parent = snapshot.parent;\n\t}\n\tif (snapshot.children) {\n\t\tconnectionSnapshot.children = snapshot.children;\n\t}\n\tif (replay) {\n\t\tconnectionSnapshot.replay = replay;\n\t}\n\treturn connectionSnapshot;\n}\n\nfunction getDaemonMessageSequence(message: DaemonOutbound): number | undefined {\n\tif (!(\"meta\" in message)) {\n\t\treturn undefined;\n\t}\n\treturn message.meta?.sequence;\n}\n\nfunction getDaemonMessageCursor(message: DaemonOutbound): DaemonEventCursor | undefined {\n\tif (!(\"meta\" in message)) {\n\t\treturn undefined;\n\t}\n\treturn message.meta?.cursor;\n}\n\nfunction invalidatesCachedSnapshot(commandType: DaemonCommandBody[\"type\"]): boolean {\n\tswitch (commandType) {\n\t\tcase \"attach\":\n\t\tcase \"reattach\":\n\t\tcase \"detach\":\n\t\tcase \"list\":\n\t\tcase \"list_saved_sessions\":\n\t\tcase \"wait_for_idle\":\n\t\tcase \"get_state\":\n\t\tcase \"get_connection_state\":\n\t\tcase \"get_messages\":\n\t\tcase \"get_session_stats\":\n\t\tcase \"get_commands\":\n\t\tcase \"get_resource_snapshot\":\n\t\tcase \"get_model_catalog\":\n\t\tcase \"get_available_models\":\n\t\tcase \"get_queue\":\n\t\tcase \"cron_list\":\n\t\tcase \"heartbeats_list\":\n\t\tcase \"get_session_context\":\n\t\tcase \"get_session_tree\":\n\t\tcase \"get_user_messages_for_forking\":\n\t\tcase \"get_last_assistant_text\":\n\t\tcase \"get_system_prompt\":\n\t\tcase \"get_tool_definition\":\n\t\tcase \"start_side_question\":\n\t\tcase \"abort_side_question\":\n\t\tcase \"export_html\":\n\t\tcase \"export_jsonl\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n"]}
1
+ {"version":3,"file":"daemon-agent-connection.d.ts","sourceRoot":"","sources":["../../../src/modes/agent-connection/daemon-agent-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentMessage, ThinkingLevel } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, ServiceTier, Transport } from \"@ponythewhite/base-context-ai\";\nimport { appendRotatingLog, getAgentLogPath, getDaemonLogPath } from \"../../config.js\";\nimport type { AgentSessionMessageReceipt, AgentSessionMessageSafetyStatus } from \"../../core/agent-messages.js\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntimeConfig } from \"../../core/agent-session-config.js\";\nimport type { AgentAutonomousStatus } from \"../../core/autonomous.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\nimport type { CompactionResult } from \"../../core/compaction/index.js\";\nimport type { ContextTreeNode } from \"../../core/context-tree.js\";\nimport type {\n\tAgentCronJob,\n\tAgentHeartbeatDeliveryMode,\n\tAgentHeartbeatManagementAction,\n\tAgentHeartbeatUpdateAction,\n} from \"../../core/cron-jobs.js\";\nimport type { AcpMcpServerConfig } from \"../../core/mcp/acp-mcp-types.js\";\nimport type { RefinementResult } from \"../../core/refinement/index.js\";\nimport type { DeleteSessionFileResult } from \"../../core/session-file-actions.js\";\nimport { SessionAlreadyActiveError } from \"../../core/session-lease.js\";\nimport type { SessionStats } from \"../../core/session-stats.js\";\nimport { AgentsViewRosterStore, STALE_ROSTER_DAEMON_MESSAGE } from \"../agents-view/roster-store.js\";\nimport {\n\tDaemonCapabilityUnavailableError,\n\ttype DaemonTransportClient,\n\tgetDaemonSocketCloseReason,\n} from \"../daemon/daemon-client.js\";\nimport { deserializeDaemonError } from \"../daemon/daemon-errors.js\";\nimport {\n\tcollectDaemonClientEnv,\n\tcollectDaemonLaunchEnv,\n\ttype DaemonAttachResult,\n\ttype DaemonCommand,\n\ttype DaemonEventCursor,\n\ttype DaemonOutbound,\n\ttype DaemonReplayInfo,\n\ttype DaemonSessionClosedReason,\n\ttype DaemonSessionSnapshot,\n\tisUnknownDaemonCommandError,\n} from \"../daemon/daemon-protocol.js\";\nimport {\n\tcreateDaemonSessionTransport,\n\tDaemonControlPlaneTransportError,\n\tDaemonDirectTransportClosedError,\n\tDaemonRoutedClient,\n} from \"../daemon/daemon-routed-client.js\";\nimport type { SessionSummary } from \"../daemon/daemon-session-list.js\";\nimport { listDaemonHeartbeats } from \"../daemon/heartbeat-catalog.js\";\nimport {\n\tdeleteDaemonSavedSession,\n\tlistDaemonSavedSessions,\n\trenameDaemonSavedSession,\n} from \"../daemon/saved-session-catalog.js\";\nimport type {\n\tAgentConnection,\n\tAgentConnectionBeforeSessionInvalidateListener,\n\tAgentConnectionEvent,\n\tAgentConnectionEventListener,\n\tAgentConnectionExecuteBashOptions,\n\tAgentConnectionExtensionUiResponse,\n\tAgentConnectionForkOptions,\n\tAgentConnectionHeadlessCompletionOptions,\n\tAgentConnectionHeartbeat,\n\tAgentConnectionModel,\n\tAgentConnectionModelCatalog,\n\tAgentConnectionModelCycleResult,\n\tAgentConnectionNavigateTreeOptions,\n\tAgentConnectionNavigateTreeResult,\n\tAgentConnectionNewSessionOptions,\n\tAgentConnectionPromptOptions,\n\tAgentConnectionQueuedMessageLane,\n\tAgentConnectionQueuedMessageMutation,\n\tAgentConnectionQueuedMessageMutationStatus,\n\tAgentConnectionQueueMode,\n\tAgentConnectionQueueState,\n\tAgentConnectionResourceSnapshot,\n\tAgentConnectionRlmChildAgentSnapshot,\n\tAgentConnectionSavedSessionInfo,\n\tAgentConnectionSavedSessionScope,\n\tAgentConnectionScopedModel,\n\tAgentConnectionSessionContext,\n\tAgentConnectionSessionHeader,\n\tAgentConnectionSessionInputPause,\n\tAgentConnectionSessionListCallbacks,\n\tAgentConnectionSessionTreeFlatNode,\n\tAgentConnectionSessionTreeNode,\n\tAgentConnectionSessionWatcher,\n\tAgentConnectionSideQuestionEvent,\n\tAgentConnectionSideQuestionTurn,\n\tAgentConnectionSlashCommand,\n\tAgentConnectionSnapshot,\n\tAgentConnectionState,\n\tAgentConnectionSwitchSessionOptions,\n\tAgentConnectionToolDefinition,\n\tAgentConnectionUserMessage,\n} from \"./types.js\";\nimport { AgentConnectionPromptAdmissionError } from \"./types.js\";\n\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\ntype DaemonCommandBody = DistributiveOmit<DaemonCommand, \"id\">;\ntype DaemonSnapshotBegin = Extract<DaemonOutbound, { type: \"session_snapshot_begin\" }>;\n\ninterface DaemonSnapshotAssembly {\n\tbegin?: DaemonSnapshotBegin;\n\tchunks: Map<number, AgentMessage[]>;\n\tpromise: Promise<DaemonSessionSnapshot>;\n\tresolve: (snapshot: DaemonSessionSnapshot) => void;\n\treject: (error: Error) => void;\n\ttimeout: ReturnType<typeof setTimeout>;\n}\n\nexport const DAEMON_REFINE_REQUEST_TIMEOUT_MS = 10 * 60 * 1000;\nconst DAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS = 24 * 60 * 60 * 1000;\nexport const DAEMON_RECONNECT_TIMEOUT_MS = 60_000;\nexport const DAEMON_SNAPSHOT_TIMEOUT_MS = 30_000;\nconst MAX_IGNORED_SNAPSHOT_IDS = 128;\nconst UPDATE_RECONNECT_TIMEOUT_MS = 120000;\nconst UPDATE_RECONNECT_RETRY_MS = 100;\nconst MAX_COMPLETED_SNAPSHOTS = 128;\nconst OWNED_SESSION_DISPOSE_RECONNECT_WAIT_MS = 10_000;\nconst updateTransportReconnects = new WeakMap<DaemonTransportClient, Promise<void>>();\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction formatErrorSentence(error: unknown): string {\n\tconst message = (error instanceof Error ? error.message : String(error)).trim();\n\tif (!message) {\n\t\treturn \"Unknown daemon error.\";\n\t}\n\treturn /[.!?]$/.test(message) ? message : `${message}.`;\n}\n\nfunction reconnectDaemonTransportAfterUpdate(client: DaemonTransportClient): Promise<void> {\n\tconst existing = updateTransportReconnects.get(client);\n\tif (existing) {\n\t\treturn existing;\n\t}\n\tconst reconnectPromise = Promise.resolve()\n\t\t.then(async () => {\n\t\t\tclient.disconnectForReconnect(\"update\");\n\t\t\tconst deadline = Date.now() + UPDATE_RECONNECT_TIMEOUT_MS;\n\t\t\tlet lastError: unknown;\n\t\t\twhile (Date.now() < deadline) {\n\t\t\t\ttry {\n\t\t\t\t\tawait client.reconnect(1000);\n\t\t\t\t\treturn;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlastError = error;\n\t\t\t\t}\n\t\t\t\tawait delay(UPDATE_RECONNECT_RETRY_MS);\n\t\t\t}\n\t\t\tthrow lastError ?? new Error(\"the updated daemon did not become available\");\n\t\t})\n\t\t.finally(() => {\n\t\t\tif (updateTransportReconnects.get(client) === reconnectPromise) {\n\t\t\t\tupdateTransportReconnects.delete(client);\n\t\t\t}\n\t\t});\n\tupdateTransportReconnects.set(client, reconnectPromise);\n\treturn reconnectPromise;\n}\n\nexport interface DaemonAgentConnectionOptions {\n\tcloseClientOnDispose?: boolean;\n\t/** Secondary watchers pass false to stay on the shared control-plane socket. */\n\tdirectTransport?: boolean;\n\t/** Restart/probe the detached supervisor after a transient socket loss. */\n\trecoverDaemon?: () => Promise<void>;\n\t/** Bound supervisor recovery before surfacing a fatal connection error. */\n\treconnectTimeoutMs?: number;\n\t/** Bound an incomplete streamed snapshot before failing the attach or resync. */\n\tsnapshotTimeoutMs?: number;\n\t/**\n\t * Send this client's allowlisted env (herdr pane identity) with attach so\n\t * an env-less session (e.g. cron-created) adopts it. Set only by the\n\t * primary interactive connection — the daemon adopts-if-absent, never\n\t * rebinds, so watchers must not send env at all.\n\t */\n\tsendClientEnv?: boolean;\n\t/** Advertise support for interactive extension dialogs. */\n\tsupportsExtensionUi?: boolean;\n\t/** Dispose the connection by stopping its hidden worker instead of detaching. */\n\townedSession?: boolean;\n\t/** Fresh runtime context used only if the owned worker must be relaunched. */\n\townedSessionRecoveryConfig?: AgentSessionRuntimeConfig;\n}\n\n/**\n * AgentConnection adapter for the local daemon JSONL socket transport.\n *\n * InteractiveMode depends only on AgentConnection; local socket ownership and\n * daemon command details stay inside this adapter.\n */\nexport function buildSessionTreeFromFlatNodes(\n\tflatNodes: readonly AgentConnectionSessionTreeFlatNode[],\n): AgentConnectionSessionTreeNode[] {\n\tconst byId = new Map<string, AgentConnectionSessionTreeNode>();\n\tconst roots: AgentConnectionSessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) {\n\t\tbyId.set(flatNode.entry.id, { ...flatNode, children: [] });\n\t}\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = byId.get(entry.id)!;\n\t\tconst parent = entry.parentId === null || entry.parentId === entry.id ? undefined : byId.get(entry.parentId);\n\t\tif (parent) parent.children.push(node);\n\t\telse roots.push(node);\n\t}\n\t// Match SessionManager.getTree() ordering without recursively walking deep\n\t// chains: every node is already indexed, so sort each sibling array directly.\n\tfor (const node of byId.values()) {\n\t\tnode.children.sort(\n\t\t\t(left, right) => new Date(left.entry.timestamp).getTime() - new Date(right.entry.timestamp).getTime(),\n\t\t);\n\t}\n\treturn roots;\n}\n\nexport class DaemonAgentConnection implements AgentConnection {\n\tprivate readonly listeners = new Set<AgentConnectionEventListener>();\n\tprivate readonly unsubscribeDaemonMessages: () => void;\n\tprivate readonly unsubscribeDaemonClose: () => void;\n\tprivate readonly clientId = `daemon-agent-connection:${randomUUID()}`;\n\tprivate readonly sessionInputPauses = new Map<string, Promise<AgentConnectionSessionInputPause>>();\n\tprivate sessionInputPauseGeneration = 0;\n\tprivate ownedSessionPromotionTail = Promise.resolve();\n\tprivate lastEventCursor: DaemonEventCursor | undefined;\n\tprivate readonly retiredEventGenerations = new Set<string>();\n\tprivate lastEventSequence: number | undefined;\n\tprivate childRosterSequence: number | undefined;\n\tprivate latestSnapshot: AgentConnectionSnapshot | undefined;\n\tprivate latestSnapshotIsFresh = false;\n\tprivate attachedSessionId: string | undefined;\n\tprivate attachedSessionFile: string | undefined;\n\tprivate daemonLogPath: string | undefined;\n\tprivate updateRestartPending = false;\n\tprivate updateReconnectFailed = false;\n\tprivate terminalCloseEmitted = false;\n\tprivate updateReconnectPromise?: Promise<void>;\n\tprivate readonly activeSideQuestionIds = new Set<string>();\n\tprivate readonly snapshotAssemblies = new Map<string, DaemonSnapshotAssembly>();\n\tprivate readonly completedSnapshots = new Map<string, DaemonSessionSnapshot>();\n\tprivate readonly pendingReattachActiveSessionIds = new Set<string>();\n\tprivate readonly snapshotRecoveryPromises = new Map<string, Promise<void>>();\n\tprivate readonly ignoredSnapshotIds = new Set<string>();\n\tprivate rosterStore: AgentsViewRosterStore | undefined;\n\tprivate reconnectPromise?: Promise<void>;\n\tprivate initialAttachPending = false;\n\tprivate initialControlPlaneClose?: Error;\n\tprivate readonly definitiveRequestErrors = new WeakSet<Error>();\n\tprivate disposing = false;\n\tprivate disposed = false;\n\n\tconstructor(\n\t\tprivate readonly client: DaemonTransportClient,\n\t\tprivate activeSessionId: string,\n\t\tprivate readonly options: DaemonAgentConnectionOptions = {},\n\t) {\n\t\tif (options.recoverDaemon) {\n\t\t\tthis.client.enableRequestRecovery();\n\t\t}\n\t\tthis.unsubscribeDaemonMessages = this.client.onMessage((message) => {\n\t\t\tvoid this.handleDaemonMessage(message).catch((error: unknown) => {\n\t\t\t\ttry {\n\t\t\t\t\tappendRotatingLog(\n\t\t\t\t\t\tgetAgentLogPath(),\n\t\t\t\t\t\t`[${new Date().toISOString()}] daemon-message: ignored ${message.type} failure: ${String(error)}`,\n\t\t\t\t\t);\n\t\t\t\t} catch {\n\t\t\t\t\t// Logging failure must not turn an isolated message error into a connection failure.\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\tthis.captureDaemonLogPath();\n\t\tthis.unsubscribeDaemonClose = this.client.onClose((error) => this.handleTransportClose(error));\n\t}\n\n\tprivate handleTransportClose(error: Error): void {\n\t\tconst directSessionSurvives =\n\t\t\tthis.client instanceof DaemonRoutedClient &&\n\t\t\tthis.client.hasDirectTransport &&\n\t\t\t!(error instanceof DaemonDirectTransportClosedError);\n\t\tconst invalidatedInputPause = !directSessionSurvives && this.sessionInputPauses.size > 0;\n\t\tif (!directSessionSurvives) {\n\t\t\tthis.sessionInputPauses.clear();\n\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\tthis.rejectSnapshotAssemblies(error);\n\t\t}\n\t\tif (this.initialAttachPending) {\n\t\t\t// attach() owns failure handling until the initial attach settles.\n\t\t\tif (directSessionSurvives) this.initialControlPlaneClose = error;\n\t\t\treturn;\n\t\t}\n\t\tif (this.disposed || this.terminalCloseEmitted) {\n\t\t\treturn;\n\t\t}\n\t\t// A lost direct link invalidates the fence (holders learn via the generation bump) yet the session falls back.\n\t\tif (invalidatedInputPause && !(error instanceof DaemonDirectTransportClosedError)) {\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tvoid this.emit({\n\t\t\t\ttype: \"closed\",\n\t\t\t\terror: \"Daemon connection closed while session input was paused; the fence was invalidated.\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// An authoritative shutdown/update reason outranks the surviving direct link.\n\t\tconst closeReason = getDaemonSocketCloseReason(error);\n\t\tif (closeReason === \"shutdown\") {\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tvoid this.emit({ type: \"closed\", error: this.formatDaemonSessionClosedError(\"shutdown\") });\n\t\t\treturn;\n\t\t}\n\t\tif ((this.updateRestartPending || closeReason === \"update\") && !this.updateReconnectFailed) {\n\t\t\tthis.updateRestartPending = true;\n\t\t\tvoid this.reconnectAfterUpdate();\n\t\t\treturn;\n\t\t}\n\t\t// A direct-transport loss is never itself a session loss: fall back through a supervisor re-attach.\n\t\tif (directSessionSurvives || error instanceof DaemonDirectTransportClosedError || this.options.recoverDaemon) {\n\t\t\tvoid this.reconnect(error);\n\t\t\treturn;\n\t\t}\n\t\tthis.terminalCloseEmitted = true;\n\t\tvoid this.emit({ type: \"closed\", error: this.formatDaemonConnectionClosedError(error) });\n\t}\n\n\tstatic async attach(\n\t\tclient: DaemonTransportClient,\n\t\tactiveSessionId: string,\n\t\toptions?: DaemonAgentConnectionOptions,\n\t): Promise<DaemonAgentConnection> {\n\t\tconst transport = await createDaemonSessionTransport(\n\t\t\tclient,\n\t\t\tactiveSessionId,\n\t\t\toptions?.ownedSession === true || options?.directTransport === false,\n\t\t);\n\t\tconst connection = new DaemonAgentConnection(transport, activeSessionId, options);\n\t\tconnection.initialAttachPending = true;\n\t\ttry {\n\t\t\ttry {\n\t\t\t\tawait connection.attach();\n\t\t\t} catch (error) {\n\t\t\t\tif (!(transport instanceof DaemonRoutedClient)) throw error;\n\t\t\t\ttransport.fallbackToSupervisor();\n\t\t\t\ttry {\n\t\t\t\t\t// This retry owns its failure; a parked request would pend the attach forever.\n\t\t\t\t\tawait connection.attach({ recoverable: false });\n\t\t\t\t} catch (retryError) {\n\t\t\t\t\t// A control-plane close saved during the window is the authoritative cause.\n\t\t\t\t\tthrow connection.initialControlPlaneClose ?? retryError;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconnection.initialAttachPending = false;\n\t\t\tconst initialControlPlaneClose = connection.initialControlPlaneClose;\n\t\t\tconnection.initialControlPlaneClose = undefined;\n\t\t\tif (initialControlPlaneClose) {\n\t\t\t\t// No listeners exist yet: a terminal close rejects the attach; the rest replays through the one handler.\n\t\t\t\tif (getDaemonSocketCloseReason(initialControlPlaneClose) === \"shutdown\") {\n\t\t\t\t\tthrow initialControlPlaneClose;\n\t\t\t\t}\n\t\t\t\tconnection.handleTransportClose(initialControlPlaneClose);\n\t\t\t}\n\t\t\treturn connection;\n\t\t} catch (error) {\n\t\t\tconnection.initialAttachPending = false;\n\t\t\tawait connection.dispose();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync attach(options?: { recoverable?: boolean }): Promise<void> {\n\t\tconst supportsExtensionUi = this.options.supportsExtensionUi !== false;\n\t\tconst result = await this.requestData<SessionSummary | DaemonAttachResult>(\n\t\t\t{\n\t\t\t\ttype: \"attach\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tsupportsExtensionUi,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tcapabilities: [\n\t\t\t\t\t\"attach_snapshot\",\n\t\t\t\t\t\"event_sequence\",\n\t\t\t\t\t...(supportsExtensionUi ? ([\"extension_ui\"] as const) : []),\n\t\t\t\t\t\"slim_attach\",\n\t\t\t\t\t\"chunked_snapshot\",\n\t\t\t\t\t...(this.options.ownedSession ? ([\"client_owned_sessions\"] as const) : []),\n\t\t\t\t],\n\t\t\t\tenv: this.options.sendClientEnv ? collectDaemonClientEnv() : undefined,\n\t\t\t\tlaunchEnv: this.options.ownedSession ? collectDaemonLaunchEnv() : undefined,\n\t\t\t\t...(this.options.ownedSession &&\n\t\t\t\tthis.options.ownedSessionRecoveryConfig &&\n\t\t\t\tthis.client.supportsServerCapability(\"owned_session_recovery_context\")\n\t\t\t\t\t? { recoveryConfig: this.options.ownedSessionRecoveryConfig }\n\t\t\t\t\t: {}),\n\t\t\t\tresumeCursor:\n\t\t\t\t\tthis.lastEventCursor === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\t\t\t\t...this.lastEventCursor,\n\t\t\t\t\t\t\t},\n\t\t\t},\n\t\t\tundefined,\n\t\t\toptions,\n\t\t);\n\t\tthis.activeSessionId = getAttachActiveSessionId(result);\n\t\tconst summary = \"snapshot\" in result ? result.snapshot.summary : result;\n\t\tthis.attachedSessionId = summary.sessionId;\n\t\tthis.attachedSessionFile =\n\t\t\tsummary.sessionFile ?? (\"snapshot\" in result ? result.snapshot.state.sessionFile : undefined);\n\t\tthis.captureDaemonLogPath();\n\t\tthis.updateReconnectFailed = false;\n\t\tthis.terminalCloseEmitted = false;\n\t\tconst attachCursor = getAttachLastEventCursor(result);\n\t\tif (attachCursor) {\n\t\t\tthis.observeEventCursor(attachCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, getAttachLastEventSequence(result));\n\t\tif (\"snapshot\" in result) {\n\t\t\tconst snapshot = result.snapshotStream\n\t\t\t\t? await this.waitForSnapshot(result.snapshotStream.id)\n\t\t\t\t: result.snapshot;\n\t\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot, result.replay);\n\t\t\tif (Array.isArray(snapshot.children)) this.childRosterSequence = snapshot.lastEventSequence;\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tthis.latestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tthis.latestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t} else {\n\t\t\tthis.latestSnapshot = undefined;\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t}\n\t\t// The roster bar is an accessory: its subscribe failure must never fail an\n\t\t// otherwise-recovered session. The bar degrades; the next reconnect or rebind\n\t\t// re-attaches through this same seam.\n\t\tif (this.rosterStore) await this.rosterStore.attach(this.client).catch(() => undefined);\n\t}\n\n\tasync subscribeAgentRoster(\n\t\tlistener: () => void,\n\t): Promise<{ summaries(): SessionSummary[]; dispose(): Promise<void> }> {\n\t\tthis.rosterStore ??= new AgentsViewRosterStore();\n\t\tconst store = this.rosterStore;\n\t\tif (!(await store.attach(this.client))) {\n\t\t\tthrow new Error(STALE_ROSTER_DAEMON_MESSAGE);\n\t\t}\n\t\tconst unsubscribe = store.onUpdate(listener);\n\t\treturn {\n\t\t\tsummaries: () => store.summaries(),\n\t\t\tdispose: async () => unsubscribe(),\n\t\t};\n\t}\n\n\tsubscribe(listener: AgentConnectionEventListener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tonBeforeSessionInvalidate(_listener: AgentConnectionBeforeSessionInvalidateListener): () => void {\n\t\treturn () => {};\n\t}\n\n\tasync getState(): Promise<AgentConnectionState> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot.state;\n\t\t}\n\t\treturn this.requestData<AgentConnectionState>({\n\t\t\ttype: \"get_connection_state\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getInitialSnapshot(options?: { recoverable?: boolean }): Promise<AgentConnectionSnapshot> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot;\n\t\t}\n\t\t// The session tree is intentionally not fetched here: it is large on long\n\t\t// sessions and only needed when the user opens the tree/branch selector.\n\t\t// getSessionTree() fetches it lazily via get_session_tree on first use.\n\t\tconst snapshotCursor = this.lastEventCursor;\n\t\tconst snapshotSequence = this.lastEventSequence;\n\t\tconst [state, messagesData, sessionContextData] = await Promise.all([\n\t\t\tthis.requestData<AgentConnectionState>(\n\t\t\t\t{ type: \"get_connection_state\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t\tthis.requestData<{ messages: AgentMessage[] }>(\n\t\t\t\t{ type: \"get_messages\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t\tthis.requestData<{ context: AgentConnectionSessionContext }>(\n\t\t\t\t{ type: \"get_session_context\", activeSessionId: this.activeSessionId },\n\t\t\t\tundefined,\n\t\t\t\toptions,\n\t\t\t),\n\t\t]);\n\t\tconst children = this.latestSnapshot?.children;\n\t\tconst streamingMessage = this.latestSnapshot?.streamingMessage;\n\t\tthis.latestSnapshot = {\n\t\t\tstate,\n\t\t\tmessages: messagesData.messages,\n\t\t\tsessionContext: sessionContextData.context,\n\t\t\t...(children ? { children } : {}),\n\t\t\t...(streamingMessage ? { streamingMessage } : {}),\n\t\t};\n\t\tif (snapshotSequence !== undefined) {\n\t\t\tthis.latestSnapshot.lastEventSequence = snapshotSequence;\n\t\t}\n\t\tif (snapshotCursor) {\n\t\t\tthis.latestSnapshot.lastEventCursor = snapshotCursor;\n\t\t}\n\t\tthis.latestSnapshotIsFresh =\n\t\t\tsnapshotSequence === this.lastEventSequence &&\n\t\t\tsnapshotCursor?.generation === this.lastEventCursor?.generation &&\n\t\t\tsnapshotCursor?.sequence === this.lastEventCursor?.sequence;\n\t\treturn this.latestSnapshot;\n\t}\n\n\tasync getRlmChildSnapshots(): Promise<AgentConnectionRlmChildAgentSnapshot[]> {\n\t\tif (!this.client.supportsServerCapability(\"authoritative_child_roster\")) {\n\t\t\tthrow new DaemonCapabilityUnavailableError(\"get_rlm_children\", \"authoritative_child_roster\");\n\t\t}\n\t\tconst data = await this.requestData<{\n\t\t\tchildren: AgentConnectionRlmChildAgentSnapshot[];\n\t\t\teventSequence: number;\n\t\t}>({ type: \"get_rlm_children\", activeSessionId: this.activeSessionId });\n\t\tif (!Array.isArray(data.children) || !Number.isInteger(data.eventSequence)) {\n\t\t\tthrow new Error(\"Daemon returned an invalid child roster\");\n\t\t}\n\t\tif ((this.childRosterSequence ?? -1) > data.eventSequence) {\n\t\t\treturn this.latestSnapshot?.children ?? data.children;\n\t\t}\n\t\tthis.childRosterSequence = data.eventSequence;\n\t\tif (this.latestSnapshot) {\n\t\t\tthis.latestSnapshot = { ...this.latestSnapshot, children: data.children };\n\t\t}\n\t\treturn data.children;\n\t}\n\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot) {\n\t\t\treturn this.latestSnapshot.messages;\n\t\t}\n\t\tconst data = await this.requestData<{ messages: AgentMessage[] }>({\n\t\t\ttype: \"get_messages\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.messages;\n\t}\n\n\tasync getSessionHeader(): Promise<AgentConnectionSessionHeader | undefined> {\n\t\tconst data = await this.requestData<{ header?: AgentConnectionSessionHeader | null }>({\n\t\t\ttype: \"get_session_header\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.header ?? undefined;\n\t}\n\n\tasync getCommands(): Promise<AgentConnectionSlashCommand[]> {\n\t\tconst data = await this.requestData<{ commands: AgentConnectionSlashCommand[] }>({\n\t\t\ttype: \"get_commands\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.commands;\n\t}\n\n\tasync getResourceSnapshot(): Promise<AgentConnectionResourceSnapshot> {\n\t\treturn this.requestData<AgentConnectionResourceSnapshot>({\n\t\t\ttype: \"get_resource_snapshot\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tsupportsAcpMcpServers(): boolean {\n\t\treturn this.client.supportsServerCapability(\"acp_mcp_servers\");\n\t}\n\n\tasync replaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): Promise<void> {\n\t\tif (!this.supportsAcpMcpServers()) {\n\t\t\tthrow new DaemonCapabilityUnavailableError(\"replace_acp_mcp_servers\", \"acp_mcp_servers\");\n\t\t}\n\t\tawait this.requestOk({\n\t\t\ttype: \"replace_acp_mcp_servers\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\townerId,\n\t\t\tservers: [...servers],\n\t\t});\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, _serverNames: readonly string[]): Promise<void> {\n\t\tawait this.replaceAcpMcpServers([], ownerId);\n\t}\n\n\tasync getAvailableModels(): Promise<AgentConnectionModel[]> {\n\t\tconst data = await this.requestData<{ models: AgentConnectionModel[] }>({\n\t\t\ttype: \"get_available_models\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.models;\n\t}\n\n\tasync getModelCatalog(): Promise<AgentConnectionModelCatalog> {\n\t\tif (!this.client.supportsServerCapability(\"model_catalog\")) {\n\t\t\tconst models = await this.getAvailableModels();\n\t\t\treturn {\n\t\t\t\tmodels,\n\t\t\t\tconfiguredProviders: [...new Set(models.map((model) => model.provider))],\n\t\t\t};\n\t\t}\n\t\treturn this.requestData<AgentConnectionModelCatalog>({\n\t\t\ttype: \"get_model_catalog\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\treturn this.requestData<SessionStats>({\n\t\t\ttype: \"get_session_stats\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getContextTree(): Promise<ContextTreeNode> {\n\t\treturn this.requestData<ContextTreeNode>({\n\t\t\ttype: \"get_context_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getSessionContext(): Promise<AgentConnectionSessionContext> {\n\t\tif (this.latestSnapshotIsFresh && this.latestSnapshot?.sessionContext) {\n\t\t\treturn this.latestSnapshot.sessionContext;\n\t\t}\n\t\tconst data = await this.requestData<{ context: AgentConnectionSessionContext }>({\n\t\t\ttype: \"get_session_context\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.context;\n\t}\n\n\tasync getSessionTree(): Promise<{ tree: AgentConnectionSessionTreeNode[]; leafId: string | null }> {\n\t\tconst data = await this.requestData<{\n\t\t\tflatNodes: AgentConnectionSessionTreeFlatNode[];\n\t\t\tleafId: string | null;\n\t\t}>({\n\t\t\ttype: \"get_session_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn { tree: buildSessionTreeFromFlatNodes(data.flatNodes), leafId: data.leafId };\n\t}\n\n\tasync listSavedSessions(\n\t\tscope: AgentConnectionSavedSessionScope,\n\t\tcallbacks?: AgentConnectionSessionListCallbacks,\n\t): Promise<AgentConnectionSavedSessionInfo[]> {\n\t\treturn listDaemonSavedSessions(this.client, { activeSessionId: this.activeSessionId }, scope, callbacks);\n\t}\n\n\tasync getQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.requestData<AgentConnectionQueueState>({\n\t\t\ttype: \"get_queue\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync mutateQueuedMessage(\n\t\tlane: AgentConnectionQueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: AgentConnectionQueuedMessageMutation,\n\t): Promise<AgentConnectionQueuedMessageMutationStatus> {\n\t\tif (!this.client.supportsServerCapability(\"queue_message_mutation\")) return \"unsupported\";\n\t\tconst data = await this.requestData<{ status: AgentConnectionQueuedMessageMutationStatus }>({\n\t\t\ttype: \"mutate_queued_message\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tlane,\n\t\t\tindex,\n\t\t\texpectedText,\n\t\t\tmutation,\n\t\t});\n\t\treturn data.status;\n\t}\n\n\tasync clearQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.requestData<AgentConnectionQueueState>({\n\t\t\ttype: \"clear_queue\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync abortAndClearQueue(): Promise<AgentConnectionQueueState> {\n\t\ttry {\n\t\t\treturn await this.requestData<AgentConnectionQueueState>({\n\t\t\t\ttype: \"abort_and_clear_queue\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"abort_and_clear_queue\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync acquireSessionInputPause(leaseKey: string): Promise<AgentConnectionSessionInputPause> {\n\t\tif (this.terminalCloseEmitted) throw new Error(\"Daemon connection is closed; cannot acquire an input pause.\");\n\t\tconst activeSessionId = this.activeSessionId;\n\t\tconst generation = this.sessionInputPauseGeneration;\n\t\tconst acquisitionKey = JSON.stringify([activeSessionId, leaseKey]);\n\t\tconst existing = this.sessionInputPauses.get(acquisitionKey);\n\t\tif (existing) return existing;\n\t\tconst acquisition = (async (): Promise<AgentConnectionSessionInputPause> => {\n\t\t\tconst { pauseId } = await this.requestData<{ pauseId: string }>({\n\t\t\t\ttype: \"acquire_session_input_pause\",\n\t\t\t\tactiveSessionId,\n\t\t\t\tleaseKey,\n\t\t\t});\n\t\t\tif (generation !== this.sessionInputPauseGeneration || this.terminalCloseEmitted) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.requestData({\n\t\t\t\t\t\ttype: \"release_session_input_pause\",\n\t\t\t\t\t\tactiveSessionId,\n\t\t\t\t\t\tpauseId,\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tthis.client.close();\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"Session input pause acquisition was invalidated by a daemon reconnect.\");\n\t\t\t}\n\t\t\tlet released = false;\n\t\t\treturn {\n\t\t\t\trelease: async () => {\n\t\t\t\t\tif (released) return;\n\t\t\t\t\tif (generation !== this.sessionInputPauseGeneration) {\n\t\t\t\t\t\tthrow new Error(\"Session input pause was invalidated by a daemon reconnect.\");\n\t\t\t\t\t}\n\t\t\t\t\tawait this.requestData({\n\t\t\t\t\t\ttype: \"release_session_input_pause\",\n\t\t\t\t\t\tactiveSessionId,\n\t\t\t\t\t\tpauseId,\n\t\t\t\t\t});\n\t\t\t\t\treleased = true;\n\t\t\t\t\tif (this.sessionInputPauses.get(acquisitionKey) === acquisition) {\n\t\t\t\t\t\tthis.sessionInputPauses.delete(acquisitionKey);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t})();\n\t\tthis.sessionInputPauses.set(acquisitionKey, acquisition);\n\t\ttry {\n\t\t\treturn await acquisition;\n\t\t} catch (error) {\n\t\t\tif (this.sessionInputPauses.get(acquisitionKey) === acquisition)\n\t\t\t\tthis.sessionInputPauses.delete(acquisitionKey);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync listCronJobs(options: { includeInactive?: boolean } = {}): Promise<AgentCronJob[]> {\n\t\tconst data = await this.requestData<{ jobs: AgentCronJob[] }>({\n\t\t\ttype: \"cron_list\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tincludeInactive: options.includeInactive,\n\t\t});\n\t\treturn data.jobs;\n\t}\n\n\tasync listHeartbeats(): Promise<AgentConnectionHeartbeat[]> {\n\t\treturn listDaemonHeartbeats(this.client, this.options.ownedSession ? this.activeSessionId : undefined);\n\t}\n\n\tasync manageHeartbeat(\n\t\tactiveSessionId: string,\n\t\tjobId: string,\n\t\taction: AgentHeartbeatManagementAction,\n\t): Promise<AgentCronJob> {\n\t\tif (!this.client.supportsServerCapability(\"heartbeat_management\")) {\n\t\t\tthrow new Error(\"Heartbeat management requires a newer Base Context daemon.\");\n\t\t}\n\t\ttry {\n\t\t\tconst data = await this.requestData<{ heartbeat: AgentCronJob }>({\n\t\t\t\ttype: \"heartbeat_manage\",\n\t\t\t\tactiveSessionId,\n\t\t\t\tjobId,\n\t\t\t\taction,\n\t\t\t});\n\t\t\treturn data.heartbeat;\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"heartbeat_manage\")) {\n\t\t\t\tthrow new Error(\"Heartbeat management requires a newer Base Context daemon.\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync addCronJob(schedule: string, prompt: string): Promise<AgentCronJob> {\n\t\treturn this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tconst data = await this.requestData<{ job: AgentCronJob }>({\n\t\t\t\ttype: \"cron_add\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tschedule,\n\t\t\t\tprompt,\n\t\t\t\tpromoteOwnedSession,\n\t\t\t});\n\t\t\treturn data.job;\n\t\t});\n\t}\n\n\tasync cancelCronJob(jobId: string): Promise<AgentCronJob> {\n\t\tconst data = await this.requestData<{ job: AgentCronJob }>({\n\t\t\ttype: \"cron_cancel\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tjobId,\n\t\t});\n\t\treturn data.job;\n\t}\n\n\tasync getHeartbeat(): Promise<AgentCronJob | undefined> {\n\t\tconst data = await this.requestData<{ heartbeat?: AgentCronJob | null }>({\n\t\t\ttype: \"heartbeat_get\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.heartbeat ?? undefined;\n\t}\n\n\tasync setHeartbeat(\n\t\tschedule: string,\n\t\tinstruction: string,\n\t\tdeliveryMode?: AgentHeartbeatDeliveryMode,\n\t): Promise<AgentCronJob> {\n\t\treturn this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tconst data = await this.requestData<{ heartbeat: AgentCronJob }>({\n\t\t\t\ttype: \"heartbeat_set\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tschedule,\n\t\t\t\tprompt: instruction,\n\t\t\t\t...(deliveryMode ? { deliveryMode } : {}),\n\t\t\t\tpromoteOwnedSession,\n\t\t\t});\n\t\t\treturn data.heartbeat;\n\t\t});\n\t}\n\n\tasync updateHeartbeat(action: AgentHeartbeatUpdateAction): Promise<AgentCronJob | undefined> {\n\t\tconst data = await this.requestData<{ heartbeat?: AgentCronJob | null }>({\n\t\t\ttype: \"heartbeat_update\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\taction,\n\t\t});\n\t\treturn data.heartbeat ?? undefined;\n\t}\n\n\tasync sendAgentMessage(targetActiveSessionId: string, message: string): Promise<AgentSessionMessageReceipt> {\n\t\treturn this.requestData<AgentSessionMessageReceipt>({\n\t\t\ttype: \"send_message\",\n\t\t\ttargetActiveSessionId,\n\t\t\tmessage,\n\t\t\tfromActiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getAgentMessageStatus(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_status\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync pauseAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_pause\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync resumeAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\treturn this.requestData<AgentSessionMessageSafetyStatus>({\n\t\t\ttype: \"agent_messages_resume\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync clearAgentMessages(): Promise<number> {\n\t\treturn this.requestData<number>({\n\t\t\ttype: \"agent_messages_clear\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync getUserMessagesForForking(): Promise<AgentConnectionUserMessage[]> {\n\t\tconst data = await this.requestData<{ messages: AgentConnectionUserMessage[] }>({\n\t\t\ttype: \"get_user_messages_for_forking\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.messages;\n\t}\n\n\tasync getLastAssistantText(): Promise<string | undefined> {\n\t\tconst data = await this.requestData<{ text?: string | null }>({\n\t\t\ttype: \"get_last_assistant_text\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.text ?? undefined;\n\t}\n\n\tasync getSystemPrompt(): Promise<string> {\n\t\tconst data = await this.requestData<{ systemPrompt: string }>({\n\t\t\ttype: \"get_system_prompt\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn data.systemPrompt;\n\t}\n\n\tasync getToolDefinition(name: string): Promise<AgentConnectionToolDefinition | undefined> {\n\t\tconst data = await this.requestData<{ toolDefinition?: AgentConnectionToolDefinition }>({\n\t\t\ttype: \"get_tool_definition\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tname,\n\t\t});\n\t\treturn data.toolDefinition;\n\t}\n\n\tasync setSessionEntryLabel(entryId: string, label: string | undefined): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"set_session_entry_label\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tentryId,\n\t\t\tlabel,\n\t\t});\n\t}\n\n\tasync respondToExtensionUiRequest(requestId: string, response: AgentConnectionExtensionUiResponse): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"extension_ui_response\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\trequestId,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync prompt(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.promptWithAdmissionCancellation(\"prompt\", message, options);\n\t}\n\n\tasync promptAndWait(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.promptWithAdmissionCancellation(\"prompt_and_wait\", message, options);\n\t}\n\n\tprivate async promptWithAdmissionCancellation(\n\t\ttype: \"prompt\" | \"prompt_and_wait\",\n\t\tmessage: string,\n\t\toptions?: AgentConnectionPromptOptions,\n\t): Promise<void> {\n\t\tconst signal = options?.signal;\n\t\tif (signal?.aborted) {\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\"Prompt admission was cancelled.\", \"cancelled\");\n\t\t}\n\t\tif (!signal) {\n\t\t\tawait this.requestData<unknown>(\n\t\t\t\t{\n\t\t\t\t\ttype,\n\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\tmessage,\n\t\t\t\t\timages: options?.images,\n\t\t\t\t\tstreamingBehavior: options?.streamingBehavior,\n\t\t\t\t\tqueueIfBusy: options?.queueIfBusy,\n\t\t\t\t\tsource: options?.source,\n\t\t\t\t},\n\t\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst admissionId = `prompt-admission:${randomUUID()}`;\n\t\tlet resolveAbort = () => {};\n\t\tconst aborted = new Promise<\"abort\">((resolve) => {\n\t\t\tresolveAbort = () => resolve(\"abort\");\n\t\t});\n\t\tconst onAbort = () => resolveAbort();\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t// Close the listener-registration race before issuing the first request.\n\t\tif (signal.aborted) {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\"Prompt admission was cancelled.\", \"cancelled\");\n\t\t}\n\t\tconst command = {\n\t\t\ttype,\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tmessage,\n\t\t\timages: options.images,\n\t\t\tstreamingBehavior: options.streamingBehavior,\n\t\t\tqueueIfBusy: options.queueIfBusy,\n\t\t\tsource: options.source,\n\t\t\tadmissionId,\n\t\t} as Extract<DaemonCommandBody, { type: typeof type }>;\n\t\tlet promptError: unknown;\n\t\tconst promptRequest = this.requestData<unknown>(command, DAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS).catch(\n\t\t\t(error: unknown) => {\n\t\t\t\tpromptError =\n\t\t\t\t\terror instanceof DaemonCapabilityUnavailableError && !error.afterReconnect\n\t\t\t\t\t\t? new AgentConnectionPromptAdmissionError(error.message, \"unsupported\", { cause: error })\n\t\t\t\t\t\t: error;\n\t\t\t\treturn \"failed\" as const;\n\t\t\t},\n\t\t);\n\t\ttry {\n\t\t\tconst first = await Promise.race([promptRequest.then(() => \"settled\" as const), aborted]);\n\t\t\tif (first === \"settled\" && promptError === undefined) return;\n\t\t\tif (first === \"settled\" && promptError instanceof AgentConnectionPromptAdmissionError) throw promptError;\n\t\t\tif (\n\t\t\t\tfirst === \"settled\" &&\n\t\t\t\t!signal.aborted &&\n\t\t\t\tpromptError instanceof Error &&\n\t\t\t\tthis.definitiveRequestErrors.has(promptError)\n\t\t\t) {\n\t\t\t\tthrow promptError;\n\t\t\t}\n\t\t\tlet status: \"cancelled\" | \"owned\" | \"unknown\" = \"unknown\";\n\t\t\ttry {\n\t\t\t\tconst result = await this.requestData<{ status: \"cancelled\" | \"owned\" | \"unknown\" }>({\n\t\t\t\t\ttype: \"cancel_prompt_admission\",\n\t\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t\tadmissionId,\n\t\t\t\t\t...(this.client.supportsServerCapability(\"owned_prompt_cancellation\") ? { cancelOwned: true } : {}),\n\t\t\t\t});\n\t\t\t\tstatus = result.status;\n\t\t\t} catch {\n\t\t\t\t// Timeout/transport is indistinguishable from accepted ownership.\n\t\t\t}\n\t\t\tawait promptRequest;\n\t\t\tif (promptError instanceof AgentConnectionPromptAdmissionError) throw promptError;\n\t\t\tconst definitiveFailure = promptError instanceof Error && this.definitiveRequestErrors.has(promptError);\n\t\t\tif (promptError === undefined || (status === \"owned\" && type === \"prompt\" && !definitiveFailure)) return;\n\t\t\tthrow new AgentConnectionPromptAdmissionError(\n\t\t\t\tpromptError instanceof Error ? promptError.message : \"Prompt admission did not complete.\",\n\t\t\t\tstatus,\n\t\t\t\tpromptError === undefined ? undefined : { cause: promptError },\n\t\t\t);\n\t\t} finally {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t}\n\t}\n\n\tasync startSideQuestion(\n\t\tid: string,\n\t\tquestion: string,\n\t\tpreviousTurns?: AgentConnectionSideQuestionTurn[],\n\t): Promise<void> {\n\t\tif (previousTurns?.length && !this.client.supportsServerCapability(\"side_question_transcript\")) {\n\t\t\t// An older daemon would silently ignore previousTurns and answer the\n\t\t\t// follow-up without the side-conversation context; fail loudly instead.\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without side-conversation follow-ups; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\tthis.activeSideQuestionIds.add(id);\n\t\ttry {\n\t\t\tawait this.requestOk({\n\t\t\t\ttype: \"start_side_question\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tsideQuestionId: id,\n\t\t\t\tquestion,\n\t\t\t\tpreviousTurns,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.activeSideQuestionIds.delete(id);\n\t\t\tif (isUnknownDaemonCommandError(error, \"start_side_question\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync abortSideQuestion(id: string): Promise<boolean> {\n\t\tconst data = await this.requestData<{ aborted: boolean }>({\n\t\t\ttype: \"abort_side_question\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tsideQuestionId: id,\n\t\t});\n\t\tthis.activeSideQuestionIds.delete(id);\n\t\treturn data.aborted;\n\t}\n\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.requestOk({ type: \"steer\", activeSessionId: this.activeSessionId, message, images });\n\t}\n\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.requestOk({ type: \"follow_up\", activeSessionId: this.activeSessionId, message, images });\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync cancelRlmChild(childId: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst result = await this.requestData<{ cancelled: boolean }>({\n\t\t\t\ttype: \"cancel_rlm_child\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tchildId,\n\t\t\t});\n\t\t\treturn result.cancelled;\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"cancel_rlm_child\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this.requestData<unknown>(\n\t\t\t{ type: \"wait_for_idle\", activeSessionId: this.activeSessionId },\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync waitForHeadlessCompletion(options?: AgentConnectionHeadlessCompletionOptions): Promise<AgentAutonomousStatus> {\n\t\tif (options?.waitForRlmQuiescence && !this.client.supportsServerCapability(\"rlm_quiescence_barrier\")) {\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without RLM quiescence barriers; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\treturn this.requestData<AgentAutonomousStatus>(\n\t\t\t{\n\t\t\t\ttype: \"wait_for_headless_completion\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\t...(options?.waitForRlmQuiescence ? { waitForRlmQuiescence: true } : {}),\n\t\t\t},\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync executeBash(command: string, options?: AgentConnectionExecuteBashOptions): Promise<void> {\n\t\tif (options?.transient && !this.client.supportsServerCapability(\"transient_bash\")) {\n\t\t\t// An older daemon would record the run into the session, leaking the\n\t\t\t// side conversation into the main transcript; fail loudly instead.\n\t\t\tthrow new Error(\n\t\t\t\t\"the daemon is running an older build without side-conversation bash; restart the daemon and try again\",\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tawait this.requestOk({\n\t\t\t\ttype: \"execute_bash\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tcommand,\n\t\t\t\texcludeFromContext: options?.excludeFromContext,\n\t\t\t\ttransient: options?.transient,\n\t\t\t\trunId: options?.runId,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"execute_bash\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync executeBashAndWait(command: string): Promise<BashResult> {\n\t\treturn this.requestData<BashResult>(\n\t\t\t{\n\t\t\t\ttype: \"execute_bash_and_wait\",\n\t\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\t\tcommand,\n\t\t\t},\n\t\t\tDAEMON_LONG_RUNNING_REQUEST_TIMEOUT_MS,\n\t\t);\n\t}\n\n\tasync abortBash(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.requestOk({ type: \"abort_bash\", activeSessionId: this.activeSessionId });\n\t\t} catch (error) {\n\t\t\tif (isUnknownDaemonCommandError(error, \"abort_bash\")) {\n\t\t\t\tthrow new Error(\"the daemon is running an older build; restart the daemon and try again\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync setModel(provider: string, modelId: string): Promise<AgentConnectionModel> {\n\t\treturn this.requestData<AgentConnectionModel>({\n\t\t\ttype: \"set_model\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t});\n\t}\n\n\tasync cycleModel(direction?: \"forward\" | \"backward\"): Promise<AgentConnectionModelCycleResult | undefined> {\n\t\tconst result = await this.requestData<AgentConnectionModelCycleResult | null>({\n\t\t\ttype: \"cycle_model\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tdirection,\n\t\t});\n\t\treturn result ?? undefined;\n\t}\n\n\tasync setScopedModels(scopedModels: AgentConnectionScopedModel[]): Promise<void> {\n\t\tawait this.requestOk({\n\t\t\ttype: \"set_scoped_models\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tscopedModels,\n\t\t});\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_thinking_level\", activeSessionId: this.activeSessionId, level });\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_service_tier\", activeSessionId: this.activeSessionId, serviceTier });\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\tconst result = await this.requestData<{ level: ThinkingLevel } | null>({\n\t\t\ttype: \"cycle_thinking_level\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t\treturn result?.level;\n\t}\n\n\tasync setTransport(transport: Transport): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_transport\", activeSessionId: this.activeSessionId, transport });\n\t}\n\n\tasync setSteeringMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_steering_mode\", activeSessionId: this.activeSessionId, mode });\n\t}\n\n\tasync setFollowUpMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_follow_up_mode\", activeSessionId: this.activeSessionId, mode });\n\t}\n\n\tasync setAutoCompactionEnabled(enabled: boolean): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_auto_compaction\", activeSessionId: this.activeSessionId, enabled });\n\t}\n\n\tasync setAutoRetryEnabled(enabled: boolean): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_auto_retry\", activeSessionId: this.activeSessionId, enabled });\n\t}\n\n\tasync compact(customInstructions?: string): Promise<CompactionResult> {\n\t\treturn this.requestData<CompactionResult>({\n\t\t\ttype: \"compact\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tcustomInstructions,\n\t\t});\n\t}\n\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t): Promise<RefinementResult> {\n\t\tconst command: {\n\t\t\ttype: \"refine\";\n\t\t\tactiveSessionId: string;\n\t\t\tinstructions?: string;\n\t\t\trollbackId?: string;\n\t\t\tglobal?: boolean;\n\t\t} = {\n\t\t\ttype: \"refine\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tinstructions: options.instructions,\n\t\t\trollbackId: options.rollbackId,\n\t\t};\n\t\tif (options.global !== undefined) {\n\t\t\tcommand.global = options.global;\n\t\t}\n\t\treturn this.requestData<RefinementResult>(command, DAEMON_REFINE_REQUEST_TIMEOUT_MS);\n\t}\n\n\tasync abortCompaction(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_compaction\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync abortBranchSummary(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_branch_summary\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync abortRetry(): Promise<void> {\n\t\tawait this.requestOk({ type: \"abort_retry\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tawait this.requestOk({ type: \"reload\", activeSessionId: this.activeSessionId });\n\t}\n\n\tasync newSession(options?: AgentConnectionNewSessionOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.requestData<{ cancelled: boolean }>({\n\t\t\ttype: \"new_session\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tparentSession: options?.parentSession,\n\t\t});\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: AgentConnectionSwitchSessionOptions,\n\t): Promise<{ cancelled: boolean }> {\n\t\tconst sourceActiveSessionId = this.activeSessionId;\n\t\ttry {\n\t\t\treturn await this.requestData<{ cancelled: boolean }>({\n\t\t\t\ttype: \"switch_session\",\n\t\t\t\tactiveSessionId: sourceActiveSessionId,\n\t\t\t\tsessionPath,\n\t\t\t\tcwdOverride: options?.cwdOverride,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof SessionAlreadyActiveError) || !error.activeSessionId) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (this.options.ownedSession) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (error.activeSessionId === sourceActiveSessionId) {\n\t\t\t\treturn { cancelled: false };\n\t\t\t}\n\t\t\treturn this.reattachSession(sourceActiveSessionId, error.activeSessionId);\n\t\t}\n\t}\n\n\tprivate async reattachSession(\n\t\tsourceActiveSessionId: string,\n\t\ttargetActiveSessionId: string,\n\t): Promise<{ cancelled: false }> {\n\t\tconst previousState = {\n\t\t\tlastEventCursor: this.lastEventCursor,\n\t\t\tlastEventSequence: this.lastEventSequence,\n\t\t\tlatestSnapshot: this.latestSnapshot,\n\t\t\tlatestSnapshotIsFresh: this.latestSnapshotIsFresh,\n\t\t\tretiredEventGenerations: new Set(this.retiredEventGenerations),\n\t\t};\n\t\tthis.activeSessionId = targetActiveSessionId;\n\t\tthis.lastEventCursor = undefined;\n\t\tthis.lastEventSequence = undefined;\n\t\tthis.latestSnapshot = undefined;\n\t\tthis.latestSnapshotIsFresh = false;\n\t\tthis.retiredEventGenerations.clear();\n\t\tthis.pendingReattachActiveSessionIds.add(targetActiveSessionId);\n\t\tlet reattached = false;\n\t\ttry {\n\t\t\tconst supportsExtensionUi = this.options.supportsExtensionUi !== false;\n\t\t\tconst result = await this.requestData<DaemonAttachResult>({\n\t\t\t\ttype: \"reattach\",\n\t\t\t\tactiveSessionId: sourceActiveSessionId,\n\t\t\t\ttargetActiveSessionId,\n\t\t\t\tsupportsExtensionUi,\n\t\t\t\tclientId: this.clientId,\n\t\t\t\tcapabilities: [\n\t\t\t\t\t\"attach_snapshot\",\n\t\t\t\t\t\"event_sequence\",\n\t\t\t\t\t...(supportsExtensionUi ? ([\"extension_ui\"] as const) : []),\n\t\t\t\t\t\"slim_attach\",\n\t\t\t\t\t\"chunked_snapshot\",\n\t\t\t\t\t...(this.options.ownedSession ? ([\"client_owned_sessions\"] as const) : []),\n\t\t\t\t],\n\t\t\t\tenv: this.options.sendClientEnv ? collectDaemonClientEnv() : undefined,\n\t\t\t\tlaunchEnv: this.options.ownedSession ? collectDaemonLaunchEnv() : undefined,\n\t\t\t});\n\t\t\t// Reattach rebinds the connection (and drops any direct link); pauses on the old session are gone.\n\t\t\tthis.sessionInputPauses.clear();\n\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\treattached = true;\n\t\t\tthis.activeSessionId = result.activeSessionId;\n\t\t\tthis.activeSideQuestionIds.clear();\n\t\t\tif (result.snapshotStream) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.waitForSnapshot(result.snapshotStream.id);\n\t\t\t\t} catch (snapshotError) {\n\t\t\t\t\tawait this.snapshotRecoveryPromises.get(result.snapshotStream.id);\n\t\t\t\t\tif (!this.latestSnapshotIsFresh) {\n\t\t\t\t\t\tthrow snapshotError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.applyReplacementSnapshot(result.snapshot, result.replay);\n\t\t\t\tawait this.emit({\n\t\t\t\t\ttype: \"session_replaced\",\n\t\t\t\t\tstate: result.snapshot.state,\n\t\t\t\t\tmessages: result.snapshot.messages,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { cancelled: false };\n\t\t} catch (error) {\n\t\t\tif (!reattached) {\n\t\t\t\tthis.activeSessionId = sourceActiveSessionId;\n\t\t\t\tthis.lastEventCursor = previousState.lastEventCursor;\n\t\t\t\tthis.lastEventSequence = previousState.lastEventSequence;\n\t\t\t\tthis.latestSnapshot = previousState.latestSnapshot;\n\t\t\t\tthis.latestSnapshotIsFresh = previousState.latestSnapshotIsFresh;\n\t\t\t\tthis.retiredEventGenerations.clear();\n\t\t\t\tfor (const generation of previousState.retiredEventGenerations) {\n\t\t\t\t\tthis.retiredEventGenerations.add(generation);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingReattachActiveSessionIds.delete(targetActiveSessionId);\n\t\t}\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: AgentConnectionForkOptions,\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\treturn this.requestData<{ cancelled: boolean; selectedText?: string }>({\n\t\t\ttype: \"fork\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tentryId,\n\t\t\tposition: options?.position,\n\t\t});\n\t}\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions?: AgentConnectionNavigateTreeOptions,\n\t): Promise<AgentConnectionNavigateTreeResult> {\n\t\treturn this.requestData<AgentConnectionNavigateTreeResult>({\n\t\t\ttype: \"navigate_tree\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\ttargetId,\n\t\t\tsummarize: options?.summarize,\n\t\t\tcustomInstructions: options?.customInstructions,\n\t\t\treplaceInstructions: options?.replaceInstructions,\n\t\t\tlabel: options?.label,\n\t\t});\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\treturn this.requestData<{ cancelled: boolean }>({\n\t\t\ttype: \"import_jsonl\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tinputPath,\n\t\t\tcwdOverride,\n\t\t});\n\t}\n\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\tconst data = await this.requestData<{ path: string }>({\n\t\t\ttype: \"export_html\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\toutputPath,\n\t\t});\n\t\treturn data.path;\n\t}\n\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\tconst data = await this.requestData<{ path: string }>({\n\t\t\ttype: \"export_jsonl\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\toutputPath,\n\t\t});\n\t\treturn data.path;\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.requestOk({ type: \"set_session_name\", activeSessionId: this.activeSessionId, name });\n\t}\n\n\tasync getRlmMaxSubagentsStatus() {\n\t\treturn this.requestData<{ maxSubagents: number }>({\n\t\t\ttype: \"get_rlm_max_subagents_status\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync setRlmMaxSubagents(maxSubagents: number) {\n\t\treturn this.requestData<{ maxSubagents: number }>({\n\t\t\ttype: \"set_rlm_max_subagents\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tmaxSubagents,\n\t\t});\n\t}\n\n\tasync getRlmMaxDepthStatus() {\n\t\treturn this.requestData<{ maxDepth: number; source: \"default\" | \"env\" | \"global\" | \"inherited\" | \"chat\" }>({\n\t\t\ttype: \"get_rlm_max_depth_status\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t});\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options?: { global?: boolean }) {\n\t\treturn this.requestData<{\n\t\t\tmaxDepth: number;\n\t\t\tsource: \"default\" | \"env\" | \"global\" | \"inherited\" | \"chat\";\n\t\t\tglobalSaved: boolean;\n\t\t\tglobalError?: string;\n\t\t}>({\n\t\t\ttype: \"set_rlm_max_depth\",\n\t\t\tactiveSessionId: this.activeSessionId,\n\t\t\tmaxDepth,\n\t\t\tglobal: options?.global,\n\t\t});\n\t}\n\n\tasync renameSavedSession(sessionPath: string, name: string): Promise<void> {\n\t\tawait renameDaemonSavedSession(this.client, { activeSessionId: this.activeSessionId }, sessionPath, name);\n\t}\n\n\tasync deleteSavedSession(sessionPath: string): Promise<DeleteSessionFileResult> {\n\t\treturn deleteDaemonSavedSession(this.client, { activeSessionId: this.activeSessionId }, sessionPath);\n\t}\n\n\tasync watchSession(activeSessionId: string): Promise<AgentConnectionSessionWatcher | undefined> {\n\t\t// A second connection on the shared client; each one filters to its own session id.\n\t\t// attach() rejects for an unknown/exited session — treat that as unreachable.\n\t\tlet connection: DaemonAgentConnection;\n\t\ttry {\n\t\t\tconst watchClient =\n\t\t\t\tthis.client instanceof DaemonRoutedClient ? this.client.controlPlaneTransport : this.client;\n\t\t\tconnection = await DaemonAgentConnection.attach(watchClient, activeSessionId, {\n\t\t\t\tcloseClientOnDispose: false,\n\t\t\t\tdirectTransport: false,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tgetMessages: () => connection.getMessages(),\n\t\t\tgetCommands: () => connection.getCommands(),\n\t\t\tsubscribe: (listener) => connection.subscribe(listener),\n\t\t\tgetToolDefinition: (name) => connection.getToolDefinition(name),\n\t\t\tclose: () => connection.dispose(),\n\t\t};\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tif (this.disposed || this.disposing) {\n\t\t\treturn;\n\t\t}\n\t\tthis.disposing = true;\n\t\tif (this.options.ownedSession && !this.client.isConnected && this.reconnectPromise) {\n\t\t\tawait Promise.race([this.reconnectPromise, delay(OWNED_SESSION_DISPOSE_RECONNECT_WAIT_MS)]).catch(\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t}\n\t\tthis.disposed = true;\n\t\tthis.updateRestartPending = false;\n\t\tawait Promise.allSettled([...this.activeSideQuestionIds].map((id) => this.abortSideQuestion(id)));\n\t\tawait this.rosterStore?.dispose().catch(() => undefined);\n\t\tthis.rosterStore = undefined;\n\t\tthis.unsubscribeDaemonMessages();\n\t\tthis.unsubscribeDaemonClose();\n\t\tif (this.options.ownedSession) {\n\t\t\tawait this.requestOk({ type: \"complete_owned_session\", activeSessionId: this.activeSessionId }).catch(\n\t\t\t\t() => undefined,\n\t\t\t);\n\t\t} else {\n\t\t\tawait this.requestOk({ type: \"detach\", activeSessionId: this.activeSessionId }).catch(() => undefined);\n\t\t}\n\t\tif (this.options.closeClientOnDispose) {\n\t\t\tthis.client.close();\n\t\t}\n\t\tthis.rejectSnapshotAssemblies(new Error(\"Daemon connection disposed during snapshot transfer\"));\n\t}\n\n\tasync promoteToResident(): Promise<void> {\n\t\tawait this.withOwnedSessionPromotion(async (promoteOwnedSession) => {\n\t\t\tif (!promoteOwnedSession) return;\n\t\t\tawait this.requestOk({ type: \"promote_owned_session\", activeSessionId: this.activeSessionId });\n\t\t});\n\t}\n\n\tprivate withOwnedSessionPromotion<T>(operation: (promoteOwnedSession: boolean) => Promise<T>): Promise<T> {\n\t\tconst run = this.ownedSessionPromotionTail.then(async () => {\n\t\t\tconst promoteOwnedSession = this.options.ownedSession === true;\n\t\t\tconst result = await operation(promoteOwnedSession);\n\t\t\tif (promoteOwnedSession) {\n\t\t\t\tthis.options.ownedSession = false;\n\t\t\t}\n\t\t\treturn result;\n\t\t});\n\t\tthis.ownedSessionPromotionTail = run.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn run;\n\t}\n\n\tprivate async reconnect(cause: Error): Promise<void> {\n\t\tif (this.reconnectPromise) {\n\t\t\treturn this.reconnectPromise;\n\t\t}\n\t\tthis.reconnectPromise = (async () => {\n\t\t\tvoid this.emit({ type: \"connection_status\", status: \"reconnecting\", error: cause.message });\n\t\t\tconst timeoutMs = this.options.reconnectTimeoutMs ?? DAEMON_RECONNECT_TIMEOUT_MS;\n\t\t\tlet deadline: number | undefined;\n\t\t\tlet attempt = 0;\n\t\t\tlet lastError: Error = cause;\n\t\t\twhile (!this.disposed) {\n\t\t\t\t// A held direct link owns session liveness: control-plane recovery retries unbounded,\n\t\t\t\t// and the bounded session-plane deadline arms only once the direct link is gone.\n\t\t\t\tconst directSessionHeld = this.client instanceof DaemonRoutedClient && this.client.hasDirectTransport;\n\t\t\t\tif (directSessionHeld) {\n\t\t\t\t\tdeadline = undefined;\n\t\t\t\t} else {\n\t\t\t\t\tdeadline ??= Date.now() + timeoutMs;\n\t\t\t\t\tif (Date.now() >= deadline) break;\n\t\t\t\t}\n\t\t\t\tlet controlPlaneHandshakeComplete = false;\n\t\t\t\ttry {\n\t\t\t\t\tawait this.options.recoverDaemon?.();\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.client.connect(1000);\n\t\t\t\t\tawait this.client.waitForHello(3000);\n\t\t\t\t\tcontrolPlaneHandshakeComplete = true;\n\t\t\t\t\tif (directSessionHeld) {\n\t\t\t\t\t\t// The roster subscription is a control-plane accessory; its usual rebind seam (attach) is skipped while held.\n\t\t\t\t\t\tif (this.rosterStore) await this.rosterStore.attach(this.client).catch(() => undefined);\n\t\t\t\t\t\t// One check after the last await, against the close handler's own dispatch outputs:\n\t\t\t\t\t\t// terminal closes set terminalCloseEmitted, update closes set updateRestartPending\n\t\t\t\t\t\t// (restoration owns the client), and recoverable closes joined this loop.\n\t\t\t\t\t\tif (this.disposed || this.terminalCloseEmitted || this.updateRestartPending) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (this.client instanceof DaemonRoutedClient && this.client.hasDirectTransport) {\n\t\t\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// The direct link died mid-recovery: rerun as a bounded session-plane reconnect.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// This loop owns the retry: a socket close must reject these instead of parking them behind a hello it can never produce.\n\t\t\t\t\tawait this.attach({ recoverable: false });\n\t\t\t\t\tif (!this.disposed) {\n\t\t\t\t\t\tconst snapshot = await this.getInitialSnapshot({ recoverable: false });\n\t\t\t\t\t\tvoid this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlastError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// A direct-half failure must not tear down a control-plane socket with a completed handshake.\n\t\t\t\t\tconst shouldResetControlPlane =\n\t\t\t\t\t\t!(this.client instanceof DaemonRoutedClient) ||\n\t\t\t\t\t\t!controlPlaneHandshakeComplete ||\n\t\t\t\t\t\terror instanceof DaemonControlPlaneTransportError ||\n\t\t\t\t\t\t!this.client.isControlPlaneReady;\n\t\t\t\t\tif (shouldResetControlPlane) this.client.resetTransportForReconnect();\n\t\t\t\t\tif (deadline !== undefined && deadline - Date.now() <= 0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst delayMs = Math.min(\n\t\t\t\t\t\t...(deadline !== undefined ? [deadline - Date.now()] : []),\n\t\t\t\t\t\t2000,\n\t\t\t\t\t\t100 * 2 ** Math.min(attempt, 5),\n\t\t\t\t\t);\n\t\t\t\t\tattempt++;\n\t\t\t\t\tawait new Promise((resolveDelay) => setTimeout(resolveDelay, delayMs));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!this.disposed) {\n\t\t\t\tthis.sessionInputPauses.clear();\n\t\t\t\tthis.sessionInputPauseGeneration++;\n\t\t\t\tthis.client.close();\n\t\t\t\tawait this.emit({ type: \"closed\", error: `Daemon reconnection failed: ${lastError.message}` });\n\t\t\t}\n\t\t})().finally(() => {\n\t\t\tthis.reconnectPromise = undefined;\n\t\t});\n\t\treturn this.reconnectPromise;\n\t}\n\n\tprivate async requestOk(command: DaemonCommandBody): Promise<void> {\n\t\tawait this.requestData<unknown>(command);\n\t}\n\n\tprivate async requestData<T>(\n\t\tcommand: DaemonCommandBody,\n\t\ttimeoutMs?: number,\n\t\toptions?: Parameters<DaemonTransportClient[\"request\"]>[2],\n\t): Promise<T> {\n\t\tconst response = await this.client.request(command, timeoutMs, options);\n\t\tif (!response.success) {\n\t\t\tconst error = deserializeDaemonError(response);\n\t\t\tthis.definitiveRequestErrors.add(error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (invalidatesCachedSnapshot(command.type)) {\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t}\n\t\treturn response.data as T;\n\t}\n\n\tprivate async handleDaemonMessage(message: DaemonOutbound): Promise<void> {\n\t\tif (message.type === \"heartbeats_changed\") {\n\t\t\tawait this.emit({ type: \"heartbeats_changed\" });\n\t\t\treturn;\n\t\t}\n\t\tif (!this.isMessageForActiveSession(message)) {\n\t\t\treturn;\n\t\t}\n\t\tif (\"snapshotId\" in message && this.ignoredSnapshotIds.has(message.snapshotId)) {\n\t\t\tif (message.type === \"session_snapshot_end\" || message.type === \"session_snapshot_failed\") {\n\t\t\t\tthis.ignoredSnapshotIds.delete(message.snapshotId);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_begin\") {\n\t\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\t\tassembly.begin = message;\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_chunk\") {\n\t\t\tthis.getSnapshotAssembly(message.snapshotId).chunks.set(message.index, message.messages);\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_end\") {\n\t\t\tawait this.completeSnapshotAssembly(message);\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_snapshot_failed\") {\n\t\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\t\tconst purpose = assembly.begin?.purpose ?? \"attach\";\n\t\t\tconst snapshotError = new Error(message.error);\n\t\t\tconst recoveryPromise =\n\t\t\t\tpurpose === \"replacement\" || purpose === \"resync\"\n\t\t\t\t\t? this.recoverFailedSnapshot(purpose, snapshotError)\n\t\t\t\t\t: undefined;\n\t\t\tif (recoveryPromise) {\n\t\t\t\tthis.snapshotRecoveryPromises.set(message.snapshotId, recoveryPromise);\n\t\t\t}\n\t\t\tthis.rejectSnapshotAssembly(message.snapshotId, assembly, snapshotError);\n\t\t\tthis.ignoreSnapshotId(message.snapshotId);\n\t\t\tif (recoveryPromise) {\n\t\t\t\ttry {\n\t\t\t\t\tawait recoveryPromise;\n\t\t\t\t} finally {\n\t\t\t\t\tthis.snapshotRecoveryPromises.delete(message.snapshotId);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.isStaleSequencedMessage(message)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.observeDaemonEventSequence(message);\n\n\t\tif (message.type === \"session_event\") {\n\t\t\tif (message.event.type !== \"refine_complete\" && message.event.type !== \"refine_failed\") {\n\t\t\t\tthis.observeStreamingMessage(message.event);\n\t\t\t}\n\t\t\tif (message.event.type === \"rlm_child_update\") {\n\t\t\t\tthis.childRosterSequence = maxEventSequence(this.childRosterSequence, getDaemonMessageSequence(message));\n\t\t\t\tthis.observeRlmChildUpdate(message.event.child);\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t\tawait this.emit({ type: \"session_event\", event: message.event });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"side_question_event\") {\n\t\t\tthis.observeSideQuestionEvent(message.event);\n\t\t\tawait this.emit({ type: \"side_question_event\", event: message.event });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_status\") {\n\t\t\t// Keep a cached snapshot's recap current so a later re-attach seeds it.\n\t\t\tif (this.latestSnapshot) {\n\t\t\t\tthis.latestSnapshot = {\n\t\t\t\t\t...this.latestSnapshot,\n\t\t\t\t\tstate: { ...this.latestSnapshot.state, recap: message.recap },\n\t\t\t\t};\n\t\t\t}\n\t\t\tawait this.emit({ type: \"session_status\", recap: message.recap });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_resynced\") {\n\t\t\tthis.attachedSessionId = message.snapshot.state.sessionId;\n\t\t\tthis.attachedSessionFile = message.snapshot.state.sessionFile;\n\t\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(message.snapshot);\n\t\t\tif (Array.isArray(message.snapshot.children)) {\n\t\t\t\tthis.childRosterSequence = message.snapshot.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tthis.latestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tthis.latestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t\tawait this.emit({ type: \"session_resynced\", snapshot: this.latestSnapshot });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_replaced\") {\n\t\t\tthis.attachedSessionId = message.state.sessionId;\n\t\t\tthis.attachedSessionFile = message.state.sessionFile;\n\t\t\tif (message.snapshotFollows) {\n\t\t\t\tthis.latestSnapshotIsFresh = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst latestSnapshot: AgentConnectionSnapshot = {\n\t\t\t\tstate: message.state,\n\t\t\t\tmessages: message.messages,\n\t\t\t};\n\t\t\tif (this.lastEventSequence !== undefined) {\n\t\t\t\tlatestSnapshot.lastEventSequence = this.lastEventSequence;\n\t\t\t}\n\t\t\tif (this.lastEventCursor) {\n\t\t\t\tlatestSnapshot.lastEventCursor = this.lastEventCursor;\n\t\t\t}\n\t\t\tthis.latestSnapshot = latestSnapshot;\n\t\t\tthis.childRosterSequence = undefined;\n\t\t\tthis.latestSnapshotIsFresh = true;\n\t\t\tawait this.emit({ type: \"session_replaced\", state: message.state, messages: message.messages });\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"extension_ui_request\") {\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"extension_ui_request\",\n\t\t\t\trequest: {\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tmethod: message.method,\n\t\t\t\t\tpayload: message.payload,\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"extension_error\") {\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"extension_error\",\n\t\t\t\textensionPath: message.extensionPath,\n\t\t\t\tevent: message.event,\n\t\t\t\terror: message.error,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (message.type === \"session_closed\") {\n\t\t\tif (message.reason === \"update\") {\n\t\t\t\tthis.captureDaemonLogPath();\n\t\t\t\tthis.updateRestartPending = true;\n\t\t\t\tvoid this.reconnectAfterUpdate();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tawait this.emit({ type: \"closed\", error: this.formatDaemonSessionClosedError(message.reason) });\n\t\t}\n\t}\n\n\tprivate captureDaemonLogPath(): void {\n\t\tconst socketPath = this.client.hello?.socketPath;\n\t\tif (socketPath) {\n\t\t\tthis.daemonLogPath = getDaemonLogPath(socketPath);\n\t\t}\n\t}\n\n\tprivate formatDaemonSessionClosedError(reason: DaemonSessionClosedReason): string {\n\t\tconst explanation: Record<DaemonSessionClosedReason, string> = {\n\t\t\tkilled:\n\t\t\t\t\"The daemon stopped this agent session. Its transcript remains saved and can be reopened from Agents View.\",\n\t\t\tshutdown:\n\t\t\t\t\"The Base Context daemon shut down while this window was attached. The session transcript remains saved; restart Base Context and reopen it from Agents View.\",\n\t\t\tcompleted:\n\t\t\t\t\"The daemon closed this agent session after it completed. Its transcript remains available from Agents View.\",\n\t\t\treplaced:\n\t\t\t\t\"The daemon replaced this agent session with another session. Reopen the current session from Agents View.\",\n\t\t\tupdate:\n\t\t\t\t\"The Base Context daemon restarted for an update, but this window did not restore automatically. The session transcript remains saved; restart Base Context and reopen it from Agents View.\",\n\t\t};\n\t\treturn `${explanation[reason]} ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatDaemonConnectionClosedError(error: Error): string {\n\t\treturn `Lost connection to the Base Context daemon. Cause: ${formatErrorSentence(error)} The session transcript remains saved; restart Base Context or reopen the session from Agents View. ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatUpdateReconnectError(error: unknown): string {\n\t\treturn `The Base Context daemon restarted for an update, but this window could not reconnect to its restored session before the recovery timeout expired. Last error: ${formatErrorSentence(error)} The session transcript remains saved; restart Base Context and reopen it from Agents View. ${this.formatDaemonDiagnosticContext()}`;\n\t}\n\n\tprivate formatDaemonDiagnosticContext(): string {\n\t\tconst details: string[] = [];\n\t\tif (this.attachedSessionId) {\n\t\t\tdetails.push(`Session ID: ${this.attachedSessionId}.`);\n\t\t}\n\t\tif (this.attachedSessionFile) {\n\t\t\tdetails.push(`Session file: ${this.attachedSessionFile}.`);\n\t\t}\n\t\tdetails.push(`Diagnostic log: ${this.daemonLogPath ?? getAgentLogPath()}.`);\n\t\treturn details.join(\" \");\n\t}\n\n\tprivate reconnectAfterUpdate(): Promise<void> {\n\t\tif (this.updateReconnectPromise) {\n\t\t\treturn this.updateReconnectPromise;\n\t\t}\n\t\tvoid this.emit({\n\t\t\ttype: \"connection_status\",\n\t\t\tstatus: \"reconnecting\",\n\t\t\terror: \"The Base Context daemon is restarting for an update.\",\n\t\t});\n\t\tconst reconnectPromise = reconnectDaemonTransportAfterUpdate(this.client)\n\t\t\t.then(() => this.restoreConnectionAfterUpdate())\n\t\t\t.then(() => {\n\t\t\t\tif (!this.disposed) {\n\t\t\t\t\tvoid this.emit({ type: \"connection_status\", status: \"connected\" });\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(async (error: unknown) => {\n\t\t\t\tthis.updateRestartPending = false;\n\t\t\t\tthis.updateReconnectFailed = true;\n\t\t\t\tif (!this.disposed) {\n\t\t\t\t\tthis.terminalCloseEmitted = true;\n\t\t\t\t\tawait this.emit({\n\t\t\t\t\t\ttype: \"closed\",\n\t\t\t\t\t\terror: this.formatUpdateReconnectError(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.updateReconnectPromise === reconnectPromise) {\n\t\t\t\t\tthis.updateReconnectPromise = undefined;\n\t\t\t\t}\n\t\t\t});\n\t\tthis.updateReconnectPromise = reconnectPromise;\n\t\treturn reconnectPromise;\n\t}\n\n\tprivate async restoreConnectionAfterUpdate(): Promise<void> {\n\t\tconst sessionId = this.attachedSessionId;\n\t\tconst sessionFile = this.attachedSessionFile;\n\t\tif (!sessionId && !sessionFile) {\n\t\t\tthrow new Error(\"the previous session identity is unavailable\");\n\t\t}\n\t\tconst deadline = Date.now() + UPDATE_RECONNECT_TIMEOUT_MS;\n\t\tlet lastError: unknown;\n\t\twhile (!this.disposed && Date.now() < deadline) {\n\t\t\ttry {\n\t\t\t\tawait this.client.reconnect(1000);\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// This loop owns the retry: a socket close must reject these instead of parking them behind a hello it can never produce.\n\t\t\t\tconst response = await this.client.request({ type: \"list\" }, 30000, { recoverable: false });\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!response.success) {\n\t\t\t\t\tthrow deserializeDaemonError(response);\n\t\t\t\t}\n\t\t\t\tconst sessions = readSessionSummaries(response.data);\n\t\t\t\tconst restored = sessions.find(\n\t\t\t\t\t(summary) =>\n\t\t\t\t\t\tsummary.activeSessionId !== undefined &&\n\t\t\t\t\t\t((sessionFile !== undefined && summary.sessionFile === sessionFile) ||\n\t\t\t\t\t\t\t(sessionId !== undefined && summary.sessionId === sessionId)),\n\t\t\t\t);\n\t\t\t\tif (restored?.activeSessionId) {\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.activeSessionId = restored.activeSessionId;\n\t\t\t\t\tthis.lastEventSequence = undefined;\n\t\t\t\t\tthis.lastEventCursor = undefined;\n\t\t\t\t\tthis.retiredEventGenerations.clear();\n\t\t\t\t\tawait this.attach({ recoverable: false });\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst snapshot = await this.getInitialSnapshot({ recoverable: false });\n\t\t\t\t\tif (this.disposed) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.updateRestartPending = false;\n\t\t\t\t\tvoid this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error;\n\t\t\t}\n\t\t\tawait delay(UPDATE_RECONNECT_RETRY_MS);\n\t\t}\n\t\tif (this.disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthrow lastError ?? new Error(\"the restored session did not become available\");\n\t}\n\n\tprivate getSnapshotAssembly(snapshotId: string): DaemonSnapshotAssembly {\n\t\tconst existing = this.snapshotAssemblies.get(snapshotId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\t\tlet resolveSnapshot!: (snapshot: DaemonSessionSnapshot) => void;\n\t\tlet rejectSnapshot!: (error: Error) => void;\n\t\tconst promise = new Promise<DaemonSessionSnapshot>((resolve, reject) => {\n\t\t\tresolveSnapshot = resolve;\n\t\t\trejectSnapshot = reject;\n\t\t});\n\t\tvoid promise.catch(() => undefined);\n\t\tconst timeout = setTimeout(() => {\n\t\t\tconst current = this.snapshotAssemblies.get(snapshotId);\n\t\t\tif (current) {\n\t\t\t\tcurrent.reject(new Error(`Timed out waiting for snapshot ${snapshotId}`));\n\t\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t\t\tthis.ignoreSnapshotId(snapshotId);\n\t\t\t}\n\t\t}, this.options.snapshotTimeoutMs ?? DAEMON_SNAPSHOT_TIMEOUT_MS);\n\t\ttimeout.unref();\n\t\tconst assembly: DaemonSnapshotAssembly = {\n\t\t\tchunks: new Map(),\n\t\t\tpromise,\n\t\t\tresolve: resolveSnapshot,\n\t\t\treject: rejectSnapshot,\n\t\t\ttimeout,\n\t\t};\n\t\tthis.snapshotAssemblies.set(snapshotId, assembly);\n\t\treturn assembly;\n\t}\n\n\tprivate rejectSnapshotAssemblies(error: Error): void {\n\t\tfor (const assembly of this.snapshotAssemblies.values()) {\n\t\t\tclearTimeout(assembly.timeout);\n\t\t\tassembly.reject(error);\n\t\t}\n\t\tthis.snapshotAssemblies.clear();\n\t\tthis.completedSnapshots.clear();\n\t\tthis.snapshotRecoveryPromises.clear();\n\t\tthis.ignoredSnapshotIds.clear();\n\t}\n\n\tprivate ignoreSnapshotId(snapshotId: string): void {\n\t\tthis.ignoredSnapshotIds.add(snapshotId);\n\t\twhile (this.ignoredSnapshotIds.size > MAX_IGNORED_SNAPSHOT_IDS) {\n\t\t\tconst oldest = this.ignoredSnapshotIds.values().next().value;\n\t\t\tif (oldest === undefined) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.ignoredSnapshotIds.delete(oldest);\n\t\t}\n\t}\n\n\tprivate rejectSnapshotAssembly(snapshotId: string, assembly: DaemonSnapshotAssembly, error: Error): void {\n\t\tassembly.reject(error);\n\t\tclearTimeout(assembly.timeout);\n\t\tif (assembly.begin?.purpose && assembly.begin.purpose !== \"attach\") {\n\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t}\n\t}\n\n\tprivate async recoverFailedSnapshot(purpose: \"replacement\" | \"resync\", snapshotError: Error): Promise<void> {\n\t\tthis.latestSnapshotIsFresh = false;\n\t\tif (purpose === \"replacement\") {\n\t\t\tthis.latestSnapshot = undefined;\n\t\t}\n\t\ttry {\n\t\t\tconst snapshot = await this.getInitialSnapshot();\n\t\t\tif (this.disposed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\t\tif (purpose === \"replacement\") {\n\t\t\t\tawait this.emit({ type: \"session_replaced\", state: snapshot.state, messages: snapshot.messages });\n\t\t\t} else {\n\t\t\t\tawait this.emit({ type: \"session_resynced\", snapshot });\n\t\t\t}\n\t\t} catch (recoveryError) {\n\t\t\tif (this.disposed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.terminalCloseEmitted = true;\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"closed\",\n\t\t\t\terror: `Failed to recover from a ${purpose} snapshot transfer. Snapshot error: ${formatErrorSentence(snapshotError)} Recovery error: ${formatErrorSentence(recoveryError)} ${this.formatDaemonDiagnosticContext()}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async waitForSnapshot(snapshotId: string): Promise<DaemonSessionSnapshot> {\n\t\tconst completed = this.completedSnapshots.get(snapshotId);\n\t\tif (completed) {\n\t\t\tthis.completedSnapshots.delete(snapshotId);\n\t\t\treturn completed;\n\t\t}\n\t\tconst assembly = this.getSnapshotAssembly(snapshotId);\n\t\ttry {\n\t\t\treturn await assembly.promise;\n\t\t} finally {\n\t\t\tclearTimeout(assembly.timeout);\n\t\t\tthis.snapshotAssemblies.delete(snapshotId);\n\t\t\tthis.completedSnapshots.delete(snapshotId);\n\t\t}\n\t}\n\n\tprivate applyReplacementSnapshot(snapshot: DaemonSessionSnapshot, replay?: DaemonReplayInfo): void {\n\t\tif (snapshot.lastEventCursor) {\n\t\t\tthis.observeEventCursor(snapshot.lastEventCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, snapshot.lastEventSequence);\n\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot, replay);\n\t\tthis.childRosterSequence = Array.isArray(snapshot.children) ? snapshot.lastEventSequence : undefined;\n\t\tthis.latestSnapshotIsFresh = true;\n\t}\n\n\tprivate async completeSnapshotAssembly(\n\t\tmessage: Extract<DaemonOutbound, { type: \"session_snapshot_end\" }>,\n\t): Promise<void> {\n\t\tconst assembly = this.getSnapshotAssembly(message.snapshotId);\n\t\tif (!assembly.begin) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(`Snapshot ${message.snapshotId} ended before it began`),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (assembly.chunks.size !== message.chunkCount) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(\n\t\t\t\t\t`Snapshot ${message.snapshotId} ended with ${assembly.chunks.size} of ${message.chunkCount} chunks`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst messages: AgentMessage[] = [];\n\t\tfor (let index = 0; index < message.chunkCount; index++) {\n\t\t\tconst chunk = assembly.chunks.get(index);\n\t\t\tif (!chunk) {\n\t\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\t\tmessage.snapshotId,\n\t\t\t\t\tassembly,\n\t\t\t\t\tnew Error(`Snapshot ${message.snapshotId} is missing chunk ${index}`),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tmessages.push(...chunk);\n\t\t}\n\t\tif (messages.length !== assembly.begin.messageCount) {\n\t\t\tthis.rejectSnapshotAssembly(\n\t\t\t\tmessage.snapshotId,\n\t\t\t\tassembly,\n\t\t\t\tnew Error(\n\t\t\t\t\t`Snapshot ${message.snapshotId} contained ${messages.length} of ${assembly.begin.messageCount} messages`,\n\t\t\t\t),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot: DaemonSessionSnapshot = {\n\t\t\t...assembly.begin.snapshot,\n\t\t\tmessages,\n\t\t\tlastEventSequence: message.lastEventSequence,\n\t\t\tlastEventCursor: message.lastEventCursor,\n\t\t};\n\t\tif (message.lastEventCursor) {\n\t\t\tthis.observeEventCursor(message.lastEventCursor);\n\t\t}\n\t\tthis.lastEventSequence = maxEventSequence(this.lastEventSequence, message.lastEventSequence);\n\t\tthis.attachedSessionId = snapshot.state.sessionId;\n\t\tthis.attachedSessionFile = snapshot.state.sessionFile;\n\t\tthis.latestSnapshot = mapDaemonSessionSnapshot(snapshot);\n\t\tthis.latestSnapshotIsFresh = true;\n\t\tassembly.resolve(snapshot);\n\t\tconst purpose = assembly.begin.purpose ?? \"attach\";\n\t\tclearTimeout(assembly.timeout);\n\t\tif (purpose !== \"attach\") {\n\t\t\tthis.snapshotAssemblies.delete(message.snapshotId);\n\t\t\tif (this.pendingReattachActiveSessionIds.has(message.activeSessionId)) {\n\t\t\t\tthis.completedSnapshots.set(message.snapshotId, snapshot);\n\t\t\t\twhile (this.completedSnapshots.size > MAX_COMPLETED_SNAPSHOTS) {\n\t\t\t\t\tconst oldest = this.completedSnapshots.keys().next().value;\n\t\t\t\t\tif (oldest === undefined) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tthis.completedSnapshots.delete(oldest);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (purpose === \"replacement\") {\n\t\t\tawait this.emit({ type: \"session_replaced\", state: snapshot.state, messages });\n\t\t} else if (purpose === \"resync\") {\n\t\t\tawait this.emit({ type: \"session_resynced\", snapshot: this.latestSnapshot });\n\t\t}\n\t}\n\n\tprivate observeRlmChildUpdate(child: AgentConnectionRlmChildAgentSnapshot): void {\n\t\tif (!this.latestSnapshot) return;\n\t\tconst children = this.latestSnapshot.children ?? [];\n\t\tconst index = children.findIndex((candidate) => candidate.id === child.id);\n\t\tconst updatedChildren = [...children];\n\t\tif (index === -1) {\n\t\t\tupdatedChildren.push(child);\n\t\t} else {\n\t\t\tupdatedChildren[index] = child;\n\t\t}\n\t\tthis.latestSnapshot = { ...this.latestSnapshot, children: updatedChildren };\n\t}\n\n\tprivate observeStreamingMessage(event: AgentSessionEvent): void {\n\t\tif (!this.latestSnapshot) {\n\t\t\treturn;\n\t\t}\n\t\tif ((event.type === \"message_start\" || event.type === \"message_update\") && event.message.role === \"assistant\") {\n\t\t\tthis.latestSnapshot = { ...this.latestSnapshot, streamingMessage: event.message };\n\t\t\treturn;\n\t\t}\n\t\tif ((event.type === \"message_end\" && event.message.role === \"assistant\") || event.type === \"agent_end\") {\n\t\t\tconst { streamingMessage: _streamingMessage, ...snapshot } = this.latestSnapshot;\n\t\t\tthis.latestSnapshot = snapshot;\n\t\t}\n\t}\n\n\tprivate isMessageForActiveSession(message: DaemonOutbound): boolean {\n\t\tif (!(\"activeSessionId\" in message)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn message.activeSessionId === this.activeSessionId;\n\t}\n\n\tprivate isStaleSequencedMessage(message: DaemonOutbound): boolean {\n\t\tconst cursor = getDaemonMessageCursor(message);\n\t\tif (cursor) {\n\t\t\tif (this.retiredEventGenerations.has(cursor.generation)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn (\n\t\t\t\tthis.lastEventCursor?.generation === cursor.generation && cursor.sequence <= this.lastEventCursor.sequence\n\t\t\t);\n\t\t}\n\t\tconst sequence = getDaemonMessageSequence(message);\n\t\treturn sequence !== undefined && this.lastEventSequence !== undefined && sequence <= this.lastEventSequence;\n\t}\n\n\tprivate observeDaemonEventSequence(message: DaemonOutbound): void {\n\t\tconst cursor = getDaemonMessageCursor(message);\n\t\tif (cursor) {\n\t\t\tthis.observeEventCursor(cursor);\n\t\t\tthis.lastEventSequence = cursor.sequence;\n\t\t\treturn;\n\t\t}\n\t\tconst sequence = getDaemonMessageSequence(message);\n\t\tif (sequence === undefined) {\n\t\t\treturn;\n\t\t}\n\t\tthis.lastEventSequence =\n\t\t\tthis.lastEventSequence === undefined ? sequence : Math.max(this.lastEventSequence, sequence);\n\t\tif (this.lastEventCursor) {\n\t\t\tthis.lastEventCursor = {\n\t\t\t\t...this.lastEventCursor,\n\t\t\t\tsequence: Math.max(this.lastEventCursor.sequence, sequence),\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate observeEventCursor(cursor: DaemonEventCursor): void {\n\t\tconst current = this.lastEventCursor;\n\t\tif (current && current.generation !== cursor.generation) {\n\t\t\tthis.retiredEventGenerations.add(current.generation);\n\t\t}\n\t\tif (!current || current.generation !== cursor.generation || cursor.sequence > current.sequence) {\n\t\t\tthis.lastEventCursor = cursor;\n\t\t}\n\t}\n\n\tprivate async emit(event: AgentConnectionEvent): Promise<void> {\n\t\tconst deliveries: Promise<void>[] = [];\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\ttry {\n\t\t\t\tdeliveries.push(Promise.resolve(listener(event)));\n\t\t\t} catch {\n\t\t\t\t// One attachment must not interrupt delivery or transport recovery for the others.\n\t\t\t}\n\t\t}\n\t\tawait Promise.allSettled(deliveries);\n\t}\n\n\tprivate observeSideQuestionEvent(event: AgentConnectionSideQuestionEvent): void {\n\t\tif (event.status !== \"running\") {\n\t\t\tthis.activeSideQuestionIds.delete(event.id);\n\t\t}\n\t}\n}\n\nfunction readSessionSummaries(value: unknown): SessionSummary[] {\n\tif (!value || typeof value !== \"object\" || !Array.isArray((value as { sessions?: unknown }).sessions)) {\n\t\tthrow new Error(\"Daemon returned an invalid session list response\");\n\t}\n\treturn (value as { sessions: SessionSummary[] }).sessions;\n}\n\nfunction getAttachActiveSessionId(result: SessionSummary | DaemonAttachResult): string {\n\tif (\"snapshot\" in result) {\n\t\treturn result.activeSessionId;\n\t}\n\treturn result.activeSessionId ?? result.id;\n}\n\nfunction getAttachLastEventSequence(result: SessionSummary | DaemonAttachResult): number | undefined {\n\tif (\"lastEventSequence\" in result) {\n\t\treturn result.lastEventSequence;\n\t}\n\treturn undefined;\n}\n\nfunction getAttachLastEventCursor(result: SessionSummary | DaemonAttachResult): DaemonEventCursor | undefined {\n\tif (\"lastEventCursor\" in result) {\n\t\treturn result.lastEventCursor;\n\t}\n\treturn undefined;\n}\n\nfunction maxEventSequence(current: number | undefined, observed: number | undefined): number | undefined {\n\tif (current === undefined) {\n\t\treturn observed;\n\t}\n\tif (observed === undefined) {\n\t\treturn current;\n\t}\n\treturn Math.max(current, observed);\n}\n\nfunction mapDaemonSessionSnapshot(snapshot: DaemonSessionSnapshot, replay?: DaemonReplayInfo): AgentConnectionSnapshot {\n\tconst connectionSnapshot: AgentConnectionSnapshot = {\n\t\tstate: snapshot.state,\n\t\tmessages: snapshot.messages,\n\t\t...(snapshot.summary.streamingMessage ? { streamingMessage: snapshot.summary.streamingMessage } : {}),\n\t\tlastEventSequence: snapshot.lastEventSequence,\n\t\tlastEventCursor: snapshot.lastEventCursor,\n\t};\n\tif (snapshot.sessionContext) {\n\t\tconnectionSnapshot.sessionContext = snapshot.sessionContext;\n\t}\n\tif (snapshot.sessionTree) {\n\t\tconnectionSnapshot.sessionTree = snapshot.sessionTree;\n\t}\n\tif (snapshot.parent) {\n\t\tconnectionSnapshot.parent = snapshot.parent;\n\t}\n\tif (snapshot.children) {\n\t\tconnectionSnapshot.children = snapshot.children;\n\t}\n\tif (replay) {\n\t\tconnectionSnapshot.replay = replay;\n\t}\n\treturn connectionSnapshot;\n}\n\nfunction getDaemonMessageSequence(message: DaemonOutbound): number | undefined {\n\tif (!(\"meta\" in message)) {\n\t\treturn undefined;\n\t}\n\treturn message.meta?.sequence;\n}\n\nfunction getDaemonMessageCursor(message: DaemonOutbound): DaemonEventCursor | undefined {\n\tif (!(\"meta\" in message)) {\n\t\treturn undefined;\n\t}\n\treturn message.meta?.cursor;\n}\n\nfunction invalidatesCachedSnapshot(commandType: DaemonCommandBody[\"type\"]): boolean {\n\tswitch (commandType) {\n\t\tcase \"attach\":\n\t\tcase \"reattach\":\n\t\tcase \"detach\":\n\t\tcase \"list\":\n\t\tcase \"list_saved_sessions\":\n\t\tcase \"wait_for_idle\":\n\t\tcase \"get_state\":\n\t\tcase \"get_connection_state\":\n\t\tcase \"get_messages\":\n\t\tcase \"get_session_stats\":\n\t\tcase \"get_commands\":\n\t\tcase \"get_resource_snapshot\":\n\t\tcase \"get_model_catalog\":\n\t\tcase \"get_available_models\":\n\t\tcase \"get_queue\":\n\t\tcase \"cron_list\":\n\t\tcase \"heartbeats_list\":\n\t\tcase \"get_session_context\":\n\t\tcase \"get_session_tree\":\n\t\tcase \"get_user_messages_for_forking\":\n\t\tcase \"get_last_assistant_text\":\n\t\tcase \"get_system_prompt\":\n\t\tcase \"get_tool_definition\":\n\t\tcase \"start_side_question\":\n\t\tcase \"abort_side_question\":\n\t\tcase \"export_html\":\n\t\tcase \"export_jsonl\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn true;\n\t}\n}\n"]}
@@ -253,7 +253,6 @@ export class DaemonAgentConnection {
253
253
  this.client.supportsServerCapability("owned_session_recovery_context")
254
254
  ? { recoveryConfig: this.options.ownedSessionRecoveryConfig }
255
255
  : {}),
256
- telemetryDisabled: this.options.telemetryDisabled,
257
256
  resumeCursor: this.lastEventCursor === undefined
258
257
  ? undefined
259
258
  : {
@@ -1081,7 +1080,6 @@ export class DaemonAgentConnection {
1081
1080
  ],
1082
1081
  env: this.options.sendClientEnv ? collectDaemonClientEnv() : undefined,
1083
1082
  launchEnv: this.options.ownedSession ? collectDaemonLaunchEnv() : undefined,
1084
- telemetryDisabled: this.options.telemetryDisabled,
1085
1083
  });
1086
1084
  // Reattach rebinds the connection (and drops any direct link); pauses on the old session are gone.
1087
1085
  this.sessionInputPauses.clear();
@@ -1174,6 +1172,19 @@ export class DaemonAgentConnection {
1174
1172
  async setSessionName(name) {
1175
1173
  await this.requestOk({ type: "set_session_name", activeSessionId: this.activeSessionId, name });
1176
1174
  }
1175
+ async getRlmMaxSubagentsStatus() {
1176
+ return this.requestData({
1177
+ type: "get_rlm_max_subagents_status",
1178
+ activeSessionId: this.activeSessionId,
1179
+ });
1180
+ }
1181
+ async setRlmMaxSubagents(maxSubagents) {
1182
+ return this.requestData({
1183
+ type: "set_rlm_max_subagents",
1184
+ activeSessionId: this.activeSessionId,
1185
+ maxSubagents,
1186
+ });
1187
+ }
1177
1188
  async getRlmMaxDepthStatus() {
1178
1189
  return this.requestData({
1179
1190
  type: "get_rlm_max_depth_status",