@seawork/server 1.0.0

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 (682) hide show
  1. package/.env.example +23 -0
  2. package/README.md +107 -0
  3. package/dist/scripts/dev-runner.js +27 -0
  4. package/dist/scripts/dev-runner.js.map +1 -0
  5. package/dist/scripts/mcp-stdio-socket-bridge-cli.mjs +62 -0
  6. package/dist/scripts/supervisor-entrypoint.js +123 -0
  7. package/dist/scripts/supervisor-entrypoint.js.map +1 -0
  8. package/dist/scripts/supervisor.js +148 -0
  9. package/dist/scripts/supervisor.js.map +1 -0
  10. package/dist/server/client/daemon-client-relay-e2ee-transport.d.ts +8 -0
  11. package/dist/server/client/daemon-client-relay-e2ee-transport.d.ts.map +1 -0
  12. package/dist/server/client/daemon-client-relay-e2ee-transport.js +161 -0
  13. package/dist/server/client/daemon-client-relay-e2ee-transport.js.map +1 -0
  14. package/dist/server/client/daemon-client-transport-types.d.ts +34 -0
  15. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -0
  16. package/dist/server/client/daemon-client-transport-types.js +2 -0
  17. package/dist/server/client/daemon-client-transport-types.js.map +1 -0
  18. package/dist/server/client/daemon-client-transport-utils.d.ts +9 -0
  19. package/dist/server/client/daemon-client-transport-utils.d.ts.map +1 -0
  20. package/dist/server/client/daemon-client-transport-utils.js +121 -0
  21. package/dist/server/client/daemon-client-transport-utils.js.map +1 -0
  22. package/dist/server/client/daemon-client-transport.d.ts +5 -0
  23. package/dist/server/client/daemon-client-transport.d.ts.map +1 -0
  24. package/dist/server/client/daemon-client-transport.js +4 -0
  25. package/dist/server/client/daemon-client-transport.js.map +1 -0
  26. package/dist/server/client/daemon-client-websocket-transport.d.ts +7 -0
  27. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -0
  28. package/dist/server/client/daemon-client-websocket-transport.js +119 -0
  29. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -0
  30. package/dist/server/client/daemon-client.d.ts +697 -0
  31. package/dist/server/client/daemon-client.d.ts.map +1 -0
  32. package/dist/server/client/daemon-client.js +2885 -0
  33. package/dist/server/client/daemon-client.js.map +1 -0
  34. package/dist/server/server/agent/activity-curator.d.ts +8 -0
  35. package/dist/server/server/agent/activity-curator.d.ts.map +1 -0
  36. package/dist/server/server/agent/activity-curator.js +243 -0
  37. package/dist/server/server/agent/activity-curator.js.map +1 -0
  38. package/dist/server/server/agent/agent-management-mcp.d.ts +41 -0
  39. package/dist/server/server/agent/agent-management-mcp.d.ts.map +1 -0
  40. package/dist/server/server/agent/agent-management-mcp.js +767 -0
  41. package/dist/server/server/agent/agent-management-mcp.js.map +1 -0
  42. package/dist/server/server/agent/agent-manager.d.ts +287 -0
  43. package/dist/server/server/agent/agent-manager.d.ts.map +1 -0
  44. package/dist/server/server/agent/agent-manager.js +1956 -0
  45. package/dist/server/server/agent/agent-manager.js.map +1 -0
  46. package/dist/server/server/agent/agent-metadata-generator.d.ts +29 -0
  47. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -0
  48. package/dist/server/server/agent/agent-metadata-generator.js +161 -0
  49. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -0
  50. package/dist/server/server/agent/agent-projections.d.ts +17 -0
  51. package/dist/server/server/agent/agent-projections.d.ts.map +1 -0
  52. package/dist/server/server/agent/agent-projections.js +280 -0
  53. package/dist/server/server/agent/agent-projections.js.map +1 -0
  54. package/dist/server/server/agent/agent-response-loop.d.ts +60 -0
  55. package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -0
  56. package/dist/server/server/agent/agent-response-loop.js +304 -0
  57. package/dist/server/server/agent/agent-response-loop.js.map +1 -0
  58. package/dist/server/server/agent/agent-sdk-types.d.ts +470 -0
  59. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -0
  60. package/dist/server/server/agent/agent-sdk-types.js +12 -0
  61. package/dist/server/server/agent/agent-sdk-types.js.map +1 -0
  62. package/dist/server/server/agent/agent-storage.d.ts +336 -0
  63. package/dist/server/server/agent/agent-storage.d.ts.map +1 -0
  64. package/dist/server/server/agent/agent-storage.js +304 -0
  65. package/dist/server/server/agent/agent-storage.js.map +1 -0
  66. package/dist/server/server/agent/agent-title-limits.d.ts +3 -0
  67. package/dist/server/server/agent/agent-title-limits.d.ts.map +1 -0
  68. package/dist/server/server/agent/agent-title-limits.js +3 -0
  69. package/dist/server/server/agent/agent-title-limits.js.map +1 -0
  70. package/dist/server/server/agent/audio-utils.d.ts +3 -0
  71. package/dist/server/server/agent/audio-utils.d.ts.map +1 -0
  72. package/dist/server/server/agent/audio-utils.js +19 -0
  73. package/dist/server/server/agent/audio-utils.js.map +1 -0
  74. package/dist/server/server/agent/dictation-debug.d.ts +13 -0
  75. package/dist/server/server/agent/dictation-debug.d.ts.map +1 -0
  76. package/dist/server/server/agent/dictation-debug.js +50 -0
  77. package/dist/server/server/agent/dictation-debug.js.map +1 -0
  78. package/dist/server/server/agent/llm-openai.d.ts +7 -0
  79. package/dist/server/server/agent/llm-openai.d.ts.map +1 -0
  80. package/dist/server/server/agent/llm-openai.js +8 -0
  81. package/dist/server/server/agent/llm-openai.js.map +1 -0
  82. package/dist/server/server/agent/mcp-server.d.ts +33 -0
  83. package/dist/server/server/agent/mcp-server.d.ts.map +1 -0
  84. package/dist/server/server/agent/mcp-server.js +1279 -0
  85. package/dist/server/server/agent/mcp-server.js.map +1 -0
  86. package/dist/server/server/agent/mcp-shared.d.ts +251 -0
  87. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -0
  88. package/dist/server/server/agent/mcp-shared.js +242 -0
  89. package/dist/server/server/agent/mcp-shared.js.map +1 -0
  90. package/dist/server/server/agent/model-resolver.d.ts +11 -0
  91. package/dist/server/server/agent/model-resolver.d.ts.map +1 -0
  92. package/dist/server/server/agent/model-resolver.js +21 -0
  93. package/dist/server/server/agent/model-resolver.js.map +1 -0
  94. package/dist/server/server/agent/orchestrator-instructions.d.ts +7 -0
  95. package/dist/server/server/agent/orchestrator-instructions.d.ts.map +1 -0
  96. package/dist/server/server/agent/orchestrator-instructions.js +51 -0
  97. package/dist/server/server/agent/orchestrator-instructions.js.map +1 -0
  98. package/dist/server/server/agent/orchestrator.d.ts +12 -0
  99. package/dist/server/server/agent/orchestrator.d.ts.map +1 -0
  100. package/dist/server/server/agent/orchestrator.js +12 -0
  101. package/dist/server/server/agent/orchestrator.js.map +1 -0
  102. package/dist/server/server/agent/pcm16-resampler.d.ts +14 -0
  103. package/dist/server/server/agent/pcm16-resampler.d.ts.map +1 -0
  104. package/dist/server/server/agent/pcm16-resampler.js +63 -0
  105. package/dist/server/server/agent/pcm16-resampler.js.map +1 -0
  106. package/dist/server/server/agent/provider-launch-config.d.ts +138 -0
  107. package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -0
  108. package/dist/server/server/agent/provider-launch-config.js +80 -0
  109. package/dist/server/server/agent/provider-launch-config.js.map +1 -0
  110. package/dist/server/server/agent/provider-manifest.d.ts +29 -0
  111. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -0
  112. package/dist/server/server/agent/provider-manifest.js +157 -0
  113. package/dist/server/server/agent/provider-manifest.js.map +1 -0
  114. package/dist/server/server/agent/provider-registry.d.ts +19 -0
  115. package/dist/server/server/agent/provider-registry.d.ts.map +1 -0
  116. package/dist/server/server/agent/provider-registry.js +58 -0
  117. package/dist/server/server/agent/provider-registry.js.map +1 -0
  118. package/dist/server/server/agent/provider-snapshot-manager.d.ts +27 -0
  119. package/dist/server/server/agent/provider-snapshot-manager.d.ts.map +1 -0
  120. package/dist/server/server/agent/provider-snapshot-manager.js +181 -0
  121. package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -0
  122. package/dist/server/server/agent/providers/acp-agent.d.ts +202 -0
  123. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -0
  124. package/dist/server/server/agent/providers/acp-agent.js +1650 -0
  125. package/dist/server/server/agent/providers/acp-agent.js.map +1 -0
  126. package/dist/server/server/agent/providers/claude/claude-models.d.ts +8 -0
  127. package/dist/server/server/agent/providers/claude/claude-models.d.ts.map +1 -0
  128. package/dist/server/server/agent/providers/claude/claude-models.js +63 -0
  129. package/dist/server/server/agent/providers/claude/claude-models.js.map +1 -0
  130. package/dist/server/server/agent/providers/claude/partial-json.d.ts +5 -0
  131. package/dist/server/server/agent/providers/claude/partial-json.d.ts.map +1 -0
  132. package/dist/server/server/agent/providers/claude/partial-json.js +306 -0
  133. package/dist/server/server/agent/providers/claude/partial-json.js.map +1 -0
  134. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +20 -0
  135. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -0
  136. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +230 -0
  137. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -0
  138. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +55 -0
  139. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -0
  140. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +267 -0
  141. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
  142. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts +3 -0
  143. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -0
  144. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +121 -0
  145. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -0
  146. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +16 -0
  147. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -0
  148. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +252 -0
  149. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -0
  150. package/dist/server/server/agent/providers/claude-agent.d.ts +44 -0
  151. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -0
  152. package/dist/server/server/agent/providers/claude-agent.js +3452 -0
  153. package/dist/server/server/agent/providers/claude-agent.js.map +1 -0
  154. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +12 -0
  155. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -0
  156. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js +104 -0
  157. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -0
  158. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +15 -0
  159. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -0
  160. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +762 -0
  161. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -0
  162. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +200 -0
  163. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -0
  164. package/dist/server/server/agent/providers/codex-app-server-agent.js +3474 -0
  165. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -0
  166. package/dist/server/server/agent/providers/codex-feature-definitions.d.ts +11 -0
  167. package/dist/server/server/agent/providers/codex-feature-definitions.d.ts.map +1 -0
  168. package/dist/server/server/agent/providers/codex-feature-definitions.js +45 -0
  169. package/dist/server/server/agent/providers/codex-feature-definitions.js.map +1 -0
  170. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts +9 -0
  171. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -0
  172. package/dist/server/server/agent/providers/codex-rollout-timeline.js +544 -0
  173. package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -0
  174. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +16 -0
  175. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts.map +1 -0
  176. package/dist/server/server/agent/providers/copilot-acp-agent.js +95 -0
  177. package/dist/server/server/agent/providers/copilot-acp-agent.js.map +1 -0
  178. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +17 -0
  179. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -0
  180. package/dist/server/server/agent/providers/diagnostic-utils.js +56 -0
  181. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -0
  182. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +3 -0
  183. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -0
  184. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +39 -0
  185. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -0
  186. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +13 -0
  187. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -0
  188. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +144 -0
  189. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -0
  190. package/dist/server/server/agent/providers/opencode-agent.d.ts +121 -0
  191. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -0
  192. package/dist/server/server/agent/providers/opencode-agent.js +1649 -0
  193. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -0
  194. package/dist/server/server/agent/providers/pi-acp-agent.d.ts +28 -0
  195. package/dist/server/server/agent/providers/pi-acp-agent.d.ts.map +1 -0
  196. package/dist/server/server/agent/providers/pi-acp-agent.js +302 -0
  197. package/dist/server/server/agent/providers/pi-acp-agent.js.map +1 -0
  198. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts +3 -0
  199. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts.map +1 -0
  200. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +57 -0
  201. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -0
  202. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +1745 -0
  203. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -0
  204. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +686 -0
  205. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -0
  206. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +18 -0
  207. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -0
  208. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +115 -0
  209. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -0
  210. package/dist/server/server/agent/recordings-debug.d.ts +3 -0
  211. package/dist/server/server/agent/recordings-debug.d.ts.map +1 -0
  212. package/dist/server/server/agent/recordings-debug.js +19 -0
  213. package/dist/server/server/agent/recordings-debug.js.map +1 -0
  214. package/dist/server/server/agent/stt-debug.d.ts +10 -0
  215. package/dist/server/server/agent/stt-debug.d.ts.map +1 -0
  216. package/dist/server/server/agent/stt-debug.js +33 -0
  217. package/dist/server/server/agent/stt-debug.js.map +1 -0
  218. package/dist/server/server/agent/stt-manager.d.ts +33 -0
  219. package/dist/server/server/agent/stt-manager.d.ts.map +1 -0
  220. package/dist/server/server/agent/stt-manager.js +232 -0
  221. package/dist/server/server/agent/stt-manager.js.map +1 -0
  222. package/dist/server/server/agent/timeline-append.d.ts +10 -0
  223. package/dist/server/server/agent/timeline-append.d.ts.map +1 -0
  224. package/dist/server/server/agent/timeline-append.js +27 -0
  225. package/dist/server/server/agent/timeline-append.js.map +1 -0
  226. package/dist/server/server/agent/timeline-projection.d.ts +39 -0
  227. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -0
  228. package/dist/server/server/agent/timeline-projection.js +215 -0
  229. package/dist/server/server/agent/timeline-projection.js.map +1 -0
  230. package/dist/server/server/agent/tool-name-normalization.d.ts +9 -0
  231. package/dist/server/server/agent/tool-name-normalization.d.ts.map +1 -0
  232. package/dist/server/server/agent/tool-name-normalization.js +82 -0
  233. package/dist/server/server/agent/tool-name-normalization.js.map +1 -0
  234. package/dist/server/server/agent/tts-debug.d.ts +8 -0
  235. package/dist/server/server/agent/tts-debug.d.ts.map +1 -0
  236. package/dist/server/server/agent/tts-debug.js +24 -0
  237. package/dist/server/server/agent/tts-debug.js.map +1 -0
  238. package/dist/server/server/agent/tts-manager.d.ts +41 -0
  239. package/dist/server/server/agent/tts-manager.d.ts.map +1 -0
  240. package/dist/server/server/agent/tts-manager.js +374 -0
  241. package/dist/server/server/agent/tts-manager.js.map +1 -0
  242. package/dist/server/server/agent/wait-for-agent-tracker.d.ts +15 -0
  243. package/dist/server/server/agent/wait-for-agent-tracker.d.ts.map +1 -0
  244. package/dist/server/server/agent/wait-for-agent-tracker.js +53 -0
  245. package/dist/server/server/agent/wait-for-agent-tracker.js.map +1 -0
  246. package/dist/server/server/agent-attention-policy.d.ts +20 -0
  247. package/dist/server/server/agent-attention-policy.d.ts.map +1 -0
  248. package/dist/server/server/agent-attention-policy.js +40 -0
  249. package/dist/server/server/agent-attention-policy.js.map +1 -0
  250. package/dist/server/server/allowed-hosts.d.ts +13 -0
  251. package/dist/server/server/allowed-hosts.d.ts.map +1 -0
  252. package/dist/server/server/allowed-hosts.js +94 -0
  253. package/dist/server/server/allowed-hosts.js.map +1 -0
  254. package/dist/server/server/bootstrap.d.ts +74 -0
  255. package/dist/server/server/bootstrap.d.ts.map +1 -0
  256. package/dist/server/server/bootstrap.js +537 -0
  257. package/dist/server/server/bootstrap.js.map +1 -0
  258. package/dist/server/server/chat/chat-mentions.d.ts +31 -0
  259. package/dist/server/server/chat/chat-mentions.d.ts.map +1 -0
  260. package/dist/server/server/chat/chat-mentions.js +71 -0
  261. package/dist/server/server/chat/chat-mentions.js.map +1 -0
  262. package/dist/server/server/chat/chat-rpc-schemas.d.ts +728 -0
  263. package/dist/server/server/chat/chat-rpc-schemas.d.ts.map +1 -0
  264. package/dist/server/server/chat/chat-rpc-schemas.js +103 -0
  265. package/dist/server/server/chat/chat-rpc-schemas.js.map +1 -0
  266. package/dist/server/server/chat/chat-service.d.ts +74 -0
  267. package/dist/server/server/chat/chat-service.d.ts.map +1 -0
  268. package/dist/server/server/chat/chat-service.js +330 -0
  269. package/dist/server/server/chat/chat-service.js.map +1 -0
  270. package/dist/server/server/chat/chat-types.d.ts +75 -0
  271. package/dist/server/server/chat/chat-types.d.ts.map +1 -0
  272. package/dist/server/server/chat/chat-types.js +22 -0
  273. package/dist/server/server/chat/chat-types.js.map +1 -0
  274. package/dist/server/server/checkout-diff-manager.d.ts +45 -0
  275. package/dist/server/server/checkout-diff-manager.d.ts.map +1 -0
  276. package/dist/server/server/checkout-diff-manager.js +374 -0
  277. package/dist/server/server/checkout-diff-manager.js.map +1 -0
  278. package/dist/server/server/checkout-git-utils.d.ts +9 -0
  279. package/dist/server/server/checkout-git-utils.d.ts.map +1 -0
  280. package/dist/server/server/checkout-git-utils.js +37 -0
  281. package/dist/server/server/checkout-git-utils.js.map +1 -0
  282. package/dist/server/server/client-message-id.d.ts +3 -0
  283. package/dist/server/server/client-message-id.d.ts.map +1 -0
  284. package/dist/server/server/client-message-id.js +12 -0
  285. package/dist/server/server/client-message-id.js.map +1 -0
  286. package/dist/server/server/config.d.ts +14 -0
  287. package/dist/server/server/config.d.ts.map +1 -0
  288. package/dist/server/server/config.js +96 -0
  289. package/dist/server/server/config.js.map +1 -0
  290. package/dist/server/server/connection-offer.d.ts +19 -0
  291. package/dist/server/server/connection-offer.d.ts.map +1 -0
  292. package/dist/server/server/connection-offer.js +59 -0
  293. package/dist/server/server/connection-offer.js.map +1 -0
  294. package/dist/server/server/daemon-config-store.d.ts +23 -0
  295. package/dist/server/server/daemon-config-store.d.ts.map +1 -0
  296. package/dist/server/server/daemon-config-store.js +114 -0
  297. package/dist/server/server/daemon-config-store.js.map +1 -0
  298. package/dist/server/server/daemon-keypair.d.ts +8 -0
  299. package/dist/server/server/daemon-keypair.d.ts.map +1 -0
  300. package/dist/server/server/daemon-keypair.js +40 -0
  301. package/dist/server/server/daemon-keypair.js.map +1 -0
  302. package/dist/server/server/daemon-version.d.ts +5 -0
  303. package/dist/server/server/daemon-version.d.ts.map +1 -0
  304. package/dist/server/server/daemon-version.js +22 -0
  305. package/dist/server/server/daemon-version.js.map +1 -0
  306. package/dist/server/server/dictation/dictation-stream-manager.d.ts +85 -0
  307. package/dist/server/server/dictation/dictation-stream-manager.d.ts.map +1 -0
  308. package/dist/server/server/dictation/dictation-stream-manager.js +571 -0
  309. package/dist/server/server/dictation/dictation-stream-manager.js.map +1 -0
  310. package/dist/server/server/editor-targets.d.ts +18 -0
  311. package/dist/server/server/editor-targets.d.ts.map +1 -0
  312. package/dist/server/server/editor-targets.js +113 -0
  313. package/dist/server/server/editor-targets.js.map +1 -0
  314. package/dist/server/server/exports.d.ts +19 -0
  315. package/dist/server/server/exports.d.ts.map +1 -0
  316. package/dist/server/server/exports.js +21 -0
  317. package/dist/server/server/exports.js.map +1 -0
  318. package/dist/server/server/file-download/token-store.d.ts +24 -0
  319. package/dist/server/server/file-download/token-store.d.ts.map +1 -0
  320. package/dist/server/server/file-download/token-store.js +40 -0
  321. package/dist/server/server/file-download/token-store.js.map +1 -0
  322. package/dist/server/server/file-explorer/service.d.ts +41 -0
  323. package/dist/server/server/file-explorer/service.d.ts.map +1 -0
  324. package/dist/server/server/file-explorer/service.js +194 -0
  325. package/dist/server/server/file-explorer/service.js.map +1 -0
  326. package/dist/server/server/index.d.ts +2 -0
  327. package/dist/server/server/index.d.ts.map +1 -0
  328. package/dist/server/server/index.js +176 -0
  329. package/dist/server/server/index.js.map +1 -0
  330. package/dist/server/server/json-utils.d.ts +11 -0
  331. package/dist/server/server/json-utils.d.ts.map +1 -0
  332. package/dist/server/server/json-utils.js +45 -0
  333. package/dist/server/server/json-utils.js.map +1 -0
  334. package/dist/server/server/logger.d.ts +33 -0
  335. package/dist/server/server/logger.d.ts.map +1 -0
  336. package/dist/server/server/logger.js +195 -0
  337. package/dist/server/server/logger.js.map +1 -0
  338. package/dist/server/server/loop/rpc-schemas.d.ts +2937 -0
  339. package/dist/server/server/loop/rpc-schemas.d.ts.map +1 -0
  340. package/dist/server/server/loop/rpc-schemas.js +159 -0
  341. package/dist/server/server/loop/rpc-schemas.js.map +1 -0
  342. package/dist/server/server/loop-service.d.ts +520 -0
  343. package/dist/server/server/loop-service.d.ts.map +1 -0
  344. package/dist/server/server/loop-service.js +739 -0
  345. package/dist/server/server/loop-service.js.map +1 -0
  346. package/dist/server/server/messages.d.ts +9 -0
  347. package/dist/server/server/messages.d.ts.map +1 -0
  348. package/dist/server/server/messages.js +29 -0
  349. package/dist/server/server/messages.js.map +1 -0
  350. package/dist/server/server/package-version.d.ts +13 -0
  351. package/dist/server/server/package-version.d.ts.map +1 -0
  352. package/dist/server/server/package-version.js +46 -0
  353. package/dist/server/server/package-version.js.map +1 -0
  354. package/dist/server/server/pairing-offer.d.ts +16 -0
  355. package/dist/server/server/pairing-offer.d.ts.map +1 -0
  356. package/dist/server/server/pairing-offer.js +45 -0
  357. package/dist/server/server/pairing-offer.js.map +1 -0
  358. package/dist/server/server/pairing-qr.d.ts +7 -0
  359. package/dist/server/server/pairing-qr.d.ts.map +1 -0
  360. package/dist/server/server/pairing-qr.js +45 -0
  361. package/dist/server/server/pairing-qr.js.map +1 -0
  362. package/dist/server/server/path-utils.d.ts +3 -0
  363. package/dist/server/server/path-utils.d.ts.map +1 -0
  364. package/dist/server/server/path-utils.js +20 -0
  365. package/dist/server/server/path-utils.js.map +1 -0
  366. package/dist/server/server/persisted-config.d.ts +625 -0
  367. package/dist/server/server/persisted-config.d.ts.map +1 -0
  368. package/dist/server/server/persisted-config.js +265 -0
  369. package/dist/server/server/persisted-config.js.map +1 -0
  370. package/dist/server/server/persistence-hooks.d.ts +24 -0
  371. package/dist/server/server/persistence-hooks.d.ts.map +1 -0
  372. package/dist/server/server/persistence-hooks.js +60 -0
  373. package/dist/server/server/persistence-hooks.js.map +1 -0
  374. package/dist/server/server/pid-lock.d.ts +29 -0
  375. package/dist/server/server/pid-lock.d.ts.map +1 -0
  376. package/dist/server/server/pid-lock.js +148 -0
  377. package/dist/server/server/pid-lock.js.map +1 -0
  378. package/dist/server/server/push/push-service.d.ts +22 -0
  379. package/dist/server/server/push/push-service.d.ts.map +1 -0
  380. package/dist/server/server/push/push-service.js +69 -0
  381. package/dist/server/server/push/push-service.js.map +1 -0
  382. package/dist/server/server/push/token-store.d.ts +18 -0
  383. package/dist/server/server/push/token-store.d.ts.map +1 -0
  384. package/dist/server/server/push/token-store.js +70 -0
  385. package/dist/server/server/push/token-store.js.map +1 -0
  386. package/dist/server/server/relay-transport.d.ts +23 -0
  387. package/dist/server/server/relay-transport.d.ts.map +1 -0
  388. package/dist/server/server/relay-transport.js +461 -0
  389. package/dist/server/server/relay-transport.js.map +1 -0
  390. package/dist/server/server/schedule/cron.d.ts +4 -0
  391. package/dist/server/server/schedule/cron.d.ts.map +1 -0
  392. package/dist/server/server/schedule/cron.js +103 -0
  393. package/dist/server/server/schedule/cron.js.map +1 -0
  394. package/dist/server/server/schedule/rpc-schemas.d.ts +2773 -0
  395. package/dist/server/server/schedule/rpc-schemas.d.ts.map +1 -0
  396. package/dist/server/server/schedule/rpc-schemas.js +112 -0
  397. package/dist/server/server/schedule/rpc-schemas.js.map +1 -0
  398. package/dist/server/server/schedule/service.d.ts +39 -0
  399. package/dist/server/server/schedule/service.d.ts.map +1 -0
  400. package/dist/server/server/schedule/service.js +410 -0
  401. package/dist/server/server/schedule/service.js.map +1 -0
  402. package/dist/server/server/schedule/store.d.ts +13 -0
  403. package/dist/server/server/schedule/store.d.ts.map +1 -0
  404. package/dist/server/server/schedule/store.js +56 -0
  405. package/dist/server/server/schedule/store.js.map +1 -0
  406. package/dist/server/server/schedule/types.d.ts +710 -0
  407. package/dist/server/server/schedule/types.d.ts.map +1 -0
  408. package/dist/server/server/schedule/types.js +73 -0
  409. package/dist/server/server/schedule/types.js.map +1 -0
  410. package/dist/server/server/seawork-home.d.ts +2 -0
  411. package/dist/server/server/seawork-home.d.ts.map +1 -0
  412. package/dist/server/server/seawork-home.js +19 -0
  413. package/dist/server/server/seawork-home.js.map +1 -0
  414. package/dist/server/server/server-id.d.ts +17 -0
  415. package/dist/server/server/server-id.d.ts.map +1 -0
  416. package/dist/server/server/server-id.js +63 -0
  417. package/dist/server/server/server-id.js.map +1 -0
  418. package/dist/server/server/session.d.ts +510 -0
  419. package/dist/server/server/session.d.ts.map +1 -0
  420. package/dist/server/server/session.js +6414 -0
  421. package/dist/server/server/session.js.map +1 -0
  422. package/dist/server/server/speech/audio.d.ts +10 -0
  423. package/dist/server/server/speech/audio.d.ts.map +1 -0
  424. package/dist/server/server/speech/audio.js +101 -0
  425. package/dist/server/server/speech/audio.js.map +1 -0
  426. package/dist/server/server/speech/provider-resolver.d.ts +3 -0
  427. package/dist/server/server/speech/provider-resolver.d.ts.map +1 -0
  428. package/dist/server/server/speech/provider-resolver.js +7 -0
  429. package/dist/server/server/speech/provider-resolver.js.map +1 -0
  430. package/dist/server/server/speech/providers/local/config.d.ts +25 -0
  431. package/dist/server/server/speech/providers/local/config.d.ts.map +1 -0
  432. package/dist/server/server/speech/providers/local/config.js +74 -0
  433. package/dist/server/server/speech/providers/local/config.js.map +1 -0
  434. package/dist/server/server/speech/providers/local/models.d.ts +11 -0
  435. package/dist/server/server/speech/providers/local/models.d.ts.map +1 -0
  436. package/dist/server/server/speech/providers/local/models.js +17 -0
  437. package/dist/server/server/speech/providers/local/models.js.map +1 -0
  438. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts +24 -0
  439. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -0
  440. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +436 -0
  441. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -0
  442. package/dist/server/server/speech/providers/local/runtime.d.ts +31 -0
  443. package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -0
  444. package/dist/server/server/speech/providers/local/runtime.js +247 -0
  445. package/dist/server/server/speech/providers/local/runtime.js.map +1 -0
  446. package/dist/server/server/speech/providers/local/sherpa/assets/silero_vad.onnx +0 -0
  447. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +117 -0
  448. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -0
  449. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +166 -0
  450. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -0
  451. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +15 -0
  452. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -0
  453. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +165 -0
  454. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -0
  455. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +28 -0
  456. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -0
  457. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +73 -0
  458. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -0
  459. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts +37 -0
  460. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -0
  461. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +84 -0
  462. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -0
  463. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts +7 -0
  464. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts.map +1 -0
  465. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +11 -0
  466. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +1 -0
  467. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +9 -0
  468. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts.map +1 -0
  469. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +102 -0
  470. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -0
  471. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts +28 -0
  472. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -0
  473. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +135 -0
  474. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -0
  475. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +21 -0
  476. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -0
  477. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +131 -0
  478. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -0
  479. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts +23 -0
  480. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -0
  481. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +110 -0
  482. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -0
  483. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +18 -0
  484. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts.map +1 -0
  485. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  486. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.js.map +1 -0
  487. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts +23 -0
  488. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -0
  489. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +138 -0
  490. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -0
  491. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +21 -0
  492. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -0
  493. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +108 -0
  494. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -0
  495. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts +19 -0
  496. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts.map +1 -0
  497. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js +49 -0
  498. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js.map +1 -0
  499. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts +38 -0
  500. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts.map +1 -0
  501. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js +176 -0
  502. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js.map +1 -0
  503. package/dist/server/server/speech/providers/openai/config.d.ts +22 -0
  504. package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -0
  505. package/dist/server/server/speech/providers/openai/config.js +80 -0
  506. package/dist/server/server/speech/providers/openai/config.js.map +1 -0
  507. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts +42 -0
  508. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -0
  509. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +168 -0
  510. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -0
  511. package/dist/server/server/speech/providers/openai/runtime.d.ts +29 -0
  512. package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -0
  513. package/dist/server/server/speech/providers/openai/runtime.js +112 -0
  514. package/dist/server/server/speech/providers/openai/runtime.js.map +1 -0
  515. package/dist/server/server/speech/providers/openai/stt.d.ts +22 -0
  516. package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -0
  517. package/dist/server/server/speech/providers/openai/stt.js +206 -0
  518. package/dist/server/server/speech/providers/openai/stt.js.map +1 -0
  519. package/dist/server/server/speech/providers/openai/tts.d.ts +18 -0
  520. package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -0
  521. package/dist/server/server/speech/providers/openai/tts.js +46 -0
  522. package/dist/server/server/speech/providers/openai/tts.js.map +1 -0
  523. package/dist/server/server/speech/speech-config-resolver.d.ts +11 -0
  524. package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -0
  525. package/dist/server/server/speech/speech-config-resolver.js +104 -0
  526. package/dist/server/server/speech/speech-config-resolver.js.map +1 -0
  527. package/dist/server/server/speech/speech-provider.d.ts +59 -0
  528. package/dist/server/server/speech/speech-provider.d.ts.map +1 -0
  529. package/dist/server/server/speech/speech-provider.js +2 -0
  530. package/dist/server/server/speech/speech-provider.js.map +1 -0
  531. package/dist/server/server/speech/speech-runtime.d.ts +43 -0
  532. package/dist/server/server/speech/speech-runtime.d.ts.map +1 -0
  533. package/dist/server/server/speech/speech-runtime.js +560 -0
  534. package/dist/server/server/speech/speech-runtime.js.map +1 -0
  535. package/dist/server/server/speech/speech-types.d.ts +24 -0
  536. package/dist/server/server/speech/speech-types.d.ts.map +1 -0
  537. package/dist/server/server/speech/speech-types.js +8 -0
  538. package/dist/server/server/speech/speech-types.js.map +1 -0
  539. package/dist/server/server/speech/turn-detection-provider.d.ts +23 -0
  540. package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -0
  541. package/dist/server/server/speech/turn-detection-provider.js +2 -0
  542. package/dist/server/server/speech/turn-detection-provider.js.map +1 -0
  543. package/dist/server/server/types.d.ts +5 -0
  544. package/dist/server/server/types.d.ts.map +1 -0
  545. package/dist/server/server/types.js +3 -0
  546. package/dist/server/server/types.js.map +1 -0
  547. package/dist/server/server/utils/diff-highlighter.d.ts +60 -0
  548. package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -0
  549. package/dist/server/server/utils/diff-highlighter.js +257 -0
  550. package/dist/server/server/utils/diff-highlighter.js.map +1 -0
  551. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts +16 -0
  552. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts.map +1 -0
  553. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js +35 -0
  554. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js.map +1 -0
  555. package/dist/server/server/voice/voice-turn-controller.d.ts +34 -0
  556. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -0
  557. package/dist/server/server/voice/voice-turn-controller.js +160 -0
  558. package/dist/server/server/voice/voice-turn-controller.js.map +1 -0
  559. package/dist/server/server/voice-config.d.ts +15 -0
  560. package/dist/server/server/voice-config.d.ts.map +1 -0
  561. package/dist/server/server/voice-config.js +54 -0
  562. package/dist/server/server/voice-config.js.map +1 -0
  563. package/dist/server/server/voice-permission-policy.d.ts +4 -0
  564. package/dist/server/server/voice-permission-policy.d.ts.map +1 -0
  565. package/dist/server/server/voice-permission-policy.js +13 -0
  566. package/dist/server/server/voice-permission-policy.js.map +1 -0
  567. package/dist/server/server/voice-types.d.ts +12 -0
  568. package/dist/server/server/voice-types.d.ts.map +1 -0
  569. package/dist/server/server/voice-types.js +2 -0
  570. package/dist/server/server/voice-types.js.map +1 -0
  571. package/dist/server/server/websocket-server.d.ts +122 -0
  572. package/dist/server/server/websocket-server.d.ts.map +1 -0
  573. package/dist/server/server/websocket-server.js +1092 -0
  574. package/dist/server/server/websocket-server.js.map +1 -0
  575. package/dist/server/server/workspace-git-service.d.ts +108 -0
  576. package/dist/server/server/workspace-git-service.d.ts.map +1 -0
  577. package/dist/server/server/workspace-git-service.js +404 -0
  578. package/dist/server/server/workspace-git-service.js.map +1 -0
  579. package/dist/server/server/workspace-registry-bootstrap.d.ts +11 -0
  580. package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -0
  581. package/dist/server/server/workspace-registry-bootstrap.js +100 -0
  582. package/dist/server/server/workspace-registry-bootstrap.js.map +1 -0
  583. package/dist/server/server/workspace-registry-model.d.ts +33 -0
  584. package/dist/server/server/workspace-registry-model.d.ts.map +1 -0
  585. package/dist/server/server/workspace-registry-model.js +167 -0
  586. package/dist/server/server/workspace-registry-model.js.map +1 -0
  587. package/dist/server/server/workspace-registry.d.ts +130 -0
  588. package/dist/server/server/workspace-registry.d.ts.map +1 -0
  589. package/dist/server/server/workspace-registry.js +151 -0
  590. package/dist/server/server/workspace-registry.js.map +1 -0
  591. package/dist/server/server/worktree-bootstrap.d.ts +29 -0
  592. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -0
  593. package/dist/server/server/worktree-bootstrap.js +508 -0
  594. package/dist/server/server/worktree-bootstrap.js.map +1 -0
  595. package/dist/server/server/worktree-session.d.ts +131 -0
  596. package/dist/server/server/worktree-session.d.ts.map +1 -0
  597. package/dist/server/server/worktree-session.js +487 -0
  598. package/dist/server/server/worktree-session.js.map +1 -0
  599. package/dist/server/shared/agent-attention-notification.d.ts +40 -0
  600. package/dist/server/shared/agent-attention-notification.d.ts.map +1 -0
  601. package/dist/server/shared/agent-attention-notification.js +130 -0
  602. package/dist/server/shared/agent-attention-notification.js.map +1 -0
  603. package/dist/server/shared/agent-lifecycle.d.ts +3 -0
  604. package/dist/server/shared/agent-lifecycle.d.ts.map +1 -0
  605. package/dist/server/shared/agent-lifecycle.js +8 -0
  606. package/dist/server/shared/agent-lifecycle.js.map +1 -0
  607. package/dist/server/shared/connection-offer.d.ts +62 -0
  608. package/dist/server/shared/connection-offer.d.ts.map +1 -0
  609. package/dist/server/shared/connection-offer.js +17 -0
  610. package/dist/server/shared/connection-offer.js.map +1 -0
  611. package/dist/server/shared/daemon-endpoints.d.ts +28 -0
  612. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -0
  613. package/dist/server/shared/daemon-endpoints.js +122 -0
  614. package/dist/server/shared/daemon-endpoints.js.map +1 -0
  615. package/dist/server/shared/literal-union.d.ts +2 -0
  616. package/dist/server/shared/literal-union.d.ts.map +1 -0
  617. package/dist/server/shared/literal-union.js +2 -0
  618. package/dist/server/shared/literal-union.js.map +1 -0
  619. package/dist/server/shared/messages.d.ts +81816 -0
  620. package/dist/server/shared/messages.d.ts.map +1 -0
  621. package/dist/server/shared/messages.js +2553 -0
  622. package/dist/server/shared/messages.js.map +1 -0
  623. package/dist/server/shared/path-utils.d.ts +2 -0
  624. package/dist/server/shared/path-utils.d.ts.map +1 -0
  625. package/dist/server/shared/path-utils.js +16 -0
  626. package/dist/server/shared/path-utils.js.map +1 -0
  627. package/dist/server/shared/terminal-stream-protocol.d.ts +36 -0
  628. package/dist/server/shared/terminal-stream-protocol.d.ts.map +1 -0
  629. package/dist/server/shared/terminal-stream-protocol.js +99 -0
  630. package/dist/server/shared/terminal-stream-protocol.js.map +1 -0
  631. package/dist/server/shared/tool-call-display.d.ts +11 -0
  632. package/dist/server/shared/tool-call-display.d.ts.map +1 -0
  633. package/dist/server/shared/tool-call-display.js +133 -0
  634. package/dist/server/shared/tool-call-display.js.map +1 -0
  635. package/dist/server/terminal/terminal-manager.d.ts +30 -0
  636. package/dist/server/terminal/terminal-manager.d.ts.map +1 -0
  637. package/dist/server/terminal/terminal-manager.js +136 -0
  638. package/dist/server/terminal/terminal-manager.js.map +1 -0
  639. package/dist/server/terminal/terminal.d.ts +68 -0
  640. package/dist/server/terminal/terminal.d.ts.map +1 -0
  641. package/dist/server/terminal/terminal.js +384 -0
  642. package/dist/server/terminal/terminal.js.map +1 -0
  643. package/dist/server/utils/checkout-git.d.ts +180 -0
  644. package/dist/server/utils/checkout-git.d.ts.map +1 -0
  645. package/dist/server/utils/checkout-git.js +1621 -0
  646. package/dist/server/utils/checkout-git.js.map +1 -0
  647. package/dist/server/utils/directory-suggestions.d.ts +24 -0
  648. package/dist/server/utils/directory-suggestions.d.ts.map +1 -0
  649. package/dist/server/utils/directory-suggestions.js +671 -0
  650. package/dist/server/utils/directory-suggestions.js.map +1 -0
  651. package/dist/server/utils/executable.d.ts +33 -0
  652. package/dist/server/utils/executable.d.ts.map +1 -0
  653. package/dist/server/utils/executable.js +134 -0
  654. package/dist/server/utils/executable.js.map +1 -0
  655. package/dist/server/utils/path.d.ts +5 -0
  656. package/dist/server/utils/path.d.ts.map +1 -0
  657. package/dist/server/utils/path.js +15 -0
  658. package/dist/server/utils/path.js.map +1 -0
  659. package/dist/server/utils/project-icon.d.ts +39 -0
  660. package/dist/server/utils/project-icon.d.ts.map +1 -0
  661. package/dist/server/utils/project-icon.js +389 -0
  662. package/dist/server/utils/project-icon.js.map +1 -0
  663. package/dist/server/utils/spawn.d.ts +13 -0
  664. package/dist/server/utils/spawn.d.ts.map +1 -0
  665. package/dist/server/utils/spawn.js +33 -0
  666. package/dist/server/utils/spawn.js.map +1 -0
  667. package/dist/server/utils/worktree-metadata.d.ts +47 -0
  668. package/dist/server/utils/worktree-metadata.d.ts.map +1 -0
  669. package/dist/server/utils/worktree-metadata.js +116 -0
  670. package/dist/server/utils/worktree-metadata.js.map +1 -0
  671. package/dist/server/utils/worktree.d.ts +144 -0
  672. package/dist/server/utils/worktree.d.ts.map +1 -0
  673. package/dist/server/utils/worktree.js +745 -0
  674. package/dist/server/utils/worktree.js.map +1 -0
  675. package/dist/src/server/pid-lock.js +148 -0
  676. package/dist/src/server/pid-lock.js.map +1 -0
  677. package/dist/src/server/seawork-home.js +19 -0
  678. package/dist/src/server/seawork-home.js.map +1 -0
  679. package/dist/src/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  680. package/dist/src/server/speech/providers/local/sherpa/sherpa-runtime-env.js.map +1 -0
  681. package/package.json +117 -0
  682. package/src/server/speech/providers/local/sherpa/assets/silero_vad.onnx +0 -0
@@ -0,0 +1,2885 @@
1
+ import { AgentCreateFailedStatusPayloadSchema, AgentCreatedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, AgentResumedStatusPayloadSchema, parseServerInfoStatusPayload, RestartRequestedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, SessionInboundMessageSchema, WSOutboundMessageSchema, } from "../shared/messages.js";
2
+ import { isRelayClientWebSocketUrl } from "../shared/daemon-endpoints.js";
3
+ import { asUint8Array, decodeTerminalSnapshotPayload, decodeTerminalStreamFrame, encodeTerminalResizePayload, encodeTerminalStreamFrame, TerminalStreamOpcode, } from "../shared/terminal-stream-protocol.js";
4
+ import { createRelayE2eeTransportFactory, createWebSocketTransportFactory, decodeMessageData, defaultWebSocketFactory, describeTransportClose, describeTransportError, encodeUtf8String, } from "./daemon-client-transport.js";
5
+ const consoleLogger = {
6
+ debug: () => { },
7
+ info: (obj, msg) => console.info(msg, obj),
8
+ warn: (obj, msg) => console.warn(msg, obj),
9
+ error: (obj, msg) => console.error(msg, obj),
10
+ };
11
+ class DaemonRpcError extends Error {
12
+ constructor(params) {
13
+ const parts = [params.error];
14
+ if (params.requestType)
15
+ parts.push(`requestType=${params.requestType}`);
16
+ if (params.code)
17
+ parts.push(`code=${params.code}`);
18
+ super(parts.join(" "));
19
+ this.name = "DaemonRpcError";
20
+ this.requestId = params.requestId;
21
+ this.requestType = params.requestType;
22
+ this.code = params.code;
23
+ }
24
+ }
25
+ const DEFAULT_RECONNECT_BASE_DELAY_MS = 1500;
26
+ const DEFAULT_RECONNECT_MAX_DELAY_MS = 30000;
27
+ const DEFAULT_CONNECT_TIMEOUT_MS = 15000;
28
+ /** Default timeout for waiting for connection before sending queued messages */
29
+ const DEFAULT_SEND_QUEUE_TIMEOUT_MS = 10000;
30
+ const DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS = 15000;
31
+ const DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
32
+ const DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS = 5000;
33
+ function isWaiterTimeoutError(error) {
34
+ return error instanceof Error && error.message.startsWith("Timeout waiting for message");
35
+ }
36
+ function normalizeClientId(value) {
37
+ if (typeof value !== "string") {
38
+ return null;
39
+ }
40
+ const trimmed = value.trim();
41
+ return trimmed.length > 0 ? trimmed : null;
42
+ }
43
+ function hashForLog(value) {
44
+ let hash = 0;
45
+ for (let index = 0; index < value.length; index += 1) {
46
+ hash = (hash * 31 + value.charCodeAt(index)) | 0;
47
+ }
48
+ return `h_${Math.abs(hash).toString(16)}`;
49
+ }
50
+ function toReasonCode(reason) {
51
+ if (!reason) {
52
+ return null;
53
+ }
54
+ const normalized = reason.toLowerCase();
55
+ if (normalized.includes("timed out")) {
56
+ return "connect_timeout";
57
+ }
58
+ if (normalized.includes("disposed")) {
59
+ return "disposed";
60
+ }
61
+ if (normalized.includes("client closed")) {
62
+ return "client_closed";
63
+ }
64
+ if (normalized.includes("transport")) {
65
+ return "transport_error";
66
+ }
67
+ if (normalized.includes("failed to connect")) {
68
+ return "connect_failed";
69
+ }
70
+ return "unknown";
71
+ }
72
+ export class DaemonClient {
73
+ constructor(config) {
74
+ this.config = config;
75
+ this.transport = null;
76
+ this.transportCleanup = [];
77
+ this.rawMessageListeners = new Set();
78
+ this.messageHandlers = new Map();
79
+ this.eventListeners = new Set();
80
+ this.waiters = new Set();
81
+ this.checkoutStatusInFlight = new Map();
82
+ this.connectionListeners = new Set();
83
+ this.reconnectTimeout = null;
84
+ this.connectTimeout = null;
85
+ this.pendingGenericTransportErrorTimeout = null;
86
+ this.reconnectAttempt = 0;
87
+ this.shouldReconnect = true;
88
+ this.connectPromise = null;
89
+ this.connectResolve = null;
90
+ this.connectReject = null;
91
+ this.lastErrorValue = null;
92
+ this.connectionState = { status: "idle" };
93
+ this.checkoutDiffSubscriptions = new Map();
94
+ this.terminalDirectorySubscriptions = new Set();
95
+ this.terminalSlots = new Map();
96
+ this.slotTerminals = new Map();
97
+ this.terminalStreamListeners = new Set();
98
+ this.pendingSendQueue = [];
99
+ this.lastServerInfoMessage = null;
100
+ this.logger = config.logger ?? consoleLogger;
101
+ this.logConnectionPath = isRelayClientWebSocketUrl(this.config.url) ? "relay" : "direct";
102
+ let parsedUrlForLog = null;
103
+ try {
104
+ parsedUrlForLog = new URL(this.config.url);
105
+ }
106
+ catch {
107
+ parsedUrlForLog = null;
108
+ }
109
+ const parsedServerIdForLog = normalizeClientId(parsedUrlForLog?.searchParams.get("serverId"));
110
+ this.logServerId = parsedServerIdForLog ?? parsedUrlForLog?.host ?? null;
111
+ const resolvedClientId = normalizeClientId(this.config.clientId);
112
+ if (!resolvedClientId) {
113
+ throw new Error("Daemon client requires a non-empty clientId");
114
+ }
115
+ this.config.clientId = resolvedClientId;
116
+ this.logClientIdHash = hashForLog(resolvedClientId);
117
+ this.logGeneration =
118
+ typeof this.config.runtimeGeneration === "number" &&
119
+ Number.isFinite(this.config.runtimeGeneration)
120
+ ? this.config.runtimeGeneration
121
+ : null;
122
+ }
123
+ // ============================================================================
124
+ // Connection
125
+ // ============================================================================
126
+ async connect() {
127
+ if (this.connectionState.status === "disposed") {
128
+ throw new Error("Daemon client is disposed");
129
+ }
130
+ if (this.connectionState.status === "connected") {
131
+ return;
132
+ }
133
+ if (this.connectPromise) {
134
+ return this.connectPromise;
135
+ }
136
+ this.shouldReconnect = true;
137
+ this.connectPromise = new Promise((resolve, reject) => {
138
+ this.connectResolve = resolve;
139
+ this.connectReject = reject;
140
+ this.attemptConnect();
141
+ });
142
+ return this.connectPromise;
143
+ }
144
+ attemptConnect() {
145
+ if (this.connectionState.status === "disposed") {
146
+ this.rejectConnect(new Error("Daemon client is disposed"));
147
+ return;
148
+ }
149
+ if (!this.shouldReconnect) {
150
+ this.rejectConnect(new Error("Daemon client is closed"));
151
+ return;
152
+ }
153
+ if (this.connectionState.status === "connecting") {
154
+ return;
155
+ }
156
+ const headers = {};
157
+ if (this.config.authHeader) {
158
+ headers["Authorization"] = this.config.authHeader;
159
+ }
160
+ try {
161
+ // Reconnect can overlap with browser close/error delivery ordering.
162
+ // Always dispose previous transport before constructing the next one.
163
+ this.disposeTransport();
164
+ const baseTransportFactory = this.config.transportFactory ??
165
+ createWebSocketTransportFactory(this.config.webSocketFactory ?? defaultWebSocketFactory);
166
+ const shouldUseRelayE2ee = this.config.e2ee?.enabled === true && isRelayClientWebSocketUrl(this.config.url);
167
+ let transportFactory = baseTransportFactory;
168
+ if (shouldUseRelayE2ee) {
169
+ const daemonPublicKeyB64 = this.config.e2ee?.daemonPublicKeyB64;
170
+ if (!daemonPublicKeyB64) {
171
+ throw new Error("daemonPublicKeyB64 is required for relay E2EE");
172
+ }
173
+ transportFactory = createRelayE2eeTransportFactory({
174
+ baseFactory: baseTransportFactory,
175
+ daemonPublicKeyB64,
176
+ logger: this.logger,
177
+ });
178
+ }
179
+ const transportUrl = this.resolveTransportUrlForAttempt();
180
+ const transport = transportFactory({ url: transportUrl, headers });
181
+ this.transport = transport;
182
+ this.lastServerInfoMessage = null;
183
+ this.updateConnectionState({
184
+ status: "connecting",
185
+ attempt: this.reconnectAttempt,
186
+ }, { event: "CONNECT_REQUEST" });
187
+ this.resetConnectTimeout();
188
+ const timeoutMs = Math.max(1, this.config.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS);
189
+ this.connectTimeout = setTimeout(() => {
190
+ if (this.connectionState.status !== "connecting") {
191
+ return;
192
+ }
193
+ this.lastErrorValue = "Connection timed out";
194
+ this.disposeTransport(1001, "Connection timed out");
195
+ this.scheduleReconnect({
196
+ reason: "Connection timed out",
197
+ event: "CONNECT_TIMEOUT",
198
+ reasonCode: "connect_timeout",
199
+ });
200
+ }, timeoutMs);
201
+ this.transportCleanup = [
202
+ transport.onOpen(() => {
203
+ if (this.pendingGenericTransportErrorTimeout) {
204
+ clearTimeout(this.pendingGenericTransportErrorTimeout);
205
+ this.pendingGenericTransportErrorTimeout = null;
206
+ }
207
+ this.lastErrorValue = null;
208
+ this.sendHelloMessage();
209
+ }),
210
+ transport.onClose((event) => {
211
+ this.resetConnectTimeout();
212
+ if (this.pendingGenericTransportErrorTimeout) {
213
+ clearTimeout(this.pendingGenericTransportErrorTimeout);
214
+ this.pendingGenericTransportErrorTimeout = null;
215
+ }
216
+ const reason = describeTransportClose(event);
217
+ if (reason) {
218
+ this.lastErrorValue = reason;
219
+ }
220
+ this.scheduleReconnect({
221
+ reason,
222
+ event: "TRANSPORT_CLOSE",
223
+ reasonCode: "transport_closed",
224
+ });
225
+ }),
226
+ transport.onError((event) => {
227
+ this.resetConnectTimeout();
228
+ const reason = describeTransportError(event);
229
+ const isGeneric = reason === "Transport error";
230
+ // Browser WebSocket.onerror often provides no useful details and is followed
231
+ // by a close event (often with code 1006). Prefer surfacing the close details
232
+ // instead of immediately disconnecting with a generic "Transport error".
233
+ if (isGeneric) {
234
+ this.lastErrorValue ?? (this.lastErrorValue = reason);
235
+ if (!this.pendingGenericTransportErrorTimeout) {
236
+ this.pendingGenericTransportErrorTimeout = setTimeout(() => {
237
+ this.pendingGenericTransportErrorTimeout = null;
238
+ if (this.connectionState.status === "connected" ||
239
+ this.connectionState.status === "connecting") {
240
+ this.lastErrorValue = reason;
241
+ this.scheduleReconnect({
242
+ reason,
243
+ event: "TRANSPORT_ERROR",
244
+ reasonCode: "transport_error",
245
+ });
246
+ }
247
+ }, 250);
248
+ }
249
+ return;
250
+ }
251
+ if (this.pendingGenericTransportErrorTimeout) {
252
+ clearTimeout(this.pendingGenericTransportErrorTimeout);
253
+ this.pendingGenericTransportErrorTimeout = null;
254
+ }
255
+ this.lastErrorValue = reason;
256
+ this.scheduleReconnect({
257
+ reason,
258
+ event: "TRANSPORT_ERROR",
259
+ reasonCode: "transport_error",
260
+ });
261
+ }),
262
+ transport.onMessage((data) => this.handleTransportMessage(data)),
263
+ ];
264
+ }
265
+ catch (error) {
266
+ this.resetConnectTimeout();
267
+ const message = error instanceof Error ? error.message : "Failed to connect";
268
+ this.lastErrorValue = message;
269
+ this.scheduleReconnect({
270
+ reason: message,
271
+ event: "CONNECT_FAILED",
272
+ reasonCode: "connect_failed",
273
+ });
274
+ this.rejectConnect(error instanceof Error ? error : new Error(message));
275
+ }
276
+ }
277
+ resolveConnect() {
278
+ if (this.connectResolve) {
279
+ this.connectResolve();
280
+ }
281
+ this.connectPromise = null;
282
+ this.connectResolve = null;
283
+ this.connectReject = null;
284
+ }
285
+ rejectConnect(error) {
286
+ if (this.connectReject) {
287
+ this.connectReject(error);
288
+ }
289
+ this.connectPromise = null;
290
+ this.connectResolve = null;
291
+ this.connectReject = null;
292
+ }
293
+ async close() {
294
+ if (this.connectionState.status === "disposed") {
295
+ return;
296
+ }
297
+ this.shouldReconnect = false;
298
+ this.connectPromise = null;
299
+ this.connectResolve = null;
300
+ this.connectReject = null;
301
+ if (this.reconnectTimeout) {
302
+ clearTimeout(this.reconnectTimeout);
303
+ this.reconnectTimeout = null;
304
+ }
305
+ this.resetConnectTimeout();
306
+ this.disposeTransport(1000, "Client closed");
307
+ this.clearWaiters(new Error("Daemon client closed"));
308
+ this.rejectPendingSendQueue(new Error("Daemon client closed"));
309
+ this.clearTerminalSlots();
310
+ this.lastServerInfoMessage = null;
311
+ this.updateConnectionState({ status: "disposed" }, { event: "DISPOSE", reason: "Client closed", reasonCode: "disposed" });
312
+ }
313
+ ensureConnected() {
314
+ if (this.connectionState.status === "disposed") {
315
+ return;
316
+ }
317
+ if (!this.shouldReconnect) {
318
+ this.shouldReconnect = true;
319
+ }
320
+ if (this.connectionState.status === "connected" ||
321
+ this.connectionState.status === "connecting") {
322
+ return;
323
+ }
324
+ void this.connect();
325
+ }
326
+ getConnectionState() {
327
+ return this.connectionState;
328
+ }
329
+ subscribeConnectionStatus(listener) {
330
+ this.connectionListeners.add(listener);
331
+ listener(this.connectionState);
332
+ return () => {
333
+ this.connectionListeners.delete(listener);
334
+ };
335
+ }
336
+ get isConnected() {
337
+ return this.connectionState.status === "connected";
338
+ }
339
+ get isConnecting() {
340
+ return this.connectionState.status === "connecting";
341
+ }
342
+ get lastError() {
343
+ return this.lastErrorValue;
344
+ }
345
+ // ============================================================================
346
+ // Message Subscription
347
+ // ============================================================================
348
+ subscribe(handler) {
349
+ this.eventListeners.add(handler);
350
+ return () => this.eventListeners.delete(handler);
351
+ }
352
+ subscribeRawMessages(handler) {
353
+ this.rawMessageListeners.add(handler);
354
+ return () => {
355
+ this.rawMessageListeners.delete(handler);
356
+ };
357
+ }
358
+ on(arg1, arg2) {
359
+ if (typeof arg1 === "function") {
360
+ return this.subscribe(arg1);
361
+ }
362
+ const type = arg1;
363
+ const handler = arg2;
364
+ if (!this.messageHandlers.has(type)) {
365
+ this.messageHandlers.set(type, new Set());
366
+ }
367
+ this.messageHandlers.get(type).add(handler);
368
+ return () => {
369
+ const handlers = this.messageHandlers.get(type);
370
+ if (!handlers) {
371
+ return;
372
+ }
373
+ handlers.delete(handler);
374
+ if (handlers.size === 0) {
375
+ this.messageHandlers.delete(type);
376
+ }
377
+ };
378
+ }
379
+ // ============================================================================
380
+ // Core Send Helpers
381
+ // ============================================================================
382
+ /**
383
+ * Send a session message. For fire-and-forget messages (heartbeats, etc.),
384
+ * failures are suppressed if `suppressSendErrors` is configured.
385
+ * For RPC methods that wait for responses, use `sendSessionMessageOrThrow` instead.
386
+ */
387
+ sendSessionMessage(message) {
388
+ if (!this.transport || this.connectionState.status !== "connected") {
389
+ if (this.config.suppressSendErrors) {
390
+ return;
391
+ }
392
+ throw new Error(`Transport not connected (status: ${this.connectionState.status})`);
393
+ }
394
+ const payload = SessionInboundMessageSchema.parse(message);
395
+ try {
396
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
397
+ }
398
+ catch (error) {
399
+ if (this.config.suppressSendErrors) {
400
+ return;
401
+ }
402
+ throw error instanceof Error ? error : new Error(String(error));
403
+ }
404
+ }
405
+ sendBinaryFrame(frame) {
406
+ if (!this.transport || this.connectionState.status !== "connected") {
407
+ if (this.config.suppressSendErrors) {
408
+ return;
409
+ }
410
+ throw new Error(`Transport not connected (status: ${this.connectionState.status})`);
411
+ }
412
+ try {
413
+ this.transport.send(frame);
414
+ }
415
+ catch (error) {
416
+ if (this.config.suppressSendErrors) {
417
+ return;
418
+ }
419
+ throw error instanceof Error ? error : new Error(String(error));
420
+ }
421
+ }
422
+ /**
423
+ * Send a session message for RPC methods that create waiters.
424
+ * If the connection is still being established ("connecting"), the message
425
+ * is queued and will be sent once connected (or rejected after timeout).
426
+ * This prevents waiters from hanging forever when called during connection.
427
+ */
428
+ sendSessionMessageOrThrow(message) {
429
+ const status = this.connectionState.status;
430
+ // If connected, send immediately
431
+ if (this.transport && status === "connected") {
432
+ const payload = SessionInboundMessageSchema.parse(message);
433
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
434
+ return Promise.resolve();
435
+ }
436
+ // If connecting, queue the message to be sent once connected
437
+ if (status === "connecting") {
438
+ return new Promise((resolve, reject) => {
439
+ const timeoutHandle = setTimeout(() => {
440
+ // Remove from queue
441
+ const idx = this.pendingSendQueue.findIndex((p) => p.resolve === resolve);
442
+ if (idx !== -1) {
443
+ this.pendingSendQueue.splice(idx, 1);
444
+ }
445
+ reject(new Error(`Timed out waiting for connection to send message`));
446
+ }, DEFAULT_SEND_QUEUE_TIMEOUT_MS);
447
+ this.pendingSendQueue.push({ message, resolve, reject, timeoutHandle });
448
+ });
449
+ }
450
+ // Not connected and not connecting - fail immediately
451
+ return Promise.reject(new Error(`Transport not connected (status: ${status})`));
452
+ }
453
+ /**
454
+ * Flush pending send queue - called when connection is established.
455
+ */
456
+ flushPendingSendQueue() {
457
+ const queue = this.pendingSendQueue;
458
+ this.pendingSendQueue = [];
459
+ for (const pending of queue) {
460
+ clearTimeout(pending.timeoutHandle);
461
+ try {
462
+ if (this.transport && this.connectionState.status === "connected") {
463
+ const payload = SessionInboundMessageSchema.parse(pending.message);
464
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
465
+ pending.resolve();
466
+ }
467
+ else {
468
+ pending.reject(new Error("Connection lost before message could be sent"));
469
+ }
470
+ }
471
+ catch (error) {
472
+ pending.reject(error instanceof Error ? error : new Error(String(error)));
473
+ }
474
+ }
475
+ }
476
+ /**
477
+ * Reject all pending sends - called when connection fails or is closed.
478
+ */
479
+ rejectPendingSendQueue(error) {
480
+ const queue = this.pendingSendQueue;
481
+ this.pendingSendQueue = [];
482
+ for (const pending of queue) {
483
+ clearTimeout(pending.timeoutHandle);
484
+ pending.reject(error);
485
+ }
486
+ }
487
+ async sendRequest(params) {
488
+ const { promise, cancel } = this.waitForWithCancel((msg) => {
489
+ if (msg.type === "rpc_error" && msg.payload.requestId === params.requestId) {
490
+ return {
491
+ kind: "error",
492
+ error: new DaemonRpcError({
493
+ requestId: msg.payload.requestId,
494
+ error: msg.payload.error,
495
+ requestType: msg.payload.requestType,
496
+ code: msg.payload.code,
497
+ }),
498
+ };
499
+ }
500
+ const value = params.select(msg);
501
+ if (value === null) {
502
+ return null;
503
+ }
504
+ return { kind: "ok", value };
505
+ }, params.timeout, params.options);
506
+ try {
507
+ await this.sendSessionMessageOrThrow(params.message);
508
+ }
509
+ catch (error) {
510
+ const err = error instanceof Error ? error : new Error(String(error));
511
+ cancel(err);
512
+ void promise.catch(() => undefined);
513
+ throw err;
514
+ }
515
+ const result = await promise;
516
+ if (result.kind === "error") {
517
+ throw result.error;
518
+ }
519
+ return result.value;
520
+ }
521
+ async sendCorrelatedRequest(params) {
522
+ return this.sendRequest({
523
+ requestId: params.requestId,
524
+ message: params.message,
525
+ timeout: params.timeout,
526
+ options: params.options,
527
+ select: (msg) => {
528
+ const correlated = msg;
529
+ if (correlated.type !== params.responseType) {
530
+ return null;
531
+ }
532
+ const payload = correlated.payload;
533
+ if (payload.requestId !== params.requestId) {
534
+ return null;
535
+ }
536
+ if (!params.selectPayload) {
537
+ return payload;
538
+ }
539
+ return params.selectPayload(payload);
540
+ },
541
+ });
542
+ }
543
+ sendCorrelatedSessionRequest(params) {
544
+ const resolvedRequestId = this.createRequestId(params.requestId);
545
+ const message = SessionInboundMessageSchema.parse({
546
+ ...params.message,
547
+ requestId: resolvedRequestId,
548
+ });
549
+ return this.sendCorrelatedRequest({
550
+ requestId: resolvedRequestId,
551
+ message,
552
+ responseType: params.responseType,
553
+ timeout: params.timeout,
554
+ options: { skipQueue: true },
555
+ ...(params.selectPayload ? { selectPayload: params.selectPayload } : {}),
556
+ });
557
+ }
558
+ sendSessionMessageStrict(message) {
559
+ if (!this.transport || this.connectionState.status !== "connected") {
560
+ throw new Error("Transport not connected");
561
+ }
562
+ const payload = SessionInboundMessageSchema.parse(message);
563
+ try {
564
+ this.transport.send(JSON.stringify({ type: "session", message: payload }));
565
+ }
566
+ catch (error) {
567
+ throw error instanceof Error ? error : new Error(String(error));
568
+ }
569
+ }
570
+ clearAgentAttention(agentId) {
571
+ this.sendSessionMessage({ type: "clear_agent_attention", agentId });
572
+ }
573
+ sendHeartbeat(params) {
574
+ this.sendSessionMessage({
575
+ type: "client_heartbeat",
576
+ deviceType: params.deviceType,
577
+ focusedAgentId: params.focusedAgentId,
578
+ lastActivityAt: params.lastActivityAt,
579
+ appVisible: params.appVisible,
580
+ appVisibilityChangedAt: params.appVisibilityChangedAt,
581
+ });
582
+ }
583
+ registerPushToken(token) {
584
+ this.sendSessionMessage({
585
+ type: "register_push_token",
586
+ token,
587
+ });
588
+ }
589
+ async ping(params) {
590
+ const requestId = params?.requestId ?? `ping-${Date.now()}-${Math.random().toString(36).slice(2)}`;
591
+ const clientSentAt = Date.now();
592
+ const payload = await this.sendRequest({
593
+ requestId,
594
+ message: { type: "ping", requestId, clientSentAt },
595
+ timeout: params?.timeoutMs ?? 5000,
596
+ select: (msg) => {
597
+ if (msg.type !== "pong")
598
+ return null;
599
+ if (msg.payload.requestId !== requestId)
600
+ return null;
601
+ if (typeof msg.payload.serverReceivedAt !== "number")
602
+ return null;
603
+ if (typeof msg.payload.serverSentAt !== "number")
604
+ return null;
605
+ return msg.payload;
606
+ },
607
+ });
608
+ return {
609
+ requestId,
610
+ clientSentAt,
611
+ serverReceivedAt: payload.serverReceivedAt,
612
+ serverSentAt: payload.serverSentAt,
613
+ rttMs: Date.now() - clientSentAt,
614
+ };
615
+ }
616
+ // ============================================================================
617
+ // Agent RPCs (requestId-correlated)
618
+ // ============================================================================
619
+ async fetchAgents(options) {
620
+ const resolvedRequestId = this.createRequestId(options?.requestId);
621
+ const message = SessionInboundMessageSchema.parse({
622
+ type: "fetch_agents_request",
623
+ requestId: resolvedRequestId,
624
+ ...(options?.filter ? { filter: options.filter } : {}),
625
+ ...(options?.sort ? { sort: options.sort } : {}),
626
+ ...(options?.page ? { page: options.page } : {}),
627
+ ...(options?.subscribe ? { subscribe: options.subscribe } : {}),
628
+ });
629
+ return this.sendRequest({
630
+ requestId: resolvedRequestId,
631
+ message,
632
+ timeout: 10000,
633
+ options: { skipQueue: true },
634
+ select: (msg) => {
635
+ if (msg.type !== "fetch_agents_response") {
636
+ return null;
637
+ }
638
+ if (msg.payload.requestId !== resolvedRequestId) {
639
+ return null;
640
+ }
641
+ return msg.payload;
642
+ },
643
+ });
644
+ }
645
+ async fetchWorkspaces(options) {
646
+ const resolvedRequestId = this.createRequestId(options?.requestId);
647
+ const message = SessionInboundMessageSchema.parse({
648
+ type: "fetch_workspaces_request",
649
+ requestId: resolvedRequestId,
650
+ ...(options?.filter ? { filter: options.filter } : {}),
651
+ ...(options?.sort ? { sort: options.sort } : {}),
652
+ ...(options?.page ? { page: options.page } : {}),
653
+ ...(options?.subscribe ? { subscribe: options.subscribe } : {}),
654
+ });
655
+ return this.sendRequest({
656
+ requestId: resolvedRequestId,
657
+ message,
658
+ timeout: 10000,
659
+ options: { skipQueue: true },
660
+ select: (msg) => {
661
+ if (msg.type !== "fetch_workspaces_response") {
662
+ return null;
663
+ }
664
+ if (msg.payload.requestId !== resolvedRequestId) {
665
+ return null;
666
+ }
667
+ return msg.payload;
668
+ },
669
+ });
670
+ }
671
+ async openProject(cwd, requestId) {
672
+ return this.sendCorrelatedSessionRequest({
673
+ requestId,
674
+ message: {
675
+ type: "open_project_request",
676
+ cwd,
677
+ },
678
+ responseType: "open_project_response",
679
+ timeout: 10000,
680
+ });
681
+ }
682
+ async listAvailableEditors(requestId) {
683
+ return this.sendCorrelatedSessionRequest({
684
+ requestId,
685
+ message: {
686
+ type: "list_available_editors_request",
687
+ },
688
+ responseType: "list_available_editors_response",
689
+ timeout: 10000,
690
+ });
691
+ }
692
+ async openInEditor(path, editorId, requestId) {
693
+ return this.sendCorrelatedSessionRequest({
694
+ requestId,
695
+ message: {
696
+ type: "open_in_editor_request",
697
+ path,
698
+ editorId,
699
+ },
700
+ responseType: "open_in_editor_response",
701
+ timeout: 10000,
702
+ });
703
+ }
704
+ async archiveWorkspace(workspaceId, requestId) {
705
+ return this.sendCorrelatedSessionRequest({
706
+ requestId,
707
+ message: {
708
+ type: "archive_workspace_request",
709
+ workspaceId,
710
+ },
711
+ responseType: "archive_workspace_response",
712
+ timeout: 10000,
713
+ });
714
+ }
715
+ async fetchAgent(agentId, requestId) {
716
+ const resolvedRequestId = this.createRequestId(requestId);
717
+ const message = SessionInboundMessageSchema.parse({
718
+ type: "fetch_agent_request",
719
+ requestId: resolvedRequestId,
720
+ agentId,
721
+ });
722
+ const payload = await this.sendRequest({
723
+ requestId: resolvedRequestId,
724
+ message,
725
+ timeout: 10000,
726
+ options: { skipQueue: true },
727
+ select: (msg) => {
728
+ if (msg.type !== "fetch_agent_response") {
729
+ return null;
730
+ }
731
+ if (msg.payload.requestId !== resolvedRequestId) {
732
+ return null;
733
+ }
734
+ return msg.payload;
735
+ },
736
+ });
737
+ if (payload.error) {
738
+ throw new Error(payload.error);
739
+ }
740
+ if (!payload.agent) {
741
+ return null;
742
+ }
743
+ return { agent: payload.agent, project: payload.project ?? null };
744
+ }
745
+ resubscribeCheckoutDiffSubscriptions() {
746
+ if (this.checkoutDiffSubscriptions.size === 0) {
747
+ return;
748
+ }
749
+ for (const [subscriptionId, subscription] of this.checkoutDiffSubscriptions) {
750
+ const message = SessionInboundMessageSchema.parse({
751
+ type: "subscribe_checkout_diff_request",
752
+ subscriptionId,
753
+ cwd: subscription.cwd,
754
+ compare: subscription.compare,
755
+ requestId: this.createRequestId(),
756
+ });
757
+ this.sendSessionMessage(message);
758
+ }
759
+ }
760
+ resubscribeTerminalDirectorySubscriptions() {
761
+ if (this.terminalDirectorySubscriptions.size === 0) {
762
+ return;
763
+ }
764
+ for (const cwd of this.terminalDirectorySubscriptions) {
765
+ this.sendSessionMessage({
766
+ type: "subscribe_terminals_request",
767
+ cwd,
768
+ });
769
+ }
770
+ }
771
+ // ============================================================================
772
+ // Agent Lifecycle
773
+ // ============================================================================
774
+ async createAgent(options) {
775
+ const requestId = this.createRequestId(options.requestId);
776
+ const config = resolveAgentConfig(options);
777
+ const message = SessionInboundMessageSchema.parse({
778
+ type: "create_agent_request",
779
+ requestId,
780
+ config,
781
+ ...(options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}),
782
+ ...(options.clientMessageId ? { clientMessageId: options.clientMessageId } : {}),
783
+ ...(options.outputSchema ? { outputSchema: options.outputSchema } : {}),
784
+ ...(options.images && options.images.length > 0 ? { images: options.images } : {}),
785
+ ...(options.git ? { git: options.git } : {}),
786
+ ...(options.worktreeName ? { worktreeName: options.worktreeName } : {}),
787
+ ...(options.labels && Object.keys(options.labels).length > 0
788
+ ? { labels: options.labels }
789
+ : {}),
790
+ });
791
+ const status = await this.sendRequest({
792
+ requestId,
793
+ message,
794
+ timeout: 60000,
795
+ options: { skipQueue: true },
796
+ select: (msg) => {
797
+ if (msg.type !== "status") {
798
+ return null;
799
+ }
800
+ const created = AgentCreatedStatusPayloadSchema.safeParse(msg.payload);
801
+ if (created.success && created.data.requestId === requestId) {
802
+ return created.data;
803
+ }
804
+ const failed = AgentCreateFailedStatusPayloadSchema.safeParse(msg.payload);
805
+ if (failed.success && failed.data.requestId === requestId) {
806
+ return failed.data;
807
+ }
808
+ return null;
809
+ },
810
+ });
811
+ if (status.status === "agent_create_failed") {
812
+ throw new Error(status.error);
813
+ }
814
+ return status.agent;
815
+ }
816
+ async deleteAgent(agentId) {
817
+ const requestId = this.createRequestId();
818
+ const message = SessionInboundMessageSchema.parse({
819
+ type: "delete_agent_request",
820
+ agentId,
821
+ requestId,
822
+ });
823
+ await this.sendRequest({
824
+ requestId,
825
+ message,
826
+ timeout: 10000,
827
+ options: { skipQueue: true },
828
+ select: (msg) => {
829
+ if (msg.type !== "agent_deleted") {
830
+ return null;
831
+ }
832
+ if (msg.payload.requestId !== requestId) {
833
+ return null;
834
+ }
835
+ return msg.payload;
836
+ },
837
+ });
838
+ }
839
+ async archiveAgent(agentId) {
840
+ const requestId = this.createRequestId();
841
+ const message = SessionInboundMessageSchema.parse({
842
+ type: "archive_agent_request",
843
+ agentId,
844
+ requestId,
845
+ });
846
+ const result = await this.sendRequest({
847
+ requestId,
848
+ message,
849
+ timeout: 10000,
850
+ options: { skipQueue: true },
851
+ select: (msg) => {
852
+ if (msg.type !== "agent_archived") {
853
+ return null;
854
+ }
855
+ if (msg.payload.requestId !== requestId) {
856
+ return null;
857
+ }
858
+ return msg.payload;
859
+ },
860
+ });
861
+ return { archivedAt: result.archivedAt };
862
+ }
863
+ async updateAgent(agentId, updates) {
864
+ const requestId = this.createRequestId();
865
+ const message = SessionInboundMessageSchema.parse({
866
+ type: "update_agent_request",
867
+ agentId,
868
+ ...(updates.name !== undefined ? { name: updates.name } : {}),
869
+ ...(updates.labels && Object.keys(updates.labels).length > 0
870
+ ? { labels: updates.labels }
871
+ : {}),
872
+ requestId,
873
+ });
874
+ const payload = await this.sendRequest({
875
+ requestId,
876
+ message,
877
+ timeout: 10000,
878
+ options: { skipQueue: true },
879
+ select: (msg) => {
880
+ if (msg.type !== "update_agent_response") {
881
+ return null;
882
+ }
883
+ if (msg.payload.requestId !== requestId) {
884
+ return null;
885
+ }
886
+ return msg.payload;
887
+ },
888
+ });
889
+ if (!payload.accepted) {
890
+ throw new Error(payload.error ?? "updateAgent rejected");
891
+ }
892
+ }
893
+ async resumeAgent(handle, overrides) {
894
+ const requestId = this.createRequestId();
895
+ const message = SessionInboundMessageSchema.parse({
896
+ type: "resume_agent_request",
897
+ requestId,
898
+ handle,
899
+ ...(overrides ? { overrides } : {}),
900
+ });
901
+ const status = await this.sendRequest({
902
+ requestId,
903
+ message,
904
+ timeout: 15000,
905
+ options: { skipQueue: true },
906
+ select: (msg) => {
907
+ if (msg.type !== "status") {
908
+ return null;
909
+ }
910
+ const resumed = AgentResumedStatusPayloadSchema.safeParse(msg.payload);
911
+ if (resumed.success && resumed.data.requestId === requestId) {
912
+ return resumed.data;
913
+ }
914
+ return null;
915
+ },
916
+ });
917
+ return status.agent;
918
+ }
919
+ async refreshAgent(agentId, requestId) {
920
+ const resolvedRequestId = this.createRequestId(requestId);
921
+ const message = SessionInboundMessageSchema.parse({
922
+ type: "refresh_agent_request",
923
+ agentId,
924
+ requestId: resolvedRequestId,
925
+ });
926
+ return this.sendRequest({
927
+ requestId: resolvedRequestId,
928
+ message,
929
+ timeout: 15000,
930
+ options: { skipQueue: true },
931
+ select: (msg) => {
932
+ if (msg.type !== "status") {
933
+ return null;
934
+ }
935
+ const refreshed = AgentRefreshedStatusPayloadSchema.safeParse(msg.payload);
936
+ if (refreshed.success && refreshed.data.requestId === resolvedRequestId) {
937
+ return refreshed.data;
938
+ }
939
+ return null;
940
+ },
941
+ });
942
+ }
943
+ async fetchAgentTimeline(agentId, options = {}) {
944
+ const resolvedRequestId = this.createRequestId(options.requestId);
945
+ const message = SessionInboundMessageSchema.parse({
946
+ type: "fetch_agent_timeline_request",
947
+ agentId,
948
+ requestId: resolvedRequestId,
949
+ ...(options.direction ? { direction: options.direction } : {}),
950
+ ...(options.cursor ? { cursor: options.cursor } : {}),
951
+ ...(typeof options.limit === "number" ? { limit: options.limit } : {}),
952
+ ...(options.projection ? { projection: options.projection } : {}),
953
+ });
954
+ const payload = await this.sendRequest({
955
+ requestId: resolvedRequestId,
956
+ message,
957
+ timeout: 15000,
958
+ options: { skipQueue: true },
959
+ select: (msg) => {
960
+ if (msg.type !== "fetch_agent_timeline_response") {
961
+ return null;
962
+ }
963
+ if (msg.payload.requestId !== resolvedRequestId) {
964
+ return null;
965
+ }
966
+ return msg.payload;
967
+ },
968
+ });
969
+ if (payload.error) {
970
+ throw new Error(payload.error);
971
+ }
972
+ return payload;
973
+ }
974
+ // ============================================================================
975
+ // Agent Interaction
976
+ // ============================================================================
977
+ async sendAgentMessage(agentId, text, options) {
978
+ const requestId = this.createRequestId();
979
+ const messageId = options?.messageId ?? crypto.randomUUID();
980
+ const message = SessionInboundMessageSchema.parse({
981
+ type: "send_agent_message_request",
982
+ requestId,
983
+ agentId,
984
+ text,
985
+ ...(messageId ? { messageId } : {}),
986
+ ...(options?.images ? { images: options.images } : {}),
987
+ });
988
+ const payload = await this.sendRequest({
989
+ requestId,
990
+ message,
991
+ timeout: 15000,
992
+ options: { skipQueue: true },
993
+ select: (msg) => {
994
+ if (msg.type !== "send_agent_message_response") {
995
+ return null;
996
+ }
997
+ if (msg.payload.requestId !== requestId) {
998
+ return null;
999
+ }
1000
+ return msg.payload;
1001
+ },
1002
+ });
1003
+ if (!payload.accepted) {
1004
+ throw new Error(payload.error ?? "sendAgentMessage rejected");
1005
+ }
1006
+ }
1007
+ async sendMessage(agentId, text, options) {
1008
+ await this.sendAgentMessage(agentId, text, options);
1009
+ }
1010
+ async cancelAgent(agentId) {
1011
+ this.sendSessionMessage({ type: "cancel_agent_request", agentId });
1012
+ }
1013
+ async setAgentMode(agentId, modeId) {
1014
+ const requestId = this.createRequestId();
1015
+ const message = SessionInboundMessageSchema.parse({
1016
+ type: "set_agent_mode_request",
1017
+ agentId,
1018
+ modeId,
1019
+ requestId,
1020
+ });
1021
+ const payload = await this.sendRequest({
1022
+ requestId,
1023
+ message,
1024
+ timeout: 15000,
1025
+ options: { skipQueue: true },
1026
+ select: (msg) => {
1027
+ if (msg.type !== "set_agent_mode_response") {
1028
+ return null;
1029
+ }
1030
+ if (msg.payload.requestId !== requestId) {
1031
+ return null;
1032
+ }
1033
+ return msg.payload;
1034
+ },
1035
+ });
1036
+ if (!payload.accepted) {
1037
+ throw new Error(payload.error ?? "setAgentMode rejected");
1038
+ }
1039
+ }
1040
+ async setAgentModel(agentId, modelId) {
1041
+ const requestId = this.createRequestId();
1042
+ const message = SessionInboundMessageSchema.parse({
1043
+ type: "set_agent_model_request",
1044
+ agentId,
1045
+ modelId,
1046
+ requestId,
1047
+ });
1048
+ const payload = await this.sendRequest({
1049
+ requestId,
1050
+ message,
1051
+ timeout: 15000,
1052
+ options: { skipQueue: true },
1053
+ select: (msg) => {
1054
+ if (msg.type !== "set_agent_model_response") {
1055
+ return null;
1056
+ }
1057
+ if (msg.payload.requestId !== requestId) {
1058
+ return null;
1059
+ }
1060
+ return msg.payload;
1061
+ },
1062
+ });
1063
+ if (!payload.accepted) {
1064
+ throw new Error(payload.error ?? "setAgentModel rejected");
1065
+ }
1066
+ }
1067
+ async setAgentFeature(agentId, featureId, value) {
1068
+ const requestId = this.createRequestId();
1069
+ const message = SessionInboundMessageSchema.parse({
1070
+ type: "set_agent_feature_request",
1071
+ agentId,
1072
+ featureId,
1073
+ value,
1074
+ requestId,
1075
+ });
1076
+ const payload = await this.sendRequest({
1077
+ requestId,
1078
+ message,
1079
+ timeout: 15000,
1080
+ options: { skipQueue: true },
1081
+ select: (msg) => {
1082
+ if (msg.type !== "set_agent_feature_response") {
1083
+ return null;
1084
+ }
1085
+ if (msg.payload.requestId !== requestId) {
1086
+ return null;
1087
+ }
1088
+ return msg.payload;
1089
+ },
1090
+ });
1091
+ if (!payload.accepted) {
1092
+ throw new Error(payload.error ?? "setAgentFeature rejected");
1093
+ }
1094
+ }
1095
+ async setAgentThinkingOption(agentId, thinkingOptionId) {
1096
+ const requestId = this.createRequestId();
1097
+ const message = SessionInboundMessageSchema.parse({
1098
+ type: "set_agent_thinking_request",
1099
+ agentId,
1100
+ thinkingOptionId,
1101
+ requestId,
1102
+ });
1103
+ const payload = await this.sendRequest({
1104
+ requestId,
1105
+ message,
1106
+ timeout: 15000,
1107
+ options: { skipQueue: true },
1108
+ select: (msg) => {
1109
+ if (msg.type !== "set_agent_thinking_response") {
1110
+ return null;
1111
+ }
1112
+ if (msg.payload.requestId !== requestId) {
1113
+ return null;
1114
+ }
1115
+ return msg.payload;
1116
+ },
1117
+ });
1118
+ if (!payload.accepted) {
1119
+ throw new Error(payload.error ?? "setAgentThinkingOption rejected");
1120
+ }
1121
+ }
1122
+ async restartServer(reason, requestId) {
1123
+ const resolvedRequestId = this.createRequestId(requestId);
1124
+ const message = SessionInboundMessageSchema.parse({
1125
+ type: "restart_server_request",
1126
+ ...(reason && reason.trim().length > 0 ? { reason } : {}),
1127
+ requestId: resolvedRequestId,
1128
+ });
1129
+ return this.sendRequest({
1130
+ requestId: resolvedRequestId,
1131
+ message,
1132
+ timeout: 10000,
1133
+ options: { skipQueue: true },
1134
+ select: (msg) => {
1135
+ if (msg.type !== "status") {
1136
+ return null;
1137
+ }
1138
+ const restarted = RestartRequestedStatusPayloadSchema.safeParse(msg.payload);
1139
+ if (!restarted.success) {
1140
+ return null;
1141
+ }
1142
+ if (restarted.data.requestId !== resolvedRequestId) {
1143
+ return null;
1144
+ }
1145
+ return restarted.data;
1146
+ },
1147
+ });
1148
+ }
1149
+ async shutdownServer(requestId) {
1150
+ const resolvedRequestId = this.createRequestId(requestId);
1151
+ const message = SessionInboundMessageSchema.parse({
1152
+ type: "shutdown_server_request",
1153
+ requestId: resolvedRequestId,
1154
+ });
1155
+ return this.sendRequest({
1156
+ requestId: resolvedRequestId,
1157
+ message,
1158
+ timeout: 10000,
1159
+ options: { skipQueue: true },
1160
+ select: (msg) => {
1161
+ if (msg.type !== "status") {
1162
+ return null;
1163
+ }
1164
+ const shutdown = ShutdownRequestedStatusPayloadSchema.safeParse(msg.payload);
1165
+ if (!shutdown.success) {
1166
+ return null;
1167
+ }
1168
+ if (shutdown.data.requestId !== resolvedRequestId) {
1169
+ return null;
1170
+ }
1171
+ return shutdown.data;
1172
+ },
1173
+ });
1174
+ }
1175
+ // ============================================================================
1176
+ // Audio / Voice
1177
+ // ============================================================================
1178
+ async setVoiceMode(enabled, agentId) {
1179
+ const requestId = this.createRequestId();
1180
+ const message = SessionInboundMessageSchema.parse({
1181
+ type: "set_voice_mode",
1182
+ enabled,
1183
+ ...(agentId ? { agentId } : {}),
1184
+ requestId,
1185
+ });
1186
+ const response = await this.sendRequest({
1187
+ requestId,
1188
+ message,
1189
+ timeout: 10000,
1190
+ select: (msg) => {
1191
+ if (msg.type !== "set_voice_mode_response") {
1192
+ return null;
1193
+ }
1194
+ if (msg.payload.requestId !== requestId) {
1195
+ return null;
1196
+ }
1197
+ return msg.payload;
1198
+ },
1199
+ });
1200
+ if (!response.accepted) {
1201
+ const codeSuffix = typeof response.reasonCode === "string" && response.reasonCode.trim().length > 0
1202
+ ? ` (${response.reasonCode})`
1203
+ : "";
1204
+ throw new Error((response.error ?? "Failed to set voice mode") + codeSuffix);
1205
+ }
1206
+ return response;
1207
+ }
1208
+ async sendVoiceAudioChunk(audio, format, isLast = false) {
1209
+ this.sendSessionMessage({ type: "voice_audio_chunk", audio, format, isLast });
1210
+ }
1211
+ async startDictationStream(dictationId, format) {
1212
+ const ack = this.waitForWithCancel((msg) => {
1213
+ if (msg.type !== "dictation_stream_ack") {
1214
+ return null;
1215
+ }
1216
+ if (msg.payload.dictationId !== dictationId) {
1217
+ return null;
1218
+ }
1219
+ if (msg.payload.ackSeq !== -1) {
1220
+ return null;
1221
+ }
1222
+ return msg.payload;
1223
+ }, 30000, { skipQueue: true });
1224
+ const ackPromise = ack.promise.then(() => undefined);
1225
+ const streamError = this.waitForWithCancel((msg) => {
1226
+ if (msg.type !== "dictation_stream_error") {
1227
+ return null;
1228
+ }
1229
+ if (msg.payload.dictationId !== dictationId) {
1230
+ return null;
1231
+ }
1232
+ return msg.payload;
1233
+ }, 30000, { skipQueue: true });
1234
+ const errorPromise = streamError.promise.then((payload) => {
1235
+ throw new Error(payload.error);
1236
+ });
1237
+ const cleanupError = new Error("Cancelled dictation start waiter");
1238
+ try {
1239
+ this.sendSessionMessageStrict({ type: "dictation_stream_start", dictationId, format });
1240
+ await Promise.race([ackPromise, errorPromise]);
1241
+ }
1242
+ finally {
1243
+ ack.cancel(cleanupError);
1244
+ streamError.cancel(cleanupError);
1245
+ void ackPromise.catch(() => undefined);
1246
+ void errorPromise.catch(() => undefined);
1247
+ }
1248
+ }
1249
+ sendDictationStreamChunk(dictationId, seq, audio, format) {
1250
+ this.sendSessionMessageStrict({
1251
+ type: "dictation_stream_chunk",
1252
+ dictationId,
1253
+ seq,
1254
+ audio,
1255
+ format,
1256
+ });
1257
+ }
1258
+ async finishDictationStream(dictationId, finalSeq) {
1259
+ const final = this.waitForWithCancel((msg) => {
1260
+ if (msg.type !== "dictation_stream_final") {
1261
+ return null;
1262
+ }
1263
+ if (msg.payload.dictationId !== dictationId) {
1264
+ return null;
1265
+ }
1266
+ return msg.payload;
1267
+ }, 0, { skipQueue: true });
1268
+ const streamError = this.waitForWithCancel((msg) => {
1269
+ if (msg.type !== "dictation_stream_error") {
1270
+ return null;
1271
+ }
1272
+ if (msg.payload.dictationId !== dictationId) {
1273
+ return null;
1274
+ }
1275
+ return msg.payload;
1276
+ }, 0, { skipQueue: true });
1277
+ const finishAccepted = this.waitForWithCancel((msg) => {
1278
+ if (msg.type !== "dictation_stream_finish_accepted") {
1279
+ return null;
1280
+ }
1281
+ if (msg.payload.dictationId !== dictationId) {
1282
+ return null;
1283
+ }
1284
+ return msg.payload;
1285
+ }, DEFAULT_DICTATION_FINISH_ACCEPT_TIMEOUT_MS, { skipQueue: true });
1286
+ const finalPromise = final.promise;
1287
+ const errorPromise = streamError.promise.then((payload) => {
1288
+ throw new Error(payload.error);
1289
+ });
1290
+ const finishAcceptedPromise = finishAccepted.promise;
1291
+ const finalOutcomePromise = finalPromise.then((payload) => ({
1292
+ kind: "final",
1293
+ payload,
1294
+ }));
1295
+ const errorOutcomePromise = errorPromise.then(() => ({
1296
+ kind: "error",
1297
+ error: new Error("Unexpected dictation stream error state"),
1298
+ }), (error) => ({
1299
+ kind: "error",
1300
+ error: error instanceof Error ? error : new Error(String(error)),
1301
+ }));
1302
+ const finishAcceptedOutcomePromise = finishAcceptedPromise.then((payload) => ({ kind: "accepted", payload }), (error) => {
1303
+ if (isWaiterTimeoutError(error)) {
1304
+ return { kind: "accepted_timeout" };
1305
+ }
1306
+ return {
1307
+ kind: "accepted_error",
1308
+ error: error instanceof Error ? error : new Error(String(error)),
1309
+ };
1310
+ });
1311
+ const waitForFinalResult = async (timeoutMs) => {
1312
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
1313
+ const outcome = await Promise.race([finalOutcomePromise, errorOutcomePromise]);
1314
+ if (outcome.kind === "error") {
1315
+ throw outcome.error;
1316
+ }
1317
+ return outcome.payload;
1318
+ }
1319
+ let timeoutHandle = null;
1320
+ const timeoutPromise = new Promise((resolve) => {
1321
+ timeoutHandle = setTimeout(() => resolve({ kind: "timeout" }), timeoutMs);
1322
+ });
1323
+ const outcome = await Promise.race([
1324
+ finalOutcomePromise,
1325
+ errorOutcomePromise,
1326
+ timeoutPromise,
1327
+ ]);
1328
+ if (timeoutHandle) {
1329
+ clearTimeout(timeoutHandle);
1330
+ }
1331
+ if (outcome.kind === "timeout") {
1332
+ throw new Error(`Timeout waiting for dictation finalization (${timeoutMs}ms)`);
1333
+ }
1334
+ if (outcome.kind === "error") {
1335
+ throw outcome.error;
1336
+ }
1337
+ return outcome.payload;
1338
+ };
1339
+ const cleanupError = new Error("Cancelled dictation finish waiter");
1340
+ try {
1341
+ this.sendSessionMessageStrict({ type: "dictation_stream_finish", dictationId, finalSeq });
1342
+ const firstOutcome = await Promise.race([
1343
+ finalOutcomePromise,
1344
+ errorOutcomePromise,
1345
+ finishAcceptedOutcomePromise,
1346
+ ]);
1347
+ if (firstOutcome.kind === "final") {
1348
+ return firstOutcome.payload;
1349
+ }
1350
+ if (firstOutcome.kind === "error") {
1351
+ throw firstOutcome.error;
1352
+ }
1353
+ if (firstOutcome.kind === "accepted") {
1354
+ return await waitForFinalResult(firstOutcome.payload.timeoutMs + DEFAULT_DICTATION_FINISH_TIMEOUT_GRACE_MS);
1355
+ }
1356
+ return await waitForFinalResult(DEFAULT_DICTATION_FINISH_FALLBACK_TIMEOUT_MS);
1357
+ }
1358
+ finally {
1359
+ final.cancel(cleanupError);
1360
+ streamError.cancel(cleanupError);
1361
+ finishAccepted.cancel(cleanupError);
1362
+ void finalPromise.catch(() => undefined);
1363
+ void errorPromise.catch(() => undefined);
1364
+ void finishAcceptedPromise.catch(() => undefined);
1365
+ }
1366
+ }
1367
+ cancelDictationStream(dictationId) {
1368
+ this.sendSessionMessageStrict({ type: "dictation_stream_cancel", dictationId });
1369
+ }
1370
+ async abortRequest() {
1371
+ this.sendSessionMessage({ type: "abort_request" });
1372
+ }
1373
+ async audioPlayed(id) {
1374
+ this.sendSessionMessage({ type: "audio_played", id });
1375
+ }
1376
+ // ============================================================================
1377
+ // Git Operations
1378
+ // ============================================================================
1379
+ async getCheckoutStatus(cwd, options) {
1380
+ const requestId = options?.requestId;
1381
+ if (!requestId) {
1382
+ const existing = this.checkoutStatusInFlight.get(cwd);
1383
+ if (existing) {
1384
+ return existing;
1385
+ }
1386
+ }
1387
+ const resolvedRequestId = this.createRequestId(requestId);
1388
+ const message = SessionInboundMessageSchema.parse({
1389
+ type: "checkout_status_request",
1390
+ cwd,
1391
+ requestId: resolvedRequestId,
1392
+ });
1393
+ const responsePromise = this.sendRequest({
1394
+ requestId: resolvedRequestId,
1395
+ message,
1396
+ timeout: 60000,
1397
+ options: { skipQueue: true },
1398
+ select: (msg) => {
1399
+ if (msg.type !== "checkout_status_response") {
1400
+ return null;
1401
+ }
1402
+ if (msg.payload.requestId !== resolvedRequestId) {
1403
+ return null;
1404
+ }
1405
+ return msg.payload;
1406
+ },
1407
+ });
1408
+ if (!requestId) {
1409
+ this.checkoutStatusInFlight.set(cwd, responsePromise);
1410
+ void responsePromise
1411
+ .finally(() => {
1412
+ if (this.checkoutStatusInFlight.get(cwd) === responsePromise) {
1413
+ this.checkoutStatusInFlight.delete(cwd);
1414
+ }
1415
+ })
1416
+ .catch(() => undefined);
1417
+ }
1418
+ return responsePromise;
1419
+ }
1420
+ normalizeCheckoutDiffCompare(compare) {
1421
+ const ignoreWhitespace = compare.ignoreWhitespace === true;
1422
+ if (compare.mode === "uncommitted") {
1423
+ return { mode: "uncommitted", ignoreWhitespace };
1424
+ }
1425
+ const trimmedBaseRef = compare.baseRef?.trim();
1426
+ if (!trimmedBaseRef) {
1427
+ return { mode: "base", ignoreWhitespace };
1428
+ }
1429
+ return { mode: "base", baseRef: trimmedBaseRef, ignoreWhitespace };
1430
+ }
1431
+ async getCheckoutDiff(cwd, compare, requestId) {
1432
+ const oneShotSubscriptionId = `oneshot-checkout-diff:${crypto.randomUUID()}`;
1433
+ try {
1434
+ const payload = await this.subscribeCheckoutDiff(cwd, compare, {
1435
+ subscriptionId: oneShotSubscriptionId,
1436
+ requestId,
1437
+ });
1438
+ return {
1439
+ cwd: payload.cwd,
1440
+ files: payload.files,
1441
+ error: payload.error,
1442
+ requestId: payload.requestId,
1443
+ };
1444
+ }
1445
+ finally {
1446
+ try {
1447
+ this.unsubscribeCheckoutDiff(oneShotSubscriptionId);
1448
+ }
1449
+ catch {
1450
+ // Ignore disconnect races during one-shot cleanup.
1451
+ }
1452
+ }
1453
+ }
1454
+ async subscribeCheckoutDiff(cwd, compare, options) {
1455
+ const subscriptionId = options?.subscriptionId ?? crypto.randomUUID();
1456
+ const normalizedCompare = this.normalizeCheckoutDiffCompare(compare);
1457
+ const previousSubscription = this.checkoutDiffSubscriptions.get(subscriptionId) ?? null;
1458
+ this.checkoutDiffSubscriptions.set(subscriptionId, {
1459
+ cwd,
1460
+ compare: normalizedCompare,
1461
+ });
1462
+ const resolvedRequestId = this.createRequestId(options?.requestId);
1463
+ const message = SessionInboundMessageSchema.parse({
1464
+ type: "subscribe_checkout_diff_request",
1465
+ subscriptionId,
1466
+ cwd,
1467
+ compare: normalizedCompare,
1468
+ requestId: resolvedRequestId,
1469
+ });
1470
+ try {
1471
+ return await this.sendCorrelatedRequest({
1472
+ requestId: resolvedRequestId,
1473
+ message,
1474
+ responseType: "subscribe_checkout_diff_response",
1475
+ timeout: 60000,
1476
+ options: { skipQueue: true },
1477
+ selectPayload: (payload) => {
1478
+ if (payload.subscriptionId !== subscriptionId) {
1479
+ return null;
1480
+ }
1481
+ return payload;
1482
+ },
1483
+ });
1484
+ }
1485
+ catch (error) {
1486
+ if (previousSubscription) {
1487
+ this.checkoutDiffSubscriptions.set(subscriptionId, previousSubscription);
1488
+ }
1489
+ else {
1490
+ this.checkoutDiffSubscriptions.delete(subscriptionId);
1491
+ }
1492
+ throw error;
1493
+ }
1494
+ }
1495
+ unsubscribeCheckoutDiff(subscriptionId) {
1496
+ this.checkoutDiffSubscriptions.delete(subscriptionId);
1497
+ this.sendSessionMessage({
1498
+ type: "unsubscribe_checkout_diff_request",
1499
+ subscriptionId,
1500
+ });
1501
+ }
1502
+ async checkoutCommit(cwd, input, requestId) {
1503
+ return this.sendCorrelatedSessionRequest({
1504
+ requestId,
1505
+ message: {
1506
+ type: "checkout_commit_request",
1507
+ cwd,
1508
+ message: input.message,
1509
+ addAll: input.addAll,
1510
+ },
1511
+ responseType: "checkout_commit_response",
1512
+ timeout: 60000,
1513
+ });
1514
+ }
1515
+ async checkoutMerge(cwd, input, requestId) {
1516
+ return this.sendCorrelatedSessionRequest({
1517
+ requestId,
1518
+ message: {
1519
+ type: "checkout_merge_request",
1520
+ cwd,
1521
+ baseRef: input.baseRef,
1522
+ strategy: input.strategy,
1523
+ requireCleanTarget: input.requireCleanTarget,
1524
+ },
1525
+ responseType: "checkout_merge_response",
1526
+ timeout: 60000,
1527
+ });
1528
+ }
1529
+ async checkoutMergeFromBase(cwd, input, requestId) {
1530
+ return this.sendCorrelatedSessionRequest({
1531
+ requestId,
1532
+ message: {
1533
+ type: "checkout_merge_from_base_request",
1534
+ cwd,
1535
+ baseRef: input.baseRef,
1536
+ requireCleanTarget: input.requireCleanTarget,
1537
+ },
1538
+ responseType: "checkout_merge_from_base_response",
1539
+ timeout: 60000,
1540
+ });
1541
+ }
1542
+ async checkoutPull(cwd, requestId) {
1543
+ return this.sendCorrelatedSessionRequest({
1544
+ requestId,
1545
+ message: {
1546
+ type: "checkout_pull_request",
1547
+ cwd,
1548
+ },
1549
+ responseType: "checkout_pull_response",
1550
+ timeout: 60000,
1551
+ });
1552
+ }
1553
+ async checkoutPush(cwd, requestId) {
1554
+ return this.sendCorrelatedSessionRequest({
1555
+ requestId,
1556
+ message: {
1557
+ type: "checkout_push_request",
1558
+ cwd,
1559
+ },
1560
+ responseType: "checkout_push_response",
1561
+ timeout: 60000,
1562
+ });
1563
+ }
1564
+ async checkoutPrCreate(cwd, input, requestId) {
1565
+ return this.sendCorrelatedSessionRequest({
1566
+ requestId,
1567
+ message: {
1568
+ type: "checkout_pr_create_request",
1569
+ cwd,
1570
+ title: input.title,
1571
+ body: input.body,
1572
+ baseRef: input.baseRef,
1573
+ },
1574
+ responseType: "checkout_pr_create_response",
1575
+ timeout: 60000,
1576
+ });
1577
+ }
1578
+ async checkoutPrStatus(cwd, requestId) {
1579
+ return this.sendCorrelatedSessionRequest({
1580
+ requestId,
1581
+ message: {
1582
+ type: "checkout_pr_status_request",
1583
+ cwd,
1584
+ },
1585
+ responseType: "checkout_pr_status_response",
1586
+ timeout: 60000,
1587
+ });
1588
+ }
1589
+ async checkoutSwitchBranch(cwd, branch, requestId) {
1590
+ return this.sendCorrelatedSessionRequest({
1591
+ requestId,
1592
+ message: {
1593
+ type: "checkout_switch_branch_request",
1594
+ cwd,
1595
+ branch,
1596
+ },
1597
+ responseType: "checkout_switch_branch_response",
1598
+ timeout: 30000,
1599
+ });
1600
+ }
1601
+ async stashSave(cwd, options, requestId) {
1602
+ return this.sendCorrelatedSessionRequest({
1603
+ requestId,
1604
+ message: {
1605
+ type: "stash_save_request",
1606
+ cwd,
1607
+ branch: options?.branch,
1608
+ },
1609
+ responseType: "stash_save_response",
1610
+ timeout: 30000,
1611
+ });
1612
+ }
1613
+ async stashPop(cwd, stashIndex, requestId) {
1614
+ return this.sendCorrelatedSessionRequest({
1615
+ requestId,
1616
+ message: {
1617
+ type: "stash_pop_request",
1618
+ cwd,
1619
+ stashIndex,
1620
+ },
1621
+ responseType: "stash_pop_response",
1622
+ timeout: 30000,
1623
+ });
1624
+ }
1625
+ async stashList(cwd, options, requestId) {
1626
+ return this.sendCorrelatedSessionRequest({
1627
+ requestId,
1628
+ message: {
1629
+ type: "stash_list_request",
1630
+ cwd,
1631
+ seaworkOnly: options?.seaworkOnly,
1632
+ },
1633
+ responseType: "stash_list_response",
1634
+ timeout: 10000,
1635
+ });
1636
+ }
1637
+ async getSeaworkWorktreeList(input, requestId) {
1638
+ return this.sendCorrelatedSessionRequest({
1639
+ requestId,
1640
+ message: {
1641
+ type: "seawork_worktree_list_request",
1642
+ cwd: input.cwd,
1643
+ repoRoot: input.repoRoot,
1644
+ },
1645
+ responseType: "seawork_worktree_list_response",
1646
+ timeout: 60000,
1647
+ });
1648
+ }
1649
+ async archiveSeaworkWorktree(input, requestId) {
1650
+ return this.sendCorrelatedSessionRequest({
1651
+ requestId,
1652
+ message: {
1653
+ type: "seawork_worktree_archive_request",
1654
+ worktreePath: input.worktreePath,
1655
+ repoRoot: input.repoRoot,
1656
+ branchName: input.branchName,
1657
+ },
1658
+ responseType: "seawork_worktree_archive_response",
1659
+ timeout: 20000,
1660
+ });
1661
+ }
1662
+ async createSeaworkWorktree(input, requestId) {
1663
+ return this.sendCorrelatedSessionRequest({
1664
+ requestId,
1665
+ message: {
1666
+ type: "create_seawork_worktree_request",
1667
+ cwd: input.cwd,
1668
+ worktreeSlug: input.worktreeSlug,
1669
+ },
1670
+ responseType: "create_seawork_worktree_response",
1671
+ timeout: 60000,
1672
+ });
1673
+ }
1674
+ async validateBranch(options, requestId) {
1675
+ return this.sendCorrelatedSessionRequest({
1676
+ requestId,
1677
+ message: {
1678
+ type: "validate_branch_request",
1679
+ cwd: options.cwd,
1680
+ branchName: options.branchName,
1681
+ },
1682
+ responseType: "validate_branch_response",
1683
+ timeout: 10000,
1684
+ });
1685
+ }
1686
+ async getBranchSuggestions(options, requestId) {
1687
+ return this.sendCorrelatedSessionRequest({
1688
+ requestId,
1689
+ message: {
1690
+ type: "branch_suggestions_request",
1691
+ cwd: options.cwd,
1692
+ query: options.query,
1693
+ limit: options.limit,
1694
+ },
1695
+ responseType: "branch_suggestions_response",
1696
+ timeout: 10000,
1697
+ });
1698
+ }
1699
+ async getDirectorySuggestions(options, requestId) {
1700
+ return this.sendCorrelatedSessionRequest({
1701
+ requestId,
1702
+ message: {
1703
+ type: "directory_suggestions_request",
1704
+ query: options.query,
1705
+ cwd: options.cwd,
1706
+ includeFiles: options.includeFiles,
1707
+ includeDirectories: options.includeDirectories,
1708
+ limit: options.limit,
1709
+ },
1710
+ responseType: "directory_suggestions_response",
1711
+ timeout: 10000,
1712
+ });
1713
+ }
1714
+ // ============================================================================
1715
+ // File Explorer
1716
+ // ============================================================================
1717
+ async exploreFileSystem(cwd, path, mode = "list", requestId) {
1718
+ return this.sendCorrelatedSessionRequest({
1719
+ requestId,
1720
+ message: {
1721
+ type: "file_explorer_request",
1722
+ cwd,
1723
+ path,
1724
+ mode,
1725
+ },
1726
+ responseType: "file_explorer_response",
1727
+ timeout: 10000,
1728
+ });
1729
+ }
1730
+ async requestDownloadToken(cwd, path, requestId) {
1731
+ return this.sendCorrelatedSessionRequest({
1732
+ requestId,
1733
+ message: {
1734
+ type: "file_download_token_request",
1735
+ cwd,
1736
+ path,
1737
+ },
1738
+ responseType: "file_download_token_response",
1739
+ timeout: 10000,
1740
+ });
1741
+ }
1742
+ async requestProjectIcon(cwd, requestId) {
1743
+ return this.sendCorrelatedSessionRequest({
1744
+ requestId,
1745
+ message: {
1746
+ type: "project_icon_request",
1747
+ cwd,
1748
+ },
1749
+ responseType: "project_icon_response",
1750
+ timeout: 10000,
1751
+ });
1752
+ }
1753
+ // ============================================================================
1754
+ // Provider Models / Commands
1755
+ // ============================================================================
1756
+ async listProviderModels(provider, options) {
1757
+ return this.sendCorrelatedSessionRequest({
1758
+ requestId: options?.requestId,
1759
+ message: {
1760
+ type: "list_provider_models_request",
1761
+ provider,
1762
+ cwd: options?.cwd,
1763
+ },
1764
+ responseType: "list_provider_models_response",
1765
+ // Provider SDK cold starts (especially model discovery) can exceed 30s.
1766
+ timeout: 45000,
1767
+ });
1768
+ }
1769
+ async listProviderModes(provider, options) {
1770
+ return this.sendCorrelatedSessionRequest({
1771
+ requestId: options?.requestId,
1772
+ message: {
1773
+ type: "list_provider_modes_request",
1774
+ provider,
1775
+ cwd: options?.cwd,
1776
+ },
1777
+ responseType: "list_provider_modes_response",
1778
+ timeout: 45000,
1779
+ });
1780
+ }
1781
+ async listProviderFeatures(draftConfig, options) {
1782
+ return this.sendCorrelatedSessionRequest({
1783
+ requestId: options?.requestId,
1784
+ message: {
1785
+ type: "list_provider_features_request",
1786
+ draftConfig,
1787
+ },
1788
+ responseType: "list_provider_features_response",
1789
+ timeout: 45000,
1790
+ });
1791
+ }
1792
+ async listAvailableProviders(options) {
1793
+ return this.sendCorrelatedSessionRequest({
1794
+ requestId: options?.requestId,
1795
+ message: {
1796
+ type: "list_available_providers_request",
1797
+ },
1798
+ responseType: "list_available_providers_response",
1799
+ timeout: 30000,
1800
+ });
1801
+ }
1802
+ async getProvidersSnapshot(options) {
1803
+ return this.sendCorrelatedSessionRequest({
1804
+ requestId: options?.requestId,
1805
+ message: {
1806
+ type: "get_providers_snapshot_request",
1807
+ cwd: options?.cwd,
1808
+ },
1809
+ responseType: "get_providers_snapshot_response",
1810
+ timeout: 10000,
1811
+ });
1812
+ }
1813
+ async getDaemonConfig(requestId) {
1814
+ return this.sendCorrelatedSessionRequest({
1815
+ requestId,
1816
+ message: {
1817
+ type: "get_daemon_config_request",
1818
+ },
1819
+ responseType: "get_daemon_config_response",
1820
+ timeout: 10000,
1821
+ });
1822
+ }
1823
+ async patchDaemonConfig(config, requestId) {
1824
+ return this.sendCorrelatedSessionRequest({
1825
+ requestId,
1826
+ message: {
1827
+ type: "set_daemon_config_request",
1828
+ config,
1829
+ },
1830
+ responseType: "set_daemon_config_response",
1831
+ timeout: 10000,
1832
+ });
1833
+ }
1834
+ async refreshProvidersSnapshot(options) {
1835
+ return this.sendCorrelatedSessionRequest({
1836
+ requestId: options?.requestId,
1837
+ message: {
1838
+ type: "refresh_providers_snapshot_request",
1839
+ cwd: options?.cwd,
1840
+ },
1841
+ responseType: "refresh_providers_snapshot_response",
1842
+ timeout: 5000,
1843
+ });
1844
+ }
1845
+ async getProviderDiagnostic(provider, options) {
1846
+ return this.sendCorrelatedSessionRequest({
1847
+ requestId: options?.requestId,
1848
+ message: {
1849
+ type: "provider_diagnostic_request",
1850
+ provider,
1851
+ },
1852
+ responseType: "provider_diagnostic_response",
1853
+ timeout: 30000,
1854
+ });
1855
+ }
1856
+ async listCommands(agentId, requestIdOrOptions) {
1857
+ const requestId = typeof requestIdOrOptions === "string" ? requestIdOrOptions : requestIdOrOptions?.requestId;
1858
+ const draftConfig = typeof requestIdOrOptions === "string" ? undefined : requestIdOrOptions?.draftConfig;
1859
+ return this.sendCorrelatedSessionRequest({
1860
+ requestId,
1861
+ message: {
1862
+ type: "list_commands_request",
1863
+ agentId,
1864
+ ...(draftConfig ? { draftConfig } : {}),
1865
+ },
1866
+ responseType: "list_commands_response",
1867
+ timeout: 30000,
1868
+ });
1869
+ }
1870
+ // ============================================================================
1871
+ // Permissions
1872
+ // ============================================================================
1873
+ async respondToPermission(agentId, requestId, response) {
1874
+ this.sendSessionMessage({
1875
+ type: "agent_permission_response",
1876
+ agentId,
1877
+ requestId,
1878
+ response,
1879
+ });
1880
+ }
1881
+ async respondToPermissionAndWait(agentId, requestId, response, timeout = 15000) {
1882
+ const message = SessionInboundMessageSchema.parse({
1883
+ type: "agent_permission_response",
1884
+ agentId,
1885
+ requestId,
1886
+ response,
1887
+ });
1888
+ return this.sendRequest({
1889
+ requestId,
1890
+ message,
1891
+ timeout,
1892
+ options: { skipQueue: true },
1893
+ select: (msg) => {
1894
+ if (msg.type !== "agent_permission_resolved") {
1895
+ return null;
1896
+ }
1897
+ if (msg.payload.requestId !== requestId) {
1898
+ return null;
1899
+ }
1900
+ if (msg.payload.agentId !== agentId) {
1901
+ return null;
1902
+ }
1903
+ return msg.payload;
1904
+ },
1905
+ });
1906
+ }
1907
+ // ============================================================================
1908
+ // Waiting / Streaming Helpers
1909
+ // ============================================================================
1910
+ async waitForAgentUpsert(agentId, predicate, timeout = 60000) {
1911
+ const initialResult = await this.fetchAgent(agentId).catch(() => null);
1912
+ if (initialResult && predicate(initialResult.agent)) {
1913
+ return initialResult.agent;
1914
+ }
1915
+ const deadline = Date.now() + timeout;
1916
+ return await new Promise((resolve, reject) => {
1917
+ let settled = false;
1918
+ let pollInFlight = false;
1919
+ let pollTimer = null;
1920
+ let timeoutTimer = null;
1921
+ let unsubscribe = null;
1922
+ const finish = (result) => {
1923
+ if (settled) {
1924
+ return;
1925
+ }
1926
+ settled = true;
1927
+ if (timeoutTimer) {
1928
+ clearTimeout(timeoutTimer);
1929
+ timeoutTimer = null;
1930
+ }
1931
+ if (pollTimer) {
1932
+ clearInterval(pollTimer);
1933
+ pollTimer = null;
1934
+ }
1935
+ if (unsubscribe) {
1936
+ unsubscribe();
1937
+ unsubscribe = null;
1938
+ }
1939
+ if (result.kind === "ok") {
1940
+ resolve(result.snapshot);
1941
+ return;
1942
+ }
1943
+ reject(result.error);
1944
+ };
1945
+ const maybeResolve = (snapshot) => {
1946
+ if (!snapshot) {
1947
+ return false;
1948
+ }
1949
+ if (!predicate(snapshot)) {
1950
+ return false;
1951
+ }
1952
+ finish({ kind: "ok", snapshot });
1953
+ return true;
1954
+ };
1955
+ const poll = async () => {
1956
+ if (settled || pollInFlight) {
1957
+ return;
1958
+ }
1959
+ pollInFlight = true;
1960
+ try {
1961
+ const result = await this.fetchAgent(agentId).catch(() => null);
1962
+ maybeResolve(result?.agent ?? null);
1963
+ }
1964
+ finally {
1965
+ pollInFlight = false;
1966
+ }
1967
+ };
1968
+ unsubscribe = this.on("agent_update", (message) => {
1969
+ if (settled) {
1970
+ return;
1971
+ }
1972
+ if (message.type !== "agent_update") {
1973
+ return;
1974
+ }
1975
+ if (message.payload.kind !== "upsert") {
1976
+ return;
1977
+ }
1978
+ const snapshot = message.payload.agent;
1979
+ if (snapshot.id !== agentId) {
1980
+ return;
1981
+ }
1982
+ maybeResolve(snapshot);
1983
+ });
1984
+ const remaining = Math.max(1, deadline - Date.now());
1985
+ timeoutTimer = setTimeout(() => {
1986
+ finish({
1987
+ kind: "error",
1988
+ error: new Error(`Timed out waiting for agent ${agentId}`),
1989
+ });
1990
+ }, remaining);
1991
+ pollTimer = setInterval(() => {
1992
+ void poll();
1993
+ }, 250);
1994
+ void poll();
1995
+ });
1996
+ }
1997
+ async waitForFinish(agentId, timeout = 60000) {
1998
+ const requestId = this.createRequestId();
1999
+ const hasTimeout = Number.isFinite(timeout) && timeout > 0;
2000
+ const message = SessionInboundMessageSchema.parse({
2001
+ type: "wait_for_finish_request",
2002
+ requestId,
2003
+ agentId,
2004
+ ...(hasTimeout ? { timeoutMs: timeout } : {}),
2005
+ });
2006
+ const payload = await this.sendCorrelatedRequest({
2007
+ requestId,
2008
+ message,
2009
+ responseType: "wait_for_finish_response",
2010
+ timeout: hasTimeout ? timeout + 5000 : 0,
2011
+ options: { skipQueue: true },
2012
+ });
2013
+ return {
2014
+ status: payload.status,
2015
+ final: payload.final,
2016
+ error: payload.error,
2017
+ lastMessage: payload.lastMessage,
2018
+ };
2019
+ }
2020
+ // ============================================================================
2021
+ // Terminals
2022
+ // ============================================================================
2023
+ subscribeTerminals(input) {
2024
+ this.terminalDirectorySubscriptions.add(input.cwd);
2025
+ if (!this.transport || this.connectionState.status !== "connected") {
2026
+ return;
2027
+ }
2028
+ this.sendSessionMessage({
2029
+ type: "subscribe_terminals_request",
2030
+ cwd: input.cwd,
2031
+ });
2032
+ }
2033
+ unsubscribeTerminals(input) {
2034
+ this.terminalDirectorySubscriptions.delete(input.cwd);
2035
+ if (!this.transport || this.connectionState.status !== "connected") {
2036
+ return;
2037
+ }
2038
+ this.sendSessionMessage({
2039
+ type: "unsubscribe_terminals_request",
2040
+ cwd: input.cwd,
2041
+ });
2042
+ }
2043
+ async listTerminals(cwd, requestId) {
2044
+ const resolvedRequestId = this.createRequestId(requestId);
2045
+ const message = SessionInboundMessageSchema.parse({
2046
+ type: "list_terminals_request",
2047
+ ...(cwd === undefined ? {} : { cwd }),
2048
+ requestId: resolvedRequestId,
2049
+ });
2050
+ return this.sendCorrelatedRequest({
2051
+ requestId: resolvedRequestId,
2052
+ message,
2053
+ responseType: "list_terminals_response",
2054
+ timeout: 10000,
2055
+ options: { skipQueue: true },
2056
+ });
2057
+ }
2058
+ async createTerminal(cwd, name, requestId) {
2059
+ const resolvedRequestId = this.createRequestId(requestId);
2060
+ const message = SessionInboundMessageSchema.parse({
2061
+ type: "create_terminal_request",
2062
+ cwd,
2063
+ name,
2064
+ requestId: resolvedRequestId,
2065
+ });
2066
+ return this.sendCorrelatedRequest({
2067
+ requestId: resolvedRequestId,
2068
+ message,
2069
+ responseType: "create_terminal_response",
2070
+ timeout: 10000,
2071
+ options: { skipQueue: true },
2072
+ });
2073
+ }
2074
+ async subscribeTerminal(terminalId, requestId) {
2075
+ const resolvedRequestId = this.createRequestId(requestId);
2076
+ const message = SessionInboundMessageSchema.parse({
2077
+ type: "subscribe_terminal_request",
2078
+ terminalId,
2079
+ requestId: resolvedRequestId,
2080
+ });
2081
+ const payload = await this.sendCorrelatedRequest({
2082
+ requestId: resolvedRequestId,
2083
+ message,
2084
+ responseType: "subscribe_terminal_response",
2085
+ timeout: 10000,
2086
+ options: { skipQueue: true },
2087
+ });
2088
+ if (payload.error === null) {
2089
+ this.setTerminalSlot(terminalId, payload.slot);
2090
+ }
2091
+ return payload;
2092
+ }
2093
+ unsubscribeTerminal(terminalId) {
2094
+ this.removeTerminalSlot(terminalId);
2095
+ this.sendSessionMessage({
2096
+ type: "unsubscribe_terminal_request",
2097
+ terminalId,
2098
+ });
2099
+ }
2100
+ sendTerminalInput(terminalId, message) {
2101
+ const slot = this.terminalSlots.get(terminalId);
2102
+ if (typeof slot === "number") {
2103
+ if (message.type === "input") {
2104
+ this.sendBinaryFrame(encodeTerminalStreamFrame({
2105
+ opcode: TerminalStreamOpcode.Input,
2106
+ slot,
2107
+ payload: encodeUtf8String(message.data),
2108
+ }));
2109
+ return;
2110
+ }
2111
+ if (message.type === "resize") {
2112
+ this.sendBinaryFrame(encodeTerminalStreamFrame({
2113
+ opcode: TerminalStreamOpcode.Resize,
2114
+ slot,
2115
+ payload: encodeTerminalResizePayload({
2116
+ rows: message.rows,
2117
+ cols: message.cols,
2118
+ }),
2119
+ }));
2120
+ return;
2121
+ }
2122
+ }
2123
+ this.sendSessionMessage({
2124
+ type: "terminal_input",
2125
+ terminalId,
2126
+ message,
2127
+ });
2128
+ }
2129
+ async killTerminal(terminalId, requestId) {
2130
+ const resolvedRequestId = this.createRequestId(requestId);
2131
+ const message = SessionInboundMessageSchema.parse({
2132
+ type: "kill_terminal_request",
2133
+ terminalId,
2134
+ requestId: resolvedRequestId,
2135
+ });
2136
+ return this.sendCorrelatedRequest({
2137
+ requestId: resolvedRequestId,
2138
+ message,
2139
+ responseType: "kill_terminal_response",
2140
+ timeout: 10000,
2141
+ options: { skipQueue: true },
2142
+ });
2143
+ }
2144
+ async closeItems(input, requestId) {
2145
+ const resolvedRequestId = this.createRequestId(requestId);
2146
+ const message = SessionInboundMessageSchema.parse({
2147
+ type: "close_items_request",
2148
+ agentIds: input.agentIds ?? [],
2149
+ terminalIds: input.terminalIds ?? [],
2150
+ requestId: resolvedRequestId,
2151
+ });
2152
+ return this.sendCorrelatedRequest({
2153
+ requestId: resolvedRequestId,
2154
+ message,
2155
+ responseType: "close_items_response",
2156
+ timeout: 10000,
2157
+ options: { skipQueue: true },
2158
+ });
2159
+ }
2160
+ async captureTerminal(terminalId, options, requestId) {
2161
+ const resolvedRequestId = this.createRequestId(requestId);
2162
+ const message = SessionInboundMessageSchema.parse({
2163
+ type: "capture_terminal_request",
2164
+ terminalId,
2165
+ ...(options?.start === undefined ? {} : { start: options.start }),
2166
+ ...(options?.end === undefined ? {} : { end: options.end }),
2167
+ ...(options?.stripAnsi === undefined ? {} : { stripAnsi: options.stripAnsi }),
2168
+ requestId: resolvedRequestId,
2169
+ });
2170
+ return this.sendCorrelatedRequest({
2171
+ requestId: resolvedRequestId,
2172
+ message,
2173
+ responseType: "capture_terminal_response",
2174
+ timeout: 10000,
2175
+ options: { skipQueue: true },
2176
+ });
2177
+ }
2178
+ async createChatRoom(options) {
2179
+ return this.sendCorrelatedSessionRequest({
2180
+ requestId: options.requestId,
2181
+ message: {
2182
+ type: "chat/create",
2183
+ name: options.name,
2184
+ ...(options.purpose ? { purpose: options.purpose } : {}),
2185
+ },
2186
+ responseType: "chat/create/response",
2187
+ timeout: 10000,
2188
+ });
2189
+ }
2190
+ async listChatRooms(requestId) {
2191
+ return this.sendCorrelatedSessionRequest({
2192
+ requestId,
2193
+ message: {
2194
+ type: "chat/list",
2195
+ },
2196
+ responseType: "chat/list/response",
2197
+ timeout: 10000,
2198
+ });
2199
+ }
2200
+ async inspectChatRoom(options) {
2201
+ return this.sendCorrelatedSessionRequest({
2202
+ requestId: options.requestId,
2203
+ message: {
2204
+ type: "chat/inspect",
2205
+ room: options.room,
2206
+ },
2207
+ responseType: "chat/inspect/response",
2208
+ timeout: 10000,
2209
+ });
2210
+ }
2211
+ async deleteChatRoom(options) {
2212
+ return this.sendCorrelatedSessionRequest({
2213
+ requestId: options.requestId,
2214
+ message: {
2215
+ type: "chat/delete",
2216
+ room: options.room,
2217
+ },
2218
+ responseType: "chat/delete/response",
2219
+ timeout: 10000,
2220
+ });
2221
+ }
2222
+ async postChatMessage(options) {
2223
+ return this.sendCorrelatedSessionRequest({
2224
+ requestId: options.requestId,
2225
+ message: {
2226
+ type: "chat/post",
2227
+ room: options.room,
2228
+ body: options.body,
2229
+ ...(options.authorAgentId ? { authorAgentId: options.authorAgentId } : {}),
2230
+ ...(options.replyToMessageId ? { replyToMessageId: options.replyToMessageId } : {}),
2231
+ },
2232
+ responseType: "chat/post/response",
2233
+ timeout: 10000,
2234
+ });
2235
+ }
2236
+ async readChatMessages(options) {
2237
+ return this.sendCorrelatedSessionRequest({
2238
+ requestId: options.requestId,
2239
+ message: {
2240
+ type: "chat/read",
2241
+ room: options.room,
2242
+ ...(typeof options.limit === "number" ? { limit: options.limit } : {}),
2243
+ ...(options.since ? { since: options.since } : {}),
2244
+ ...(options.authorAgentId ? { authorAgentId: options.authorAgentId } : {}),
2245
+ },
2246
+ responseType: "chat/read/response",
2247
+ timeout: 10000,
2248
+ });
2249
+ }
2250
+ async waitForChatMessages(options) {
2251
+ return this.sendCorrelatedSessionRequest({
2252
+ requestId: options.requestId,
2253
+ message: {
2254
+ type: "chat/wait",
2255
+ room: options.room,
2256
+ ...(options.afterMessageId ? { afterMessageId: options.afterMessageId } : {}),
2257
+ ...(typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {}),
2258
+ },
2259
+ responseType: "chat/wait/response",
2260
+ timeout: (options.timeoutMs ?? 0) + 10000,
2261
+ });
2262
+ }
2263
+ async scheduleCreate(options) {
2264
+ return this.sendCorrelatedSessionRequest({
2265
+ requestId: options.requestId,
2266
+ message: {
2267
+ type: "schedule/create",
2268
+ prompt: options.prompt,
2269
+ cadence: options.cadence,
2270
+ target: options.target,
2271
+ ...(options.name ? { name: options.name } : {}),
2272
+ ...(typeof options.maxRuns === "number" ? { maxRuns: options.maxRuns } : {}),
2273
+ ...(options.expiresAt ? { expiresAt: options.expiresAt } : {}),
2274
+ },
2275
+ responseType: "schedule/create/response",
2276
+ timeout: 10000,
2277
+ });
2278
+ }
2279
+ async scheduleList(requestId) {
2280
+ return this.sendCorrelatedSessionRequest({
2281
+ requestId,
2282
+ message: {
2283
+ type: "schedule/list",
2284
+ },
2285
+ responseType: "schedule/list/response",
2286
+ timeout: 10000,
2287
+ });
2288
+ }
2289
+ async scheduleInspect(options) {
2290
+ return this.sendCorrelatedSessionRequest({
2291
+ requestId: options.requestId,
2292
+ message: {
2293
+ type: "schedule/inspect",
2294
+ scheduleId: options.id,
2295
+ },
2296
+ responseType: "schedule/inspect/response",
2297
+ timeout: 10000,
2298
+ });
2299
+ }
2300
+ async scheduleLogs(options) {
2301
+ return this.sendCorrelatedSessionRequest({
2302
+ requestId: options.requestId,
2303
+ message: {
2304
+ type: "schedule/logs",
2305
+ scheduleId: options.id,
2306
+ },
2307
+ responseType: "schedule/logs/response",
2308
+ timeout: 10000,
2309
+ });
2310
+ }
2311
+ async schedulePause(options) {
2312
+ return this.sendCorrelatedSessionRequest({
2313
+ requestId: options.requestId,
2314
+ message: {
2315
+ type: "schedule/pause",
2316
+ scheduleId: options.id,
2317
+ },
2318
+ responseType: "schedule/pause/response",
2319
+ timeout: 10000,
2320
+ });
2321
+ }
2322
+ async scheduleResume(options) {
2323
+ return this.sendCorrelatedSessionRequest({
2324
+ requestId: options.requestId,
2325
+ message: {
2326
+ type: "schedule/resume",
2327
+ scheduleId: options.id,
2328
+ },
2329
+ responseType: "schedule/resume/response",
2330
+ timeout: 10000,
2331
+ });
2332
+ }
2333
+ async scheduleDelete(options) {
2334
+ return this.sendCorrelatedSessionRequest({
2335
+ requestId: options.requestId,
2336
+ message: {
2337
+ type: "schedule/delete",
2338
+ scheduleId: options.id,
2339
+ },
2340
+ responseType: "schedule/delete/response",
2341
+ timeout: 10000,
2342
+ });
2343
+ }
2344
+ async loopRun(options) {
2345
+ return this.sendCorrelatedSessionRequest({
2346
+ requestId: options.requestId,
2347
+ message: {
2348
+ type: "loop/run",
2349
+ prompt: options.prompt,
2350
+ cwd: options.cwd,
2351
+ ...(options.verifyPrompt ? { verifyPrompt: options.verifyPrompt } : {}),
2352
+ ...(options.verifyChecks && options.verifyChecks.length > 0
2353
+ ? { verifyChecks: options.verifyChecks }
2354
+ : {}),
2355
+ ...(options.name ? { name: options.name } : {}),
2356
+ ...(typeof options.sleepMs === "number" ? { sleepMs: options.sleepMs } : {}),
2357
+ ...(typeof options.maxIterations === "number"
2358
+ ? { maxIterations: options.maxIterations }
2359
+ : {}),
2360
+ ...(typeof options.maxTimeMs === "number" ? { maxTimeMs: options.maxTimeMs } : {}),
2361
+ },
2362
+ responseType: "loop/run/response",
2363
+ timeout: 15000,
2364
+ });
2365
+ }
2366
+ async loopList(requestId) {
2367
+ return this.sendCorrelatedSessionRequest({
2368
+ requestId,
2369
+ message: {
2370
+ type: "loop/list",
2371
+ },
2372
+ responseType: "loop/list/response",
2373
+ timeout: 10000,
2374
+ });
2375
+ }
2376
+ async loopInspect(options) {
2377
+ const normalized = typeof options === "string" ? { id: options } : options;
2378
+ return this.sendCorrelatedSessionRequest({
2379
+ requestId: normalized.requestId,
2380
+ message: {
2381
+ type: "loop/inspect",
2382
+ id: normalized.id,
2383
+ },
2384
+ responseType: "loop/inspect/response",
2385
+ timeout: 10000,
2386
+ });
2387
+ }
2388
+ async loopLogs(options, afterSeq) {
2389
+ const normalized = typeof options === "string" ? { id: options, afterSeq } : options;
2390
+ return this.sendCorrelatedSessionRequest({
2391
+ requestId: normalized.requestId,
2392
+ message: {
2393
+ type: "loop/logs",
2394
+ id: normalized.id,
2395
+ ...(typeof normalized.afterSeq === "number" ? { afterSeq: normalized.afterSeq } : {}),
2396
+ },
2397
+ responseType: "loop/logs/response",
2398
+ timeout: 10000,
2399
+ });
2400
+ }
2401
+ async loopStop(options) {
2402
+ const normalized = typeof options === "string" ? { id: options } : options;
2403
+ return this.sendCorrelatedSessionRequest({
2404
+ requestId: normalized.requestId,
2405
+ message: {
2406
+ type: "loop/stop",
2407
+ id: normalized.id,
2408
+ },
2409
+ responseType: "loop/stop/response",
2410
+ timeout: 10000,
2411
+ });
2412
+ }
2413
+ onTerminalStreamEvent(handler) {
2414
+ this.terminalStreamListeners.add(handler);
2415
+ return () => {
2416
+ this.terminalStreamListeners.delete(handler);
2417
+ };
2418
+ }
2419
+ async waitForTerminalStreamEvent(predicate, timeout = 5000) {
2420
+ return new Promise((resolve, reject) => {
2421
+ const timeoutHandle = setTimeout(() => {
2422
+ unsubscribe();
2423
+ reject(new Error(`Timeout waiting for terminal stream event (${timeout}ms)`));
2424
+ }, timeout);
2425
+ const unsubscribe = this.onTerminalStreamEvent((event) => {
2426
+ if (!predicate(event)) {
2427
+ return;
2428
+ }
2429
+ clearTimeout(timeoutHandle);
2430
+ unsubscribe();
2431
+ resolve(event);
2432
+ });
2433
+ });
2434
+ }
2435
+ // ============================================================================
2436
+ // Internals
2437
+ // ============================================================================
2438
+ createRequestId(requestId) {
2439
+ return requestId ?? crypto.randomUUID();
2440
+ }
2441
+ setTerminalSlot(terminalId, slot) {
2442
+ const existingTerminalId = this.slotTerminals.get(slot);
2443
+ if (existingTerminalId && existingTerminalId !== terminalId) {
2444
+ this.terminalSlots.delete(existingTerminalId);
2445
+ }
2446
+ const existingSlot = this.terminalSlots.get(terminalId);
2447
+ if (typeof existingSlot === "number" && existingSlot !== slot) {
2448
+ this.slotTerminals.delete(existingSlot);
2449
+ }
2450
+ this.terminalSlots.set(terminalId, slot);
2451
+ this.slotTerminals.set(slot, terminalId);
2452
+ }
2453
+ removeTerminalSlot(terminalId) {
2454
+ const slot = this.terminalSlots.get(terminalId);
2455
+ if (typeof slot !== "number") {
2456
+ return;
2457
+ }
2458
+ this.terminalSlots.delete(terminalId);
2459
+ if (this.slotTerminals.get(slot) === terminalId) {
2460
+ this.slotTerminals.delete(slot);
2461
+ }
2462
+ }
2463
+ clearTerminalSlots() {
2464
+ this.terminalSlots.clear();
2465
+ this.slotTerminals.clear();
2466
+ }
2467
+ getLastServerInfoMessage() {
2468
+ return this.lastServerInfoMessage;
2469
+ }
2470
+ resolveTransportUrlForAttempt() {
2471
+ return this.config.url;
2472
+ }
2473
+ sendHelloMessage() {
2474
+ if (!this.transport) {
2475
+ this.scheduleReconnect({
2476
+ reason: "Transport unavailable before hello",
2477
+ event: "HELLO_TRANSPORT_MISSING",
2478
+ reasonCode: "transport_error",
2479
+ });
2480
+ return;
2481
+ }
2482
+ try {
2483
+ this.transport.send(JSON.stringify({
2484
+ type: "hello",
2485
+ clientId: this.config.clientId,
2486
+ clientType: this.config.clientType ?? "cli",
2487
+ protocolVersion: 1,
2488
+ ...(this.config.appVersion ? { appVersion: this.config.appVersion } : {}),
2489
+ }));
2490
+ }
2491
+ catch (error) {
2492
+ const message = error instanceof Error ? error.message : "Failed to send hello message";
2493
+ this.lastErrorValue = message;
2494
+ this.scheduleReconnect({
2495
+ reason: message,
2496
+ event: "HELLO_SEND_FAILED",
2497
+ reasonCode: "transport_error",
2498
+ });
2499
+ }
2500
+ }
2501
+ disposeTransport(code = 1001, reason = "Reconnecting") {
2502
+ this.cleanupTransport();
2503
+ if (this.transport) {
2504
+ try {
2505
+ this.transport.close(code, reason);
2506
+ }
2507
+ catch {
2508
+ // no-op
2509
+ }
2510
+ this.transport = null;
2511
+ }
2512
+ }
2513
+ cleanupTransport() {
2514
+ this.resetConnectTimeout();
2515
+ if (this.pendingGenericTransportErrorTimeout) {
2516
+ clearTimeout(this.pendingGenericTransportErrorTimeout);
2517
+ this.pendingGenericTransportErrorTimeout = null;
2518
+ }
2519
+ for (const cleanup of this.transportCleanup) {
2520
+ try {
2521
+ cleanup();
2522
+ }
2523
+ catch {
2524
+ // no-op
2525
+ }
2526
+ }
2527
+ this.transportCleanup = [];
2528
+ }
2529
+ resetConnectTimeout() {
2530
+ if (!this.connectTimeout) {
2531
+ return;
2532
+ }
2533
+ clearTimeout(this.connectTimeout);
2534
+ this.connectTimeout = null;
2535
+ }
2536
+ handleTransportMessage(data) {
2537
+ const rawData = data && typeof data === "object" && "data" in data ? data.data : data;
2538
+ if (typeof Blob !== "undefined" &&
2539
+ rawData instanceof Blob &&
2540
+ typeof rawData.arrayBuffer === "function") {
2541
+ void rawData
2542
+ .arrayBuffer()
2543
+ .then((buffer) => {
2544
+ this.handleTransportMessage(buffer);
2545
+ })
2546
+ .catch(() => {
2547
+ // Ignore failed blob decoding and allow reconnect logic to recover.
2548
+ });
2549
+ return;
2550
+ }
2551
+ const rawBytes = asUint8Array(rawData);
2552
+ if (rawBytes) {
2553
+ const frame = decodeTerminalStreamFrame(rawBytes);
2554
+ if (frame) {
2555
+ this.handleBinaryFrame(frame);
2556
+ return;
2557
+ }
2558
+ }
2559
+ const payload = decodeMessageData(rawData);
2560
+ if (!payload) {
2561
+ return;
2562
+ }
2563
+ let parsedJson;
2564
+ try {
2565
+ parsedJson = JSON.parse(payload);
2566
+ }
2567
+ catch {
2568
+ return;
2569
+ }
2570
+ const parsed = WSOutboundMessageSchema.safeParse(parsedJson);
2571
+ if (!parsed.success) {
2572
+ const msgType = parsedJson?.type ?? "unknown";
2573
+ this.logger.warn({ msgType, error: parsed.error.message }, "Message validation failed");
2574
+ return;
2575
+ }
2576
+ if (parsed.data.type === "pong") {
2577
+ return;
2578
+ }
2579
+ this.handleSessionMessage(parsed.data.message);
2580
+ }
2581
+ handleBinaryFrame(frame) {
2582
+ const terminalId = this.slotTerminals.get(frame.slot);
2583
+ if (!terminalId) {
2584
+ return;
2585
+ }
2586
+ if (frame.opcode === TerminalStreamOpcode.Output) {
2587
+ this.emitTerminalStreamEvent({
2588
+ terminalId,
2589
+ type: "output",
2590
+ data: frame.payload,
2591
+ });
2592
+ return;
2593
+ }
2594
+ if (frame.opcode === TerminalStreamOpcode.Snapshot) {
2595
+ const state = decodeTerminalSnapshotPayload(frame.payload);
2596
+ if (!state) {
2597
+ return;
2598
+ }
2599
+ this.emitTerminalStreamEvent({
2600
+ terminalId,
2601
+ type: "snapshot",
2602
+ state,
2603
+ });
2604
+ }
2605
+ }
2606
+ emitTerminalStreamEvent(event) {
2607
+ for (const listener of this.terminalStreamListeners) {
2608
+ try {
2609
+ listener(event);
2610
+ }
2611
+ catch {
2612
+ // no-op
2613
+ }
2614
+ }
2615
+ }
2616
+ updateConnectionState(next, metadata) {
2617
+ const previous = this.connectionState;
2618
+ this.connectionState = next;
2619
+ const reasonFromNext = next.status === "disconnected" && typeof next.reason === "string" ? next.reason : null;
2620
+ const reason = metadata?.reason ?? reasonFromNext;
2621
+ const reasonCode = metadata?.reasonCode ?? toReasonCode(reason);
2622
+ this.logger.debug({
2623
+ serverId: this.logServerId,
2624
+ clientIdHash: this.logClientIdHash,
2625
+ from: previous.status,
2626
+ to: next.status,
2627
+ event: metadata?.event ?? "STATE_UPDATE",
2628
+ connectionPath: this.logConnectionPath,
2629
+ generation: this.logGeneration,
2630
+ reasonCode,
2631
+ reason,
2632
+ }, "DaemonClientTransition");
2633
+ for (const listener of this.connectionListeners) {
2634
+ try {
2635
+ listener(next);
2636
+ }
2637
+ catch {
2638
+ // no-op
2639
+ }
2640
+ }
2641
+ }
2642
+ setReconnectEnabled(enabled) {
2643
+ this.config = { ...this.config, reconnect: { ...this.config.reconnect, enabled } };
2644
+ }
2645
+ scheduleReconnect(input) {
2646
+ if (this.reconnectTimeout) {
2647
+ clearTimeout(this.reconnectTimeout);
2648
+ this.reconnectTimeout = null;
2649
+ }
2650
+ const wasDisposed = this.connectionState.status === "disposed";
2651
+ const reason = input?.reason;
2652
+ if (typeof reason === "string" && reason.trim().length > 0) {
2653
+ this.lastErrorValue = reason.trim();
2654
+ }
2655
+ // Clear all pending waiters and queued sends since the connection was lost
2656
+ // and responses from the previous connection will never arrive.
2657
+ this.clearWaiters(new Error(reason ?? "Connection lost"));
2658
+ this.rejectPendingSendQueue(new Error(reason ?? "Connection lost"));
2659
+ this.clearTerminalSlots();
2660
+ this.lastServerInfoMessage = null;
2661
+ if (wasDisposed) {
2662
+ this.rejectConnect(new Error(reason ?? "Daemon client is disposed"));
2663
+ return;
2664
+ }
2665
+ this.updateConnectionState({
2666
+ status: "disconnected",
2667
+ ...(reason ? { reason } : {}),
2668
+ }, {
2669
+ event: input?.event ?? "TRANSPORT_CLOSE",
2670
+ ...(reason ? { reason } : {}),
2671
+ ...(input?.reasonCode ? { reasonCode: input.reasonCode } : {}),
2672
+ });
2673
+ if (!this.shouldReconnect || this.config.reconnect?.enabled === false) {
2674
+ this.rejectConnect(new Error(reason ?? "Transport disconnected before connect"));
2675
+ return;
2676
+ }
2677
+ const attempt = this.reconnectAttempt;
2678
+ const baseDelay = this.config.reconnect?.baseDelayMs ?? DEFAULT_RECONNECT_BASE_DELAY_MS;
2679
+ const maxDelay = this.config.reconnect?.maxDelayMs ?? DEFAULT_RECONNECT_MAX_DELAY_MS;
2680
+ const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
2681
+ this.reconnectAttempt = attempt + 1;
2682
+ this.reconnectTimeout = setTimeout(() => {
2683
+ this.reconnectTimeout = null;
2684
+ if (!this.shouldReconnect) {
2685
+ return;
2686
+ }
2687
+ this.attemptConnect();
2688
+ }, delay);
2689
+ }
2690
+ handleSessionMessage(msg) {
2691
+ if (msg.type === "status") {
2692
+ const serverInfo = parseServerInfoStatusPayload(msg.payload);
2693
+ if (serverInfo) {
2694
+ this.lastServerInfoMessage = serverInfo;
2695
+ if (this.connectionState.status === "connecting") {
2696
+ this.resetConnectTimeout();
2697
+ this.reconnectAttempt = 0;
2698
+ this.updateConnectionState({ status: "connected" }, { event: "HELLO_SERVER_INFO" });
2699
+ this.resubscribeCheckoutDiffSubscriptions();
2700
+ this.resubscribeTerminalDirectorySubscriptions();
2701
+ this.flushPendingSendQueue();
2702
+ this.resolveConnect();
2703
+ }
2704
+ }
2705
+ }
2706
+ if (msg.type === "terminal_stream_exit") {
2707
+ this.removeTerminalSlot(msg.payload.terminalId);
2708
+ }
2709
+ if (this.rawMessageListeners.size > 0) {
2710
+ for (const handler of this.rawMessageListeners) {
2711
+ try {
2712
+ handler(msg);
2713
+ }
2714
+ catch {
2715
+ // no-op
2716
+ }
2717
+ }
2718
+ }
2719
+ const handlers = this.messageHandlers.get(msg.type);
2720
+ if (handlers) {
2721
+ for (const handler of handlers) {
2722
+ try {
2723
+ handler(msg);
2724
+ }
2725
+ catch {
2726
+ // no-op
2727
+ }
2728
+ }
2729
+ }
2730
+ const event = this.toEvent(msg);
2731
+ if (event) {
2732
+ for (const handler of this.eventListeners) {
2733
+ handler(event);
2734
+ }
2735
+ }
2736
+ this.resolveWaiters(msg);
2737
+ }
2738
+ resolveWaiters(msg) {
2739
+ for (const waiter of Array.from(this.waiters)) {
2740
+ const result = waiter.predicate(msg);
2741
+ if (result !== null) {
2742
+ this.waiters.delete(waiter);
2743
+ if (waiter.timeoutHandle) {
2744
+ clearTimeout(waiter.timeoutHandle);
2745
+ }
2746
+ waiter.resolve(result);
2747
+ }
2748
+ }
2749
+ }
2750
+ clearWaiters(error) {
2751
+ for (const waiter of Array.from(this.waiters)) {
2752
+ if (waiter.timeoutHandle) {
2753
+ clearTimeout(waiter.timeoutHandle);
2754
+ }
2755
+ waiter.reject(error);
2756
+ }
2757
+ this.waiters.clear();
2758
+ }
2759
+ toEvent(msg) {
2760
+ switch (msg.type) {
2761
+ case "agent_update":
2762
+ return {
2763
+ type: "agent_update",
2764
+ agentId: msg.payload.kind === "upsert" ? msg.payload.agent.id : msg.payload.agentId,
2765
+ payload: msg.payload,
2766
+ };
2767
+ case "workspace_update":
2768
+ return {
2769
+ type: "workspace_update",
2770
+ workspaceId: msg.payload.kind === "upsert" ? msg.payload.workspace.id : msg.payload.id,
2771
+ payload: msg.payload,
2772
+ };
2773
+ case "agent_stream":
2774
+ return {
2775
+ type: "agent_stream",
2776
+ agentId: msg.payload.agentId,
2777
+ event: msg.payload.event,
2778
+ timestamp: msg.payload.timestamp,
2779
+ ...(typeof msg.payload.seq === "number" ? { seq: msg.payload.seq } : {}),
2780
+ ...(typeof msg.payload.epoch === "string" ? { epoch: msg.payload.epoch } : {}),
2781
+ };
2782
+ case "status":
2783
+ return { type: "status", payload: msg.payload };
2784
+ case "agent_deleted":
2785
+ return { type: "agent_deleted", agentId: msg.payload.agentId };
2786
+ case "agent_permission_request":
2787
+ return {
2788
+ type: "agent_permission_request",
2789
+ agentId: msg.payload.agentId,
2790
+ request: msg.payload.request,
2791
+ };
2792
+ case "agent_permission_resolved":
2793
+ return {
2794
+ type: "agent_permission_resolved",
2795
+ agentId: msg.payload.agentId,
2796
+ requestId: msg.payload.requestId,
2797
+ resolution: msg.payload.resolution,
2798
+ };
2799
+ case "providers_snapshot_update":
2800
+ return {
2801
+ type: "providers_snapshot_update",
2802
+ payload: msg.payload,
2803
+ };
2804
+ default:
2805
+ return null;
2806
+ }
2807
+ }
2808
+ waitForWithCancel(predicate, timeout = 30000, _options) {
2809
+ // Capture stack trace at call site, not inside setTimeout
2810
+ const timeoutError = new Error(`Timeout waiting for message (${timeout}ms)`);
2811
+ let waiter = null;
2812
+ let settled = false;
2813
+ let rejectFn = null;
2814
+ const promise = new Promise((resolve, reject) => {
2815
+ const wrappedResolve = (value) => {
2816
+ if (settled)
2817
+ return;
2818
+ settled = true;
2819
+ resolve(value);
2820
+ };
2821
+ const wrappedReject = (error) => {
2822
+ if (settled)
2823
+ return;
2824
+ settled = true;
2825
+ reject(error);
2826
+ };
2827
+ rejectFn = wrappedReject;
2828
+ const timeoutHandle = timeout > 0
2829
+ ? setTimeout(() => {
2830
+ if (waiter) {
2831
+ this.waiters.delete(waiter);
2832
+ }
2833
+ wrappedReject(timeoutError);
2834
+ }, timeout)
2835
+ : null;
2836
+ waiter = {
2837
+ predicate,
2838
+ resolve: wrappedResolve,
2839
+ reject: wrappedReject,
2840
+ timeoutHandle,
2841
+ };
2842
+ this.waiters.add(waiter);
2843
+ });
2844
+ const cancel = (error) => {
2845
+ if (settled) {
2846
+ return;
2847
+ }
2848
+ if (waiter) {
2849
+ this.waiters.delete(waiter);
2850
+ if (waiter.timeoutHandle) {
2851
+ clearTimeout(waiter.timeoutHandle);
2852
+ }
2853
+ }
2854
+ if (rejectFn) {
2855
+ rejectFn(error);
2856
+ return;
2857
+ }
2858
+ // Extremely unlikely: cancel called before the Promise executor ran.
2859
+ queueMicrotask(() => {
2860
+ if (!settled && rejectFn) {
2861
+ rejectFn(error);
2862
+ }
2863
+ });
2864
+ };
2865
+ return { promise, cancel };
2866
+ }
2867
+ }
2868
+ function resolveAgentConfig(options) {
2869
+ const { config, provider, cwd, initialPrompt: _initialPrompt, images: _images, git: _git, worktreeName: _worktreeName, requestId: _requestId, labels: _labels, ...overrides } = options;
2870
+ const baseConfig = {
2871
+ ...(provider ? { provider } : {}),
2872
+ ...(cwd ? { cwd } : {}),
2873
+ ...overrides,
2874
+ };
2875
+ const merged = config ? { ...baseConfig, ...config } : baseConfig;
2876
+ if (!merged.provider || !merged.cwd) {
2877
+ throw new Error("createAgent requires provider and cwd");
2878
+ }
2879
+ return {
2880
+ ...merged,
2881
+ provider: merged.provider,
2882
+ cwd: merged.cwd,
2883
+ };
2884
+ }
2885
+ //# sourceMappingURL=daemon-client.js.map