@getpaseo/server 0.1.63 → 0.1.65

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 (265) hide show
  1. package/dist/server/client/daemon-client-transport-types.d.ts +2 -0
  2. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -1
  3. package/dist/server/client/daemon-client-websocket-transport.d.ts +2 -1
  4. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
  5. package/dist/server/client/daemon-client-websocket-transport.js +4 -4
  6. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  7. package/dist/server/client/daemon-client.d.ts +30 -20
  8. package/dist/server/client/daemon-client.d.ts.map +1 -1
  9. package/dist/server/client/daemon-client.js +206 -98
  10. package/dist/server/client/daemon-client.js.map +1 -1
  11. package/dist/server/client/terminal-stream-router.d.ts +24 -0
  12. package/dist/server/client/terminal-stream-router.d.ts.map +1 -0
  13. package/dist/server/client/terminal-stream-router.js +100 -0
  14. package/dist/server/client/terminal-stream-router.js.map +1 -0
  15. package/dist/server/server/agent/activity-curator.d.ts +6 -3
  16. package/dist/server/server/agent/activity-curator.d.ts.map +1 -1
  17. package/dist/server/server/agent/activity-curator.js +45 -138
  18. package/dist/server/server/agent/activity-curator.js.map +1 -1
  19. package/dist/server/server/agent/agent-manager.d.ts +3 -14
  20. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  21. package/dist/server/server/agent/agent-manager.js +75 -140
  22. package/dist/server/server/agent/agent-manager.js.map +1 -1
  23. package/dist/server/server/agent/agent-metadata-generator.d.ts +0 -5
  24. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  25. package/dist/server/server/agent/agent-metadata-generator.js +3 -93
  26. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  27. package/dist/server/server/agent/agent-sdk-types.d.ts +15 -1
  28. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  29. package/dist/server/server/agent/agent-stream-coalescer.d.ts +1 -1
  30. package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
  31. package/dist/server/server/agent/agent-stream-coalescer.js +1 -1
  32. package/dist/server/server/agent/agent-stream-coalescer.js.map +1 -1
  33. package/dist/server/server/agent/agent-timeline-store.d.ts.map +1 -1
  34. package/dist/server/server/agent/agent-timeline-store.js +29 -32
  35. package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
  36. package/dist/server/server/agent/foreground-run-state.d.ts +50 -0
  37. package/dist/server/server/agent/foreground-run-state.d.ts.map +1 -0
  38. package/dist/server/server/agent/foreground-run-state.js +162 -0
  39. package/dist/server/server/agent/foreground-run-state.js.map +1 -0
  40. package/dist/server/server/agent/mcp-server.d.ts +5 -3
  41. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  42. package/dist/server/server/agent/mcp-server.js +110 -99
  43. package/dist/server/server/agent/mcp-server.js.map +1 -1
  44. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
  45. package/dist/server/server/agent/mcp-shared.js +7 -1
  46. package/dist/server/server/agent/mcp-shared.js.map +1 -1
  47. package/dist/server/server/agent/prompt-attachments.d.ts +4 -3
  48. package/dist/server/server/agent/prompt-attachments.d.ts.map +1 -1
  49. package/dist/server/server/agent/prompt-attachments.js +43 -4
  50. package/dist/server/server/agent/prompt-attachments.js.map +1 -1
  51. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -1
  52. package/dist/server/server/agent/provider-manifest.js +7 -0
  53. package/dist/server/server/agent/provider-manifest.js.map +1 -1
  54. package/dist/server/server/agent/providers/acp-agent.d.ts +38 -1
  55. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  56. package/dist/server/server/agent/providers/acp-agent.js +257 -140
  57. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  58. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -1
  59. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +1 -1
  60. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -1
  61. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  62. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +68 -198
  63. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  64. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  65. package/dist/server/server/agent/providers/claude-agent.js +52 -102
  66. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  67. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  68. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +125 -141
  69. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  70. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +36 -6
  71. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  72. package/dist/server/server/agent/providers/codex-app-server-agent.js +374 -219
  73. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  74. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +6 -2
  75. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
  76. package/dist/server/server/agent/providers/mock-load-test-agent.js +294 -113
  77. package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
  78. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +1 -1
  79. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -1
  80. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +94 -2
  81. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -1
  82. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
  83. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +24 -115
  84. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -1
  85. package/dist/server/server/agent/providers/opencode-agent.d.ts +102 -1
  86. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  87. package/dist/server/server/agent/providers/opencode-agent.js +416 -158
  88. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  89. package/dist/server/server/agent/providers/provider-runner.d.ts +27 -0
  90. package/dist/server/server/agent/providers/provider-runner.d.ts.map +1 -0
  91. package/dist/server/server/agent/providers/provider-runner.js +80 -0
  92. package/dist/server/server/agent/providers/provider-runner.js.map +1 -0
  93. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +6 -3
  94. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  95. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +2 -0
  96. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
  97. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +31 -0
  98. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -1
  99. package/dist/server/server/agent/timeline-projection.d.ts +21 -5
  100. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  101. package/dist/server/server/agent/timeline-projection.js +59 -9
  102. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  103. package/dist/server/server/auth.d.ts +25 -0
  104. package/dist/server/server/auth.d.ts.map +1 -0
  105. package/dist/server/server/auth.js +93 -0
  106. package/dist/server/server/auth.js.map +1 -0
  107. package/dist/server/server/bootstrap.d.ts +3 -1
  108. package/dist/server/server/bootstrap.d.ts.map +1 -1
  109. package/dist/server/server/bootstrap.js +87 -30
  110. package/dist/server/server/bootstrap.js.map +1 -1
  111. package/dist/server/server/config.d.ts.map +1 -1
  112. package/dist/server/server/config.js +11 -0
  113. package/dist/server/server/config.js.map +1 -1
  114. package/dist/server/server/exports.d.ts +7 -1
  115. package/dist/server/server/exports.d.ts.map +1 -1
  116. package/dist/server/server/exports.js +6 -1
  117. package/dist/server/server/exports.js.map +1 -1
  118. package/dist/server/server/file-explorer/service.d.ts +10 -0
  119. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  120. package/dist/server/server/file-explorer/service.js +38 -4
  121. package/dist/server/server/file-explorer/service.js.map +1 -1
  122. package/dist/server/server/index.js +9 -6
  123. package/dist/server/server/index.js.map +1 -1
  124. package/dist/server/server/logger.d.ts.map +1 -1
  125. package/dist/server/server/logger.js +15 -1
  126. package/dist/server/server/logger.js.map +1 -1
  127. package/dist/server/server/pagination/cursor.d.ts +16 -0
  128. package/dist/server/server/pagination/cursor.d.ts.map +1 -0
  129. package/dist/server/server/pagination/cursor.js +62 -0
  130. package/dist/server/server/pagination/cursor.js.map +1 -0
  131. package/dist/server/server/pagination/sortable-pager.d.ts +24 -0
  132. package/dist/server/server/pagination/sortable-pager.d.ts.map +1 -0
  133. package/dist/server/server/pagination/sortable-pager.js +68 -0
  134. package/dist/server/server/pagination/sortable-pager.js.map +1 -0
  135. package/dist/server/server/paseo-worktree-archive-service.d.ts +3 -1
  136. package/dist/server/server/paseo-worktree-archive-service.d.ts.map +1 -1
  137. package/dist/server/server/paseo-worktree-archive-service.js +61 -53
  138. package/dist/server/server/paseo-worktree-archive-service.js.map +1 -1
  139. package/dist/server/server/paseo-worktree-service.d.ts +13 -0
  140. package/dist/server/server/paseo-worktree-service.d.ts.map +1 -1
  141. package/dist/server/server/paseo-worktree-service.js +72 -3
  142. package/dist/server/server/paseo-worktree-service.js.map +1 -1
  143. package/dist/server/server/persisted-config.d.ts +25 -0
  144. package/dist/server/server/persisted-config.d.ts.map +1 -1
  145. package/dist/server/server/persisted-config.js +9 -0
  146. package/dist/server/server/persisted-config.js.map +1 -1
  147. package/dist/server/server/relay-transport.d.ts.map +1 -1
  148. package/dist/server/server/relay-transport.js +16 -4
  149. package/dist/server/server/relay-transport.js.map +1 -1
  150. package/dist/server/server/resolve-worktree-creation-intent.d.ts +0 -10
  151. package/dist/server/server/resolve-worktree-creation-intent.d.ts.map +1 -1
  152. package/dist/server/server/resolve-worktree-creation-intent.js +1 -45
  153. package/dist/server/server/resolve-worktree-creation-intent.js.map +1 -1
  154. package/dist/server/server/script-status-projection.d.ts +6 -1
  155. package/dist/server/server/script-status-projection.d.ts.map +1 -1
  156. package/dist/server/server/script-status-projection.js +12 -3
  157. package/dist/server/server/script-status-projection.js.map +1 -1
  158. package/dist/server/server/session.d.ts +19 -51
  159. package/dist/server/server/session.d.ts.map +1 -1
  160. package/dist/server/server/session.js +354 -1069
  161. package/dist/server/server/session.js.map +1 -1
  162. package/dist/server/server/websocket-server.d.ts +4 -2
  163. package/dist/server/server/websocket-server.d.ts.map +1 -1
  164. package/dist/server/server/websocket-server.js +65 -12
  165. package/dist/server/server/websocket-server.js.map +1 -1
  166. package/dist/server/server/workspace-directory.d.ts +69 -0
  167. package/dist/server/server/workspace-directory.d.ts.map +1 -0
  168. package/dist/server/server/workspace-directory.js +229 -0
  169. package/dist/server/server/workspace-directory.js.map +1 -0
  170. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  171. package/dist/server/server/worktree-bootstrap.js +6 -2
  172. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  173. package/dist/server/server/worktree-core.d.ts +2 -0
  174. package/dist/server/server/worktree-core.d.ts.map +1 -1
  175. package/dist/server/server/worktree-core.js.map +1 -1
  176. package/dist/server/server/worktree-errors.d.ts +1 -1
  177. package/dist/server/server/worktree-errors.d.ts.map +1 -1
  178. package/dist/server/server/worktree-errors.js +1 -4
  179. package/dist/server/server/worktree-errors.js.map +1 -1
  180. package/dist/server/server/worktree-session.d.ts +47 -20
  181. package/dist/server/server/worktree-session.d.ts.map +1 -1
  182. package/dist/server/server/worktree-session.js +68 -25
  183. package/dist/server/server/worktree-session.js.map +1 -1
  184. package/dist/server/shared/binary-frames/file-transfer.d.ts +56 -0
  185. package/dist/server/shared/binary-frames/file-transfer.d.ts.map +1 -0
  186. package/dist/server/shared/binary-frames/file-transfer.js +108 -0
  187. package/dist/server/shared/binary-frames/file-transfer.js.map +1 -0
  188. package/dist/server/shared/binary-frames/index.d.ts +3 -0
  189. package/dist/server/shared/binary-frames/index.d.ts.map +1 -0
  190. package/dist/server/shared/binary-frames/index.js +3 -0
  191. package/dist/server/shared/binary-frames/index.js.map +1 -0
  192. package/dist/server/shared/{terminal-stream-protocol.d.ts → binary-frames/terminal.d.ts} +2 -2
  193. package/dist/server/shared/binary-frames/terminal.d.ts.map +1 -0
  194. package/dist/server/shared/{terminal-stream-protocol.js → binary-frames/terminal.js} +2 -2
  195. package/dist/server/shared/binary-frames/terminal.js.map +1 -0
  196. package/dist/server/shared/client-capabilities.d.ts +5 -0
  197. package/dist/server/shared/client-capabilities.d.ts.map +1 -0
  198. package/dist/server/shared/client-capabilities.js +4 -0
  199. package/dist/server/shared/client-capabilities.js.map +1 -0
  200. package/dist/server/shared/connection-offer.d.ts +8 -0
  201. package/dist/server/shared/connection-offer.d.ts.map +1 -1
  202. package/dist/server/shared/connection-offer.js +35 -0
  203. package/dist/server/shared/connection-offer.js.map +1 -1
  204. package/dist/server/shared/daemon-endpoints.d.ts +16 -1
  205. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  206. package/dist/server/shared/daemon-endpoints.js +65 -6
  207. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  208. package/dist/server/shared/host-connection-schema.d.ts +23 -0
  209. package/dist/server/shared/host-connection-schema.d.ts.map +1 -0
  210. package/dist/server/shared/host-connection-schema.js +9 -0
  211. package/dist/server/shared/host-connection-schema.js.map +1 -0
  212. package/dist/server/shared/messages.d.ts +3242 -535
  213. package/dist/server/shared/messages.d.ts.map +1 -1
  214. package/dist/server/shared/messages.js +73 -34
  215. package/dist/server/shared/messages.js.map +1 -1
  216. package/dist/server/terminal/terminal-manager-factory.d.ts +7 -0
  217. package/dist/server/terminal/terminal-manager-factory.d.ts.map +1 -0
  218. package/dist/server/terminal/terminal-manager-factory.js +13 -0
  219. package/dist/server/terminal/terminal-manager-factory.js.map +1 -0
  220. package/dist/server/terminal/terminal-manager.d.ts +7 -1
  221. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  222. package/dist/server/terminal/terminal-manager.js +14 -1
  223. package/dist/server/terminal/terminal-manager.js.map +1 -1
  224. package/dist/server/terminal/terminal-session-controller.d.ts +63 -0
  225. package/dist/server/terminal/terminal-session-controller.d.ts.map +1 -0
  226. package/dist/server/terminal/terminal-session-controller.js +615 -0
  227. package/dist/server/terminal/terminal-session-controller.js.map +1 -0
  228. package/dist/server/terminal/terminal-ts-loader.mjs +20 -0
  229. package/dist/server/terminal/terminal-worker-process.d.ts +2 -0
  230. package/dist/server/terminal/terminal-worker-process.d.ts.map +1 -0
  231. package/dist/server/terminal/terminal-worker-process.js +221 -0
  232. package/dist/server/terminal/terminal-worker-process.js.map +1 -0
  233. package/dist/server/terminal/terminal-worker-protocol.d.ts +113 -0
  234. package/dist/server/terminal/terminal-worker-protocol.d.ts.map +1 -0
  235. package/dist/server/terminal/terminal-worker-protocol.js +2 -0
  236. package/dist/server/terminal/terminal-worker-protocol.js.map +1 -0
  237. package/dist/server/terminal/terminal.d.ts +7 -0
  238. package/dist/server/terminal/terminal.d.ts.map +1 -1
  239. package/dist/server/terminal/terminal.js +22 -9
  240. package/dist/server/terminal/terminal.js.map +1 -1
  241. package/dist/server/terminal/worker-terminal-manager.d.ts +19 -0
  242. package/dist/server/terminal/worker-terminal-manager.d.ts.map +1 -0
  243. package/dist/server/terminal/worker-terminal-manager.js +466 -0
  244. package/dist/server/terminal/worker-terminal-manager.js.map +1 -0
  245. package/dist/server/utils/directory-suggestions.d.ts.map +1 -1
  246. package/dist/server/utils/directory-suggestions.js +10 -1
  247. package/dist/server/utils/directory-suggestions.js.map +1 -1
  248. package/dist/server/utils/process-tree.d.ts +25 -0
  249. package/dist/server/utils/process-tree.d.ts.map +1 -0
  250. package/dist/server/utils/process-tree.js +96 -0
  251. package/dist/server/utils/process-tree.js.map +1 -0
  252. package/dist/server/utils/windows-command.d.ts.map +1 -1
  253. package/dist/server/utils/windows-command.js +5 -1
  254. package/dist/server/utils/windows-command.js.map +1 -1
  255. package/dist/server/utils/worktree-metadata.d.ts +44 -0
  256. package/dist/server/utils/worktree-metadata.d.ts.map +1 -1
  257. package/dist/server/utils/worktree-metadata.js +58 -0
  258. package/dist/server/utils/worktree-metadata.js.map +1 -1
  259. package/dist/server/utils/worktree.d.ts +14 -2
  260. package/dist/server/utils/worktree.d.ts.map +1 -1
  261. package/dist/server/utils/worktree.js +22 -13
  262. package/dist/server/utils/worktree.js.map +1 -1
  263. package/package.json +5 -4
  264. package/dist/server/shared/terminal-stream-protocol.d.ts.map +0 -1
  265. package/dist/server/shared/terminal-stream-protocol.js.map +0 -1
@@ -5,6 +5,7 @@ import { AGENT_LIFECYCLE_STATUSES, } from "../../shared/agent-lifecycle.js";
5
5
  import { z } from "zod";
6
6
  import { InMemoryAgentTimelineStore, } from "./agent-timeline-store.js";
7
7
  import { AGENT_STREAM_COALESCE_DEFAULT_WINDOW_MS, AgentStreamCoalescer, } from "./agent-stream-coalescer.js";
8
+ import { ForegroundRunState } from "./foreground-run-state.js";
8
9
  import { getAgentProviderDefinition } from "./provider-manifest.js";
9
10
  const RELOAD_SESSION_CLOSE_TIMEOUT_MS = 3000;
10
11
  const INTERRUPT_SESSION_TIMEOUT_MS = 2000;
@@ -102,7 +103,7 @@ export class AgentManager {
102
103
  this.timelineStore = new InMemoryAgentTimelineStore();
103
104
  this.agentsAwaitingInitialSnapshotPersist = new Set();
104
105
  this.sessionEventTails = new Map();
105
- this.pendingForegroundRuns = new Map();
106
+ this.foregroundRuns = new ForegroundRunState();
106
107
  this.subscribers = new Set();
107
108
  this.previousStatuses = new Map();
108
109
  this.backgroundTasks = new Set();
@@ -197,7 +198,7 @@ export class AgentManager {
197
198
  }
198
199
  return (agent.lifecycle === "running" ||
199
200
  Boolean(agent.activeForegroundTurnId) ||
200
- this.hasPendingForegroundRun(agentId));
201
+ this.foregroundRuns.hasPendingRun(agentId));
201
202
  }
202
203
  subscribe(callback, options) {
203
204
  const targetAgentId = options?.agentId == null ? null : validateAgentId(options.agentId, "subscribe");
@@ -262,6 +263,16 @@ export class AgentManager {
262
263
  .sort((a, b) => b.lastActivityAt.getTime() - a.lastActivityAt.getTime())
263
264
  .slice(0, limit);
264
265
  }
266
+ async findPersistedAgent(provider, sessionId) {
267
+ const client = this.requireClient(provider);
268
+ if (!client.listPersistedAgents) {
269
+ return null;
270
+ }
271
+ const descriptors = await client.listPersistedAgents({ limit: 200 });
272
+ return (descriptors.find((descriptor) => {
273
+ return (descriptor.sessionId === sessionId || descriptor.persistence.nativeHandle === sessionId);
274
+ }) ?? null);
275
+ }
265
276
  async listProviderAvailability() {
266
277
  const checks = Array.from(this.clients.keys()).map(async (provider) => {
267
278
  const client = this.clients.get(provider);
@@ -435,11 +446,7 @@ export class AgentManager {
435
446
  existing.unsubscribeSession();
436
447
  existing.unsubscribeSession = null;
437
448
  }
438
- for (const waiter of existing.foregroundTurnWaiters) {
439
- this.settleForegroundTurnWaiter(waiter);
440
- }
441
- existing.foregroundTurnWaiters.clear();
442
- this.settlePendingForegroundRun(agentId);
449
+ this.foregroundRuns.clearAgent(agentId, existing);
443
450
  await this.closeReloadedSession(existing.session, agentId);
444
451
  // Preserve existing labels and timeline during reload.
445
452
  return this.registerSession(session, normalizedConfig, agentId, {
@@ -793,38 +800,38 @@ export class AgentManager {
793
800
  agentId,
794
801
  lifecycle: existingAgent.lifecycle,
795
802
  activeForegroundTurnId: existingAgent.activeForegroundTurnId,
796
- hasPendingForegroundRun: this.hasPendingForegroundRun(agentId),
803
+ hasPendingForegroundRun: this.foregroundRuns.hasPendingRun(agentId),
797
804
  promptType: typeof prompt === "string" ? "string" : "structured",
798
805
  hasRunOptions: Boolean(options),
799
806
  }, "streamAgent: requested");
800
- if (existingAgent.activeForegroundTurnId || this.hasPendingForegroundRun(agentId)) {
807
+ if (existingAgent.activeForegroundTurnId || this.foregroundRuns.hasPendingRun(agentId)) {
801
808
  this.logger.trace({
802
809
  agentId,
803
810
  lifecycle: existingAgent.lifecycle,
804
- hasPendingForegroundRun: this.hasPendingForegroundRun(agentId),
811
+ hasPendingForegroundRun: this.foregroundRuns.hasPendingRun(agentId),
805
812
  }, "streamAgent: rejected because a foreground run is already in flight");
806
813
  throw new Error(`Agent ${agentId} already has an active run`);
807
814
  }
808
815
  const agent = existingAgent;
809
816
  agent.pendingReplacement = false;
810
817
  agent.lastError = undefined;
811
- const pendingRun = this.createPendingForegroundRun();
812
- this.pendingForegroundRuns.set(agentId, pendingRun);
818
+ const pendingRun = this.foregroundRuns.createPendingRun(agentId);
813
819
  const streamForwarder = async function* streamForwarder() {
814
820
  let turnId;
815
- let waiter = null;
821
+ let turnStream = null;
816
822
  try {
817
823
  const result = await agent.session.startTurn(prompt, options);
818
824
  turnId = result.turnId;
819
825
  }
820
826
  catch (error) {
821
827
  const errorMsg = error instanceof Error ? error.message : "Failed to start turn";
822
- this.handleStreamEvent(agent, {
828
+ await this.handleStreamEvent(agent, {
823
829
  type: "turn_failed",
824
830
  provider: agent.provider,
825
831
  error: errorMsg,
826
832
  });
827
833
  this.finalizeForegroundTurn(agent);
834
+ this.foregroundRuns.settlePendingRun(agentId, pendingRun.token);
828
835
  throw error;
829
836
  }
830
837
  pendingRun.started = true;
@@ -837,54 +844,18 @@ export class AgentManager {
837
844
  lifecycle: agent.lifecycle,
838
845
  activeForegroundTurnId: agent.activeForegroundTurnId,
839
846
  }, "streamAgent: started");
840
- // Create a pushable queue for this foreground turn
841
- const queue = [];
842
- let queueResolve = null;
843
- let done = false;
844
- let resolveSettled;
845
- const settledPromise = new Promise((resolvePromise) => {
846
- resolveSettled = resolvePromise;
847
- });
848
- waiter = {
849
- turnId,
850
- settled: false,
851
- settledPromise,
852
- resolveSettled,
853
- callback: (event) => {
854
- queue.push(event);
855
- if (queueResolve) {
856
- queueResolve();
857
- queueResolve = null;
858
- }
859
- },
860
- };
861
- agent.foregroundTurnWaiters.add(waiter);
847
+ turnStream = this.foregroundRuns.createTurnStream(turnId);
848
+ this.foregroundRuns.addWaiter(agent, turnStream.waiter);
862
849
  try {
863
- while (!done) {
864
- while (queue.length > 0) {
865
- const event = queue.shift();
866
- yield event;
867
- if (isTurnTerminalEvent(event)) {
868
- done = true;
869
- break;
870
- }
871
- }
872
- if (!done && queue.length === 0) {
873
- if (waiter.settled) {
874
- break;
875
- }
876
- await new Promise((resolvePromise) => {
877
- queueResolve = resolvePromise;
878
- });
879
- }
850
+ for await (const event of turnStream.events(isTurnTerminalEvent)) {
851
+ yield event;
880
852
  }
881
853
  }
882
854
  finally {
883
- if (waiter) {
884
- agent.foregroundTurnWaiters.delete(waiter);
885
- this.settleForegroundTurnWaiter(waiter);
855
+ if (turnStream) {
856
+ this.foregroundRuns.deleteWaiter(agent, turnStream.waiter);
886
857
  }
887
- this.settlePendingForegroundRun(agentId, pendingRun.token);
858
+ this.foregroundRuns.settlePendingRun(agentId, pendingRun.token);
888
859
  if (!agent.activeForegroundTurnId) {
889
860
  await this.refreshRuntimeInfo(agent);
890
861
  }
@@ -895,7 +866,7 @@ export class AgentManager {
895
866
  finalizeForegroundTurn(agent, turnId) {
896
867
  const mutableAgent = agent;
897
868
  if (turnId) {
898
- this.rememberFinalizedForegroundTurn(mutableAgent, turnId);
869
+ this.foregroundRuns.rememberFinalizedTurn(mutableAgent, turnId);
899
870
  }
900
871
  mutableAgent.activeForegroundTurnId = null;
901
872
  const terminalError = mutableAgent.lastError;
@@ -933,7 +904,7 @@ export class AgentManager {
933
904
  const snapshot = this.requireAgent(agentId);
934
905
  if (snapshot.lifecycle !== "running" &&
935
906
  !snapshot.activeForegroundTurnId &&
936
- !this.hasPendingForegroundRun(agentId)) {
907
+ !this.foregroundRuns.hasPendingRun(agentId)) {
937
908
  return this.streamAgent(agentId, prompt, options);
938
909
  }
939
910
  const agent = this.requireSessionAgent(agentId);
@@ -969,7 +940,7 @@ export class AgentManager {
969
940
  if (!snapshot) {
970
941
  throw new Error(`Agent ${agentId} not found`);
971
942
  }
972
- const pendingRun = this.getPendingForegroundRun(agentId);
943
+ const pendingRun = this.foregroundRuns.getPendingRun(agentId);
973
944
  if ((snapshot.lifecycle === "running" || pendingRun?.started) && !snapshot.pendingReplacement) {
974
945
  return;
975
946
  }
@@ -1024,7 +995,7 @@ export class AgentManager {
1024
995
  finishErr(new Error(`Agent ${agentId} not found`));
1025
996
  return true;
1026
997
  }
1027
- const currentPendingRun = this.getPendingForegroundRun(agentId);
998
+ const currentPendingRun = this.foregroundRuns.getPendingRun(agentId);
1028
999
  if ((current.lifecycle === "running" || currentPendingRun?.started) &&
1029
1000
  !current.pendingReplacement) {
1030
1001
  finishOk();
@@ -1078,7 +1049,7 @@ export class AgentManager {
1078
1049
  }
1079
1050
  async cancelAgentRun(agentId) {
1080
1051
  const agent = this.requireSessionAgent(agentId);
1081
- const pendingRun = this.getPendingForegroundRun(agentId);
1052
+ const pendingRun = this.foregroundRuns.getPendingRun(agentId);
1082
1053
  const foregroundTurnId = agent.activeForegroundTurnId;
1083
1054
  const hasForegroundTurn = Boolean(foregroundTurnId);
1084
1055
  const isAutonomousRunning = agent.lifecycle === "running" && !hasForegroundTurn && !pendingRun;
@@ -1135,7 +1106,7 @@ export class AgentManager {
1135
1106
  });
1136
1107
  // The synthetic event unblocks the streamForwarder generator, whose finally
1137
1108
  // block settles the pending foreground run asynchronously. Wait for it.
1138
- const staleRun = this.getPendingForegroundRun(agentId);
1109
+ const staleRun = this.foregroundRuns.getPendingRun(agentId);
1139
1110
  if (staleRun && !staleRun.settled) {
1140
1111
  await staleRun.settledPromise;
1141
1112
  }
@@ -1272,7 +1243,7 @@ export class AgentManager {
1272
1243
  if (!snapshot) {
1273
1244
  throw new Error(`Agent ${agentId} not found`);
1274
1245
  }
1275
- const pendingForegroundRun = this.getPendingForegroundRun(agentId);
1246
+ const pendingForegroundRun = this.foregroundRuns.getPendingRun(agentId);
1276
1247
  const hasForegroundTurn = Boolean(snapshot.activeForegroundTurnId) || Boolean(pendingForegroundRun);
1277
1248
  const immediatePermission = this.peekPendingPermission(snapshot);
1278
1249
  if (immediatePermission) {
@@ -1513,17 +1484,13 @@ export class AgentManager {
1513
1484
  agent.unsubscribeSession();
1514
1485
  agent.unsubscribeSession = null;
1515
1486
  }
1516
- for (const waiter of agent.foregroundTurnWaiters) {
1517
- waiter.callback({
1518
- type: "turn_canceled",
1519
- provider: agent.provider,
1520
- reason: cancelReason,
1521
- turnId: waiter.turnId,
1522
- });
1523
- this.settleForegroundTurnWaiter(waiter);
1524
- }
1525
- agent.foregroundTurnWaiters.clear();
1526
- this.settlePendingForegroundRun(agent.id);
1487
+ this.foregroundRuns.cancelWaiters(agent, (turnId) => ({
1488
+ type: "turn_canceled",
1489
+ provider: agent.provider,
1490
+ reason: cancelReason,
1491
+ turnId,
1492
+ }));
1493
+ this.foregroundRuns.settlePendingRun(agent.id);
1527
1494
  return {
1528
1495
  ...agent,
1529
1496
  lifecycle: "closed",
@@ -1572,70 +1539,14 @@ export class AgentManager {
1572
1539
  }
1573
1540
  async dispatchSessionEvent(agent, event) {
1574
1541
  const turnId = event.turnId;
1575
- const matchingWaiters = turnId == null
1576
- ? []
1577
- : Array.from(agent.foregroundTurnWaiters).filter((waiter) => waiter.turnId === turnId && !waiter.settled);
1542
+ const matchingWaiters = this.foregroundRuns.getMatchingWaiters(agent, turnId);
1578
1543
  const shouldNotifyWaiters = await this.handleStreamEvent(agent, event);
1579
1544
  if (!shouldNotifyWaiters) {
1580
1545
  return;
1581
1546
  }
1582
- for (const waiter of matchingWaiters) {
1583
- waiter.callback(event);
1584
- if (isTurnTerminalEvent(event)) {
1585
- this.settleForegroundTurnWaiter(waiter);
1586
- }
1587
- }
1588
- }
1589
- settleForegroundTurnWaiter(waiter) {
1590
- if (waiter.settled) {
1591
- return;
1592
- }
1593
- waiter.settled = true;
1594
- waiter.resolveSettled();
1595
- }
1596
- rememberFinalizedForegroundTurn(agent, turnId) {
1597
- agent.finalizedForegroundTurnIds.add(turnId);
1598
- if (agent.finalizedForegroundTurnIds.size <= 50) {
1599
- return;
1600
- }
1601
- const oldest = agent.finalizedForegroundTurnIds.values().next().value;
1602
- if (oldest) {
1603
- agent.finalizedForegroundTurnIds.delete(oldest);
1604
- }
1605
- }
1606
- createPendingForegroundRun() {
1607
- let resolveSettled;
1608
- const settledPromise = new Promise((resolvePromise) => {
1609
- resolveSettled = resolvePromise;
1547
+ this.foregroundRuns.notifyWaiters(matchingWaiters, event, {
1548
+ terminal: isTurnTerminalEvent(event),
1610
1549
  });
1611
- return {
1612
- token: randomUUID(),
1613
- started: false,
1614
- settled: false,
1615
- settledPromise,
1616
- resolveSettled,
1617
- };
1618
- }
1619
- getPendingForegroundRun(agentId) {
1620
- return this.pendingForegroundRuns.get(agentId) ?? null;
1621
- }
1622
- hasPendingForegroundRun(agentId) {
1623
- return this.pendingForegroundRuns.has(agentId);
1624
- }
1625
- settlePendingForegroundRun(agentId, token) {
1626
- const pendingRun = this.pendingForegroundRuns.get(agentId);
1627
- if (!pendingRun) {
1628
- return;
1629
- }
1630
- if (token && pendingRun.token !== token) {
1631
- return;
1632
- }
1633
- this.pendingForegroundRuns.delete(agentId);
1634
- if (pendingRun.settled) {
1635
- return;
1636
- }
1637
- pendingRun.settled = true;
1638
- pendingRun.resolveSettled();
1639
1550
  }
1640
1551
  async resolveInitialPersistedTitle(agentId, config) {
1641
1552
  const existing = await this.registry?.get(agentId);
@@ -1741,18 +1652,14 @@ export class AgentManager {
1741
1652
  if (!agent) {
1742
1653
  return;
1743
1654
  }
1744
- for (const waiter of agent.foregroundTurnWaiters) {
1745
- if (waiter.turnId === turnId && !waiter.settled) {
1746
- waiter.callback(event);
1747
- }
1748
- }
1655
+ this.foregroundRuns.notifyAgentWaiters(agent, event);
1749
1656
  }
1750
1657
  async handleStreamEvent(agent, event, options) {
1751
1658
  const eventTurnId = event.turnId;
1752
1659
  const isForegroundEvent = Boolean(eventTurnId && agent.activeForegroundTurnId === eventTurnId);
1753
1660
  if (eventTurnId &&
1754
1661
  isTurnTerminalEvent(event) &&
1755
- agent.finalizedForegroundTurnIds.has(eventTurnId)) {
1662
+ this.foregroundRuns.hasFinalizedTurn(agent, eventTurnId)) {
1756
1663
  return false;
1757
1664
  }
1758
1665
  // Only update timestamp for live events, not history replay
@@ -1793,6 +1700,34 @@ export class AgentManager {
1793
1700
  agent.lastUsage = event.usage;
1794
1701
  this.emitState(agent);
1795
1702
  return undefined;
1703
+ case "mode_changed":
1704
+ agent.currentModeId = event.currentModeId;
1705
+ agent.availableModes = event.availableModes;
1706
+ if (agent.runtimeInfo) {
1707
+ agent.runtimeInfo = { ...agent.runtimeInfo, modeId: event.currentModeId };
1708
+ }
1709
+ flags.shouldDispatchEvent = false;
1710
+ this.emitState(agent);
1711
+ return undefined;
1712
+ case "model_changed":
1713
+ agent.runtimeInfo = event.runtimeInfo;
1714
+ if (!agent.persistence && event.runtimeInfo.sessionId) {
1715
+ agent.persistence = attachPersistenceCwd({ provider: agent.provider, sessionId: event.runtimeInfo.sessionId }, agent.cwd);
1716
+ }
1717
+ agent.currentModeId = event.runtimeInfo.modeId ?? agent.currentModeId;
1718
+ flags.shouldDispatchEvent = false;
1719
+ this.emitState(agent);
1720
+ return undefined;
1721
+ case "thinking_option_changed":
1722
+ if (agent.runtimeInfo) {
1723
+ agent.runtimeInfo = {
1724
+ ...agent.runtimeInfo,
1725
+ thinkingOptionId: event.thinkingOptionId,
1726
+ };
1727
+ }
1728
+ flags.shouldDispatchEvent = false;
1729
+ this.emitState(agent);
1730
+ return undefined;
1796
1731
  case "timeline":
1797
1732
  return this.onStreamTimelineEvent({ agent, event, options, isForegroundEvent, flags });
1798
1733
  case "turn_completed":