@getpaseo/server 0.1.30 → 0.1.32

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 (498) hide show
  1. package/dist/scripts/daemon-runner.js +1 -1
  2. package/dist/scripts/daemon-runner.js.map +1 -1
  3. package/dist/scripts/dev-runner.js +1 -1
  4. package/dist/scripts/dev-runner.js.map +1 -1
  5. package/dist/server/client/daemon-client-relay-e2ee-transport.d.ts.map +1 -1
  6. package/dist/server/client/daemon-client-relay-e2ee-transport.js.map +1 -1
  7. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
  8. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  9. package/dist/server/client/daemon-client.d.ts +108 -103
  10. package/dist/server/client/daemon-client.d.ts.map +1 -1
  11. package/dist/server/client/daemon-client.js +417 -407
  12. package/dist/server/client/daemon-client.js.map +1 -1
  13. package/dist/server/server/agent/activity-curator.d.ts.map +1 -1
  14. package/dist/server/server/agent/activity-curator.js +5 -4
  15. package/dist/server/server/agent/activity-curator.js.map +1 -1
  16. package/dist/server/server/agent/agent-management-mcp.d.ts.map +1 -1
  17. package/dist/server/server/agent/agent-management-mcp.js +13 -17
  18. package/dist/server/server/agent/agent-management-mcp.js.map +1 -1
  19. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  20. package/dist/server/server/agent/agent-manager.js +26 -26
  21. package/dist/server/server/agent/agent-manager.js.map +1 -1
  22. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  23. package/dist/server/server/agent/agent-metadata-generator.js +1 -3
  24. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  25. package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
  26. package/dist/server/server/agent/agent-projections.js +4 -12
  27. package/dist/server/server/agent/agent-projections.js.map +1 -1
  28. package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -1
  29. package/dist/server/server/agent/agent-response-loop.js +6 -6
  30. package/dist/server/server/agent/agent-response-loop.js.map +1 -1
  31. package/dist/server/server/agent/agent-sdk-types.d.ts +23 -0
  32. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  33. package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
  34. package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
  35. package/dist/server/server/agent/agent-storage.js +2 -4
  36. package/dist/server/server/agent/agent-storage.js.map +1 -1
  37. package/dist/server/server/agent/dictation-debug.d.ts.map +1 -1
  38. package/dist/server/server/agent/dictation-debug.js.map +1 -1
  39. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  40. package/dist/server/server/agent/mcp-server.js +19 -27
  41. package/dist/server/server/agent/mcp-server.js.map +1 -1
  42. package/dist/server/server/agent/pcm16-resampler.d.ts.map +1 -1
  43. package/dist/server/server/agent/pcm16-resampler.js.map +1 -1
  44. package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -1
  45. package/dist/server/server/agent/provider-launch-config.js +4 -2
  46. package/dist/server/server/agent/provider-launch-config.js.map +1 -1
  47. package/dist/server/server/agent/provider-manifest.d.ts +2 -2
  48. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -1
  49. package/dist/server/server/agent/provider-manifest.js +63 -9
  50. package/dist/server/server/agent/provider-manifest.js.map +1 -1
  51. package/dist/server/server/agent/provider-registry.d.ts +2 -2
  52. package/dist/server/server/agent/provider-registry.d.ts.map +1 -1
  53. package/dist/server/server/agent/provider-registry.js +1 -1
  54. package/dist/server/server/agent/provider-registry.js.map +1 -1
  55. package/dist/server/server/agent/providers/claude/model-catalog.js +10 -10
  56. package/dist/server/server/agent/providers/claude/model-catalog.js.map +1 -1
  57. package/dist/server/server/agent/providers/claude/partial-json.d.ts.map +1 -1
  58. package/dist/server/server/agent/providers/claude/partial-json.js +4 -4
  59. package/dist/server/server/agent/providers/claude/partial-json.js.map +1 -1
  60. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +20 -0
  61. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -0
  62. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +230 -0
  63. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -0
  64. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +11 -0
  65. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -1
  66. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +37 -20
  67. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -1
  68. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
  69. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +21 -11
  70. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
  71. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  72. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +23 -11
  73. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  74. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  75. package/dist/server/server/agent/providers/claude-agent.js +486 -1134
  76. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  77. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -1
  78. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js +2 -2
  79. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -1
  80. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  81. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +14 -11
  82. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  83. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  84. package/dist/server/server/agent/providers/codex-app-server-agent.js +347 -163
  85. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  86. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -1
  87. package/dist/server/server/agent/providers/codex-rollout-timeline.js +21 -32
  88. package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -1
  89. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -1
  90. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +2 -2
  91. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -1
  92. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
  93. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +2 -9
  94. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -1
  95. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  96. package/dist/server/server/agent/providers/opencode-agent.js +5 -5
  97. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  98. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +277 -1
  99. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  100. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +149 -15
  101. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  102. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
  103. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +1 -3
  104. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -1
  105. package/dist/server/server/agent/stt-manager.d.ts.map +1 -1
  106. package/dist/server/server/agent/stt-manager.js +1 -2
  107. package/dist/server/server/agent/stt-manager.js.map +1 -1
  108. package/dist/server/server/agent/system-prompt.js +5 -5
  109. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  110. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  111. package/dist/server/server/agent/tts-manager.d.ts.map +1 -1
  112. package/dist/server/server/agent/tts-manager.js +27 -9
  113. package/dist/server/server/agent/tts-manager.js.map +1 -1
  114. package/dist/server/server/agent/wait-for-agent-tracker.d.ts.map +1 -1
  115. package/dist/server/server/agent/wait-for-agent-tracker.js.map +1 -1
  116. package/dist/server/server/agent-attention-policy.d.ts.map +1 -1
  117. package/dist/server/server/agent-attention-policy.js.map +1 -1
  118. package/dist/server/server/allowed-hosts.d.ts.map +1 -1
  119. package/dist/server/server/allowed-hosts.js.map +1 -1
  120. package/dist/server/server/bootstrap.d.ts.map +1 -1
  121. package/dist/server/server/bootstrap.js +46 -5
  122. package/dist/server/server/bootstrap.js.map +1 -1
  123. package/dist/server/server/config.d.ts.map +1 -1
  124. package/dist/server/server/config.js +4 -11
  125. package/dist/server/server/config.js.map +1 -1
  126. package/dist/server/server/connection-offer.d.ts +1 -1
  127. package/dist/server/server/connection-offer.d.ts.map +1 -1
  128. package/dist/server/server/connection-offer.js +2 -3
  129. package/dist/server/server/connection-offer.js.map +1 -1
  130. package/dist/server/server/daemon-version.d.ts.map +1 -1
  131. package/dist/server/server/daemon-version.js +1 -1
  132. package/dist/server/server/daemon-version.js.map +1 -1
  133. package/dist/server/server/dictation/dictation-stream-manager.d.ts.map +1 -1
  134. package/dist/server/server/dictation/dictation-stream-manager.js +4 -1
  135. package/dist/server/server/dictation/dictation-stream-manager.js.map +1 -1
  136. package/dist/server/server/exports.d.ts +1 -1
  137. package/dist/server/server/exports.d.ts.map +1 -1
  138. package/dist/server/server/exports.js +1 -1
  139. package/dist/server/server/exports.js.map +1 -1
  140. package/dist/server/server/file-explorer/service.d.ts +1 -1
  141. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  142. package/dist/server/server/file-explorer/service.js +5 -8
  143. package/dist/server/server/file-explorer/service.js.map +1 -1
  144. package/dist/server/server/index.js +1 -1
  145. package/dist/server/server/index.js.map +1 -1
  146. package/dist/server/server/logger.d.ts.map +1 -1
  147. package/dist/server/server/logger.js.map +1 -1
  148. package/dist/server/server/messages.d.ts.map +1 -1
  149. package/dist/server/server/messages.js.map +1 -1
  150. package/dist/server/server/package-version.d.ts.map +1 -1
  151. package/dist/server/server/package-version.js +1 -2
  152. package/dist/server/server/package-version.js.map +1 -1
  153. package/dist/server/server/persisted-config.d.ts.map +1 -1
  154. package/dist/server/server/persisted-config.js.map +1 -1
  155. package/dist/server/server/persistence-hooks.d.ts.map +1 -1
  156. package/dist/server/server/persistence-hooks.js.map +1 -1
  157. package/dist/server/server/pid-lock.d.ts.map +1 -1
  158. package/dist/server/server/pid-lock.js.map +1 -1
  159. package/dist/server/server/push/push-service.d.ts.map +1 -1
  160. package/dist/server/server/push/push-service.js.map +1 -1
  161. package/dist/server/server/relay-transport.d.ts.map +1 -1
  162. package/dist/server/server/relay-transport.js +6 -2
  163. package/dist/server/server/relay-transport.js.map +1 -1
  164. package/dist/server/server/session.d.ts +49 -37
  165. package/dist/server/server/session.d.ts.map +1 -1
  166. package/dist/server/server/session.js +1234 -998
  167. package/dist/server/server/session.js.map +1 -1
  168. package/dist/server/server/speech/audio.d.ts.map +1 -1
  169. package/dist/server/server/speech/audio.js.map +1 -1
  170. package/dist/server/server/speech/providers/local/config.d.ts.map +1 -1
  171. package/dist/server/server/speech/providers/local/config.js +5 -14
  172. package/dist/server/server/speech/providers/local/config.js.map +1 -1
  173. package/dist/server/server/speech/providers/local/models.d.ts.map +1 -1
  174. package/dist/server/server/speech/providers/local/models.js +1 -1
  175. package/dist/server/server/speech/providers/local/models.js.map +1 -1
  176. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -1
  177. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +21 -7
  178. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
  179. package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -1
  180. package/dist/server/server/speech/providers/local/runtime.js +1 -23
  181. package/dist/server/server/speech/providers/local/runtime.js.map +1 -1
  182. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -1
  183. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
  184. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -1
  185. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
  186. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -1
  187. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +9 -4
  188. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -1
  189. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -1
  190. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +7 -2
  191. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -1
  192. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -1
  193. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +5 -1
  194. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -1
  195. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -1
  196. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +2 -4
  197. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -1
  198. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -1
  199. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +1 -3
  200. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
  201. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -1
  202. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +2 -4
  203. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
  204. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -1
  205. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +4 -1
  206. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
  207. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts.map +1 -1
  208. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js +1 -1
  209. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js.map +1 -1
  210. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts.map +1 -1
  211. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js.map +1 -1
  212. package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -1
  213. package/dist/server/server/speech/providers/openai/config.js +5 -24
  214. package/dist/server/server/speech/providers/openai/config.js.map +1 -1
  215. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -1
  216. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +6 -3
  217. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -1
  218. package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -1
  219. package/dist/server/server/speech/providers/openai/runtime.js +2 -6
  220. package/dist/server/server/speech/providers/openai/runtime.js.map +1 -1
  221. package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -1
  222. package/dist/server/server/speech/providers/openai/stt.js +1 -3
  223. package/dist/server/server/speech/providers/openai/stt.js.map +1 -1
  224. package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -1
  225. package/dist/server/server/speech/providers/openai/tts.js.map +1 -1
  226. package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -1
  227. package/dist/server/server/speech/speech-config-resolver.js +3 -7
  228. package/dist/server/server/speech/speech-config-resolver.js.map +1 -1
  229. package/dist/server/server/speech/speech-provider.d.ts.map +1 -1
  230. package/dist/server/server/speech/speech-runtime.d.ts.map +1 -1
  231. package/dist/server/server/speech/speech-runtime.js.map +1 -1
  232. package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -1
  233. package/dist/server/server/terminal-mcp/server.d.ts.map +1 -1
  234. package/dist/server/server/terminal-mcp/server.js +3 -11
  235. package/dist/server/server/terminal-mcp/server.js.map +1 -1
  236. package/dist/server/server/terminal-mcp/terminal-manager.d.ts.map +1 -1
  237. package/dist/server/server/terminal-mcp/terminal-manager.js +2 -14
  238. package/dist/server/server/terminal-mcp/terminal-manager.js.map +1 -1
  239. package/dist/server/server/terminal-mcp/tmux.d.ts +1 -1
  240. package/dist/server/server/terminal-mcp/tmux.d.ts.map +1 -1
  241. package/dist/server/server/terminal-mcp/tmux.js +20 -123
  242. package/dist/server/server/terminal-mcp/tmux.js.map +1 -1
  243. package/dist/server/server/utils/diff-highlighter.d.ts +11 -3
  244. package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -1
  245. package/dist/server/server/utils/diff-highlighter.js +49 -36
  246. package/dist/server/server/utils/diff-highlighter.js.map +1 -1
  247. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts.map +1 -1
  248. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js.map +1 -1
  249. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -1
  250. package/dist/server/server/voice/voice-turn-controller.js +1 -3
  251. package/dist/server/server/voice/voice-turn-controller.js.map +1 -1
  252. package/dist/server/server/voice-config.d.ts.map +1 -1
  253. package/dist/server/server/voice-config.js.map +1 -1
  254. package/dist/server/server/voice-mcp-bridge.d.ts.map +1 -1
  255. package/dist/server/server/voice-mcp-bridge.js.map +1 -1
  256. package/dist/server/server/websocket-server.d.ts +1 -0
  257. package/dist/server/server/websocket-server.d.ts.map +1 -1
  258. package/dist/server/server/websocket-server.js +20 -22
  259. package/dist/server/server/websocket-server.js.map +1 -1
  260. package/dist/server/server/workspace-registry-bootstrap.d.ts +3 -3
  261. package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -1
  262. package/dist/server/server/workspace-registry-bootstrap.js +6 -6
  263. package/dist/server/server/workspace-registry-bootstrap.js.map +1 -1
  264. package/dist/server/server/workspace-registry-model.d.ts +14 -3
  265. package/dist/server/server/workspace-registry-model.d.ts.map +1 -1
  266. package/dist/server/server/workspace-registry-model.js +40 -15
  267. package/dist/server/server/workspace-registry-model.js.map +1 -1
  268. package/dist/server/server/workspace-registry.d.ts +5 -5
  269. package/dist/server/server/workspace-registry.d.ts.map +1 -1
  270. package/dist/server/server/workspace-registry.js +16 -13
  271. package/dist/server/server/workspace-registry.js.map +1 -1
  272. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  273. package/dist/server/server/worktree-bootstrap.js +17 -6
  274. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  275. package/dist/server/shared/agent-attention-notification.d.ts.map +1 -1
  276. package/dist/server/shared/agent-attention-notification.js.map +1 -1
  277. package/dist/server/shared/agent-lifecycle.d.ts.map +1 -1
  278. package/dist/server/shared/daemon-endpoints.d.ts +1 -0
  279. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  280. package/dist/server/shared/daemon-endpoints.js +11 -2
  281. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  282. package/dist/server/shared/messages.d.ts +1228 -2982
  283. package/dist/server/shared/messages.d.ts.map +1 -1
  284. package/dist/server/shared/messages.js +330 -302
  285. package/dist/server/shared/messages.js.map +1 -1
  286. package/dist/server/shared/terminal-stream-protocol.d.ts +36 -0
  287. package/dist/server/shared/terminal-stream-protocol.d.ts.map +1 -0
  288. package/dist/server/shared/terminal-stream-protocol.js +99 -0
  289. package/dist/server/shared/terminal-stream-protocol.js.map +1 -0
  290. package/dist/server/shared/tool-call-display.d.ts.map +1 -1
  291. package/dist/server/shared/tool-call-display.js +6 -3
  292. package/dist/server/shared/tool-call-display.js.map +1 -1
  293. package/dist/server/terminal/terminal.d.ts +5 -48
  294. package/dist/server/terminal/terminal.d.ts.map +1 -1
  295. package/dist/server/terminal/terminal.js +44 -98
  296. package/dist/server/terminal/terminal.js.map +1 -1
  297. package/dist/server/utils/checkout-git.d.ts +1 -0
  298. package/dist/server/utils/checkout-git.d.ts.map +1 -1
  299. package/dist/server/utils/checkout-git.js +111 -120
  300. package/dist/server/utils/checkout-git.js.map +1 -1
  301. package/dist/server/utils/directory-suggestions.d.ts +1 -1
  302. package/dist/server/utils/directory-suggestions.d.ts.map +1 -1
  303. package/dist/server/utils/directory-suggestions.js +40 -40
  304. package/dist/server/utils/directory-suggestions.js.map +1 -1
  305. package/dist/server/utils/project-icon.d.ts.map +1 -1
  306. package/dist/server/utils/project-icon.js +2 -11
  307. package/dist/server/utils/project-icon.js.map +1 -1
  308. package/dist/server/utils/worktree.d.ts +2 -0
  309. package/dist/server/utils/worktree.d.ts.map +1 -1
  310. package/dist/server/utils/worktree.js +22 -19
  311. package/dist/server/utils/worktree.js.map +1 -1
  312. package/dist/src/server/agent/activity-curator.js +5 -4
  313. package/dist/src/server/agent/activity-curator.js.map +1 -1
  314. package/dist/src/server/agent/agent-manager.js +26 -26
  315. package/dist/src/server/agent/agent-manager.js.map +1 -1
  316. package/dist/src/server/agent/agent-metadata-generator.js +1 -3
  317. package/dist/src/server/agent/agent-metadata-generator.js.map +1 -1
  318. package/dist/src/server/agent/agent-projections.js +4 -12
  319. package/dist/src/server/agent/agent-projections.js.map +1 -1
  320. package/dist/src/server/agent/agent-response-loop.js +6 -6
  321. package/dist/src/server/agent/agent-response-loop.js.map +1 -1
  322. package/dist/src/server/agent/agent-sdk-types.js.map +1 -1
  323. package/dist/src/server/agent/agent-storage.js +2 -4
  324. package/dist/src/server/agent/agent-storage.js.map +1 -1
  325. package/dist/src/server/agent/dictation-debug.js.map +1 -1
  326. package/dist/src/server/agent/mcp-server.js +19 -27
  327. package/dist/src/server/agent/mcp-server.js.map +1 -1
  328. package/dist/src/server/agent/pcm16-resampler.js.map +1 -1
  329. package/dist/src/server/agent/provider-launch-config.js +4 -2
  330. package/dist/src/server/agent/provider-launch-config.js.map +1 -1
  331. package/dist/src/server/agent/provider-manifest.js +63 -9
  332. package/dist/src/server/agent/provider-manifest.js.map +1 -1
  333. package/dist/src/server/agent/provider-registry.js +1 -1
  334. package/dist/src/server/agent/provider-registry.js.map +1 -1
  335. package/dist/src/server/agent/providers/claude/model-catalog.js +10 -10
  336. package/dist/src/server/agent/providers/claude/model-catalog.js.map +1 -1
  337. package/dist/src/server/agent/providers/claude/partial-json.js +4 -4
  338. package/dist/src/server/agent/providers/claude/partial-json.js.map +1 -1
  339. package/dist/src/server/agent/providers/claude/sidechain-tracker.js +230 -0
  340. package/dist/src/server/agent/providers/claude/sidechain-tracker.js.map +1 -0
  341. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js +37 -20
  342. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js.map +1 -1
  343. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js +21 -11
  344. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
  345. package/dist/src/server/agent/providers/claude/tool-call-mapper.js +23 -11
  346. package/dist/src/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  347. package/dist/src/server/agent/providers/claude-agent.js +486 -1134
  348. package/dist/src/server/agent/providers/claude-agent.js.map +1 -1
  349. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js +2 -2
  350. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -1
  351. package/dist/src/server/agent/providers/codex/tool-call-mapper.js +14 -11
  352. package/dist/src/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  353. package/dist/src/server/agent/providers/codex-app-server-agent.js +347 -163
  354. package/dist/src/server/agent/providers/codex-app-server-agent.js.map +1 -1
  355. package/dist/src/server/agent/providers/codex-rollout-timeline.js +21 -32
  356. package/dist/src/server/agent/providers/codex-rollout-timeline.js.map +1 -1
  357. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js +2 -2
  358. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -1
  359. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js +2 -9
  360. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js.map +1 -1
  361. package/dist/src/server/agent/providers/opencode-agent.js +5 -5
  362. package/dist/src/server/agent/providers/opencode-agent.js.map +1 -1
  363. package/dist/src/server/agent/providers/tool-call-detail-primitives.js +149 -15
  364. package/dist/src/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  365. package/dist/src/server/agent/providers/tool-call-mapper-utils.js +1 -3
  366. package/dist/src/server/agent/providers/tool-call-mapper-utils.js.map +1 -1
  367. package/dist/src/server/agent/stt-manager.js +1 -2
  368. package/dist/src/server/agent/stt-manager.js.map +1 -1
  369. package/dist/src/server/agent/timeline-projection.js.map +1 -1
  370. package/dist/src/server/agent/tts-manager.js +27 -9
  371. package/dist/src/server/agent/tts-manager.js.map +1 -1
  372. package/dist/src/server/agent/wait-for-agent-tracker.js.map +1 -1
  373. package/dist/src/server/agent-attention-policy.js.map +1 -1
  374. package/dist/src/server/allowed-hosts.js.map +1 -1
  375. package/dist/src/server/bootstrap.js +46 -5
  376. package/dist/src/server/bootstrap.js.map +1 -1
  377. package/dist/src/server/config.js +4 -11
  378. package/dist/src/server/config.js.map +1 -1
  379. package/dist/src/server/connection-offer.js +2 -3
  380. package/dist/src/server/connection-offer.js.map +1 -1
  381. package/dist/src/server/daemon-version.js +1 -1
  382. package/dist/src/server/daemon-version.js.map +1 -1
  383. package/dist/src/server/dictation/dictation-stream-manager.js +4 -1
  384. package/dist/src/server/dictation/dictation-stream-manager.js.map +1 -1
  385. package/dist/src/server/file-explorer/service.js +5 -8
  386. package/dist/src/server/file-explorer/service.js.map +1 -1
  387. package/dist/src/server/messages.js.map +1 -1
  388. package/dist/src/server/package-version.js +1 -2
  389. package/dist/src/server/package-version.js.map +1 -1
  390. package/dist/src/server/pairing-offer.js +45 -0
  391. package/dist/src/server/pairing-offer.js.map +1 -0
  392. package/dist/src/server/pairing-qr.js +45 -0
  393. package/dist/src/server/pairing-qr.js.map +1 -0
  394. package/dist/src/server/persisted-config.js.map +1 -1
  395. package/dist/src/server/persistence-hooks.js.map +1 -1
  396. package/dist/src/server/pid-lock.js.map +1 -1
  397. package/dist/src/server/push/push-service.js.map +1 -1
  398. package/dist/src/server/relay-transport.js +6 -2
  399. package/dist/src/server/relay-transport.js.map +1 -1
  400. package/dist/src/server/session.js +1234 -998
  401. package/dist/src/server/session.js.map +1 -1
  402. package/dist/src/server/speech/audio.js.map +1 -1
  403. package/dist/src/server/speech/providers/local/config.js +5 -14
  404. package/dist/src/server/speech/providers/local/config.js.map +1 -1
  405. package/dist/src/server/speech/providers/local/models.js +1 -1
  406. package/dist/src/server/speech/providers/local/models.js.map +1 -1
  407. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js +21 -7
  408. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
  409. package/dist/src/server/speech/providers/local/runtime.js +1 -23
  410. package/dist/src/server/speech/providers/local/runtime.js.map +1 -1
  411. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
  412. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
  413. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +9 -4
  414. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -1
  415. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +7 -2
  416. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -1
  417. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +5 -1
  418. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -1
  419. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +2 -4
  420. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -1
  421. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js +1 -3
  422. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
  423. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js +2 -4
  424. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
  425. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js +4 -1
  426. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
  427. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js +1 -1
  428. package/dist/src/server/speech/providers/local/sherpa/silero-vad-provider.js.map +1 -1
  429. package/dist/src/server/speech/providers/local/sherpa/silero-vad-session.js.map +1 -1
  430. package/dist/src/server/speech/providers/openai/config.js +5 -24
  431. package/dist/src/server/speech/providers/openai/config.js.map +1 -1
  432. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js +6 -3
  433. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js.map +1 -1
  434. package/dist/src/server/speech/providers/openai/runtime.js +2 -6
  435. package/dist/src/server/speech/providers/openai/runtime.js.map +1 -1
  436. package/dist/src/server/speech/providers/openai/stt.js +1 -3
  437. package/dist/src/server/speech/providers/openai/stt.js.map +1 -1
  438. package/dist/src/server/speech/providers/openai/tts.js.map +1 -1
  439. package/dist/src/server/speech/speech-config-resolver.js +3 -7
  440. package/dist/src/server/speech/speech-config-resolver.js.map +1 -1
  441. package/dist/src/server/speech/speech-runtime.js.map +1 -1
  442. package/dist/src/server/utils/diff-highlighter.js +49 -36
  443. package/dist/src/server/utils/diff-highlighter.js.map +1 -1
  444. package/dist/src/server/voice/fixed-duration-pcm-ring-buffer.js.map +1 -1
  445. package/dist/src/server/voice/voice-turn-controller.js +1 -3
  446. package/dist/src/server/voice/voice-turn-controller.js.map +1 -1
  447. package/dist/src/server/voice-config.js.map +1 -1
  448. package/dist/src/server/voice-mcp-bridge.js.map +1 -1
  449. package/dist/src/server/websocket-server.js +20 -22
  450. package/dist/src/server/websocket-server.js.map +1 -1
  451. package/dist/src/server/workspace-registry-bootstrap.js +6 -6
  452. package/dist/src/server/workspace-registry-bootstrap.js.map +1 -1
  453. package/dist/src/server/workspace-registry-model.js +40 -15
  454. package/dist/src/server/workspace-registry-model.js.map +1 -1
  455. package/dist/src/server/workspace-registry.js +16 -13
  456. package/dist/src/server/workspace-registry.js.map +1 -1
  457. package/dist/src/server/worktree-bootstrap.js +17 -6
  458. package/dist/src/server/worktree-bootstrap.js.map +1 -1
  459. package/dist/src/shared/agent-attention-notification.js.map +1 -1
  460. package/dist/src/shared/daemon-endpoints.js +11 -2
  461. package/dist/src/shared/daemon-endpoints.js.map +1 -1
  462. package/dist/src/shared/messages.js +330 -302
  463. package/dist/src/shared/messages.js.map +1 -1
  464. package/dist/src/shared/terminal-stream-protocol.js +99 -0
  465. package/dist/src/shared/terminal-stream-protocol.js.map +1 -0
  466. package/dist/src/shared/tool-call-display.js +6 -3
  467. package/dist/src/shared/tool-call-display.js.map +1 -1
  468. package/dist/src/terminal/terminal.js +44 -98
  469. package/dist/src/terminal/terminal.js.map +1 -1
  470. package/dist/src/utils/checkout-git.js +111 -120
  471. package/dist/src/utils/checkout-git.js.map +1 -1
  472. package/dist/src/utils/directory-suggestions.js +40 -40
  473. package/dist/src/utils/directory-suggestions.js.map +1 -1
  474. package/dist/src/utils/project-icon.js +2 -11
  475. package/dist/src/utils/project-icon.js.map +1 -1
  476. package/dist/src/utils/worktree.js +22 -19
  477. package/dist/src/utils/worktree.js.map +1 -1
  478. package/package.json +3 -11
  479. package/dist/server/client/daemon-client-terminal-stream-manager.d.ts +0 -43
  480. package/dist/server/client/daemon-client-terminal-stream-manager.d.ts.map +0 -1
  481. package/dist/server/client/daemon-client-terminal-stream-manager.js +0 -134
  482. package/dist/server/client/daemon-client-terminal-stream-manager.js.map +0 -1
  483. package/dist/server/server/utils/syntax-highlighter.d.ts +0 -10
  484. package/dist/server/server/utils/syntax-highlighter.d.ts.map +0 -1
  485. package/dist/server/server/utils/syntax-highlighter.js +0 -145
  486. package/dist/server/server/utils/syntax-highlighter.js.map +0 -1
  487. package/dist/server/shared/binary-mux.d.ts +0 -31
  488. package/dist/server/shared/binary-mux.d.ts.map +0 -1
  489. package/dist/server/shared/binary-mux.js +0 -114
  490. package/dist/server/shared/binary-mux.js.map +0 -1
  491. package/dist/server/shared/terminal-key-input.d.ts +0 -9
  492. package/dist/server/shared/terminal-key-input.d.ts.map +0 -1
  493. package/dist/server/shared/terminal-key-input.js +0 -132
  494. package/dist/server/shared/terminal-key-input.js.map +0 -1
  495. package/dist/src/server/utils/syntax-highlighter.js +0 -145
  496. package/dist/src/server/utils/syntax-highlighter.js.map +0 -1
  497. package/dist/src/shared/binary-mux.js +0 -114
  498. package/dist/src/shared/binary-mux.js.map +0 -1
@@ -1,10 +1,8 @@
1
- import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from '../shared/messages.js';
2
- import { getAgentProviderDefinition } from '../server/agent/provider-manifest.js';
3
- import { isRelayClientWebSocketUrl } from '../shared/daemon-endpoints.js';
4
- import { asUint8Array, decodeBinaryMuxFrame, encodeBinaryMuxFrame, BinaryMuxChannel, TerminalBinaryFlags, TerminalBinaryMessageType, } from '../shared/binary-mux.js';
5
- import { encodeTerminalKeyInput } from '../shared/terminal-key-input.js';
6
- import { TerminalStreamManager, } from './daemon-client-terminal-stream-manager.js';
7
- import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, encodeUtf8String, } from './daemon-client-transport.js';
1
+ import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from "../shared/messages.js";
2
+ import { getAgentProviderDefinition } from "../server/agent/provider-manifest.js";
3
+ import { isRelayClientWebSocketUrl } from "../shared/daemon-endpoints.js";
4
+ import { asUint8Array, decodeTerminalSnapshotPayload, decodeTerminalStreamFrame, encodeTerminalResizePayload, encodeTerminalStreamFrame, TerminalStreamOpcode, } from "../shared/terminal-stream-protocol.js";
5
+ import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, encodeUtf8String, } from "./daemon-client-transport.js";
8
6
  const consoleLogger = {
9
7
  debug: () => { },
10
8
  info: (obj, msg) => console.info(msg, obj),
@@ -13,8 +11,13 @@ const consoleLogger = {
13
11
  };
14
12
  class DaemonRpcError extends Error {
15
13
  constructor(params) {
16
- super(params.error);
17
- this.name = 'DaemonRpcError';
14
+ const parts = [params.error];
15
+ if (params.requestType)
16
+ parts.push(`requestType=${params.requestType}`);
17
+ if (params.code)
18
+ parts.push(`code=${params.code}`);
19
+ super(parts.join(" "));
20
+ this.name = "DaemonRpcError";
18
21
  this.requestId = params.requestId;
19
22
  this.requestType = params.requestType;
20
23
  this.code = params.code;
@@ -29,10 +32,10 @@ const DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS = 15000;
29
32
  const DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
30
33
  const DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS = 5000;
31
34
  function isWaiterTimeoutError(error) {
32
- return error instanceof Error && error.message.startsWith('Timeout waiting for message');
35
+ return error instanceof Error && error.message.startsWith("Timeout waiting for message");
33
36
  }
34
37
  function normalizeClientId(value) {
35
- if (typeof value !== 'string') {
38
+ if (typeof value !== "string") {
36
39
  return null;
37
40
  }
38
41
  const trimmed = value.trim();
@@ -50,22 +53,22 @@ function toReasonCode(reason) {
50
53
  return null;
51
54
  }
52
55
  const normalized = reason.toLowerCase();
53
- if (normalized.includes('timed out')) {
54
- return 'connect_timeout';
56
+ if (normalized.includes("timed out")) {
57
+ return "connect_timeout";
55
58
  }
56
- if (normalized.includes('disposed')) {
57
- return 'disposed';
59
+ if (normalized.includes("disposed")) {
60
+ return "disposed";
58
61
  }
59
- if (normalized.includes('client closed')) {
60
- return 'client_closed';
62
+ if (normalized.includes("client closed")) {
63
+ return "client_closed";
61
64
  }
62
- if (normalized.includes('transport')) {
63
- return 'transport_error';
65
+ if (normalized.includes("transport")) {
66
+ return "transport_error";
64
67
  }
65
- if (normalized.includes('failed to connect')) {
66
- return 'connect_failed';
68
+ if (normalized.includes("failed to connect")) {
69
+ return "connect_failed";
67
70
  }
68
- return 'unknown';
71
+ return "unknown";
69
72
  }
70
73
  export class DaemonClient {
71
74
  constructor(config) {
@@ -87,13 +90,16 @@ export class DaemonClient {
87
90
  this.connectResolve = null;
88
91
  this.connectReject = null;
89
92
  this.lastErrorValue = null;
90
- this.connectionState = { status: 'idle' };
93
+ this.connectionState = { status: "idle" };
91
94
  this.checkoutDiffSubscriptions = new Map();
92
95
  this.terminalDirectorySubscriptions = new Set();
96
+ this.terminalSlots = new Map();
97
+ this.slotTerminals = new Map();
98
+ this.terminalStreamListeners = new Set();
93
99
  this.pendingSendQueue = [];
94
100
  this.lastServerInfoMessage = null;
95
101
  this.logger = config.logger ?? consoleLogger;
96
- this.logConnectionPath = isRelayClientWebSocketUrl(this.config.url) ? 'relay' : 'direct';
102
+ this.logConnectionPath = isRelayClientWebSocketUrl(this.config.url) ? "relay" : "direct";
97
103
  let parsedUrlForLog = null;
98
104
  try {
99
105
  parsedUrlForLog = new URL(this.config.url);
@@ -101,38 +107,28 @@ export class DaemonClient {
101
107
  catch {
102
108
  parsedUrlForLog = null;
103
109
  }
104
- const parsedServerIdForLog = normalizeClientId(parsedUrlForLog?.searchParams.get('serverId'));
110
+ const parsedServerIdForLog = normalizeClientId(parsedUrlForLog?.searchParams.get("serverId"));
105
111
  this.logServerId = parsedServerIdForLog ?? parsedUrlForLog?.host ?? null;
106
112
  const resolvedClientId = normalizeClientId(this.config.clientId);
107
113
  if (!resolvedClientId) {
108
- throw new Error('Daemon client requires a non-empty clientId');
114
+ throw new Error("Daemon client requires a non-empty clientId");
109
115
  }
110
116
  this.config.clientId = resolvedClientId;
111
117
  this.logClientIdHash = hashForLog(resolvedClientId);
112
118
  this.logGeneration =
113
- typeof this.config.runtimeGeneration === 'number' && Number.isFinite(this.config.runtimeGeneration)
119
+ typeof this.config.runtimeGeneration === "number" &&
120
+ Number.isFinite(this.config.runtimeGeneration)
114
121
  ? this.config.runtimeGeneration
115
122
  : null;
116
- this.terminalStreams = new TerminalStreamManager({
117
- sendAck: (ack) => {
118
- this.sendBinaryFrame({
119
- channel: BinaryMuxChannel.Terminal,
120
- messageType: TerminalBinaryMessageType.Ack,
121
- streamId: ack.streamId,
122
- offset: ack.offset,
123
- payload: new Uint8Array(0),
124
- });
125
- },
126
- });
127
123
  }
128
124
  // ============================================================================
129
125
  // Connection
130
126
  // ============================================================================
131
127
  async connect() {
132
- if (this.connectionState.status === 'disposed') {
133
- throw new Error('Daemon client is disposed');
128
+ if (this.connectionState.status === "disposed") {
129
+ throw new Error("Daemon client is disposed");
134
130
  }
135
- if (this.connectionState.status === 'connected') {
131
+ if (this.connectionState.status === "connected") {
136
132
  return;
137
133
  }
138
134
  if (this.connectPromise) {
@@ -147,20 +143,20 @@ export class DaemonClient {
147
143
  return this.connectPromise;
148
144
  }
149
145
  attemptConnect() {
150
- if (this.connectionState.status === 'disposed') {
151
- this.rejectConnect(new Error('Daemon client is disposed'));
146
+ if (this.connectionState.status === "disposed") {
147
+ this.rejectConnect(new Error("Daemon client is disposed"));
152
148
  return;
153
149
  }
154
150
  if (!this.shouldReconnect) {
155
- this.rejectConnect(new Error('Daemon client is closed'));
151
+ this.rejectConnect(new Error("Daemon client is closed"));
156
152
  return;
157
153
  }
158
- if (this.connectionState.status === 'connecting') {
154
+ if (this.connectionState.status === "connecting") {
159
155
  return;
160
156
  }
161
157
  const headers = {};
162
158
  if (this.config.authHeader) {
163
- headers['Authorization'] = this.config.authHeader;
159
+ headers["Authorization"] = this.config.authHeader;
164
160
  }
165
161
  try {
166
162
  // Reconnect can overlap with browser close/error delivery ordering.
@@ -173,7 +169,7 @@ export class DaemonClient {
173
169
  if (shouldUseRelayE2ee) {
174
170
  const daemonPublicKeyB64 = this.config.e2ee?.daemonPublicKeyB64;
175
171
  if (!daemonPublicKeyB64) {
176
- throw new Error('daemonPublicKeyB64 is required for relay E2EE');
172
+ throw new Error("daemonPublicKeyB64 is required for relay E2EE");
177
173
  }
178
174
  transportFactory = createRelayE2eeTransportFactory({
179
175
  baseFactory: baseTransportFactory,
@@ -186,21 +182,21 @@ export class DaemonClient {
186
182
  this.transport = transport;
187
183
  this.lastServerInfoMessage = null;
188
184
  this.updateConnectionState({
189
- status: 'connecting',
185
+ status: "connecting",
190
186
  attempt: this.reconnectAttempt,
191
- }, { event: 'CONNECT_REQUEST' });
187
+ }, { event: "CONNECT_REQUEST" });
192
188
  this.resetConnectTimeout();
193
189
  const timeoutMs = Math.max(1, this.config.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS);
194
190
  this.connectTimeout = setTimeout(() => {
195
- if (this.connectionState.status !== 'connecting') {
191
+ if (this.connectionState.status !== "connecting") {
196
192
  return;
197
193
  }
198
- this.lastErrorValue = 'Connection timed out';
199
- this.disposeTransport(1001, 'Connection timed out');
194
+ this.lastErrorValue = "Connection timed out";
195
+ this.disposeTransport(1001, "Connection timed out");
200
196
  this.scheduleReconnect({
201
- reason: 'Connection timed out',
202
- event: 'CONNECT_TIMEOUT',
203
- reasonCode: 'connect_timeout',
197
+ reason: "Connection timed out",
198
+ event: "CONNECT_TIMEOUT",
199
+ reasonCode: "connect_timeout",
204
200
  });
205
201
  }, timeoutMs);
206
202
  this.transportCleanup = [
@@ -224,14 +220,14 @@ export class DaemonClient {
224
220
  }
225
221
  this.scheduleReconnect({
226
222
  reason,
227
- event: 'TRANSPORT_CLOSE',
228
- reasonCode: 'transport_closed',
223
+ event: "TRANSPORT_CLOSE",
224
+ reasonCode: "transport_closed",
229
225
  });
230
226
  }),
231
227
  transport.onError((event) => {
232
228
  this.resetConnectTimeout();
233
229
  const reason = describeTransportError(event);
234
- const isGeneric = reason === 'Transport error';
230
+ const isGeneric = reason === "Transport error";
235
231
  // Browser WebSocket.onerror often provides no useful details and is followed
236
232
  // by a close event (often with code 1006). Prefer surfacing the close details
237
233
  // instead of immediately disconnecting with a generic "Transport error".
@@ -240,13 +236,13 @@ export class DaemonClient {
240
236
  if (!this.pendingGenericTransportErrorTimeout) {
241
237
  this.pendingGenericTransportErrorTimeout = setTimeout(() => {
242
238
  this.pendingGenericTransportErrorTimeout = null;
243
- if (this.connectionState.status === 'connected' ||
244
- this.connectionState.status === 'connecting') {
239
+ if (this.connectionState.status === "connected" ||
240
+ this.connectionState.status === "connecting") {
245
241
  this.lastErrorValue = reason;
246
242
  this.scheduleReconnect({
247
243
  reason,
248
- event: 'TRANSPORT_ERROR',
249
- reasonCode: 'transport_error',
244
+ event: "TRANSPORT_ERROR",
245
+ reasonCode: "transport_error",
250
246
  });
251
247
  }
252
248
  }, 250);
@@ -260,8 +256,8 @@ export class DaemonClient {
260
256
  this.lastErrorValue = reason;
261
257
  this.scheduleReconnect({
262
258
  reason,
263
- event: 'TRANSPORT_ERROR',
264
- reasonCode: 'transport_error',
259
+ event: "TRANSPORT_ERROR",
260
+ reasonCode: "transport_error",
265
261
  });
266
262
  }),
267
263
  transport.onMessage((data) => this.handleTransportMessage(data)),
@@ -269,12 +265,12 @@ export class DaemonClient {
269
265
  }
270
266
  catch (error) {
271
267
  this.resetConnectTimeout();
272
- const message = error instanceof Error ? error.message : 'Failed to connect';
268
+ const message = error instanceof Error ? error.message : "Failed to connect";
273
269
  this.lastErrorValue = message;
274
270
  this.scheduleReconnect({
275
271
  reason: message,
276
- event: 'CONNECT_FAILED',
277
- reasonCode: 'connect_failed',
272
+ event: "CONNECT_FAILED",
273
+ reasonCode: "connect_failed",
278
274
  });
279
275
  this.rejectConnect(error instanceof Error ? error : new Error(message));
280
276
  }
@@ -296,7 +292,7 @@ export class DaemonClient {
296
292
  this.connectReject = null;
297
293
  }
298
294
  async close() {
299
- if (this.connectionState.status === 'disposed') {
295
+ if (this.connectionState.status === "disposed") {
300
296
  return;
301
297
  }
302
298
  this.shouldReconnect = false;
@@ -308,22 +304,22 @@ export class DaemonClient {
308
304
  this.reconnectTimeout = null;
309
305
  }
310
306
  this.resetConnectTimeout();
311
- this.disposeTransport(1000, 'Client closed');
312
- this.clearWaiters(new Error('Daemon client closed'));
313
- this.rejectPendingSendQueue(new Error('Daemon client closed'));
314
- this.terminalStreams.clearAll();
307
+ this.disposeTransport(1000, "Client closed");
308
+ this.clearWaiters(new Error("Daemon client closed"));
309
+ this.rejectPendingSendQueue(new Error("Daemon client closed"));
310
+ this.clearTerminalSlots();
315
311
  this.lastServerInfoMessage = null;
316
- this.updateConnectionState({ status: 'disposed' }, { event: 'DISPOSE', reason: 'Client closed', reasonCode: 'disposed' });
312
+ this.updateConnectionState({ status: "disposed" }, { event: "DISPOSE", reason: "Client closed", reasonCode: "disposed" });
317
313
  }
318
314
  ensureConnected() {
319
- if (this.connectionState.status === 'disposed') {
315
+ if (this.connectionState.status === "disposed") {
320
316
  return;
321
317
  }
322
318
  if (!this.shouldReconnect) {
323
319
  this.shouldReconnect = true;
324
320
  }
325
- if (this.connectionState.status === 'connected' ||
326
- this.connectionState.status === 'connecting') {
321
+ if (this.connectionState.status === "connected" ||
322
+ this.connectionState.status === "connecting") {
327
323
  return;
328
324
  }
329
325
  void this.connect();
@@ -339,10 +335,10 @@ export class DaemonClient {
339
335
  };
340
336
  }
341
337
  get isConnected() {
342
- return this.connectionState.status === 'connected';
338
+ return this.connectionState.status === "connected";
343
339
  }
344
340
  get isConnecting() {
345
- return this.connectionState.status === 'connecting';
341
+ return this.connectionState.status === "connecting";
346
342
  }
347
343
  get lastError() {
348
344
  return this.lastErrorValue;
@@ -361,7 +357,7 @@ export class DaemonClient {
361
357
  };
362
358
  }
363
359
  on(arg1, arg2) {
364
- if (typeof arg1 === 'function') {
360
+ if (typeof arg1 === "function") {
365
361
  return this.subscribe(arg1);
366
362
  }
367
363
  const type = arg1;
@@ -390,7 +386,7 @@ export class DaemonClient {
390
386
  * For RPC methods that wait for responses, use `sendSessionMessageOrThrow` instead.
391
387
  */
392
388
  sendSessionMessage(message) {
393
- if (!this.transport || this.connectionState.status !== 'connected') {
389
+ if (!this.transport || this.connectionState.status !== "connected") {
394
390
  if (this.config.suppressSendErrors) {
395
391
  return;
396
392
  }
@@ -398,7 +394,7 @@ export class DaemonClient {
398
394
  }
399
395
  const payload = SessionInboundMessageSchema.parse(message);
400
396
  try {
401
- this.transport.send(JSON.stringify({ type: 'session', message: payload }));
397
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
402
398
  }
403
399
  catch (error) {
404
400
  if (this.config.suppressSendErrors) {
@@ -408,14 +404,14 @@ export class DaemonClient {
408
404
  }
409
405
  }
410
406
  sendBinaryFrame(frame) {
411
- if (!this.transport || this.connectionState.status !== 'connected') {
407
+ if (!this.transport || this.connectionState.status !== "connected") {
412
408
  if (this.config.suppressSendErrors) {
413
409
  return;
414
410
  }
415
411
  throw new Error(`Transport not connected (status: ${this.connectionState.status})`);
416
412
  }
417
413
  try {
418
- this.transport.send(encodeBinaryMuxFrame(frame));
414
+ this.transport.send(frame);
419
415
  }
420
416
  catch (error) {
421
417
  if (this.config.suppressSendErrors) {
@@ -433,13 +429,13 @@ export class DaemonClient {
433
429
  sendSessionMessageOrThrow(message) {
434
430
  const status = this.connectionState.status;
435
431
  // If connected, send immediately
436
- if (this.transport && status === 'connected') {
432
+ if (this.transport && status === "connected") {
437
433
  const payload = SessionInboundMessageSchema.parse(message);
438
- this.transport.send(JSON.stringify({ type: 'session', message: payload }));
434
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
439
435
  return Promise.resolve();
440
436
  }
441
437
  // If connecting, queue the message to be sent once connected
442
- if (status === 'connecting') {
438
+ if (status === "connecting") {
443
439
  return new Promise((resolve, reject) => {
444
440
  const timeoutHandle = setTimeout(() => {
445
441
  // Remove from queue
@@ -464,13 +460,13 @@ export class DaemonClient {
464
460
  for (const pending of queue) {
465
461
  clearTimeout(pending.timeoutHandle);
466
462
  try {
467
- if (this.transport && this.connectionState.status === 'connected') {
463
+ if (this.transport && this.connectionState.status === "connected") {
468
464
  const payload = SessionInboundMessageSchema.parse(pending.message);
469
- this.transport.send(JSON.stringify({ type: 'session', message: payload }));
465
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
470
466
  pending.resolve();
471
467
  }
472
468
  else {
473
- pending.reject(new Error('Connection lost before message could be sent'));
469
+ pending.reject(new Error("Connection lost before message could be sent"));
474
470
  }
475
471
  }
476
472
  catch (error) {
@@ -491,9 +487,9 @@ export class DaemonClient {
491
487
  }
492
488
  async sendRequest(params) {
493
489
  const { promise, cancel } = this.waitForWithCancel((msg) => {
494
- if (msg.type === 'rpc_error' && msg.payload.requestId === params.requestId) {
490
+ if (msg.type === "rpc_error" && msg.payload.requestId === params.requestId) {
495
491
  return {
496
- kind: 'error',
492
+ kind: "error",
497
493
  error: new DaemonRpcError({
498
494
  requestId: msg.payload.requestId,
499
495
  error: msg.payload.error,
@@ -506,7 +502,7 @@ export class DaemonClient {
506
502
  if (value === null) {
507
503
  return null;
508
504
  }
509
- return { kind: 'ok', value };
505
+ return { kind: "ok", value };
510
506
  }, params.timeout, params.options);
511
507
  try {
512
508
  await this.sendSessionMessageOrThrow(params.message);
@@ -518,7 +514,7 @@ export class DaemonClient {
518
514
  throw err;
519
515
  }
520
516
  const result = await promise;
521
- if (result.kind === 'error') {
517
+ if (result.kind === "error") {
522
518
  throw result.error;
523
519
  }
524
520
  return result.value;
@@ -561,23 +557,23 @@ export class DaemonClient {
561
557
  });
562
558
  }
563
559
  sendSessionMessageStrict(message) {
564
- if (!this.transport || this.connectionState.status !== 'connected') {
565
- throw new Error('Transport not connected');
560
+ if (!this.transport || this.connectionState.status !== "connected") {
561
+ throw new Error("Transport not connected");
566
562
  }
567
563
  const payload = SessionInboundMessageSchema.parse(message);
568
564
  try {
569
- this.transport.send(JSON.stringify({ type: 'session', message: payload }));
565
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
570
566
  }
571
567
  catch (error) {
572
568
  throw error instanceof Error ? error : new Error(String(error));
573
569
  }
574
570
  }
575
571
  clearAgentAttention(agentId) {
576
- this.sendSessionMessage({ type: 'clear_agent_attention', agentId });
572
+ this.sendSessionMessage({ type: "clear_agent_attention", agentId });
577
573
  }
578
574
  sendHeartbeat(params) {
579
575
  this.sendSessionMessage({
580
- type: 'client_heartbeat',
576
+ type: "client_heartbeat",
581
577
  deviceType: params.deviceType,
582
578
  focusedAgentId: params.focusedAgentId,
583
579
  lastActivityAt: params.lastActivityAt,
@@ -587,7 +583,7 @@ export class DaemonClient {
587
583
  }
588
584
  registerPushToken(token) {
589
585
  this.sendSessionMessage({
590
- type: 'register_push_token',
586
+ type: "register_push_token",
591
587
  token,
592
588
  });
593
589
  }
@@ -596,16 +592,16 @@ export class DaemonClient {
596
592
  const clientSentAt = Date.now();
597
593
  const payload = await this.sendRequest({
598
594
  requestId,
599
- message: { type: 'ping', requestId, clientSentAt },
595
+ message: { type: "ping", requestId, clientSentAt },
600
596
  timeout: params?.timeoutMs ?? 5000,
601
597
  select: (msg) => {
602
- if (msg.type !== 'pong')
598
+ if (msg.type !== "pong")
603
599
  return null;
604
600
  if (msg.payload.requestId !== requestId)
605
601
  return null;
606
- if (typeof msg.payload.serverReceivedAt !== 'number')
602
+ if (typeof msg.payload.serverReceivedAt !== "number")
607
603
  return null;
608
- if (typeof msg.payload.serverSentAt !== 'number')
604
+ if (typeof msg.payload.serverSentAt !== "number")
609
605
  return null;
610
606
  return msg.payload;
611
607
  },
@@ -624,7 +620,7 @@ export class DaemonClient {
624
620
  async fetchAgents(options) {
625
621
  const resolvedRequestId = this.createRequestId(options?.requestId);
626
622
  const message = SessionInboundMessageSchema.parse({
627
- type: 'fetch_agents_request',
623
+ type: "fetch_agents_request",
628
624
  requestId: resolvedRequestId,
629
625
  ...(options?.filter ? { filter: options.filter } : {}),
630
626
  ...(options?.sort ? { sort: options.sort } : {}),
@@ -637,7 +633,7 @@ export class DaemonClient {
637
633
  timeout: 10000,
638
634
  options: { skipQueue: true },
639
635
  select: (msg) => {
640
- if (msg.type !== 'fetch_agents_response') {
636
+ if (msg.type !== "fetch_agents_response") {
641
637
  return null;
642
638
  }
643
639
  if (msg.payload.requestId !== resolvedRequestId) {
@@ -650,7 +646,7 @@ export class DaemonClient {
650
646
  async fetchWorkspaces(options) {
651
647
  const resolvedRequestId = this.createRequestId(options?.requestId);
652
648
  const message = SessionInboundMessageSchema.parse({
653
- type: 'fetch_workspaces_request',
649
+ type: "fetch_workspaces_request",
654
650
  requestId: resolvedRequestId,
655
651
  ...(options?.filter ? { filter: options.filter } : {}),
656
652
  ...(options?.sort ? { sort: options.sort } : {}),
@@ -663,7 +659,7 @@ export class DaemonClient {
663
659
  timeout: 10000,
664
660
  options: { skipQueue: true },
665
661
  select: (msg) => {
666
- if (msg.type !== 'fetch_workspaces_response') {
662
+ if (msg.type !== "fetch_workspaces_response") {
667
663
  return null;
668
664
  }
669
665
  if (msg.payload.requestId !== resolvedRequestId) {
@@ -677,10 +673,10 @@ export class DaemonClient {
677
673
  return this.sendCorrelatedSessionRequest({
678
674
  requestId,
679
675
  message: {
680
- type: 'open_project_request',
676
+ type: "open_project_request",
681
677
  cwd,
682
678
  },
683
- responseType: 'open_project_response',
679
+ responseType: "open_project_response",
684
680
  timeout: 10000,
685
681
  });
686
682
  }
@@ -688,17 +684,17 @@ export class DaemonClient {
688
684
  return this.sendCorrelatedSessionRequest({
689
685
  requestId,
690
686
  message: {
691
- type: 'archive_workspace_request',
687
+ type: "archive_workspace_request",
692
688
  workspaceId,
693
689
  },
694
- responseType: 'archive_workspace_response',
690
+ responseType: "archive_workspace_response",
695
691
  timeout: 10000,
696
692
  });
697
693
  }
698
694
  async fetchAgent(agentId, requestId) {
699
695
  const resolvedRequestId = this.createRequestId(requestId);
700
696
  const message = SessionInboundMessageSchema.parse({
701
- type: 'fetch_agent_request',
697
+ type: "fetch_agent_request",
702
698
  requestId: resolvedRequestId,
703
699
  agentId,
704
700
  });
@@ -708,7 +704,7 @@ export class DaemonClient {
708
704
  timeout: 10000,
709
705
  options: { skipQueue: true },
710
706
  select: (msg) => {
711
- if (msg.type !== 'fetch_agent_response') {
707
+ if (msg.type !== "fetch_agent_response") {
712
708
  return null;
713
709
  }
714
710
  if (msg.payload.requestId !== resolvedRequestId) {
@@ -731,7 +727,7 @@ export class DaemonClient {
731
727
  }
732
728
  for (const [subscriptionId, subscription] of this.checkoutDiffSubscriptions) {
733
729
  const message = SessionInboundMessageSchema.parse({
734
- type: 'subscribe_checkout_diff_request',
730
+ type: "subscribe_checkout_diff_request",
735
731
  subscriptionId,
736
732
  cwd: subscription.cwd,
737
733
  compare: subscription.compare,
@@ -746,7 +742,7 @@ export class DaemonClient {
746
742
  }
747
743
  for (const cwd of this.terminalDirectorySubscriptions) {
748
744
  this.sendSessionMessage({
749
- type: 'subscribe_terminals_request',
745
+ type: "subscribe_terminals_request",
750
746
  cwd,
751
747
  });
752
748
  }
@@ -758,7 +754,7 @@ export class DaemonClient {
758
754
  const requestId = this.createRequestId(options.requestId);
759
755
  const config = resolveAgentConfig(options);
760
756
  const message = SessionInboundMessageSchema.parse({
761
- type: 'create_agent_request',
757
+ type: "create_agent_request",
762
758
  requestId,
763
759
  config,
764
760
  ...(options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}),
@@ -777,7 +773,7 @@ export class DaemonClient {
777
773
  timeout: 15000,
778
774
  options: { skipQueue: true },
779
775
  select: (msg) => {
780
- if (msg.type !== 'status') {
776
+ if (msg.type !== "status") {
781
777
  return null;
782
778
  }
783
779
  const created = AgentCreatedStatusPayloadSchema.safeParse(msg.payload);
@@ -791,7 +787,7 @@ export class DaemonClient {
791
787
  return null;
792
788
  },
793
789
  });
794
- if (status.status === 'agent_create_failed') {
790
+ if (status.status === "agent_create_failed") {
795
791
  throw new Error(status.error);
796
792
  }
797
793
  return status.agent;
@@ -799,7 +795,7 @@ export class DaemonClient {
799
795
  async deleteAgent(agentId) {
800
796
  const requestId = this.createRequestId();
801
797
  const message = SessionInboundMessageSchema.parse({
802
- type: 'delete_agent_request',
798
+ type: "delete_agent_request",
803
799
  agentId,
804
800
  requestId,
805
801
  });
@@ -809,7 +805,7 @@ export class DaemonClient {
809
805
  timeout: 10000,
810
806
  options: { skipQueue: true },
811
807
  select: (msg) => {
812
- if (msg.type !== 'agent_deleted') {
808
+ if (msg.type !== "agent_deleted") {
813
809
  return null;
814
810
  }
815
811
  if (msg.payload.requestId !== requestId) {
@@ -822,7 +818,7 @@ export class DaemonClient {
822
818
  async archiveAgent(agentId) {
823
819
  const requestId = this.createRequestId();
824
820
  const message = SessionInboundMessageSchema.parse({
825
- type: 'archive_agent_request',
821
+ type: "archive_agent_request",
826
822
  agentId,
827
823
  requestId,
828
824
  });
@@ -832,7 +828,7 @@ export class DaemonClient {
832
828
  timeout: 10000,
833
829
  options: { skipQueue: true },
834
830
  select: (msg) => {
835
- if (msg.type !== 'agent_archived') {
831
+ if (msg.type !== "agent_archived") {
836
832
  return null;
837
833
  }
838
834
  if (msg.payload.requestId !== requestId) {
@@ -846,7 +842,7 @@ export class DaemonClient {
846
842
  async updateAgent(agentId, updates) {
847
843
  const requestId = this.createRequestId();
848
844
  const message = SessionInboundMessageSchema.parse({
849
- type: 'update_agent_request',
845
+ type: "update_agent_request",
850
846
  agentId,
851
847
  ...(updates.name !== undefined ? { name: updates.name } : {}),
852
848
  ...(updates.labels && Object.keys(updates.labels).length > 0
@@ -860,7 +856,7 @@ export class DaemonClient {
860
856
  timeout: 10000,
861
857
  options: { skipQueue: true },
862
858
  select: (msg) => {
863
- if (msg.type !== 'update_agent_response') {
859
+ if (msg.type !== "update_agent_response") {
864
860
  return null;
865
861
  }
866
862
  if (msg.payload.requestId !== requestId) {
@@ -870,13 +866,13 @@ export class DaemonClient {
870
866
  },
871
867
  });
872
868
  if (!payload.accepted) {
873
- throw new Error(payload.error ?? 'updateAgent rejected');
869
+ throw new Error(payload.error ?? "updateAgent rejected");
874
870
  }
875
871
  }
876
872
  async resumeAgent(handle, overrides) {
877
873
  const requestId = this.createRequestId();
878
874
  const message = SessionInboundMessageSchema.parse({
879
- type: 'resume_agent_request',
875
+ type: "resume_agent_request",
880
876
  requestId,
881
877
  handle,
882
878
  ...(overrides ? { overrides } : {}),
@@ -887,7 +883,7 @@ export class DaemonClient {
887
883
  timeout: 15000,
888
884
  options: { skipQueue: true },
889
885
  select: (msg) => {
890
- if (msg.type !== 'status') {
886
+ if (msg.type !== "status") {
891
887
  return null;
892
888
  }
893
889
  const resumed = AgentResumedStatusPayloadSchema.safeParse(msg.payload);
@@ -902,7 +898,7 @@ export class DaemonClient {
902
898
  async refreshAgent(agentId, requestId) {
903
899
  const resolvedRequestId = this.createRequestId(requestId);
904
900
  const message = SessionInboundMessageSchema.parse({
905
- type: 'refresh_agent_request',
901
+ type: "refresh_agent_request",
906
902
  agentId,
907
903
  requestId: resolvedRequestId,
908
904
  });
@@ -912,7 +908,7 @@ export class DaemonClient {
912
908
  timeout: 15000,
913
909
  options: { skipQueue: true },
914
910
  select: (msg) => {
915
- if (msg.type !== 'status') {
911
+ if (msg.type !== "status") {
916
912
  return null;
917
913
  }
918
914
  const refreshed = AgentRefreshedStatusPayloadSchema.safeParse(msg.payload);
@@ -926,12 +922,12 @@ export class DaemonClient {
926
922
  async fetchAgentTimeline(agentId, options = {}) {
927
923
  const resolvedRequestId = this.createRequestId(options.requestId);
928
924
  const message = SessionInboundMessageSchema.parse({
929
- type: 'fetch_agent_timeline_request',
925
+ type: "fetch_agent_timeline_request",
930
926
  agentId,
931
927
  requestId: resolvedRequestId,
932
928
  ...(options.direction ? { direction: options.direction } : {}),
933
929
  ...(options.cursor ? { cursor: options.cursor } : {}),
934
- ...(typeof options.limit === 'number' ? { limit: options.limit } : {}),
930
+ ...(typeof options.limit === "number" ? { limit: options.limit } : {}),
935
931
  ...(options.projection ? { projection: options.projection } : {}),
936
932
  });
937
933
  const payload = await this.sendRequest({
@@ -940,7 +936,7 @@ export class DaemonClient {
940
936
  timeout: 15000,
941
937
  options: { skipQueue: true },
942
938
  select: (msg) => {
943
- if (msg.type !== 'fetch_agent_timeline_response') {
939
+ if (msg.type !== "fetch_agent_timeline_response") {
944
940
  return null;
945
941
  }
946
942
  if (msg.payload.requestId !== resolvedRequestId) {
@@ -961,7 +957,7 @@ export class DaemonClient {
961
957
  const requestId = this.createRequestId();
962
958
  const messageId = options?.messageId ?? crypto.randomUUID();
963
959
  const message = SessionInboundMessageSchema.parse({
964
- type: 'send_agent_message_request',
960
+ type: "send_agent_message_request",
965
961
  requestId,
966
962
  agentId,
967
963
  text,
@@ -974,7 +970,7 @@ export class DaemonClient {
974
970
  timeout: 15000,
975
971
  options: { skipQueue: true },
976
972
  select: (msg) => {
977
- if (msg.type !== 'send_agent_message_response') {
973
+ if (msg.type !== "send_agent_message_response") {
978
974
  return null;
979
975
  }
980
976
  if (msg.payload.requestId !== requestId) {
@@ -984,19 +980,19 @@ export class DaemonClient {
984
980
  },
985
981
  });
986
982
  if (!payload.accepted) {
987
- throw new Error(payload.error ?? 'sendAgentMessage rejected');
983
+ throw new Error(payload.error ?? "sendAgentMessage rejected");
988
984
  }
989
985
  }
990
986
  async sendMessage(agentId, text, options) {
991
987
  await this.sendAgentMessage(agentId, text, options);
992
988
  }
993
989
  async cancelAgent(agentId) {
994
- this.sendSessionMessage({ type: 'cancel_agent_request', agentId });
990
+ this.sendSessionMessage({ type: "cancel_agent_request", agentId });
995
991
  }
996
992
  async setAgentMode(agentId, modeId) {
997
993
  const requestId = this.createRequestId();
998
994
  const message = SessionInboundMessageSchema.parse({
999
- type: 'set_agent_mode_request',
995
+ type: "set_agent_mode_request",
1000
996
  agentId,
1001
997
  modeId,
1002
998
  requestId,
@@ -1007,7 +1003,7 @@ export class DaemonClient {
1007
1003
  timeout: 15000,
1008
1004
  options: { skipQueue: true },
1009
1005
  select: (msg) => {
1010
- if (msg.type !== 'set_agent_mode_response') {
1006
+ if (msg.type !== "set_agent_mode_response") {
1011
1007
  return null;
1012
1008
  }
1013
1009
  if (msg.payload.requestId !== requestId) {
@@ -1017,13 +1013,13 @@ export class DaemonClient {
1017
1013
  },
1018
1014
  });
1019
1015
  if (!payload.accepted) {
1020
- throw new Error(payload.error ?? 'setAgentMode rejected');
1016
+ throw new Error(payload.error ?? "setAgentMode rejected");
1021
1017
  }
1022
1018
  }
1023
1019
  async setAgentModel(agentId, modelId) {
1024
1020
  const requestId = this.createRequestId();
1025
1021
  const message = SessionInboundMessageSchema.parse({
1026
- type: 'set_agent_model_request',
1022
+ type: "set_agent_model_request",
1027
1023
  agentId,
1028
1024
  modelId,
1029
1025
  requestId,
@@ -1034,7 +1030,7 @@ export class DaemonClient {
1034
1030
  timeout: 15000,
1035
1031
  options: { skipQueue: true },
1036
1032
  select: (msg) => {
1037
- if (msg.type !== 'set_agent_model_response') {
1033
+ if (msg.type !== "set_agent_model_response") {
1038
1034
  return null;
1039
1035
  }
1040
1036
  if (msg.payload.requestId !== requestId) {
@@ -1044,13 +1040,13 @@ export class DaemonClient {
1044
1040
  },
1045
1041
  });
1046
1042
  if (!payload.accepted) {
1047
- throw new Error(payload.error ?? 'setAgentModel rejected');
1043
+ throw new Error(payload.error ?? "setAgentModel rejected");
1048
1044
  }
1049
1045
  }
1050
1046
  async setAgentThinkingOption(agentId, thinkingOptionId) {
1051
1047
  const requestId = this.createRequestId();
1052
1048
  const message = SessionInboundMessageSchema.parse({
1053
- type: 'set_agent_thinking_request',
1049
+ type: "set_agent_thinking_request",
1054
1050
  agentId,
1055
1051
  thinkingOptionId,
1056
1052
  requestId,
@@ -1061,7 +1057,7 @@ export class DaemonClient {
1061
1057
  timeout: 15000,
1062
1058
  options: { skipQueue: true },
1063
1059
  select: (msg) => {
1064
- if (msg.type !== 'set_agent_thinking_response') {
1060
+ if (msg.type !== "set_agent_thinking_response") {
1065
1061
  return null;
1066
1062
  }
1067
1063
  if (msg.payload.requestId !== requestId) {
@@ -1071,13 +1067,13 @@ export class DaemonClient {
1071
1067
  },
1072
1068
  });
1073
1069
  if (!payload.accepted) {
1074
- throw new Error(payload.error ?? 'setAgentThinkingOption rejected');
1070
+ throw new Error(payload.error ?? "setAgentThinkingOption rejected");
1075
1071
  }
1076
1072
  }
1077
1073
  async restartServer(reason, requestId) {
1078
1074
  const resolvedRequestId = this.createRequestId(requestId);
1079
1075
  const message = SessionInboundMessageSchema.parse({
1080
- type: 'restart_server_request',
1076
+ type: "restart_server_request",
1081
1077
  ...(reason && reason.trim().length > 0 ? { reason } : {}),
1082
1078
  requestId: resolvedRequestId,
1083
1079
  });
@@ -1087,7 +1083,7 @@ export class DaemonClient {
1087
1083
  timeout: 10000,
1088
1084
  options: { skipQueue: true },
1089
1085
  select: (msg) => {
1090
- if (msg.type !== 'status') {
1086
+ if (msg.type !== "status") {
1091
1087
  return null;
1092
1088
  }
1093
1089
  const restarted = RestartRequestedStatusPayloadSchema.safeParse(msg.payload);
@@ -1104,7 +1100,7 @@ export class DaemonClient {
1104
1100
  async shutdownServer(requestId) {
1105
1101
  const resolvedRequestId = this.createRequestId(requestId);
1106
1102
  const message = SessionInboundMessageSchema.parse({
1107
- type: 'shutdown_server_request',
1103
+ type: "shutdown_server_request",
1108
1104
  requestId: resolvedRequestId,
1109
1105
  });
1110
1106
  return this.sendRequest({
@@ -1113,7 +1109,7 @@ export class DaemonClient {
1113
1109
  timeout: 10000,
1114
1110
  options: { skipQueue: true },
1115
1111
  select: (msg) => {
1116
- if (msg.type !== 'status') {
1112
+ if (msg.type !== "status") {
1117
1113
  return null;
1118
1114
  }
1119
1115
  const shutdown = ShutdownRequestedStatusPayloadSchema.safeParse(msg.payload);
@@ -1133,7 +1129,7 @@ export class DaemonClient {
1133
1129
  async setVoiceMode(enabled, agentId) {
1134
1130
  const requestId = this.createRequestId();
1135
1131
  const message = SessionInboundMessageSchema.parse({
1136
- type: 'set_voice_mode',
1132
+ type: "set_voice_mode",
1137
1133
  enabled,
1138
1134
  ...(agentId ? { agentId } : {}),
1139
1135
  requestId,
@@ -1143,7 +1139,7 @@ export class DaemonClient {
1143
1139
  message,
1144
1140
  timeout: 10000,
1145
1141
  select: (msg) => {
1146
- if (msg.type !== 'set_voice_mode_response') {
1142
+ if (msg.type !== "set_voice_mode_response") {
1147
1143
  return null;
1148
1144
  }
1149
1145
  if (msg.payload.requestId !== requestId) {
@@ -1153,19 +1149,19 @@ export class DaemonClient {
1153
1149
  },
1154
1150
  });
1155
1151
  if (!response.accepted) {
1156
- const codeSuffix = typeof response.reasonCode === 'string' && response.reasonCode.trim().length > 0
1152
+ const codeSuffix = typeof response.reasonCode === "string" && response.reasonCode.trim().length > 0
1157
1153
  ? ` (${response.reasonCode})`
1158
- : '';
1159
- throw new Error((response.error ?? 'Failed to set voice mode') + codeSuffix);
1154
+ : "";
1155
+ throw new Error((response.error ?? "Failed to set voice mode") + codeSuffix);
1160
1156
  }
1161
1157
  return response;
1162
1158
  }
1163
1159
  async sendVoiceAudioChunk(audio, format, isLast = false) {
1164
- this.sendSessionMessage({ type: 'voice_audio_chunk', audio, format, isLast });
1160
+ this.sendSessionMessage({ type: "voice_audio_chunk", audio, format, isLast });
1165
1161
  }
1166
1162
  async startDictationStream(dictationId, format) {
1167
1163
  const ack = this.waitForWithCancel((msg) => {
1168
- if (msg.type !== 'dictation_stream_ack') {
1164
+ if (msg.type !== "dictation_stream_ack") {
1169
1165
  return null;
1170
1166
  }
1171
1167
  if (msg.payload.dictationId !== dictationId) {
@@ -1178,7 +1174,7 @@ export class DaemonClient {
1178
1174
  }, 30000, { skipQueue: true });
1179
1175
  const ackPromise = ack.promise.then(() => undefined);
1180
1176
  const streamError = this.waitForWithCancel((msg) => {
1181
- if (msg.type !== 'dictation_stream_error') {
1177
+ if (msg.type !== "dictation_stream_error") {
1182
1178
  return null;
1183
1179
  }
1184
1180
  if (msg.payload.dictationId !== dictationId) {
@@ -1189,9 +1185,9 @@ export class DaemonClient {
1189
1185
  const errorPromise = streamError.promise.then((payload) => {
1190
1186
  throw new Error(payload.error);
1191
1187
  });
1192
- const cleanupError = new Error('Cancelled dictation start waiter');
1188
+ const cleanupError = new Error("Cancelled dictation start waiter");
1193
1189
  try {
1194
- this.sendSessionMessageStrict({ type: 'dictation_stream_start', dictationId, format });
1190
+ this.sendSessionMessageStrict({ type: "dictation_stream_start", dictationId, format });
1195
1191
  await Promise.race([ackPromise, errorPromise]);
1196
1192
  }
1197
1193
  finally {
@@ -1203,7 +1199,7 @@ export class DaemonClient {
1203
1199
  }
1204
1200
  sendDictationStreamChunk(dictationId, seq, audio, format) {
1205
1201
  this.sendSessionMessageStrict({
1206
- type: 'dictation_stream_chunk',
1202
+ type: "dictation_stream_chunk",
1207
1203
  dictationId,
1208
1204
  seq,
1209
1205
  audio,
@@ -1212,7 +1208,7 @@ export class DaemonClient {
1212
1208
  }
1213
1209
  async finishDictationStream(dictationId, finalSeq) {
1214
1210
  const final = this.waitForWithCancel((msg) => {
1215
- if (msg.type !== 'dictation_stream_final') {
1211
+ if (msg.type !== "dictation_stream_final") {
1216
1212
  return null;
1217
1213
  }
1218
1214
  if (msg.payload.dictationId !== dictationId) {
@@ -1221,7 +1217,7 @@ export class DaemonClient {
1221
1217
  return msg.payload;
1222
1218
  }, 0, { skipQueue: true });
1223
1219
  const streamError = this.waitForWithCancel((msg) => {
1224
- if (msg.type !== 'dictation_stream_error') {
1220
+ if (msg.type !== "dictation_stream_error") {
1225
1221
  return null;
1226
1222
  }
1227
1223
  if (msg.payload.dictationId !== dictationId) {
@@ -1230,7 +1226,7 @@ export class DaemonClient {
1230
1226
  return msg.payload;
1231
1227
  }, 0, { skipQueue: true });
1232
1228
  const finishAccepted = this.waitForWithCancel((msg) => {
1233
- if (msg.type !== 'dictation_stream_finish_accepted') {
1229
+ if (msg.type !== "dictation_stream_finish_accepted") {
1234
1230
  return null;
1235
1231
  }
1236
1232
  if (msg.payload.dictationId !== dictationId) {
@@ -1244,64 +1240,68 @@ export class DaemonClient {
1244
1240
  });
1245
1241
  const finishAcceptedPromise = finishAccepted.promise;
1246
1242
  const finalOutcomePromise = finalPromise.then((payload) => ({
1247
- kind: 'final',
1243
+ kind: "final",
1248
1244
  payload,
1249
1245
  }));
1250
1246
  const errorOutcomePromise = errorPromise.then(() => ({
1251
- kind: 'error',
1252
- error: new Error('Unexpected dictation stream error state'),
1247
+ kind: "error",
1248
+ error: new Error("Unexpected dictation stream error state"),
1253
1249
  }), (error) => ({
1254
- kind: 'error',
1250
+ kind: "error",
1255
1251
  error: error instanceof Error ? error : new Error(String(error)),
1256
1252
  }));
1257
- const finishAcceptedOutcomePromise = finishAcceptedPromise.then((payload) => ({ kind: 'accepted', payload }), (error) => {
1253
+ const finishAcceptedOutcomePromise = finishAcceptedPromise.then((payload) => ({ kind: "accepted", payload }), (error) => {
1258
1254
  if (isWaiterTimeoutError(error)) {
1259
- return { kind: 'accepted_timeout' };
1255
+ return { kind: "accepted_timeout" };
1260
1256
  }
1261
1257
  return {
1262
- kind: 'accepted_error',
1258
+ kind: "accepted_error",
1263
1259
  error: error instanceof Error ? error : new Error(String(error)),
1264
1260
  };
1265
1261
  });
1266
1262
  const waitForFinalResult = async (timeoutMs) => {
1267
1263
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
1268
1264
  const outcome = await Promise.race([finalOutcomePromise, errorOutcomePromise]);
1269
- if (outcome.kind === 'error') {
1265
+ if (outcome.kind === "error") {
1270
1266
  throw outcome.error;
1271
1267
  }
1272
1268
  return outcome.payload;
1273
1269
  }
1274
1270
  let timeoutHandle = null;
1275
1271
  const timeoutPromise = new Promise((resolve) => {
1276
- timeoutHandle = setTimeout(() => resolve({ kind: 'timeout' }), timeoutMs);
1272
+ timeoutHandle = setTimeout(() => resolve({ kind: "timeout" }), timeoutMs);
1277
1273
  });
1278
- const outcome = await Promise.race([finalOutcomePromise, errorOutcomePromise, timeoutPromise]);
1274
+ const outcome = await Promise.race([
1275
+ finalOutcomePromise,
1276
+ errorOutcomePromise,
1277
+ timeoutPromise,
1278
+ ]);
1279
1279
  if (timeoutHandle) {
1280
1280
  clearTimeout(timeoutHandle);
1281
1281
  }
1282
- if (outcome.kind === 'timeout') {
1282
+ if (outcome.kind === "timeout") {
1283
1283
  throw new Error(`Timeout waiting for dictation finalization (${timeoutMs}ms)`);
1284
1284
  }
1285
- if (outcome.kind === 'error') {
1285
+ if (outcome.kind === "error") {
1286
1286
  throw outcome.error;
1287
1287
  }
1288
1288
  return outcome.payload;
1289
1289
  };
1290
- const cleanupError = new Error('Cancelled dictation finish waiter');
1290
+ const cleanupError = new Error("Cancelled dictation finish waiter");
1291
1291
  try {
1292
- this.sendSessionMessageStrict({ type: 'dictation_stream_finish', dictationId, finalSeq });
1292
+ this.sendSessionMessageStrict({ type: "dictation_stream_finish", dictationId, finalSeq });
1293
1293
  const firstOutcome = await Promise.race([
1294
1294
  finalOutcomePromise,
1295
1295
  errorOutcomePromise,
1296
1296
  finishAcceptedOutcomePromise,
1297
1297
  ]);
1298
- if (firstOutcome.kind === 'final') {
1298
+ if (firstOutcome.kind === "final") {
1299
1299
  return firstOutcome.payload;
1300
1300
  }
1301
- if (firstOutcome.kind === 'error') {
1301
+ if (firstOutcome.kind === "error") {
1302
1302
  throw firstOutcome.error;
1303
1303
  }
1304
- if (firstOutcome.kind === 'accepted') {
1304
+ if (firstOutcome.kind === "accepted") {
1305
1305
  return await waitForFinalResult(firstOutcome.payload.timeoutMs + DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS);
1306
1306
  }
1307
1307
  return await waitForFinalResult(DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS);
@@ -1316,13 +1316,13 @@ export class DaemonClient {
1316
1316
  }
1317
1317
  }
1318
1318
  cancelDictationStream(dictationId) {
1319
- this.sendSessionMessageStrict({ type: 'dictation_stream_cancel', dictationId });
1319
+ this.sendSessionMessageStrict({ type: "dictation_stream_cancel", dictationId });
1320
1320
  }
1321
1321
  async abortRequest() {
1322
- this.sendSessionMessage({ type: 'abort_request' });
1322
+ this.sendSessionMessage({ type: "abort_request" });
1323
1323
  }
1324
1324
  async audioPlayed(id) {
1325
- this.sendSessionMessage({ type: 'audio_played', id });
1325
+ this.sendSessionMessage({ type: "audio_played", id });
1326
1326
  }
1327
1327
  // ============================================================================
1328
1328
  // Git Operations
@@ -1337,7 +1337,7 @@ export class DaemonClient {
1337
1337
  }
1338
1338
  const resolvedRequestId = this.createRequestId(requestId);
1339
1339
  const message = SessionInboundMessageSchema.parse({
1340
- type: 'checkout_status_request',
1340
+ type: "checkout_status_request",
1341
1341
  cwd,
1342
1342
  requestId: resolvedRequestId,
1343
1343
  });
@@ -1347,7 +1347,7 @@ export class DaemonClient {
1347
1347
  timeout: 60000,
1348
1348
  options: { skipQueue: true },
1349
1349
  select: (msg) => {
1350
- if (msg.type !== 'checkout_status_response') {
1350
+ if (msg.type !== "checkout_status_response") {
1351
1351
  return null;
1352
1352
  }
1353
1353
  if (msg.payload.requestId !== resolvedRequestId) {
@@ -1369,14 +1369,14 @@ export class DaemonClient {
1369
1369
  return responsePromise;
1370
1370
  }
1371
1371
  normalizeCheckoutDiffCompare(compare) {
1372
- if (compare.mode === 'uncommitted') {
1373
- return { mode: 'uncommitted' };
1372
+ if (compare.mode === "uncommitted") {
1373
+ return { mode: "uncommitted" };
1374
1374
  }
1375
1375
  const trimmedBaseRef = compare.baseRef?.trim();
1376
1376
  if (!trimmedBaseRef) {
1377
- return { mode: 'base' };
1377
+ return { mode: "base" };
1378
1378
  }
1379
- return { mode: 'base', baseRef: trimmedBaseRef };
1379
+ return { mode: "base", baseRef: trimmedBaseRef };
1380
1380
  }
1381
1381
  async getCheckoutDiff(cwd, compare, requestId) {
1382
1382
  const oneShotSubscriptionId = `oneshot-checkout-diff:${crypto.randomUUID()}`;
@@ -1411,7 +1411,7 @@ export class DaemonClient {
1411
1411
  });
1412
1412
  const resolvedRequestId = this.createRequestId(options?.requestId);
1413
1413
  const message = SessionInboundMessageSchema.parse({
1414
- type: 'subscribe_checkout_diff_request',
1414
+ type: "subscribe_checkout_diff_request",
1415
1415
  subscriptionId,
1416
1416
  cwd,
1417
1417
  compare: normalizedCompare,
@@ -1421,7 +1421,7 @@ export class DaemonClient {
1421
1421
  return await this.sendCorrelatedRequest({
1422
1422
  requestId: resolvedRequestId,
1423
1423
  message,
1424
- responseType: 'subscribe_checkout_diff_response',
1424
+ responseType: "subscribe_checkout_diff_response",
1425
1425
  timeout: 60000,
1426
1426
  options: { skipQueue: true },
1427
1427
  selectPayload: (payload) => {
@@ -1445,7 +1445,7 @@ export class DaemonClient {
1445
1445
  unsubscribeCheckoutDiff(subscriptionId) {
1446
1446
  this.checkoutDiffSubscriptions.delete(subscriptionId);
1447
1447
  this.sendSessionMessage({
1448
- type: 'unsubscribe_checkout_diff_request',
1448
+ type: "unsubscribe_checkout_diff_request",
1449
1449
  subscriptionId,
1450
1450
  });
1451
1451
  }
@@ -1453,12 +1453,12 @@ export class DaemonClient {
1453
1453
  return this.sendCorrelatedSessionRequest({
1454
1454
  requestId,
1455
1455
  message: {
1456
- type: 'checkout_commit_request',
1456
+ type: "checkout_commit_request",
1457
1457
  cwd,
1458
1458
  message: input.message,
1459
1459
  addAll: input.addAll,
1460
1460
  },
1461
- responseType: 'checkout_commit_response',
1461
+ responseType: "checkout_commit_response",
1462
1462
  timeout: 60000,
1463
1463
  });
1464
1464
  }
@@ -1466,13 +1466,13 @@ export class DaemonClient {
1466
1466
  return this.sendCorrelatedSessionRequest({
1467
1467
  requestId,
1468
1468
  message: {
1469
- type: 'checkout_merge_request',
1469
+ type: "checkout_merge_request",
1470
1470
  cwd,
1471
1471
  baseRef: input.baseRef,
1472
1472
  strategy: input.strategy,
1473
1473
  requireCleanTarget: input.requireCleanTarget,
1474
1474
  },
1475
- responseType: 'checkout_merge_response',
1475
+ responseType: "checkout_merge_response",
1476
1476
  timeout: 60000,
1477
1477
  });
1478
1478
  }
@@ -1480,12 +1480,12 @@ export class DaemonClient {
1480
1480
  return this.sendCorrelatedSessionRequest({
1481
1481
  requestId,
1482
1482
  message: {
1483
- type: 'checkout_merge_from_base_request',
1483
+ type: "checkout_merge_from_base_request",
1484
1484
  cwd,
1485
1485
  baseRef: input.baseRef,
1486
1486
  requireCleanTarget: input.requireCleanTarget,
1487
1487
  },
1488
- responseType: 'checkout_merge_from_base_response',
1488
+ responseType: "checkout_merge_from_base_response",
1489
1489
  timeout: 60000,
1490
1490
  });
1491
1491
  }
@@ -1493,10 +1493,10 @@ export class DaemonClient {
1493
1493
  return this.sendCorrelatedSessionRequest({
1494
1494
  requestId,
1495
1495
  message: {
1496
- type: 'checkout_push_request',
1496
+ type: "checkout_push_request",
1497
1497
  cwd,
1498
1498
  },
1499
- responseType: 'checkout_push_response',
1499
+ responseType: "checkout_push_response",
1500
1500
  timeout: 60000,
1501
1501
  });
1502
1502
  }
@@ -1504,13 +1504,13 @@ export class DaemonClient {
1504
1504
  return this.sendCorrelatedSessionRequest({
1505
1505
  requestId,
1506
1506
  message: {
1507
- type: 'checkout_pr_create_request',
1507
+ type: "checkout_pr_create_request",
1508
1508
  cwd,
1509
1509
  title: input.title,
1510
1510
  body: input.body,
1511
1511
  baseRef: input.baseRef,
1512
1512
  },
1513
- responseType: 'checkout_pr_create_response',
1513
+ responseType: "checkout_pr_create_response",
1514
1514
  timeout: 60000,
1515
1515
  });
1516
1516
  }
@@ -1518,10 +1518,10 @@ export class DaemonClient {
1518
1518
  return this.sendCorrelatedSessionRequest({
1519
1519
  requestId,
1520
1520
  message: {
1521
- type: 'checkout_pr_status_request',
1521
+ type: "checkout_pr_status_request",
1522
1522
  cwd,
1523
1523
  },
1524
- responseType: 'checkout_pr_status_response',
1524
+ responseType: "checkout_pr_status_response",
1525
1525
  timeout: 60000,
1526
1526
  });
1527
1527
  }
@@ -1529,11 +1529,11 @@ export class DaemonClient {
1529
1529
  return this.sendCorrelatedSessionRequest({
1530
1530
  requestId,
1531
1531
  message: {
1532
- type: 'paseo_worktree_list_request',
1532
+ type: "paseo_worktree_list_request",
1533
1533
  cwd: input.cwd,
1534
1534
  repoRoot: input.repoRoot,
1535
1535
  },
1536
- responseType: 'paseo_worktree_list_response',
1536
+ responseType: "paseo_worktree_list_response",
1537
1537
  timeout: 60000,
1538
1538
  });
1539
1539
  }
@@ -1541,24 +1541,36 @@ export class DaemonClient {
1541
1541
  return this.sendCorrelatedSessionRequest({
1542
1542
  requestId,
1543
1543
  message: {
1544
- type: 'paseo_worktree_archive_request',
1544
+ type: "paseo_worktree_archive_request",
1545
1545
  worktreePath: input.worktreePath,
1546
1546
  repoRoot: input.repoRoot,
1547
1547
  branchName: input.branchName,
1548
1548
  },
1549
- responseType: 'paseo_worktree_archive_response',
1549
+ responseType: "paseo_worktree_archive_response",
1550
1550
  timeout: 20000,
1551
1551
  });
1552
1552
  }
1553
+ async createPaseoWorktree(input, requestId) {
1554
+ return this.sendCorrelatedSessionRequest({
1555
+ requestId,
1556
+ message: {
1557
+ type: "create_paseo_worktree_request",
1558
+ cwd: input.cwd,
1559
+ worktreeSlug: input.worktreeSlug,
1560
+ },
1561
+ responseType: "create_paseo_worktree_response",
1562
+ timeout: 60000,
1563
+ });
1564
+ }
1553
1565
  async validateBranch(options, requestId) {
1554
1566
  return this.sendCorrelatedSessionRequest({
1555
1567
  requestId,
1556
1568
  message: {
1557
- type: 'validate_branch_request',
1569
+ type: "validate_branch_request",
1558
1570
  cwd: options.cwd,
1559
1571
  branchName: options.branchName,
1560
1572
  },
1561
- responseType: 'validate_branch_response',
1573
+ responseType: "validate_branch_response",
1562
1574
  timeout: 10000,
1563
1575
  });
1564
1576
  }
@@ -1566,12 +1578,12 @@ export class DaemonClient {
1566
1578
  return this.sendCorrelatedSessionRequest({
1567
1579
  requestId,
1568
1580
  message: {
1569
- type: 'branch_suggestions_request',
1581
+ type: "branch_suggestions_request",
1570
1582
  cwd: options.cwd,
1571
1583
  query: options.query,
1572
1584
  limit: options.limit,
1573
1585
  },
1574
- responseType: 'branch_suggestions_response',
1586
+ responseType: "branch_suggestions_response",
1575
1587
  timeout: 10000,
1576
1588
  });
1577
1589
  }
@@ -1579,30 +1591,30 @@ export class DaemonClient {
1579
1591
  return this.sendCorrelatedSessionRequest({
1580
1592
  requestId,
1581
1593
  message: {
1582
- type: 'directory_suggestions_request',
1594
+ type: "directory_suggestions_request",
1583
1595
  query: options.query,
1584
1596
  cwd: options.cwd,
1585
1597
  includeFiles: options.includeFiles,
1586
1598
  includeDirectories: options.includeDirectories,
1587
1599
  limit: options.limit,
1588
1600
  },
1589
- responseType: 'directory_suggestions_response',
1601
+ responseType: "directory_suggestions_response",
1590
1602
  timeout: 10000,
1591
1603
  });
1592
1604
  }
1593
1605
  // ============================================================================
1594
1606
  // File Explorer
1595
1607
  // ============================================================================
1596
- async exploreFileSystem(cwd, path, mode = 'list', requestId) {
1608
+ async exploreFileSystem(cwd, path, mode = "list", requestId) {
1597
1609
  return this.sendCorrelatedSessionRequest({
1598
1610
  requestId,
1599
1611
  message: {
1600
- type: 'file_explorer_request',
1612
+ type: "file_explorer_request",
1601
1613
  cwd,
1602
1614
  path,
1603
1615
  mode,
1604
1616
  },
1605
- responseType: 'file_explorer_response',
1617
+ responseType: "file_explorer_response",
1606
1618
  timeout: 10000,
1607
1619
  });
1608
1620
  }
@@ -1610,11 +1622,11 @@ export class DaemonClient {
1610
1622
  return this.sendCorrelatedSessionRequest({
1611
1623
  requestId,
1612
1624
  message: {
1613
- type: 'file_download_token_request',
1625
+ type: "file_download_token_request",
1614
1626
  cwd,
1615
1627
  path,
1616
1628
  },
1617
- responseType: 'file_download_token_response',
1629
+ responseType: "file_download_token_response",
1618
1630
  timeout: 10000,
1619
1631
  });
1620
1632
  }
@@ -1622,10 +1634,10 @@ export class DaemonClient {
1622
1634
  return this.sendCorrelatedSessionRequest({
1623
1635
  requestId,
1624
1636
  message: {
1625
- type: 'project_icon_request',
1637
+ type: "project_icon_request",
1626
1638
  cwd,
1627
1639
  },
1628
- responseType: 'project_icon_response',
1640
+ responseType: "project_icon_response",
1629
1641
  timeout: 10000,
1630
1642
  });
1631
1643
  }
@@ -1636,11 +1648,11 @@ export class DaemonClient {
1636
1648
  return this.sendCorrelatedSessionRequest({
1637
1649
  requestId: options?.requestId,
1638
1650
  message: {
1639
- type: 'list_provider_models_request',
1651
+ type: "list_provider_models_request",
1640
1652
  provider,
1641
1653
  cwd: options?.cwd,
1642
1654
  },
1643
- responseType: 'list_provider_models_response',
1655
+ responseType: "list_provider_models_response",
1644
1656
  // Provider SDK cold starts (especially model discovery) can exceed 30s.
1645
1657
  timeout: 45000,
1646
1658
  });
@@ -1649,9 +1661,9 @@ export class DaemonClient {
1649
1661
  return this.sendCorrelatedSessionRequest({
1650
1662
  requestId: options?.requestId,
1651
1663
  message: {
1652
- type: 'list_available_providers_request',
1664
+ type: "list_available_providers_request",
1653
1665
  },
1654
- responseType: 'list_available_providers_response',
1666
+ responseType: "list_available_providers_response",
1655
1667
  timeout: 30000,
1656
1668
  });
1657
1669
  }
@@ -1659,9 +1671,9 @@ export class DaemonClient {
1659
1671
  return this.sendCorrelatedSessionRequest({
1660
1672
  requestId,
1661
1673
  message: {
1662
- type: 'speech_models_list_request',
1674
+ type: "speech_models_list_request",
1663
1675
  },
1664
- responseType: 'speech_models_list_response',
1676
+ responseType: "speech_models_list_response",
1665
1677
  timeout: 30000,
1666
1678
  });
1667
1679
  }
@@ -1669,24 +1681,24 @@ export class DaemonClient {
1669
1681
  return this.sendCorrelatedSessionRequest({
1670
1682
  requestId: options?.requestId,
1671
1683
  message: {
1672
- type: 'speech_models_download_request',
1684
+ type: "speech_models_download_request",
1673
1685
  modelIds: options?.modelIds,
1674
1686
  },
1675
- responseType: 'speech_models_download_response',
1687
+ responseType: "speech_models_download_response",
1676
1688
  timeout: 30 * 60 * 1000,
1677
1689
  });
1678
1690
  }
1679
1691
  async listCommands(agentId, requestIdOrOptions) {
1680
- const requestId = typeof requestIdOrOptions === 'string' ? requestIdOrOptions : requestIdOrOptions?.requestId;
1681
- const draftConfig = typeof requestIdOrOptions === 'string' ? undefined : requestIdOrOptions?.draftConfig;
1692
+ const requestId = typeof requestIdOrOptions === "string" ? requestIdOrOptions : requestIdOrOptions?.requestId;
1693
+ const draftConfig = typeof requestIdOrOptions === "string" ? undefined : requestIdOrOptions?.draftConfig;
1682
1694
  return this.sendCorrelatedSessionRequest({
1683
1695
  requestId,
1684
1696
  message: {
1685
- type: 'list_commands_request',
1697
+ type: "list_commands_request",
1686
1698
  agentId,
1687
1699
  ...(draftConfig ? { draftConfig } : {}),
1688
1700
  },
1689
- responseType: 'list_commands_response',
1701
+ responseType: "list_commands_response",
1690
1702
  timeout: 30000,
1691
1703
  });
1692
1704
  }
@@ -1695,7 +1707,7 @@ export class DaemonClient {
1695
1707
  // ============================================================================
1696
1708
  async respondToPermission(agentId, requestId, response) {
1697
1709
  this.sendSessionMessage({
1698
- type: 'agent_permission_response',
1710
+ type: "agent_permission_response",
1699
1711
  agentId,
1700
1712
  requestId,
1701
1713
  response,
@@ -1703,7 +1715,7 @@ export class DaemonClient {
1703
1715
  }
1704
1716
  async respondToPermissionAndWait(agentId, requestId, response, timeout = 15000) {
1705
1717
  const message = SessionInboundMessageSchema.parse({
1706
- type: 'agent_permission_response',
1718
+ type: "agent_permission_response",
1707
1719
  agentId,
1708
1720
  requestId,
1709
1721
  response,
@@ -1714,7 +1726,7 @@ export class DaemonClient {
1714
1726
  timeout,
1715
1727
  options: { skipQueue: true },
1716
1728
  select: (msg) => {
1717
- if (msg.type !== 'agent_permission_resolved') {
1729
+ if (msg.type !== "agent_permission_resolved") {
1718
1730
  return null;
1719
1731
  }
1720
1732
  if (msg.payload.requestId !== requestId) {
@@ -1759,7 +1771,7 @@ export class DaemonClient {
1759
1771
  unsubscribe();
1760
1772
  unsubscribe = null;
1761
1773
  }
1762
- if (result.kind === 'ok') {
1774
+ if (result.kind === "ok") {
1763
1775
  resolve(result.snapshot);
1764
1776
  return;
1765
1777
  }
@@ -1772,7 +1784,7 @@ export class DaemonClient {
1772
1784
  if (!predicate(snapshot)) {
1773
1785
  return false;
1774
1786
  }
1775
- finish({ kind: 'ok', snapshot });
1787
+ finish({ kind: "ok", snapshot });
1776
1788
  return true;
1777
1789
  };
1778
1790
  const poll = async () => {
@@ -1788,14 +1800,14 @@ export class DaemonClient {
1788
1800
  pollInFlight = false;
1789
1801
  }
1790
1802
  };
1791
- unsubscribe = this.on('agent_update', (message) => {
1803
+ unsubscribe = this.on("agent_update", (message) => {
1792
1804
  if (settled) {
1793
1805
  return;
1794
1806
  }
1795
- if (message.type !== 'agent_update') {
1807
+ if (message.type !== "agent_update") {
1796
1808
  return;
1797
1809
  }
1798
- if (message.payload.kind !== 'upsert') {
1810
+ if (message.payload.kind !== "upsert") {
1799
1811
  return;
1800
1812
  }
1801
1813
  const snapshot = message.payload.agent;
@@ -1807,7 +1819,7 @@ export class DaemonClient {
1807
1819
  const remaining = Math.max(1, deadline - Date.now());
1808
1820
  timeoutTimer = setTimeout(() => {
1809
1821
  finish({
1810
- kind: 'error',
1822
+ kind: "error",
1811
1823
  error: new Error(`Timed out waiting for agent ${agentId}`),
1812
1824
  });
1813
1825
  }, remaining);
@@ -1821,7 +1833,7 @@ export class DaemonClient {
1821
1833
  const requestId = this.createRequestId();
1822
1834
  const hasTimeout = Number.isFinite(timeout) && timeout > 0;
1823
1835
  const message = SessionInboundMessageSchema.parse({
1824
- type: 'wait_for_finish_request',
1836
+ type: "wait_for_finish_request",
1825
1837
  requestId,
1826
1838
  agentId,
1827
1839
  ...(hasTimeout ? { timeoutMs: timeout } : {}),
@@ -1829,7 +1841,7 @@ export class DaemonClient {
1829
1841
  const payload = await this.sendCorrelatedRequest({
1830
1842
  requestId,
1831
1843
  message,
1832
- responseType: 'wait_for_finish_response',
1844
+ responseType: "wait_for_finish_response",
1833
1845
  timeout: hasTimeout ? timeout + 5000 : 0,
1834
1846
  options: { skipQueue: true },
1835
1847
  });
@@ -1845,35 +1857,35 @@ export class DaemonClient {
1845
1857
  // ============================================================================
1846
1858
  subscribeTerminals(input) {
1847
1859
  this.terminalDirectorySubscriptions.add(input.cwd);
1848
- if (!this.transport || this.connectionState.status !== 'connected') {
1860
+ if (!this.transport || this.connectionState.status !== "connected") {
1849
1861
  return;
1850
1862
  }
1851
1863
  this.sendSessionMessage({
1852
- type: 'subscribe_terminals_request',
1864
+ type: "subscribe_terminals_request",
1853
1865
  cwd: input.cwd,
1854
1866
  });
1855
1867
  }
1856
1868
  unsubscribeTerminals(input) {
1857
1869
  this.terminalDirectorySubscriptions.delete(input.cwd);
1858
- if (!this.transport || this.connectionState.status !== 'connected') {
1870
+ if (!this.transport || this.connectionState.status !== "connected") {
1859
1871
  return;
1860
1872
  }
1861
1873
  this.sendSessionMessage({
1862
- type: 'unsubscribe_terminals_request',
1874
+ type: "unsubscribe_terminals_request",
1863
1875
  cwd: input.cwd,
1864
1876
  });
1865
1877
  }
1866
1878
  async listTerminals(cwd, requestId) {
1867
1879
  const resolvedRequestId = this.createRequestId(requestId);
1868
1880
  const message = SessionInboundMessageSchema.parse({
1869
- type: 'list_terminals_request',
1881
+ type: "list_terminals_request",
1870
1882
  cwd,
1871
1883
  requestId: resolvedRequestId,
1872
1884
  });
1873
1885
  return this.sendCorrelatedRequest({
1874
1886
  requestId: resolvedRequestId,
1875
1887
  message,
1876
- responseType: 'list_terminals_response',
1888
+ responseType: "list_terminals_response",
1877
1889
  timeout: 10000,
1878
1890
  options: { skipQueue: true },
1879
1891
  });
@@ -1881,7 +1893,7 @@ export class DaemonClient {
1881
1893
  async createTerminal(cwd, name, requestId) {
1882
1894
  const resolvedRequestId = this.createRequestId(requestId);
1883
1895
  const message = SessionInboundMessageSchema.parse({
1884
- type: 'create_terminal_request',
1896
+ type: "create_terminal_request",
1885
1897
  cwd,
1886
1898
  name,
1887
1899
  requestId: resolvedRequestId,
@@ -1889,7 +1901,7 @@ export class DaemonClient {
1889
1901
  return this.sendCorrelatedRequest({
1890
1902
  requestId: resolvedRequestId,
1891
1903
  message,
1892
- responseType: 'create_terminal_response',
1904
+ responseType: "create_terminal_response",
1893
1905
  timeout: 10000,
1894
1906
  options: { skipQueue: true },
1895
1907
  });
@@ -1897,27 +1909,54 @@ export class DaemonClient {
1897
1909
  async subscribeTerminal(terminalId, requestId) {
1898
1910
  const resolvedRequestId = this.createRequestId(requestId);
1899
1911
  const message = SessionInboundMessageSchema.parse({
1900
- type: 'subscribe_terminal_request',
1912
+ type: "subscribe_terminal_request",
1901
1913
  terminalId,
1902
1914
  requestId: resolvedRequestId,
1903
1915
  });
1904
- return this.sendCorrelatedRequest({
1916
+ const payload = await this.sendCorrelatedRequest({
1905
1917
  requestId: resolvedRequestId,
1906
1918
  message,
1907
- responseType: 'subscribe_terminal_response',
1919
+ responseType: "subscribe_terminal_response",
1908
1920
  timeout: 10000,
1909
1921
  options: { skipQueue: true },
1910
1922
  });
1923
+ if (payload.error === null) {
1924
+ this.setTerminalSlot(terminalId, payload.slot);
1925
+ }
1926
+ return payload;
1911
1927
  }
1912
1928
  unsubscribeTerminal(terminalId) {
1929
+ this.removeTerminalSlot(terminalId);
1913
1930
  this.sendSessionMessage({
1914
- type: 'unsubscribe_terminal_request',
1931
+ type: "unsubscribe_terminal_request",
1915
1932
  terminalId,
1916
1933
  });
1917
1934
  }
1918
1935
  sendTerminalInput(terminalId, message) {
1936
+ const slot = this.terminalSlots.get(terminalId);
1937
+ if (typeof slot === "number") {
1938
+ if (message.type === "input") {
1939
+ this.sendBinaryFrame(encodeTerminalStreamFrame({
1940
+ opcode: TerminalStreamOpcode.Input,
1941
+ slot,
1942
+ payload: encodeUtf8String(message.data),
1943
+ }));
1944
+ return;
1945
+ }
1946
+ if (message.type === "resize") {
1947
+ this.sendBinaryFrame(encodeTerminalStreamFrame({
1948
+ opcode: TerminalStreamOpcode.Resize,
1949
+ slot,
1950
+ payload: encodeTerminalResizePayload({
1951
+ rows: message.rows,
1952
+ cols: message.cols,
1953
+ }),
1954
+ }));
1955
+ return;
1956
+ }
1957
+ }
1919
1958
  this.sendSessionMessage({
1920
- type: 'terminal_input',
1959
+ type: "terminal_input",
1921
1960
  terminalId,
1922
1961
  message,
1923
1962
  });
@@ -1925,117 +1964,72 @@ export class DaemonClient {
1925
1964
  async killTerminal(terminalId, requestId) {
1926
1965
  const resolvedRequestId = this.createRequestId(requestId);
1927
1966
  const message = SessionInboundMessageSchema.parse({
1928
- type: 'kill_terminal_request',
1929
- terminalId,
1930
- requestId: resolvedRequestId,
1931
- });
1932
- return this.sendCorrelatedRequest({
1933
- requestId: resolvedRequestId,
1934
- message,
1935
- responseType: 'kill_terminal_response',
1936
- timeout: 10000,
1937
- options: { skipQueue: true },
1938
- });
1939
- }
1940
- async attachTerminalStream(terminalId, options, requestId) {
1941
- const resolvedRequestId = this.createRequestId(requestId);
1942
- const message = SessionInboundMessageSchema.parse({
1943
- type: 'attach_terminal_stream_request',
1967
+ type: "kill_terminal_request",
1944
1968
  terminalId,
1945
1969
  requestId: resolvedRequestId,
1946
- ...(options?.resumeOffset !== undefined ? { resumeOffset: options.resumeOffset } : {}),
1947
- ...(options?.rows !== undefined ? { rows: options.rows } : {}),
1948
- ...(options?.cols !== undefined ? { cols: options.cols } : {}),
1949
1970
  });
1950
1971
  return this.sendCorrelatedRequest({
1951
1972
  requestId: resolvedRequestId,
1952
1973
  message,
1953
- responseType: 'attach_terminal_stream_response',
1954
- timeout: 10000,
1955
- options: { skipQueue: true },
1956
- });
1957
- }
1958
- async detachTerminalStream(streamId, requestId) {
1959
- const resolvedRequestId = this.createRequestId(requestId);
1960
- const message = SessionInboundMessageSchema.parse({
1961
- type: 'detach_terminal_stream_request',
1962
- streamId,
1963
- requestId: resolvedRequestId,
1964
- });
1965
- const payload = await this.sendCorrelatedRequest({
1966
- requestId: resolvedRequestId,
1967
- message,
1968
- responseType: 'detach_terminal_stream_response',
1974
+ responseType: "kill_terminal_response",
1969
1975
  timeout: 10000,
1970
1976
  options: { skipQueue: true },
1971
1977
  });
1972
- this.terminalStreams.clearStream({ streamId });
1973
- return payload;
1974
1978
  }
1975
- onTerminalStreamData(streamId, handler) {
1976
- return this.terminalStreams.subscribe({ streamId, handler });
1979
+ onTerminalStreamEvent(handler) {
1980
+ this.terminalStreamListeners.add(handler);
1981
+ return () => {
1982
+ this.terminalStreamListeners.delete(handler);
1983
+ };
1977
1984
  }
1978
- async waitForTerminalStreamData(streamId, predicate, timeout = 5000) {
1985
+ async waitForTerminalStreamEvent(predicate, timeout = 5000) {
1979
1986
  return new Promise((resolve, reject) => {
1980
1987
  const timeoutHandle = setTimeout(() => {
1981
1988
  unsubscribe();
1982
- reject(new Error(`Timeout waiting for terminal stream data (${timeout}ms)`));
1989
+ reject(new Error(`Timeout waiting for terminal stream event (${timeout}ms)`));
1983
1990
  }, timeout);
1984
- const unsubscribe = this.onTerminalStreamData(streamId, (chunk) => {
1985
- if (!predicate(chunk)) {
1991
+ const unsubscribe = this.onTerminalStreamEvent((event) => {
1992
+ if (!predicate(event)) {
1986
1993
  return;
1987
1994
  }
1988
1995
  clearTimeout(timeoutHandle);
1989
1996
  unsubscribe();
1990
- resolve(chunk);
1997
+ resolve(event);
1991
1998
  });
1992
1999
  });
1993
2000
  }
1994
- sendTerminalStreamInput(streamId, data) {
1995
- const payload = typeof data === 'string' ? encodeUtf8String(data) : data;
1996
- this.sendBinaryFrame({
1997
- channel: BinaryMuxChannel.Terminal,
1998
- messageType: TerminalBinaryMessageType.InputUtf8,
1999
- streamId,
2000
- offset: 0,
2001
- payload,
2002
- });
2003
- }
2004
- sendTerminalStreamKey(streamId, input) {
2005
- const encoded = encodeTerminalKeyInput(input);
2006
- if (!encoded) {
2007
- return;
2008
- }
2009
- this.sendTerminalStreamInput(streamId, encoded);
2010
- }
2011
- sendTerminalStreamAck(streamId, offset) {
2012
- const normalizedOffset = Math.max(0, Math.floor(offset));
2013
- this.terminalStreams.noteAck({ streamId, offset: normalizedOffset });
2014
- this.sendBinaryFrame({
2015
- channel: BinaryMuxChannel.Terminal,
2016
- messageType: TerminalBinaryMessageType.Ack,
2017
- streamId,
2018
- offset: normalizedOffset,
2019
- payload: new Uint8Array(0),
2020
- });
2021
- }
2022
- async waitForTerminalOutput(terminalId, timeout = 5000) {
2023
- return this.waitFor((msg) => {
2024
- if (msg.type !== 'terminal_output') {
2025
- return null;
2026
- }
2027
- if (msg.payload.terminalId !== terminalId) {
2028
- return null;
2029
- }
2030
- return msg.payload;
2031
- }, timeout, { skipQueue: true });
2032
- }
2033
2001
  // ============================================================================
2034
2002
  // Internals
2035
2003
  // ============================================================================
2036
2004
  createRequestId(requestId) {
2037
2005
  return requestId ?? crypto.randomUUID();
2038
2006
  }
2007
+ setTerminalSlot(terminalId, slot) {
2008
+ const existingTerminalId = this.slotTerminals.get(slot);
2009
+ if (existingTerminalId && existingTerminalId !== terminalId) {
2010
+ this.terminalSlots.delete(existingTerminalId);
2011
+ }
2012
+ const existingSlot = this.terminalSlots.get(terminalId);
2013
+ if (typeof existingSlot === "number" && existingSlot !== slot) {
2014
+ this.slotTerminals.delete(existingSlot);
2015
+ }
2016
+ this.terminalSlots.set(terminalId, slot);
2017
+ this.slotTerminals.set(slot, terminalId);
2018
+ }
2019
+ removeTerminalSlot(terminalId) {
2020
+ const slot = this.terminalSlots.get(terminalId);
2021
+ if (typeof slot !== "number") {
2022
+ return;
2023
+ }
2024
+ this.terminalSlots.delete(terminalId);
2025
+ if (this.slotTerminals.get(slot) === terminalId) {
2026
+ this.slotTerminals.delete(slot);
2027
+ }
2028
+ }
2029
+ clearTerminalSlots() {
2030
+ this.terminalSlots.clear();
2031
+ this.slotTerminals.clear();
2032
+ }
2039
2033
  getLastServerInfoMessage() {
2040
2034
  return this.lastServerInfoMessage;
2041
2035
  }
@@ -2045,31 +2039,31 @@ export class DaemonClient {
2045
2039
  sendHelloMessage() {
2046
2040
  if (!this.transport) {
2047
2041
  this.scheduleReconnect({
2048
- reason: 'Transport unavailable before hello',
2049
- event: 'HELLO_TRANSPORT_MISSING',
2050
- reasonCode: 'transport_error',
2042
+ reason: "Transport unavailable before hello",
2043
+ event: "HELLO_TRANSPORT_MISSING",
2044
+ reasonCode: "transport_error",
2051
2045
  });
2052
2046
  return;
2053
2047
  }
2054
2048
  try {
2055
2049
  this.transport.send(JSON.stringify({
2056
- type: 'hello',
2050
+ type: "hello",
2057
2051
  clientId: this.config.clientId,
2058
- clientType: this.config.clientType ?? 'cli',
2052
+ clientType: this.config.clientType ?? "cli",
2059
2053
  protocolVersion: 1,
2060
2054
  }));
2061
2055
  }
2062
2056
  catch (error) {
2063
- const message = error instanceof Error ? error.message : 'Failed to send hello message';
2057
+ const message = error instanceof Error ? error.message : "Failed to send hello message";
2064
2058
  this.lastErrorValue = message;
2065
2059
  this.scheduleReconnect({
2066
2060
  reason: message,
2067
- event: 'HELLO_SEND_FAILED',
2068
- reasonCode: 'transport_error',
2061
+ event: "HELLO_SEND_FAILED",
2062
+ reasonCode: "transport_error",
2069
2063
  });
2070
2064
  }
2071
2065
  }
2072
- disposeTransport(code = 1001, reason = 'Reconnecting') {
2066
+ disposeTransport(code = 1001, reason = "Reconnecting") {
2073
2067
  this.cleanupTransport();
2074
2068
  if (this.transport) {
2075
2069
  try {
@@ -2105,10 +2099,10 @@ export class DaemonClient {
2105
2099
  this.connectTimeout = null;
2106
2100
  }
2107
2101
  handleTransportMessage(data) {
2108
- const rawData = data && typeof data === 'object' && 'data' in data ? data.data : data;
2109
- if (typeof Blob !== 'undefined' &&
2102
+ const rawData = data && typeof data === "object" && "data" in data ? data.data : data;
2103
+ if (typeof Blob !== "undefined" &&
2110
2104
  rawData instanceof Blob &&
2111
- typeof rawData.arrayBuffer === 'function') {
2105
+ typeof rawData.arrayBuffer === "function") {
2112
2106
  void rawData
2113
2107
  .arrayBuffer()
2114
2108
  .then((buffer) => {
@@ -2121,7 +2115,7 @@ export class DaemonClient {
2121
2115
  }
2122
2116
  const rawBytes = asUint8Array(rawData);
2123
2117
  if (rawBytes) {
2124
- const frame = decodeBinaryMuxFrame(rawBytes);
2118
+ const frame = decodeTerminalStreamFrame(rawBytes);
2125
2119
  if (frame) {
2126
2120
  this.handleBinaryFrame(frame);
2127
2121
  return;
@@ -2140,35 +2134,54 @@ export class DaemonClient {
2140
2134
  }
2141
2135
  const parsed = WSOutboundMessageSchema.safeParse(parsedJson);
2142
2136
  if (!parsed.success) {
2143
- const msgType = parsedJson?.type ?? 'unknown';
2144
- this.logger.warn({ msgType, error: parsed.error.message }, 'Message validation failed');
2137
+ const msgType = parsedJson?.type ?? "unknown";
2138
+ this.logger.warn({ msgType, error: parsed.error.message }, "Message validation failed");
2145
2139
  return;
2146
2140
  }
2147
- if (parsed.data.type === 'pong') {
2141
+ if (parsed.data.type === "pong") {
2148
2142
  return;
2149
2143
  }
2150
2144
  this.handleSessionMessage(parsed.data.message);
2151
2145
  }
2152
2146
  handleBinaryFrame(frame) {
2153
- if (frame.channel === BinaryMuxChannel.Terminal &&
2154
- frame.messageType === TerminalBinaryMessageType.OutputUtf8) {
2155
- const chunk = {
2156
- streamId: frame.streamId,
2157
- offset: frame.offset,
2158
- endOffset: frame.offset + (frame.payload?.byteLength ?? 0),
2159
- replay: Boolean((frame.flags ?? 0) & TerminalBinaryFlags.Replay),
2160
- data: frame.payload ?? new Uint8Array(0),
2161
- };
2162
- this.terminalStreams.receiveChunk({ chunk });
2147
+ const terminalId = this.slotTerminals.get(frame.slot);
2148
+ if (!terminalId) {
2163
2149
  return;
2164
2150
  }
2151
+ if (frame.opcode === TerminalStreamOpcode.Output) {
2152
+ this.emitTerminalStreamEvent({
2153
+ terminalId,
2154
+ type: "output",
2155
+ data: frame.payload,
2156
+ });
2157
+ return;
2158
+ }
2159
+ if (frame.opcode === TerminalStreamOpcode.Snapshot) {
2160
+ const state = decodeTerminalSnapshotPayload(frame.payload);
2161
+ if (!state) {
2162
+ return;
2163
+ }
2164
+ this.emitTerminalStreamEvent({
2165
+ terminalId,
2166
+ type: "snapshot",
2167
+ state,
2168
+ });
2169
+ }
2170
+ }
2171
+ emitTerminalStreamEvent(event) {
2172
+ for (const listener of this.terminalStreamListeners) {
2173
+ try {
2174
+ listener(event);
2175
+ }
2176
+ catch {
2177
+ // no-op
2178
+ }
2179
+ }
2165
2180
  }
2166
2181
  updateConnectionState(next, metadata) {
2167
2182
  const previous = this.connectionState;
2168
2183
  this.connectionState = next;
2169
- const reasonFromNext = next.status === 'disconnected' && typeof next.reason === 'string'
2170
- ? next.reason
2171
- : null;
2184
+ const reasonFromNext = next.status === "disconnected" && typeof next.reason === "string" ? next.reason : null;
2172
2185
  const reason = metadata?.reason ?? reasonFromNext;
2173
2186
  const reasonCode = metadata?.reasonCode ?? toReasonCode(reason);
2174
2187
  this.logger.debug({
@@ -2176,12 +2189,12 @@ export class DaemonClient {
2176
2189
  clientIdHash: this.logClientIdHash,
2177
2190
  from: previous.status,
2178
2191
  to: next.status,
2179
- event: metadata?.event ?? 'STATE_UPDATE',
2192
+ event: metadata?.event ?? "STATE_UPDATE",
2180
2193
  connectionPath: this.logConnectionPath,
2181
2194
  generation: this.logGeneration,
2182
2195
  reasonCode,
2183
2196
  reason,
2184
- }, 'DaemonClientTransition');
2197
+ }, "DaemonClientTransition");
2185
2198
  for (const listener of this.connectionListeners) {
2186
2199
  try {
2187
2200
  listener(next);
@@ -2199,31 +2212,31 @@ export class DaemonClient {
2199
2212
  clearTimeout(this.reconnectTimeout);
2200
2213
  this.reconnectTimeout = null;
2201
2214
  }
2202
- const wasDisposed = this.connectionState.status === 'disposed';
2215
+ const wasDisposed = this.connectionState.status === "disposed";
2203
2216
  const reason = input?.reason;
2204
- if (typeof reason === 'string' && reason.trim().length > 0) {
2217
+ if (typeof reason === "string" && reason.trim().length > 0) {
2205
2218
  this.lastErrorValue = reason.trim();
2206
2219
  }
2207
2220
  // Clear all pending waiters and queued sends since the connection was lost
2208
2221
  // and responses from the previous connection will never arrive.
2209
- this.clearWaiters(new Error(reason ?? 'Connection lost'));
2210
- this.rejectPendingSendQueue(new Error(reason ?? 'Connection lost'));
2211
- this.terminalStreams.clearAll();
2222
+ this.clearWaiters(new Error(reason ?? "Connection lost"));
2223
+ this.rejectPendingSendQueue(new Error(reason ?? "Connection lost"));
2224
+ this.clearTerminalSlots();
2212
2225
  this.lastServerInfoMessage = null;
2213
2226
  if (wasDisposed) {
2214
- this.rejectConnect(new Error(reason ?? 'Daemon client is disposed'));
2227
+ this.rejectConnect(new Error(reason ?? "Daemon client is disposed"));
2215
2228
  return;
2216
2229
  }
2217
2230
  this.updateConnectionState({
2218
- status: 'disconnected',
2231
+ status: "disconnected",
2219
2232
  ...(reason ? { reason } : {}),
2220
2233
  }, {
2221
- event: input?.event ?? 'TRANSPORT_CLOSE',
2234
+ event: input?.event ?? "TRANSPORT_CLOSE",
2222
2235
  ...(reason ? { reason } : {}),
2223
2236
  ...(input?.reasonCode ? { reasonCode: input.reasonCode } : {}),
2224
2237
  });
2225
2238
  if (!this.shouldReconnect || this.config.reconnect?.enabled === false) {
2226
- this.rejectConnect(new Error(reason ?? 'Transport disconnected before connect'));
2239
+ this.rejectConnect(new Error(reason ?? "Transport disconnected before connect"));
2227
2240
  return;
2228
2241
  }
2229
2242
  const attempt = this.reconnectAttempt;
@@ -2240,14 +2253,14 @@ export class DaemonClient {
2240
2253
  }, delay);
2241
2254
  }
2242
2255
  handleSessionMessage(msg) {
2243
- if (msg.type === 'status') {
2256
+ if (msg.type === "status") {
2244
2257
  const serverInfo = parseServerInfoStatusPayload(msg.payload);
2245
2258
  if (serverInfo) {
2246
2259
  this.lastServerInfoMessage = serverInfo;
2247
- if (this.connectionState.status === 'connecting') {
2260
+ if (this.connectionState.status === "connecting") {
2248
2261
  this.resetConnectTimeout();
2249
2262
  this.reconnectAttempt = 0;
2250
- this.updateConnectionState({ status: 'connected' }, { event: 'HELLO_SERVER_INFO' });
2263
+ this.updateConnectionState({ status: "connected" }, { event: "HELLO_SERVER_INFO" });
2251
2264
  this.resubscribeCheckoutDiffSubscriptions();
2252
2265
  this.resubscribeTerminalDirectorySubscriptions();
2253
2266
  this.flushPendingSendQueue();
@@ -2255,8 +2268,8 @@ export class DaemonClient {
2255
2268
  }
2256
2269
  }
2257
2270
  }
2258
- if (msg.type === 'terminal_stream_exit') {
2259
- this.terminalStreams.clearStream({ streamId: msg.payload.streamId });
2271
+ if (msg.type === "terminal_stream_exit") {
2272
+ this.removeTerminalSlot(msg.payload.terminalId);
2260
2273
  }
2261
2274
  if (this.rawMessageListeners.size > 0) {
2262
2275
  for (const handler of this.rawMessageListeners) {
@@ -2310,40 +2323,40 @@ export class DaemonClient {
2310
2323
  }
2311
2324
  toEvent(msg) {
2312
2325
  switch (msg.type) {
2313
- case 'agent_update':
2326
+ case "agent_update":
2314
2327
  return {
2315
- type: 'agent_update',
2316
- agentId: msg.payload.kind === 'upsert' ? msg.payload.agent.id : msg.payload.agentId,
2328
+ type: "agent_update",
2329
+ agentId: msg.payload.kind === "upsert" ? msg.payload.agent.id : msg.payload.agentId,
2317
2330
  payload: msg.payload,
2318
2331
  };
2319
- case 'workspace_update':
2332
+ case "workspace_update":
2320
2333
  return {
2321
- type: 'workspace_update',
2322
- workspaceId: msg.payload.kind === 'upsert' ? msg.payload.workspace.id : msg.payload.id,
2334
+ type: "workspace_update",
2335
+ workspaceId: msg.payload.kind === "upsert" ? msg.payload.workspace.id : msg.payload.id,
2323
2336
  payload: msg.payload,
2324
2337
  };
2325
- case 'agent_stream':
2338
+ case "agent_stream":
2326
2339
  return {
2327
- type: 'agent_stream',
2340
+ type: "agent_stream",
2328
2341
  agentId: msg.payload.agentId,
2329
2342
  event: msg.payload.event,
2330
2343
  timestamp: msg.payload.timestamp,
2331
- ...(typeof msg.payload.seq === 'number' ? { seq: msg.payload.seq } : {}),
2332
- ...(typeof msg.payload.epoch === 'string' ? { epoch: msg.payload.epoch } : {}),
2344
+ ...(typeof msg.payload.seq === "number" ? { seq: msg.payload.seq } : {}),
2345
+ ...(typeof msg.payload.epoch === "string" ? { epoch: msg.payload.epoch } : {}),
2333
2346
  };
2334
- case 'status':
2335
- return { type: 'status', payload: msg.payload };
2336
- case 'agent_deleted':
2337
- return { type: 'agent_deleted', agentId: msg.payload.agentId };
2338
- case 'agent_permission_request':
2347
+ case "status":
2348
+ return { type: "status", payload: msg.payload };
2349
+ case "agent_deleted":
2350
+ return { type: "agent_deleted", agentId: msg.payload.agentId };
2351
+ case "agent_permission_request":
2339
2352
  return {
2340
- type: 'agent_permission_request',
2353
+ type: "agent_permission_request",
2341
2354
  agentId: msg.payload.agentId,
2342
2355
  request: msg.payload.request,
2343
2356
  };
2344
- case 'agent_permission_resolved':
2357
+ case "agent_permission_resolved":
2345
2358
  return {
2346
- type: 'agent_permission_resolved',
2359
+ type: "agent_permission_resolved",
2347
2360
  agentId: msg.payload.agentId,
2348
2361
  requestId: msg.payload.requestId,
2349
2362
  resolution: msg.payload.resolution,
@@ -2352,9 +2365,6 @@ export class DaemonClient {
2352
2365
  return null;
2353
2366
  }
2354
2367
  }
2355
- async waitFor(predicate, timeout = 30000, _options) {
2356
- return this.waitForWithCancel(predicate, timeout, _options).promise;
2357
- }
2358
2368
  waitForWithCancel(predicate, timeout = 30000, _options) {
2359
2369
  // Capture stack trace at call site, not inside setTimeout
2360
2370
  const timeoutError = new Error(`Timeout waiting for message (${timeout}ms)`);
@@ -2424,7 +2434,7 @@ function resolveAgentConfig(options) {
2424
2434
  };
2425
2435
  const merged = config ? { ...baseConfig, ...config } : baseConfig;
2426
2436
  if (!merged.provider || !merged.cwd) {
2427
- throw new Error('createAgent requires provider and cwd');
2437
+ throw new Error("createAgent requires provider and cwd");
2428
2438
  }
2429
2439
  if (!merged.modeId) {
2430
2440
  merged.modeId = getAgentProviderDefinition(merged.provider).defaultModeId ?? undefined;