@getpaseo/server 0.1.15 → 0.1.17

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 (364) hide show
  1. package/dist/scripts/daemon-runner.js +53 -14
  2. package/dist/scripts/daemon-runner.js.map +1 -1
  3. package/dist/scripts/dev-runner.js +9 -16
  4. package/dist/scripts/dev-runner.js.map +1 -1
  5. package/dist/scripts/supervisor.js +40 -13
  6. package/dist/scripts/supervisor.js.map +1 -1
  7. package/dist/server/client/daemon-client.d.ts +63 -6
  8. package/dist/server/client/daemon-client.d.ts.map +1 -1
  9. package/dist/server/client/daemon-client.js +436 -92
  10. package/dist/server/client/daemon-client.js.map +1 -1
  11. package/dist/server/server/agent/agent-manager.d.ts +13 -1
  12. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  13. package/dist/server/server/agent/agent-manager.js +404 -39
  14. package/dist/server/server/agent/agent-manager.js.map +1 -1
  15. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  16. package/dist/server/server/agent/agent-metadata-generator.js +13 -4
  17. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  18. package/dist/server/server/agent/agent-projections.d.ts +5 -0
  19. package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
  20. package/dist/server/server/agent/agent-projections.js +24 -0
  21. package/dist/server/server/agent/agent-projections.js.map +1 -1
  22. package/dist/server/server/agent/agent-response-loop.js +1 -1
  23. package/dist/server/server/agent/agent-response-loop.js.map +1 -1
  24. package/dist/server/server/agent/agent-sdk-types.d.ts +20 -0
  25. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  26. package/dist/server/server/agent/agent-sdk-types.js +11 -1
  27. package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
  28. package/dist/server/server/agent/agent-storage.d.ts +20 -6
  29. package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
  30. package/dist/server/server/agent/agent-storage.js +43 -72
  31. package/dist/server/server/agent/agent-storage.js.map +1 -1
  32. package/dist/server/server/agent/agent-title-limits.d.ts +3 -0
  33. package/dist/server/server/agent/agent-title-limits.d.ts.map +1 -0
  34. package/dist/server/server/agent/agent-title-limits.js +3 -0
  35. package/dist/server/server/agent/agent-title-limits.js.map +1 -0
  36. package/dist/server/server/agent/providers/claude/model-catalog.d.ts +29 -0
  37. package/dist/server/server/agent/providers/claude/model-catalog.d.ts.map +1 -0
  38. package/dist/server/server/agent/providers/claude/model-catalog.js +70 -0
  39. package/dist/server/server/agent/providers/claude/model-catalog.js.map +1 -0
  40. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +44 -0
  41. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -0
  42. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +250 -0
  43. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
  44. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
  45. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +17 -0
  46. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
  47. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  48. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +2 -0
  49. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  50. package/dist/server/server/agent/providers/claude-agent.d.ts +10 -3
  51. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  52. package/dist/server/server/agent/providers/claude-agent.js +1702 -330
  53. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  54. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  55. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +81 -28
  56. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  57. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  58. package/dist/server/server/agent/providers/codex-app-server-agent.js +50 -9
  59. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  60. package/dist/server/server/agent/providers/opencode-agent.d.ts +10 -1
  61. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  62. package/dist/server/server/agent/providers/opencode-agent.js +207 -176
  63. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  64. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +55 -0
  65. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  66. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +1 -0
  67. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  68. package/dist/server/server/agent/timeline-projection.d.ts +20 -0
  69. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  70. package/dist/server/server/agent/timeline-projection.js +73 -0
  71. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  72. package/dist/server/server/bootstrap.d.ts +15 -0
  73. package/dist/server/server/bootstrap.d.ts.map +1 -1
  74. package/dist/server/server/bootstrap.js +27 -4
  75. package/dist/server/server/bootstrap.js.map +1 -1
  76. package/dist/server/server/client-message-id.d.ts +3 -0
  77. package/dist/server/server/client-message-id.d.ts.map +1 -0
  78. package/dist/server/server/client-message-id.js +12 -0
  79. package/dist/server/server/client-message-id.js.map +1 -0
  80. package/dist/server/server/file-download/token-store.d.ts +0 -1
  81. package/dist/server/server/file-download/token-store.d.ts.map +1 -1
  82. package/dist/server/server/file-download/token-store.js.map +1 -1
  83. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  84. package/dist/server/server/file-explorer/service.js +56 -36
  85. package/dist/server/server/file-explorer/service.js.map +1 -1
  86. package/dist/server/server/index.js +85 -29
  87. package/dist/server/server/index.js.map +1 -1
  88. package/dist/server/server/logger.d.ts +24 -3
  89. package/dist/server/server/logger.d.ts.map +1 -1
  90. package/dist/server/server/logger.js +157 -21
  91. package/dist/server/server/logger.js.map +1 -1
  92. package/dist/server/server/persisted-config.d.ts +94 -8
  93. package/dist/server/server/persisted-config.d.ts.map +1 -1
  94. package/dist/server/server/persisted-config.js +25 -3
  95. package/dist/server/server/persisted-config.js.map +1 -1
  96. package/dist/server/server/persistence-hooks.js +1 -1
  97. package/dist/server/server/persistence-hooks.js.map +1 -1
  98. package/dist/server/server/pid-lock.d.ts +6 -2
  99. package/dist/server/server/pid-lock.d.ts.map +1 -1
  100. package/dist/server/server/pid-lock.js +7 -10
  101. package/dist/server/server/pid-lock.js.map +1 -1
  102. package/dist/server/server/relay-transport.js +28 -28
  103. package/dist/server/server/relay-transport.js.map +1 -1
  104. package/dist/server/server/session.d.ts +60 -4
  105. package/dist/server/server/session.d.ts.map +1 -1
  106. package/dist/server/server/session.js +854 -190
  107. package/dist/server/server/session.js.map +1 -1
  108. package/dist/server/server/websocket-server.d.ts +24 -5
  109. package/dist/server/server/websocket-server.d.ts.map +1 -1
  110. package/dist/server/server/websocket-server.js +400 -77
  111. package/dist/server/server/websocket-server.js.map +1 -1
  112. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  113. package/dist/server/server/worktree-bootstrap.js +45 -2
  114. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  115. package/dist/server/shared/daemon-endpoints.d.ts +9 -1
  116. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  117. package/dist/server/shared/daemon-endpoints.js +18 -3
  118. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  119. package/dist/server/shared/messages.d.ts +4432 -380
  120. package/dist/server/shared/messages.d.ts.map +1 -1
  121. package/dist/server/shared/messages.js +139 -6
  122. package/dist/server/shared/messages.js.map +1 -1
  123. package/dist/server/shared/tool-call-display.d.ts.map +1 -1
  124. package/dist/server/shared/tool-call-display.js +7 -0
  125. package/dist/server/shared/tool-call-display.js.map +1 -1
  126. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  127. package/dist/server/terminal/terminal-manager.js +1 -13
  128. package/dist/server/terminal/terminal-manager.js.map +1 -1
  129. package/dist/server/terminal/terminal.d.ts.map +1 -1
  130. package/dist/server/terminal/terminal.js +29 -5
  131. package/dist/server/terminal/terminal.js.map +1 -1
  132. package/dist/server/utils/worktree.d.ts +1 -0
  133. package/dist/server/utils/worktree.d.ts.map +1 -1
  134. package/dist/server/utils/worktree.js +17 -2
  135. package/dist/server/utils/worktree.js.map +1 -1
  136. package/dist/src/server/agent/activity-curator.js +228 -0
  137. package/dist/src/server/agent/activity-curator.js.map +1 -0
  138. package/dist/src/server/agent/agent-manager.js +1712 -0
  139. package/dist/src/server/agent/agent-manager.js.map +1 -0
  140. package/dist/src/server/agent/agent-metadata-generator.js +163 -0
  141. package/dist/src/server/agent/agent-metadata-generator.js.map +1 -0
  142. package/dist/src/server/agent/agent-projections.js +262 -0
  143. package/dist/src/server/agent/agent-projections.js.map +1 -0
  144. package/dist/src/server/agent/agent-response-loop.js +304 -0
  145. package/dist/src/server/agent/agent-response-loop.js.map +1 -0
  146. package/dist/src/server/agent/agent-sdk-types.js +12 -0
  147. package/dist/src/server/agent/agent-sdk-types.js.map +1 -0
  148. package/dist/src/server/agent/agent-storage.js +299 -0
  149. package/dist/src/server/agent/agent-storage.js.map +1 -0
  150. package/dist/src/server/agent/agent-title-limits.js +3 -0
  151. package/dist/src/server/agent/agent-title-limits.js.map +1 -0
  152. package/dist/src/server/agent/audio-utils.js +19 -0
  153. package/dist/src/server/agent/audio-utils.js.map +1 -0
  154. package/dist/src/server/agent/dictation-debug.js +50 -0
  155. package/dist/src/server/agent/dictation-debug.js.map +1 -0
  156. package/dist/src/server/agent/mcp-server.js +787 -0
  157. package/dist/src/server/agent/mcp-server.js.map +1 -0
  158. package/dist/src/server/agent/orchestrator-instructions.js +51 -0
  159. package/dist/src/server/agent/orchestrator-instructions.js.map +1 -0
  160. package/dist/src/server/agent/pcm16-resampler.js +63 -0
  161. package/dist/src/server/agent/pcm16-resampler.js.map +1 -0
  162. package/dist/src/server/agent/provider-launch-config.js +83 -0
  163. package/dist/src/server/agent/provider-launch-config.js.map +1 -0
  164. package/dist/src/server/agent/provider-manifest.js +97 -0
  165. package/dist/src/server/agent/provider-manifest.js.map +1 -0
  166. package/dist/src/server/agent/provider-registry.js +45 -0
  167. package/dist/src/server/agent/provider-registry.js.map +1 -0
  168. package/dist/src/server/agent/providers/claude/model-catalog.js +70 -0
  169. package/dist/src/server/agent/providers/claude/model-catalog.js.map +1 -0
  170. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js +250 -0
  171. package/dist/src/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
  172. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js +109 -0
  173. package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -0
  174. package/dist/src/server/agent/providers/claude/tool-call-mapper.js +238 -0
  175. package/dist/src/server/agent/providers/claude/tool-call-mapper.js.map +1 -0
  176. package/dist/src/server/agent/providers/claude-agent.js +3747 -0
  177. package/dist/src/server/agent/providers/claude-agent.js.map +1 -0
  178. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js +104 -0
  179. package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -0
  180. package/dist/src/server/agent/providers/codex/tool-call-mapper.js +720 -0
  181. package/dist/src/server/agent/providers/codex/tool-call-mapper.js.map +1 -0
  182. package/dist/src/server/agent/providers/codex-app-server-agent.js +2601 -0
  183. package/dist/src/server/agent/providers/codex-app-server-agent.js.map +1 -0
  184. package/dist/src/server/agent/providers/codex-rollout-timeline.js +487 -0
  185. package/dist/src/server/agent/providers/codex-rollout-timeline.js.map +1 -0
  186. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js +39 -0
  187. package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -0
  188. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js +151 -0
  189. package/dist/src/server/agent/providers/opencode/tool-call-mapper.js.map +1 -0
  190. package/dist/src/server/agent/providers/opencode-agent.js +905 -0
  191. package/dist/src/server/agent/providers/opencode-agent.js.map +1 -0
  192. package/dist/src/server/agent/providers/tool-call-detail-primitives.js +552 -0
  193. package/dist/src/server/agent/providers/tool-call-detail-primitives.js.map +1 -0
  194. package/dist/src/server/agent/providers/tool-call-mapper-utils.js +109 -0
  195. package/dist/src/server/agent/providers/tool-call-mapper-utils.js.map +1 -0
  196. package/dist/src/server/agent/recordings-debug.js +19 -0
  197. package/dist/src/server/agent/recordings-debug.js.map +1 -0
  198. package/dist/src/server/agent/stt-debug.js +33 -0
  199. package/dist/src/server/agent/stt-debug.js.map +1 -0
  200. package/dist/src/server/agent/stt-manager.js +233 -0
  201. package/dist/src/server/agent/stt-manager.js.map +1 -0
  202. package/dist/src/server/agent/timeline-append.js +27 -0
  203. package/dist/src/server/agent/timeline-append.js.map +1 -0
  204. package/dist/src/server/agent/timeline-projection.js +215 -0
  205. package/dist/src/server/agent/timeline-projection.js.map +1 -0
  206. package/dist/src/server/agent/tool-name-normalization.js +45 -0
  207. package/dist/src/server/agent/tool-name-normalization.js.map +1 -0
  208. package/dist/src/server/agent/tts-debug.js +24 -0
  209. package/dist/src/server/agent/tts-debug.js.map +1 -0
  210. package/dist/src/server/agent/tts-manager.js +249 -0
  211. package/dist/src/server/agent/tts-manager.js.map +1 -0
  212. package/dist/src/server/agent/wait-for-agent-tracker.js +53 -0
  213. package/dist/src/server/agent/wait-for-agent-tracker.js.map +1 -0
  214. package/dist/src/server/agent-attention-policy.js +40 -0
  215. package/dist/src/server/agent-attention-policy.js.map +1 -0
  216. package/dist/src/server/allowed-hosts.js +94 -0
  217. package/dist/src/server/allowed-hosts.js.map +1 -0
  218. package/dist/src/server/bootstrap.js +498 -0
  219. package/dist/src/server/bootstrap.js.map +1 -0
  220. package/dist/src/server/client-message-id.js +12 -0
  221. package/dist/src/server/client-message-id.js.map +1 -0
  222. package/dist/src/server/config.js +84 -0
  223. package/dist/src/server/config.js.map +1 -0
  224. package/dist/src/server/connection-offer.js +60 -0
  225. package/dist/src/server/connection-offer.js.map +1 -0
  226. package/dist/src/server/daemon-keypair.js +40 -0
  227. package/dist/src/server/daemon-keypair.js.map +1 -0
  228. package/dist/src/server/daemon-version.js +22 -0
  229. package/dist/src/server/daemon-version.js.map +1 -0
  230. package/dist/src/server/dictation/dictation-stream-manager.js +568 -0
  231. package/dist/src/server/dictation/dictation-stream-manager.js.map +1 -0
  232. package/dist/src/server/file-download/token-store.js +40 -0
  233. package/dist/src/server/file-download/token-store.js.map +1 -0
  234. package/dist/src/server/file-explorer/service.js +183 -0
  235. package/dist/src/server/file-explorer/service.js.map +1 -0
  236. package/dist/src/server/json-utils.js +45 -0
  237. package/dist/src/server/json-utils.js.map +1 -0
  238. package/dist/src/server/messages.js +29 -0
  239. package/dist/src/server/messages.js.map +1 -0
  240. package/dist/src/server/package-version.js +47 -0
  241. package/dist/src/server/package-version.js.map +1 -0
  242. package/dist/src/server/paseo-home.js +19 -0
  243. package/dist/src/server/paseo-home.js.map +1 -0
  244. package/dist/src/server/path-utils.js +20 -0
  245. package/dist/src/server/path-utils.js.map +1 -0
  246. package/dist/src/server/persisted-config.js +259 -0
  247. package/dist/src/server/persisted-config.js.map +1 -0
  248. package/dist/src/server/persistence-hooks.js +60 -0
  249. package/dist/src/server/persistence-hooks.js.map +1 -0
  250. package/dist/src/server/pid-lock.js +126 -0
  251. package/dist/src/server/pid-lock.js.map +1 -0
  252. package/dist/src/server/push/push-service.js +68 -0
  253. package/dist/src/server/push/push-service.js.map +1 -0
  254. package/dist/src/server/push/token-store.js +70 -0
  255. package/dist/src/server/push/token-store.js.map +1 -0
  256. package/dist/src/server/relay-transport.js +457 -0
  257. package/dist/src/server/relay-transport.js.map +1 -0
  258. package/dist/src/server/server-id.js +63 -0
  259. package/dist/src/server/server-id.js.map +1 -0
  260. package/dist/src/server/session.js +5947 -0
  261. package/dist/src/server/session.js.map +1 -0
  262. package/dist/src/server/speech/audio.js +101 -0
  263. package/dist/src/server/speech/audio.js.map +1 -0
  264. package/dist/src/server/speech/provider-resolver.js +7 -0
  265. package/dist/src/server/speech/provider-resolver.js.map +1 -0
  266. package/dist/src/server/speech/providers/local/config.js +83 -0
  267. package/dist/src/server/speech/providers/local/config.js.map +1 -0
  268. package/dist/src/server/speech/providers/local/models.js +17 -0
  269. package/dist/src/server/speech/providers/local/models.js.map +1 -0
  270. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js +422 -0
  271. package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -0
  272. package/dist/src/server/speech/providers/local/runtime.js +253 -0
  273. package/dist/src/server/speech/providers/local/runtime.js.map +1 -0
  274. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js +166 -0
  275. package/dist/src/server/speech/providers/local/sherpa/model-catalog.js.map +1 -0
  276. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js +165 -0
  277. package/dist/src/server/speech/providers/local/sherpa/model-downloader.js.map +1 -0
  278. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +68 -0
  279. package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -0
  280. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +79 -0
  281. package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -0
  282. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +11 -0
  283. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +1 -0
  284. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +102 -0
  285. package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -0
  286. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +131 -0
  287. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -0
  288. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +132 -0
  289. package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -0
  290. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js +112 -0
  291. package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -0
  292. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js +140 -0
  293. package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -0
  294. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js +95 -0
  295. package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -0
  296. package/dist/src/server/speech/providers/openai/config.js +99 -0
  297. package/dist/src/server/speech/providers/openai/config.js.map +1 -0
  298. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js +165 -0
  299. package/dist/src/server/speech/providers/openai/realtime-transcription-session.js.map +1 -0
  300. package/dist/src/server/speech/providers/openai/runtime.js +114 -0
  301. package/dist/src/server/speech/providers/openai/runtime.js.map +1 -0
  302. package/dist/src/server/speech/providers/openai/stt.js +208 -0
  303. package/dist/src/server/speech/providers/openai/stt.js.map +1 -0
  304. package/dist/src/server/speech/providers/openai/tts.js +46 -0
  305. package/dist/src/server/speech/providers/openai/tts.js.map +1 -0
  306. package/dist/src/server/speech/speech-config-resolver.js +85 -0
  307. package/dist/src/server/speech/speech-config-resolver.js.map +1 -0
  308. package/dist/src/server/speech/speech-provider.js +2 -0
  309. package/dist/src/server/speech/speech-provider.js.map +1 -0
  310. package/dist/src/server/speech/speech-runtime.js +497 -0
  311. package/dist/src/server/speech/speech-runtime.js.map +1 -0
  312. package/dist/src/server/speech/speech-types.js +8 -0
  313. package/dist/src/server/speech/speech-types.js.map +1 -0
  314. package/dist/src/server/utils/diff-highlighter.js +244 -0
  315. package/dist/src/server/utils/diff-highlighter.js.map +1 -0
  316. package/dist/src/server/utils/syntax-highlighter.js +145 -0
  317. package/dist/src/server/utils/syntax-highlighter.js.map +1 -0
  318. package/dist/src/server/voice-config.js +51 -0
  319. package/dist/src/server/voice-config.js.map +1 -0
  320. package/dist/src/server/voice-mcp-bridge-command.js +31 -0
  321. package/dist/src/server/voice-mcp-bridge-command.js.map +1 -0
  322. package/dist/src/server/voice-mcp-bridge.js +109 -0
  323. package/dist/src/server/voice-mcp-bridge.js.map +1 -0
  324. package/dist/src/server/voice-permission-policy.js +13 -0
  325. package/dist/src/server/voice-permission-policy.js.map +1 -0
  326. package/dist/src/server/voice-types.js +2 -0
  327. package/dist/src/server/voice-types.js.map +1 -0
  328. package/dist/src/server/websocket-server.js +967 -0
  329. package/dist/src/server/websocket-server.js.map +1 -0
  330. package/dist/src/server/worktree-bootstrap.js +497 -0
  331. package/dist/src/server/worktree-bootstrap.js.map +1 -0
  332. package/dist/src/shared/agent-attention-notification.js +130 -0
  333. package/dist/src/shared/agent-attention-notification.js.map +1 -0
  334. package/dist/src/shared/agent-lifecycle.js +8 -0
  335. package/dist/src/shared/agent-lifecycle.js.map +1 -0
  336. package/dist/src/shared/binary-mux.js +114 -0
  337. package/dist/src/shared/binary-mux.js.map +1 -0
  338. package/dist/src/shared/connection-offer.js +17 -0
  339. package/dist/src/shared/connection-offer.js.map +1 -0
  340. package/dist/src/shared/daemon-endpoints.js +113 -0
  341. package/dist/src/shared/daemon-endpoints.js.map +1 -0
  342. package/dist/src/shared/messages.js +2001 -0
  343. package/dist/src/shared/messages.js.map +1 -0
  344. package/dist/src/shared/path-utils.js +16 -0
  345. package/dist/src/shared/path-utils.js.map +1 -0
  346. package/dist/src/shared/tool-call-display.js +93 -0
  347. package/dist/src/shared/tool-call-display.js.map +1 -0
  348. package/dist/src/terminal/terminal-manager.js +136 -0
  349. package/dist/src/terminal/terminal-manager.js.map +1 -0
  350. package/dist/src/terminal/terminal.js +410 -0
  351. package/dist/src/terminal/terminal.js.map +1 -0
  352. package/dist/src/utils/checkout-git.js +1397 -0
  353. package/dist/src/utils/checkout-git.js.map +1 -0
  354. package/dist/src/utils/directory-suggestions.js +655 -0
  355. package/dist/src/utils/directory-suggestions.js.map +1 -0
  356. package/dist/src/utils/path.js +15 -0
  357. package/dist/src/utils/path.js.map +1 -0
  358. package/dist/src/utils/project-icon.js +391 -0
  359. package/dist/src/utils/project-icon.js.map +1 -0
  360. package/dist/src/utils/worktree-metadata.js +116 -0
  361. package/dist/src/utils/worktree-metadata.js.map +1 -0
  362. package/dist/src/utils/worktree.js +741 -0
  363. package/dist/src/utils/worktree.js.map +1 -0
  364. package/package.json +15 -7
@@ -5,6 +5,7 @@ import { AGENT_LIFECYCLE_STATUSES, } from "../../shared/agent-lifecycle.js";
5
5
  import { z } from "zod";
6
6
  import { AGENT_PROVIDER_IDS } from "./provider-manifest.js";
7
7
  export { AGENT_LIFECYCLE_STATUSES };
8
+ const SYSTEM_ERROR_PREFIX = "[System Error]";
8
9
  function attachPersistenceCwd(handle, cwd) {
9
10
  if (!handle) {
10
11
  return null;
@@ -17,8 +18,8 @@ function attachPersistenceCwd(handle, cwd) {
17
18
  },
18
19
  };
19
20
  }
20
- const DEFAULT_MAX_TIMELINE_ITEMS = 2000;
21
21
  const DEFAULT_TIMELINE_FETCH_LIMIT = 200;
22
+ const LIVE_BACKLOG_TERMINAL_REPLAY_DELAY_MS = 300;
22
23
  const BUSY_STATUSES = [
23
24
  "initializing",
24
25
  "running",
@@ -27,6 +28,11 @@ const AgentIdSchema = z.string().uuid();
27
28
  function isAgentBusy(status) {
28
29
  return BUSY_STATUSES.includes(status);
29
30
  }
31
+ function isTurnTerminalEvent(event) {
32
+ return (event.type === "turn_completed" ||
33
+ event.type === "turn_failed" ||
34
+ event.type === "turn_canceled");
35
+ }
30
36
  function createAbortError(signal, fallbackMessage) {
31
37
  const reason = signal?.reason;
32
38
  const message = typeof reason === "string"
@@ -43,6 +49,18 @@ function validateAgentId(agentId, source) {
43
49
  }
44
50
  return result.data;
45
51
  }
52
+ function supportsLiveEventStream(session) {
53
+ return ("streamLiveEvents" in session &&
54
+ typeof session.streamLiveEvents ===
55
+ "function");
56
+ }
57
+ function normalizeMessageId(messageId) {
58
+ if (typeof messageId !== "string") {
59
+ return undefined;
60
+ }
61
+ const trimmed = messageId.trim();
62
+ return trimmed.length > 0 ? trimmed : undefined;
63
+ }
46
64
  export class AgentManager {
47
65
  constructor(options) {
48
66
  this.clients = new Map();
@@ -50,8 +68,16 @@ export class AgentManager {
50
68
  this.subscribers = new Set();
51
69
  this.previousStatuses = new Map();
52
70
  this.backgroundTasks = new Set();
71
+ this.liveEventPumps = new Map();
72
+ this.liveEventBacklog = new Map();
73
+ this.liveEventBacklogFlushTimers = new Map();
74
+ const maxTimelineItems = options?.maxTimelineItems;
53
75
  this.maxTimelineItems =
54
- options?.maxTimelineItems ?? DEFAULT_MAX_TIMELINE_ITEMS;
76
+ typeof maxTimelineItems === "number" &&
77
+ Number.isFinite(maxTimelineItems) &&
78
+ maxTimelineItems >= 0
79
+ ? Math.floor(maxTimelineItems)
80
+ : null;
55
81
  this.idFactory = options?.idFactory ?? (() => randomUUID());
56
82
  this.registry = options?.registry;
57
83
  this.onAgentAttention = options?.onAgentAttention;
@@ -397,6 +423,9 @@ export class AgentManager {
397
423
  : await client.createSession(normalizedConfig);
398
424
  // Remove the existing agent entry before swapping sessions
399
425
  this.agents.delete(agentId);
426
+ this.liveEventPumps.delete(agentId);
427
+ this.liveEventBacklog.delete(agentId);
428
+ this.clearLiveEventBacklogFlushTimer(agentId);
400
429
  try {
401
430
  await existing.session.close();
402
431
  }
@@ -421,7 +450,16 @@ export class AgentManager {
421
450
  }
422
451
  async closeAgent(agentId) {
423
452
  const agent = this.requireAgent(agentId);
453
+ this.logger.trace({
454
+ agentId,
455
+ lifecycle: agent.lifecycle,
456
+ hasPendingRun: Boolean(agent.pendingRun),
457
+ pendingPermissions: agent.pendingPermissions.size,
458
+ }, "closeAgent: start");
424
459
  this.agents.delete(agentId);
460
+ this.liveEventPumps.delete(agentId);
461
+ this.liveEventBacklog.delete(agentId);
462
+ this.clearLiveEventBacklogFlushTimer(agentId);
425
463
  // Clean up previousStatus to prevent memory leak
426
464
  this.previousStatuses.delete(agentId);
427
465
  const session = agent.session;
@@ -433,6 +471,7 @@ export class AgentManager {
433
471
  };
434
472
  await session.close();
435
473
  this.emitState(closedAgent);
474
+ this.logger.trace({ agentId }, "closeAgent: completed");
436
475
  }
437
476
  async setAgentMode(agentId, modeId) {
438
477
  const agent = this.requireAgent(agentId);
@@ -469,7 +508,12 @@ export class AgentManager {
469
508
  }
470
509
  async setTitle(agentId, title) {
471
510
  const agent = this.requireAgent(agentId);
472
- await this.registry?.setTitle(agentId, title);
511
+ const normalizedTitle = title.trim();
512
+ if (!normalizedTitle) {
513
+ return;
514
+ }
515
+ this.touchUpdatedAt(agent);
516
+ await this.persistSnapshot(agent, { title: normalizedTitle });
473
517
  this.emitState(agent);
474
518
  }
475
519
  async setLabels(agentId, labels) {
@@ -483,6 +527,7 @@ export class AgentManager {
483
527
  if (!agent || agent.internal) {
484
528
  return;
485
529
  }
530
+ this.touchUpdatedAt(agent);
486
531
  this.emitState(agent);
487
532
  }
488
533
  async clearAgentAttention(agentId) {
@@ -507,7 +552,7 @@ export class AgentManager {
507
552
  usage = event.usage;
508
553
  }
509
554
  else if (event.type === "turn_failed") {
510
- throw new Error(event.error);
555
+ throw new Error(this.formatTurnFailedMessage(event));
511
556
  }
512
557
  else if (event.type === "turn_canceled") {
513
558
  canceled = true;
@@ -529,10 +574,11 @@ export class AgentManager {
529
574
  }
530
575
  recordUserMessage(agentId, text, options) {
531
576
  const agent = this.requireAgent(agentId);
577
+ const normalizedMessageId = normalizeMessageId(options?.messageId);
532
578
  const item = {
533
579
  type: "user_message",
534
580
  text,
535
- messageId: options?.messageId,
581
+ messageId: normalizedMessageId,
536
582
  };
537
583
  const updatedAt = this.touchUpdatedAt(agent);
538
584
  agent.lastUserMessageAt = updatedAt;
@@ -574,7 +620,18 @@ export class AgentManager {
574
620
  }
575
621
  streamAgent(agentId, prompt, options) {
576
622
  const existingAgent = this.requireAgent(agentId);
623
+ this.logger.trace({
624
+ agentId,
625
+ lifecycle: existingAgent.lifecycle,
626
+ hasPendingRun: Boolean(existingAgent.pendingRun),
627
+ promptType: typeof prompt === "string" ? "string" : "structured",
628
+ hasRunOptions: Boolean(options),
629
+ }, "streamAgent: requested");
577
630
  if (existingAgent.pendingRun) {
631
+ this.logger.trace({
632
+ agentId,
633
+ lifecycle: existingAgent.lifecycle,
634
+ }, "streamAgent: rejected because pendingRun already exists");
578
635
  throw new Error(`Agent ${agentId} already has an active run`);
579
636
  }
580
637
  const agent = existingAgent;
@@ -582,11 +639,24 @@ export class AgentManager {
582
639
  agent.lastError = undefined;
583
640
  let finalized = false;
584
641
  const finalize = (error) => {
642
+ this.logger.trace({
643
+ agentId,
644
+ error,
645
+ alreadyFinalized: finalized,
646
+ lifecycle: agent.lifecycle,
647
+ hasPendingRun: Boolean(agent.pendingRun),
648
+ }, "streamAgent.finalize: invoked");
585
649
  if (finalized) {
586
650
  return;
587
651
  }
588
652
  finalized = true;
589
653
  if (agent.pendingRun !== streamForwarder) {
654
+ this.logger.trace({
655
+ agentId,
656
+ error,
657
+ lifecycle: agent.lifecycle,
658
+ hasPendingRun: Boolean(agent.pendingRun),
659
+ }, "streamAgent.finalize: skipped because pendingRun no longer points to streamForwarder");
590
660
  if (error) {
591
661
  agent.lastError = error;
592
662
  }
@@ -594,8 +664,9 @@ export class AgentManager {
594
664
  }
595
665
  const mutableAgent = agent;
596
666
  mutableAgent.pendingRun = null;
597
- mutableAgent.lifecycle = error ? "error" : "idle";
598
- mutableAgent.lastError = error;
667
+ const terminalError = error ?? mutableAgent.lastError;
668
+ mutableAgent.lifecycle = terminalError ? "error" : "idle";
669
+ mutableAgent.lastError = terminalError;
599
670
  const persistenceHandle = mutableAgent.session.describePersistence() ??
600
671
  (mutableAgent.runtimeInfo?.sessionId
601
672
  ? { provider: mutableAgent.provider, sessionId: mutableAgent.runtimeInfo.sessionId }
@@ -603,7 +674,14 @@ export class AgentManager {
603
674
  if (persistenceHandle) {
604
675
  mutableAgent.persistence = attachPersistenceCwd(persistenceHandle, mutableAgent.cwd);
605
676
  }
677
+ this.logger.trace({
678
+ agentId,
679
+ lifecycle: mutableAgent.lifecycle,
680
+ hasPendingRun: Boolean(mutableAgent.pendingRun),
681
+ terminalError,
682
+ }, "streamAgent.finalize: applying terminal state");
606
683
  this.emitState(mutableAgent);
684
+ this.flushLiveEventBacklog(mutableAgent);
607
685
  };
608
686
  const self = this;
609
687
  const streamForwarder = (async function* streamForwarder() {
@@ -611,12 +689,28 @@ export class AgentManager {
611
689
  try {
612
690
  for await (const event of iterator) {
613
691
  self.handleStreamEvent(agent, event);
692
+ if (event.type === "turn_started" ||
693
+ event.type === "turn_completed" ||
694
+ event.type === "turn_failed" ||
695
+ event.type === "turn_canceled") {
696
+ self.logger.trace({
697
+ agentId,
698
+ eventType: event.type,
699
+ lifecycle: agent.lifecycle,
700
+ hasPendingRun: Boolean(agent.pendingRun),
701
+ }, "streamAgent: forwarded terminal/turn event");
702
+ }
614
703
  yield event;
615
704
  }
616
705
  }
617
706
  catch (error) {
618
707
  finalizeError =
619
708
  error instanceof Error ? error.message : "Agent stream failed";
709
+ self.handleStreamEvent(agent, {
710
+ type: "turn_failed",
711
+ provider: agent.provider,
712
+ error: finalizeError,
713
+ });
620
714
  throw error;
621
715
  }
622
716
  finally {
@@ -632,6 +726,11 @@ export class AgentManager {
632
726
  // deterministically order idle->running transitions.
633
727
  this.touchUpdatedAt(agent);
634
728
  self.emitState(agent);
729
+ this.logger.trace({
730
+ agentId,
731
+ lifecycle: agent.lifecycle,
732
+ hasPendingRun: Boolean(agent.pendingRun),
733
+ }, "streamAgent: started");
635
734
  return streamForwarder;
636
735
  }
637
736
  async waitForAgentRunStart(agentId, options) {
@@ -726,7 +825,9 @@ export class AgentManager {
726
825
  async cancelAgentRun(agentId) {
727
826
  const agent = this.requireAgent(agentId);
728
827
  const pendingRun = agent.pendingRun;
729
- if (!pendingRun || typeof pendingRun.return !== "function") {
828
+ const hasForegroundPendingRun = Boolean(pendingRun) && typeof pendingRun?.return === "function";
829
+ const isAutonomousRunning = agent.lifecycle === "running" && !hasForegroundPendingRun;
830
+ if (!hasForegroundPendingRun && !isAutonomousRunning) {
730
831
  return false;
731
832
  }
732
833
  try {
@@ -735,14 +836,16 @@ export class AgentManager {
735
836
  catch (error) {
736
837
  this.logger.error({ err: error, agentId }, "Failed to interrupt session");
737
838
  }
738
- try {
739
- // Await the generator's .return() to ensure the finally block runs
740
- // and pendingRun is properly cleared before we return.
741
- await pendingRun.return(undefined);
742
- }
743
- catch (error) {
744
- this.logger.error({ err: error, agentId }, "Failed to cancel run");
745
- throw error;
839
+ if (hasForegroundPendingRun && pendingRun) {
840
+ try {
841
+ // Await the generator's .return() to ensure the finally block runs
842
+ // and pendingRun is properly cleared before we return.
843
+ await pendingRun.return(undefined);
844
+ }
845
+ catch (error) {
846
+ this.logger.error({ err: error, agentId }, "Failed to cancel run");
847
+ throw error;
848
+ }
746
849
  }
747
850
  // Clear any pending permissions that weren't cleaned up by handleStreamEvent.
748
851
  // Due to microtask ordering, .return() may force the generator to its finally
@@ -841,6 +944,7 @@ export class AgentManager {
841
944
  }
842
945
  let currentStatus = initialStatus;
843
946
  let hasStarted = initialBusy || hasPendingRun;
947
+ let terminalStatusOverride = null;
844
948
  // Bug #3 Fix: Declare unsubscribe and abortHandler upfront so cleanup can reference them
845
949
  let unsubscribe = null;
846
950
  let abortHandler = null;
@@ -898,6 +1002,9 @@ export class AgentManager {
898
1002
  return;
899
1003
  }
900
1004
  if (!waitForActive || hasStarted) {
1005
+ if (terminalStatusOverride) {
1006
+ currentStatus = terminalStatusOverride;
1007
+ }
901
1008
  finish(null);
902
1009
  }
903
1010
  return;
@@ -908,20 +1015,15 @@ export class AgentManager {
908
1015
  return;
909
1016
  }
910
1017
  if (event.event.type === "turn_failed") {
911
- currentStatus = "error";
912
1018
  hasStarted = true;
913
- finish(null);
1019
+ terminalStatusOverride = "error";
914
1020
  return;
915
1021
  }
916
1022
  if (event.event.type === "turn_completed") {
917
- currentStatus = "idle";
918
1023
  hasStarted = true;
919
- finish(null);
920
1024
  }
921
1025
  if (event.event.type === "turn_canceled") {
922
- currentStatus = "idle";
923
1026
  hasStarted = true;
924
- finish(null);
925
1027
  }
926
1028
  }
927
1029
  }, { agentId, replayState: true });
@@ -932,6 +1034,7 @@ export class AgentManager {
932
1034
  if (this.agents.has(resolvedAgentId)) {
933
1035
  throw new Error(`Agent with id ${resolvedAgentId} already exists`);
934
1036
  }
1037
+ const initialPersistedTitle = await this.resolveInitialPersistedTitle(resolvedAgentId, config);
935
1038
  const now = new Date();
936
1039
  const initialTimeline = options?.timeline ? [...options.timeline] : [];
937
1040
  const initialTimelineRows = options?.timelineRows?.length
@@ -982,15 +1085,26 @@ export class AgentManager {
982
1085
  this.previousStatuses.set(resolvedAgentId, managed.lifecycle);
983
1086
  await this.refreshRuntimeInfo(managed);
984
1087
  await this.persistSnapshot(managed, {
985
- title: config.title ?? null,
1088
+ title: initialPersistedTitle,
986
1089
  });
987
1090
  this.emitState(managed);
988
1091
  await this.refreshSessionState(managed);
989
1092
  managed.lifecycle = "idle";
990
1093
  await this.persistSnapshot(managed);
991
1094
  this.emitState(managed);
1095
+ this.startLiveEventPump(managed);
992
1096
  return { ...managed };
993
1097
  }
1098
+ async resolveInitialPersistedTitle(agentId, config) {
1099
+ const existing = await this.registry?.get(agentId);
1100
+ if (existing) {
1101
+ return existing.title ?? null;
1102
+ }
1103
+ if (Object.prototype.hasOwnProperty.call(config, "title")) {
1104
+ return config.title ?? null;
1105
+ }
1106
+ return null;
1107
+ }
994
1108
  buildTimelineRowsFromItems(items, startSeq, timestamp) {
995
1109
  let nextSeq = startSeq;
996
1110
  return items.map((item) => {
@@ -1053,6 +1167,7 @@ export class AgentManager {
1053
1167
  try {
1054
1168
  const newInfo = await agent.session.getRuntimeInfo();
1055
1169
  const changed = newInfo.model !== agent.runtimeInfo?.model ||
1170
+ newInfo.thinkingOptionId !== agent.runtimeInfo?.thinkingOptionId ||
1056
1171
  newInfo.sessionId !== agent.runtimeInfo?.sessionId ||
1057
1172
  newInfo.modeId !== agent.runtimeInfo?.modeId;
1058
1173
  agent.runtimeInfo = newInfo;
@@ -1073,9 +1188,22 @@ export class AgentManager {
1073
1188
  return;
1074
1189
  }
1075
1190
  agent.historyPrimed = true;
1191
+ const canonicalUserMessagesById = new Map(agent.timelineRows.flatMap((row) => {
1192
+ if (row.item.type !== "user_message") {
1193
+ return [];
1194
+ }
1195
+ const messageId = normalizeMessageId(row.item.messageId);
1196
+ if (!messageId) {
1197
+ return [];
1198
+ }
1199
+ return [[messageId, row.item.text]];
1200
+ }));
1076
1201
  try {
1077
1202
  for await (const event of agent.session.streamHistory()) {
1078
- this.handleStreamEvent(agent, event, { fromHistory: true });
1203
+ this.handleStreamEvent(agent, event, {
1204
+ fromHistory: true,
1205
+ canonicalUserMessagesById: canonicalUserMessagesById.size > 0 ? canonicalUserMessagesById : undefined,
1206
+ });
1079
1207
  }
1080
1208
  }
1081
1209
  catch {
@@ -1104,6 +1232,23 @@ export class AgentManager {
1104
1232
  }
1105
1233
  break;
1106
1234
  case "timeline":
1235
+ // Skip provider-replayed user_message items during history hydration.
1236
+ // These are already canonically recorded by recordUserMessage() and replaying them would
1237
+ // create duplicates. Match by messageId (not text) to avoid dropping legitimate
1238
+ // provider-origin messages that happen to reuse the same text.
1239
+ if (options?.fromHistory &&
1240
+ event.item.type === "user_message") {
1241
+ const eventMessageId = normalizeMessageId(event.item.messageId);
1242
+ if (eventMessageId) {
1243
+ const canonicalText = options?.canonicalUserMessagesById?.get(eventMessageId);
1244
+ if (canonicalText === event.item.text) {
1245
+ break;
1246
+ }
1247
+ }
1248
+ }
1249
+ if (this.shouldSuppressLiveUserMessageEcho(agent, event, options)) {
1250
+ break;
1251
+ }
1107
1252
  timelineRow = this.recordTimeline(agent, event.item);
1108
1253
  if (!options?.fromHistory &&
1109
1254
  event.item.type === "user_message") {
@@ -1112,12 +1257,23 @@ export class AgentManager {
1112
1257
  }
1113
1258
  break;
1114
1259
  case "turn_completed":
1260
+ this.logger.trace({
1261
+ agentId: agent.id,
1262
+ lifecycle: agent.lifecycle,
1263
+ hasPendingRun: Boolean(agent.pendingRun),
1264
+ }, "handleStreamEvent: turn_completed");
1115
1265
  agent.lastUsage = event.usage;
1116
1266
  agent.lastError = undefined;
1267
+ if (!agent.pendingRun && agent.lifecycle !== "idle") {
1268
+ agent.lifecycle = "idle";
1269
+ this.emitState(agent);
1270
+ }
1117
1271
  void this.refreshRuntimeInfo(agent);
1118
1272
  break;
1119
1273
  case "turn_failed":
1274
+ agent.lifecycle = "error";
1120
1275
  agent.lastError = event.error;
1276
+ this.appendSystemErrorTimelineMessage(agent, event.provider, this.formatTurnFailedMessage(event), options);
1121
1277
  for (const [requestId] of agent.pendingPermissions) {
1122
1278
  agent.pendingPermissions.delete(requestId);
1123
1279
  if (!options?.fromHistory) {
@@ -1132,6 +1288,14 @@ export class AgentManager {
1132
1288
  this.emitState(agent);
1133
1289
  break;
1134
1290
  case "turn_canceled":
1291
+ this.logger.trace({
1292
+ agentId: agent.id,
1293
+ lifecycle: agent.lifecycle,
1294
+ hasPendingRun: Boolean(agent.pendingRun),
1295
+ }, "handleStreamEvent: turn_canceled");
1296
+ if (!agent.pendingRun) {
1297
+ agent.lifecycle = "idle";
1298
+ }
1135
1299
  agent.lastError = undefined;
1136
1300
  for (const [requestId] of agent.pendingPermissions) {
1137
1301
  agent.pendingPermissions.delete(requestId);
@@ -1146,8 +1310,25 @@ export class AgentManager {
1146
1310
  }
1147
1311
  this.emitState(agent);
1148
1312
  break;
1313
+ case "turn_started":
1314
+ this.logger.trace({
1315
+ agentId: agent.id,
1316
+ lifecycle: agent.lifecycle,
1317
+ hasPendingRun: Boolean(agent.pendingRun),
1318
+ }, "handleStreamEvent: turn_started");
1319
+ if (!agent.pendingRun) {
1320
+ agent.lifecycle = "running";
1321
+ this.emitState(agent);
1322
+ }
1323
+ break;
1149
1324
  case "permission_requested":
1150
- agent.pendingPermissions.set(event.request.id, event.request);
1325
+ {
1326
+ const hadPendingPermissions = agent.pendingPermissions.size > 0;
1327
+ agent.pendingPermissions.set(event.request.id, event.request);
1328
+ if (!hadPendingPermissions && !agent.internal) {
1329
+ this.broadcastAgentAttention(agent, "permission");
1330
+ }
1331
+ }
1151
1332
  this.emitState(agent);
1152
1333
  break;
1153
1334
  case "permission_resolved":
@@ -1167,6 +1348,64 @@ export class AgentManager {
1167
1348
  : undefined);
1168
1349
  }
1169
1350
  }
1351
+ appendSystemErrorTimelineMessage(agent, provider, message, options) {
1352
+ if (options?.fromHistory) {
1353
+ return;
1354
+ }
1355
+ const normalized = message.trim();
1356
+ if (!normalized) {
1357
+ return;
1358
+ }
1359
+ const text = `${SYSTEM_ERROR_PREFIX} ${normalized}`;
1360
+ const lastItem = agent.timelineRows[agent.timelineRows.length - 1]?.item;
1361
+ if (lastItem?.type === "assistant_message" && lastItem.text === text) {
1362
+ return;
1363
+ }
1364
+ const item = { type: "assistant_message", text };
1365
+ const row = this.recordTimeline(agent, item);
1366
+ this.dispatchStream(agent.id, {
1367
+ type: "timeline",
1368
+ item,
1369
+ provider,
1370
+ }, {
1371
+ seq: row.seq,
1372
+ epoch: this.ensureTimelineState(agent).epoch,
1373
+ });
1374
+ }
1375
+ formatTurnFailedMessage(event) {
1376
+ const base = event.error.trim();
1377
+ const parts = [base.length > 0 ? base : "Provider run failed"];
1378
+ const code = event.code?.trim();
1379
+ if (code) {
1380
+ parts.push(`code: ${code}`);
1381
+ }
1382
+ const diagnostic = event.diagnostic?.trim();
1383
+ if (diagnostic && diagnostic !== base) {
1384
+ parts.push(diagnostic);
1385
+ }
1386
+ return parts.join("\n\n");
1387
+ }
1388
+ shouldSuppressLiveUserMessageEcho(agent, event, options) {
1389
+ if (options?.fromHistory || event.type !== "timeline") {
1390
+ return false;
1391
+ }
1392
+ if (event.item.type !== "user_message" || !agent.pendingRun) {
1393
+ return false;
1394
+ }
1395
+ const eventMessageId = normalizeMessageId(event.item.messageId);
1396
+ const eventText = event.item.text;
1397
+ if (!eventMessageId) {
1398
+ return false;
1399
+ }
1400
+ return agent.timelineRows.some((row) => {
1401
+ const rowItem = row.item;
1402
+ if (rowItem.type !== "user_message") {
1403
+ return false;
1404
+ }
1405
+ const rowMessageId = normalizeMessageId(rowItem.messageId);
1406
+ return rowMessageId === eventMessageId && rowItem.text === eventText;
1407
+ });
1408
+ }
1170
1409
  recordTimeline(agent, item) {
1171
1410
  const timelineState = this.ensureTimelineState(agent);
1172
1411
  const row = {
@@ -1177,7 +1416,8 @@ export class AgentManager {
1177
1416
  agent.timelineNextSeq = timelineState.nextSeq + 1;
1178
1417
  agent.timeline.push(item);
1179
1418
  timelineState.rows.push(row);
1180
- if (agent.timeline.length > this.maxTimelineItems) {
1419
+ if (typeof this.maxTimelineItems === "number" &&
1420
+ agent.timeline.length > this.maxTimelineItems) {
1181
1421
  const removeCount = agent.timeline.length - this.maxTimelineItems;
1182
1422
  agent.timeline.splice(0, removeCount);
1183
1423
  timelineState.rows.splice(0, removeCount);
@@ -1185,7 +1425,7 @@ export class AgentManager {
1185
1425
  return row;
1186
1426
  }
1187
1427
  emitState(agent) {
1188
- // Check if attention should be set based on status change
1428
+ // Keep attention as an edge-triggered unread signal, not a level signal.
1189
1429
  this.checkAndSetAttention(agent);
1190
1430
  this.dispatch({
1191
1431
  type: "agent_state",
@@ -1217,7 +1457,7 @@ export class AgentManager {
1217
1457
  return;
1218
1458
  }
1219
1459
  // Check if agent entered error state
1220
- if (currentStatus === "error") {
1460
+ if (previousStatus !== "error" && currentStatus === "error") {
1221
1461
  agent.attention = {
1222
1462
  requiresAttention: true,
1223
1463
  attentionReason: "error",
@@ -1227,17 +1467,6 @@ export class AgentManager {
1227
1467
  this.enqueueBackgroundPersist(agent);
1228
1468
  return;
1229
1469
  }
1230
- // Check if agent has pending permissions
1231
- if (agent.pendingPermissions.size > 0) {
1232
- agent.attention = {
1233
- requiresAttention: true,
1234
- attentionReason: "permission",
1235
- attentionTimestamp: new Date(),
1236
- };
1237
- this.broadcastAgentAttention(agent, "permission");
1238
- this.enqueueBackgroundPersist(agent);
1239
- return;
1240
- }
1241
1470
  }
1242
1471
  enqueueBackgroundPersist(agent) {
1243
1472
  const task = this.persistSnapshot(agent).catch((err) => {
@@ -1343,5 +1572,141 @@ export class AgentManager {
1343
1572
  }
1344
1573
  return agent;
1345
1574
  }
1575
+ startLiveEventPump(agent) {
1576
+ if (!supportsLiveEventStream(agent.session)) {
1577
+ return;
1578
+ }
1579
+ if (this.liveEventPumps.has(agent.id)) {
1580
+ return;
1581
+ }
1582
+ const pump = (async () => {
1583
+ while (true) {
1584
+ const current = this.agents.get(agent.id);
1585
+ if (!current) {
1586
+ return;
1587
+ }
1588
+ if (!supportsLiveEventStream(current.session)) {
1589
+ return;
1590
+ }
1591
+ try {
1592
+ for await (const event of current.session.streamLiveEvents()) {
1593
+ const latest = this.agents.get(agent.id);
1594
+ if (!latest) {
1595
+ return;
1596
+ }
1597
+ // Keep consuming provider events even during an active foreground run,
1598
+ // then replay them immediately once that run settles.
1599
+ if (latest.pendingRun) {
1600
+ this.logger.trace({
1601
+ agentId: latest.id,
1602
+ eventType: event.type,
1603
+ backlogSize: (this.liveEventBacklog.get(latest.id)?.length ?? 0) + 1,
1604
+ }, "Live event pump: queued event because pendingRun is active");
1605
+ this.enqueueLiveEvent(latest.id, event);
1606
+ continue;
1607
+ }
1608
+ this.flushLiveEventBacklog(latest);
1609
+ this.handleStreamEvent(latest, event);
1610
+ }
1611
+ this.logger.warn({ agentId: agent.id }, "Live event pump stream ended; restarting");
1612
+ }
1613
+ catch (error) {
1614
+ this.logger.warn({ err: error, agentId: agent.id }, "Live event pump failed");
1615
+ }
1616
+ // Keep pump alive unless the agent is gone.
1617
+ await new Promise((resolve) => setTimeout(resolve, 250));
1618
+ const latest = this.agents.get(agent.id);
1619
+ if (!latest) {
1620
+ return;
1621
+ }
1622
+ if (!latest.pendingRun) {
1623
+ this.flushLiveEventBacklog(latest);
1624
+ }
1625
+ }
1626
+ })();
1627
+ this.liveEventPumps.set(agent.id, pump);
1628
+ pump.finally(() => {
1629
+ const current = this.liveEventPumps.get(agent.id);
1630
+ if (current === pump) {
1631
+ this.liveEventPumps.delete(agent.id);
1632
+ }
1633
+ });
1634
+ }
1635
+ enqueueLiveEvent(agentId, event) {
1636
+ const existing = this.liveEventBacklog.get(agentId);
1637
+ if (existing) {
1638
+ existing.push(event);
1639
+ return;
1640
+ }
1641
+ this.liveEventBacklog.set(agentId, [event]);
1642
+ }
1643
+ clearLiveEventBacklogFlushTimer(agentId) {
1644
+ const timer = this.liveEventBacklogFlushTimers.get(agentId);
1645
+ if (!timer) {
1646
+ return;
1647
+ }
1648
+ clearTimeout(timer);
1649
+ this.liveEventBacklogFlushTimers.delete(agentId);
1650
+ }
1651
+ scheduleLiveEventBacklogFlush(agentId, delayMs) {
1652
+ if (this.liveEventBacklogFlushTimers.has(agentId)) {
1653
+ return;
1654
+ }
1655
+ const timer = setTimeout(() => {
1656
+ this.liveEventBacklogFlushTimers.delete(agentId);
1657
+ const latest = this.agents.get(agentId);
1658
+ if (!latest) {
1659
+ return;
1660
+ }
1661
+ if (latest.pendingRun) {
1662
+ this.scheduleLiveEventBacklogFlush(agentId, LIVE_BACKLOG_TERMINAL_REPLAY_DELAY_MS);
1663
+ return;
1664
+ }
1665
+ this.flushLiveEventBacklog(latest);
1666
+ }, delayMs);
1667
+ this.liveEventBacklogFlushTimers.set(agentId, timer);
1668
+ }
1669
+ flushLiveEventBacklog(agent) {
1670
+ if (agent.pendingRun) {
1671
+ return;
1672
+ }
1673
+ const pending = this.liveEventBacklog.get(agent.id);
1674
+ if (!pending || pending.length === 0) {
1675
+ return;
1676
+ }
1677
+ this.clearLiveEventBacklogFlushTimer(agent.id);
1678
+ this.liveEventBacklog.delete(agent.id);
1679
+ const immediate = [];
1680
+ const deferred = [];
1681
+ let sawTurnStarted = false;
1682
+ let deferRemainder = false;
1683
+ for (const event of pending) {
1684
+ if (!deferRemainder && sawTurnStarted && isTurnTerminalEvent(event)) {
1685
+ deferRemainder = true;
1686
+ }
1687
+ if (deferRemainder) {
1688
+ deferred.push(event);
1689
+ continue;
1690
+ }
1691
+ immediate.push(event);
1692
+ if (event.type === "turn_started") {
1693
+ sawTurnStarted = true;
1694
+ }
1695
+ }
1696
+ for (const event of immediate) {
1697
+ this.handleStreamEvent(agent, event);
1698
+ }
1699
+ if (deferred.length === 0) {
1700
+ return;
1701
+ }
1702
+ const existing = this.liveEventBacklog.get(agent.id);
1703
+ if (existing && existing.length > 0) {
1704
+ this.liveEventBacklog.set(agent.id, [...deferred, ...existing]);
1705
+ }
1706
+ else {
1707
+ this.liveEventBacklog.set(agent.id, deferred);
1708
+ }
1709
+ this.scheduleLiveEventBacklogFlush(agent.id, LIVE_BACKLOG_TERMINAL_REPLAY_DELAY_MS);
1710
+ }
1346
1711
  }
1347
1712
  //# sourceMappingURL=agent-manager.js.map