@gajae-code/coding-agent 0.17.2 → 0.17.4

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 (349) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/dist/types/cli/daemon-cli.d.ts +3 -1
  3. package/dist/types/cli/github-release.d.ts +17 -0
  4. package/dist/types/cli/public-command-entry.d.ts +56 -0
  5. package/dist/types/cli/public-command-errors.d.ts +126 -0
  6. package/dist/types/cli/public-command-evidence.d.ts +99 -0
  7. package/dist/types/cli/public-command-help.d.ts +65 -0
  8. package/dist/types/cli/public-command-registry.d.ts +69 -0
  9. package/dist/types/cli/session-picker.d.ts +1 -1
  10. package/dist/types/cli/setup-cli.d.ts +1 -0
  11. package/dist/types/cli/skills-cli.d.ts +5 -0
  12. package/dist/types/cli.d.ts +3 -0
  13. package/dist/types/commands/daemon.d.ts +4 -50
  14. package/dist/types/commands/sdk.d.ts +20 -37
  15. package/dist/types/commands/setup.d.ts +3 -0
  16. package/dist/types/commands/skills.d.ts +9 -0
  17. package/dist/types/config/autorouting-tier-map.d.ts +18 -0
  18. package/dist/types/config/file-lock.d.ts +9 -1
  19. package/dist/types/config/model-profile-activation.d.ts +45 -1
  20. package/dist/types/config/model-registry.d.ts +11 -2
  21. package/dist/types/config/settings-schema.d.ts +11 -0
  22. package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
  23. package/dist/types/daemon/operator-contract.d.ts +5 -1
  24. package/dist/types/eval/js/worker-protocol.d.ts +2 -0
  25. package/dist/types/extensibility/extensions/types.d.ts +12 -0
  26. package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
  27. package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
  28. package/dist/types/extensibility/shared-events.d.ts +3 -1
  29. package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
  30. package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
  31. package/dist/types/internal-urls/index.d.ts +1 -0
  32. package/dist/types/internal-urls/parse.d.ts +9 -1
  33. package/dist/types/main.d.ts +22 -0
  34. package/dist/types/modes/acp/acp-agent.d.ts +55 -1
  35. package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
  36. package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
  37. package/dist/types/modes/components/session-selector.d.ts +5 -2
  38. package/dist/types/modes/components/user-message-selector.d.ts +5 -2
  39. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  40. package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
  41. package/dist/types/modes/interactive-mode.d.ts +1 -1
  42. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
  43. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
  44. package/dist/types/modes/types.d.ts +2 -2
  45. package/dist/types/runtime/process-lifecycle.d.ts +2 -0
  46. package/dist/types/runtime-mcp/manager.d.ts +56 -0
  47. package/dist/types/runtime-mcp/pool.d.ts +17 -0
  48. package/dist/types/runtime-mcp/redaction.d.ts +20 -0
  49. package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
  50. package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
  51. package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
  52. package/dist/types/sdk/broker/broker.d.ts +13 -2
  53. package/dist/types/sdk/broker/identity.d.ts +3 -1
  54. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
  55. package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
  56. package/dist/types/sdk/broker/runtime.d.ts +1 -1
  57. package/dist/types/sdk/broker/session-index.d.ts +22 -3
  58. package/dist/types/sdk/broker/spawn-authority.d.ts +4 -0
  59. package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
  60. package/dist/types/sdk/bus/index.d.ts +19 -0
  61. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +3 -1
  62. package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
  63. package/dist/types/sdk/cli/master-cli.d.ts +6 -10
  64. package/dist/types/sdk/cli/rows.d.ts +19 -1
  65. package/dist/types/sdk/cli/session-cli.d.ts +22 -5
  66. package/dist/types/sdk/client/client.d.ts +2 -0
  67. package/dist/types/sdk/guides/cli.d.ts +3 -4
  68. package/dist/types/sdk/guides/verify.d.ts +2 -0
  69. package/dist/types/sdk/host/host.d.ts +9 -0
  70. package/dist/types/sdk/host/session-runtime.d.ts +31 -0
  71. package/dist/types/sdk/host/types.d.ts +10 -0
  72. package/dist/types/sdk/index.d.ts +1 -0
  73. package/dist/types/sdk/prompt-deadline-flush.d.ts +83 -0
  74. package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
  75. package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
  76. package/dist/types/sdk/router/session-router.d.ts +2 -0
  77. package/dist/types/sdk/startup-capability.d.ts +2 -0
  78. package/dist/types/sdk/transport/relay.d.ts +1 -0
  79. package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
  80. package/dist/types/sdk/transport/stdio.d.ts +5 -1
  81. package/dist/types/session/agent-session.d.ts +168 -21
  82. package/dist/types/session/fallback-chain-controller.d.ts +6 -6
  83. package/dist/types/session/fold-coordinator.d.ts +17 -3
  84. package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
  85. package/dist/types/session/session-manager.d.ts +64 -1
  86. package/dist/types/session/session-work-lease.d.ts +14 -0
  87. package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
  88. package/dist/types/setup/provider-onboarding.d.ts +81 -1
  89. package/dist/types/tools/bash.d.ts +37 -11
  90. package/dist/types/tools/job.d.ts +1 -1
  91. package/dist/types/tools/steer-fold.d.ts +31 -0
  92. package/dist/types/utils/git.d.ts +28 -2
  93. package/dist/types/utils/mupdf-embedded.d.ts +2 -0
  94. package/dist/types/utils/mupdf.d.ts +4 -0
  95. package/dist/types/utils/session-title-generation.d.ts +6 -0
  96. package/dist/types/utils/title-generator.d.ts +11 -2
  97. package/dist/types/web/scrapers/types.d.ts +3 -0
  98. package/package.json +18 -10
  99. package/scripts/build-binary.ts +9 -3
  100. package/scripts/compile-args.ts +0 -9
  101. package/scripts/embed-mupdf.ts +52 -0
  102. package/scripts/generate-sdk-operation-inventory.ts +31 -1
  103. package/scripts/vendor-markit.ts +196 -0
  104. package/src/async/job-manager.ts +22 -1
  105. package/src/cli/daemon-cli.ts +53 -18
  106. package/src/cli/github-release.ts +87 -5
  107. package/src/cli/mcp-cli.ts +38 -4
  108. package/src/cli/public-command-entry.ts +450 -0
  109. package/src/cli/public-command-errors.ts +581 -0
  110. package/src/cli/public-command-evidence.ts +717 -0
  111. package/src/cli/public-command-help.ts +360 -0
  112. package/src/cli/public-command-registry.ts +535 -0
  113. package/src/cli/session-picker.ts +2 -1
  114. package/src/cli/setup-cli.ts +9 -1
  115. package/src/cli/skills-cli.ts +46 -2
  116. package/src/cli.ts +61 -1
  117. package/src/commands/daemon.ts +65 -69
  118. package/src/commands/sdk.ts +175 -117
  119. package/src/commands/setup.ts +2 -0
  120. package/src/commands/skills.ts +11 -0
  121. package/src/config/autorouting-tier-map.ts +14 -0
  122. package/src/config/file-lock.ts +147 -51
  123. package/src/config/model-profile-activation.ts +334 -43
  124. package/src/config/model-registry.ts +183 -25
  125. package/src/config/settings-schema.ts +26 -2
  126. package/src/coordinator-mcp/policy.ts +10 -5
  127. package/src/coordinator-mcp/question-gate-codec.ts +17 -0
  128. package/src/coordinator-mcp/question-state.ts +175 -8
  129. package/src/coordinator-mcp/server.ts +507 -81
  130. package/src/coordinator-mcp/session-reaper.ts +6 -4
  131. package/src/crash/record-loader.ts +6 -2
  132. package/src/daemon/operator-contract.ts +26 -12
  133. package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
  134. package/src/eval/js/context-manager.ts +8 -8
  135. package/src/eval/js/worker-core.ts +9 -4
  136. package/src/eval/js/worker-protocol.ts +2 -0
  137. package/src/extensibility/extensions/runner.ts +52 -4
  138. package/src/extensibility/extensions/types.ts +10 -0
  139. package/src/extensibility/gjc-plugins/registry.ts +196 -37
  140. package/src/extensibility/runtime-skill-discovery.ts +61 -3
  141. package/src/extensibility/shared-events.ts +3 -1
  142. package/src/gjc-runtime/session-state-lock.ts +165 -24
  143. package/src/gjc-runtime/ultragoal-succession.ts +31 -3
  144. package/src/internal-urls/docs-index.generated.ts +20 -19
  145. package/src/internal-urls/embedded-protocol.ts +83 -0
  146. package/src/internal-urls/index.ts +1 -0
  147. package/src/internal-urls/parse.ts +21 -1
  148. package/src/internal-urls/router.ts +4 -2
  149. package/src/main.ts +123 -55
  150. package/src/modes/acp/acp-agent.ts +408 -35
  151. package/src/modes/acp/startup-provenance.ts +59 -0
  152. package/src/modes/components/custom-provider-wizard.ts +308 -7
  153. package/src/modes/components/oauth-selector.ts +9 -0
  154. package/src/modes/components/session-selector.ts +47 -4
  155. package/src/modes/components/user-message-selector.ts +57 -15
  156. package/src/modes/controllers/command-controller.ts +58 -32
  157. package/src/modes/controllers/extension-ui-controller.ts +33 -7
  158. package/src/modes/controllers/input-controller.ts +4 -0
  159. package/src/modes/controllers/selector-controller.ts +161 -15
  160. package/src/modes/interactive-mode.ts +21 -7
  161. package/src/modes/runtime-init.ts +1 -0
  162. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
  163. package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
  164. package/src/modes/types.ts +2 -2
  165. package/src/prompts/agent-fragments/browser-aside.md +1 -0
  166. package/src/prompts/system/title-system.md +1 -1
  167. package/src/prompts/tools/bash.md +1 -1
  168. package/src/prompts/tools/job.md +1 -1
  169. package/src/prompts/tools/read.md +2 -0
  170. package/src/runtime/network-prewarm-service.test.ts +36 -1
  171. package/src/runtime/network-prewarm-service.ts +28 -3
  172. package/src/runtime/process-lifecycle.ts +22 -11
  173. package/src/runtime-mcp/config.ts +16 -1
  174. package/src/runtime-mcp/manager.ts +689 -55
  175. package/src/runtime-mcp/pool.test.ts +31 -0
  176. package/src/runtime-mcp/pool.ts +304 -28
  177. package/src/runtime-mcp/redaction.ts +42 -0
  178. package/src/runtime-mcp/startup-policy.ts +7 -0
  179. package/src/runtime-mcp/tool-bridge.ts +71 -0
  180. package/src/runtime-mcp/transports/http.ts +108 -25
  181. package/src/sdk/acp/adapter.ts +27 -8
  182. package/src/sdk/broker/broker.ts +378 -52
  183. package/src/sdk/broker/identity.ts +9 -1
  184. package/src/sdk/broker/lifecycle-ledger.ts +95 -31
  185. package/src/sdk/broker/lifecycle.ts +690 -141
  186. package/src/sdk/broker/runtime.ts +1 -1
  187. package/src/sdk/broker/session-index.ts +97 -4
  188. package/src/sdk/broker/spawn-authority.ts +35 -7
  189. package/src/sdk/broker/stderr-drainer.ts +59 -0
  190. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  191. package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
  192. package/src/sdk/bus/index.ts +690 -80
  193. package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
  194. package/src/sdk/bus/telegram-daemon-contract.ts +3 -1
  195. package/src/sdk/bus/telegram-daemon.ts +10 -3
  196. package/src/sdk/cli/master-cli.ts +47 -36
  197. package/src/sdk/cli/rows.ts +30 -7
  198. package/src/sdk/cli/session-cli.ts +687 -184
  199. package/src/sdk/client/client.ts +18 -0
  200. package/src/sdk/guides/catalog.ts +2 -2
  201. package/src/sdk/guides/cli.ts +20 -62
  202. package/src/sdk/guides/verify.ts +14 -0
  203. package/src/sdk/host/host.ts +49 -5
  204. package/src/sdk/host/session-runtime.test.ts +138 -2
  205. package/src/sdk/host/session-runtime.ts +311 -97
  206. package/src/sdk/host/types.ts +12 -1
  207. package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
  208. package/src/sdk/host/websocket-transport.ts +40 -6
  209. package/src/sdk/index.ts +11 -0
  210. package/src/sdk/prompt-deadline-flush.ts +334 -0
  211. package/src/sdk/prompt-deadline-manager.ts +133 -1
  212. package/src/sdk/prompt-tool-boundary.ts +121 -0
  213. package/src/sdk/protocol/operation-inventory.generated.json +106 -0
  214. package/src/sdk/router/session-router.ts +9 -1
  215. package/src/sdk/session.ts +182 -7
  216. package/src/sdk/startup-capability.ts +1 -1
  217. package/src/sdk/transport/relay.ts +71 -6
  218. package/src/sdk/transport/serve-cli.ts +397 -42
  219. package/src/sdk/transport/socket.ts +12 -11
  220. package/src/sdk/transport/stdio.ts +7 -3
  221. package/src/session/agent-session.ts +2437 -400
  222. package/src/session/fallback-chain-controller.ts +6 -7
  223. package/src/session/fold-coordinator.ts +24 -5
  224. package/src/session/internal/managed-session-scope.ts +58 -18
  225. package/src/session/internal/managed-session-storage.ts +304 -11
  226. package/src/session/session-manager.ts +382 -44
  227. package/src/session/session-work-lease.ts +34 -0
  228. package/src/setup/model-onboarding-guidance.ts +1 -1
  229. package/src/setup/provider-onboarding.ts +397 -24
  230. package/src/slash-commands/builtin-registry.ts +258 -14
  231. package/src/task/index.ts +14 -2
  232. package/src/tools/bash.ts +98 -78
  233. package/src/tools/fetch.ts +119 -20
  234. package/src/tools/job.ts +151 -25
  235. package/src/tools/output-meta.ts +15 -2
  236. package/src/tools/path-utils.ts +27 -3
  237. package/src/tools/read.ts +3 -3
  238. package/src/tools/steer-fold.ts +107 -0
  239. package/src/tools/tool-catalog.generated.ts +29 -2
  240. package/src/tools/tool-errors.ts +4 -0
  241. package/src/utils/git.ts +53 -3
  242. package/src/utils/markit.ts +55 -41
  243. package/src/utils/mupdf-assets.d.ts +4 -0
  244. package/src/utils/mupdf-embedded.ts +4 -0
  245. package/src/utils/mupdf.ts +129 -0
  246. package/src/utils/session-title-generation.ts +29 -0
  247. package/src/utils/title-generator.ts +46 -2
  248. package/src/web/scrapers/types.ts +24 -3
  249. package/vendor/markit-ai/LICENSE +21 -0
  250. package/vendor/markit-ai/MANIFEST.json +412 -0
  251. package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
  252. package/vendor/markit-ai/dist/commands/config.js +139 -0
  253. package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
  254. package/vendor/markit-ai/dist/commands/convert.js +113 -0
  255. package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
  256. package/vendor/markit-ai/dist/commands/formats.js +92 -0
  257. package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
  258. package/vendor/markit-ai/dist/commands/init.js +29 -0
  259. package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
  260. package/vendor/markit-ai/dist/commands/onboard.js +61 -0
  261. package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
  262. package/vendor/markit-ai/dist/commands/plugin.js +58 -0
  263. package/vendor/markit-ai/dist/config.d.ts +26 -0
  264. package/vendor/markit-ai/dist/config.js +42 -0
  265. package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
  266. package/vendor/markit-ai/dist/converters/audio.js +104 -0
  267. package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
  268. package/vendor/markit-ai/dist/converters/csv.js +83 -0
  269. package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
  270. package/vendor/markit-ai/dist/converters/docx.js +57 -0
  271. package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
  272. package/vendor/markit-ai/dist/converters/epub.js +128 -0
  273. package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
  274. package/vendor/markit-ai/dist/converters/github.js +148 -0
  275. package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
  276. package/vendor/markit-ai/dist/converters/html.js +30 -0
  277. package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
  278. package/vendor/markit-ai/dist/converters/image.js +124 -0
  279. package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
  280. package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
  281. package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
  282. package/vendor/markit-ai/dist/converters/iwork.js +391 -0
  283. package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
  284. package/vendor/markit-ai/dist/converters/json.js +21 -0
  285. package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
  286. package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
  287. package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
  288. package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
  289. package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
  290. package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
  291. package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
  292. package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
  293. package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
  294. package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
  295. package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
  296. package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
  297. package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
  298. package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
  299. package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
  300. package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
  301. package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
  302. package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
  303. package/vendor/markit-ai/dist/converters/pptx.js +289 -0
  304. package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
  305. package/vendor/markit-ai/dist/converters/rss.js +138 -0
  306. package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
  307. package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
  308. package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
  309. package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
  310. package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
  311. package/vendor/markit-ai/dist/converters/xml.js +18 -0
  312. package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
  313. package/vendor/markit-ai/dist/converters/yaml.js +17 -0
  314. package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
  315. package/vendor/markit-ai/dist/converters/zip.js +57 -0
  316. package/vendor/markit-ai/dist/index.d.ts +30 -0
  317. package/vendor/markit-ai/dist/index.js +26 -0
  318. package/vendor/markit-ai/dist/main.d.ts +2 -0
  319. package/vendor/markit-ai/dist/main.js +191 -0
  320. package/vendor/markit-ai/dist/markit.d.ts +45 -0
  321. package/vendor/markit-ai/dist/markit.js +267 -0
  322. package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
  323. package/vendor/markit-ai/dist/plugins/api.js +42 -0
  324. package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
  325. package/vendor/markit-ai/dist/plugins/index.js +3 -0
  326. package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
  327. package/vendor/markit-ai/dist/plugins/installer.js +176 -0
  328. package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
  329. package/vendor/markit-ai/dist/plugins/loader.js +61 -0
  330. package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
  331. package/vendor/markit-ai/dist/plugins/types.js +1 -0
  332. package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
  333. package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
  334. package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
  335. package/vendor/markit-ai/dist/providers/index.js +56 -0
  336. package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
  337. package/vendor/markit-ai/dist/providers/openai.js +76 -0
  338. package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
  339. package/vendor/markit-ai/dist/providers/types.js +1 -0
  340. package/vendor/markit-ai/dist/types.d.ts +36 -0
  341. package/vendor/markit-ai/dist/types.js +1 -0
  342. package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
  343. package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
  344. package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
  345. package/vendor/markit-ai/dist/utils/output.js +31 -0
  346. package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
  347. package/vendor/markit-ai/dist/utils/turndown.js +70 -0
  348. package/vendor/markit-ai/package.json +74 -0
  349. package/vendor/markit-ai.patch +49 -0
@@ -1,3 +1,4 @@
1
+ import { logger } from "@gajae-code/utils";
1
2
  import type { KindAwareReconciliation } from "./bus/kind-aware-reconciliation";
2
3
  import type { InvocationCorrelation, InvocationReconciliation } from "./host/session-runtime";
3
4
  import {
@@ -16,6 +17,56 @@ const MAX_UNCERTAINTY_RETRIES = 3;
16
17
  const EXPIRY_RETRY_DELAY_MS = 1_000;
17
18
  const UNCERTAINTY_RETRY_DELAY_MS = 1_000;
18
19
 
20
+ /**
21
+ * Hard real-time bound on the best-effort durability hook, shared with
22
+ * `prompt-deadline-flush` so the manager's race and the flush's own abort
23
+ * signal cannot drift apart.
24
+ */
25
+ export const DEADLINE_FLUSH_TIMEOUT_MS = 10_000;
26
+
27
+ /**
28
+ * Run a best-effort durability flush under a hard real-time bound that ALWAYS
29
+ * settles, and never let its result reach the caller.
30
+ *
31
+ * Shared by both expiry paths — this manager and the notification bus's own
32
+ * terminalization (#5583) — so there is one bound, one abort, and one warning,
33
+ * with no drift between them. A rejection is swallowed; a `run` that never
34
+ * settles is abandoned after `timeoutMs` with its signal aborted so any git
35
+ * subprocess dies. The signal alone is not sufficient: `git.withRepoLock`
36
+ * awaits its predecessor before honouring it, so a hung predecessor in the
37
+ * per-repo write chain is cut only by this outer race.
38
+ */
39
+ export async function runBoundedDeadlineFlush(
40
+ run: (signal: AbortSignal) => unknown,
41
+ timeoutMs: number = DEADLINE_FLUSH_TIMEOUT_MS,
42
+ ): Promise<void> {
43
+ const controller = new AbortController();
44
+ let timer: ReturnType<typeof setTimeout> | undefined;
45
+ // An async wrapper so a `run` that throws synchronously becomes a rejection.
46
+ const flushed = (async () => {
47
+ await run(controller.signal);
48
+ })();
49
+ // The abandoned promise may still reject long after we stop awaiting it.
50
+ flushed.catch(() => {});
51
+ try {
52
+ const bound = new Promise<"timeout">(resolve => {
53
+ timer = setTimeout(() => resolve("timeout"), timeoutMs);
54
+ // Never let a pending bound keep the process alive.
55
+ (timer as unknown as { unref?: () => void }).unref?.();
56
+ });
57
+ if ((await Promise.race([flushed.then(() => "flushed" as const), bound])) === "timeout") {
58
+ controller.abort(new Error(`prompt deadline flush exceeded ${timeoutMs}ms`));
59
+ logger.warn(
60
+ `sdk: prompt deadline flush exceeded its ${timeoutMs}ms bound; abandoning it and continuing teardown`,
61
+ );
62
+ }
63
+ } catch {
64
+ // A failing flush never changes the deadline outcome.
65
+ } finally {
66
+ if (timer !== undefined) clearTimeout(timer);
67
+ }
68
+ }
69
+
19
70
  type DeadlineReconciliation = InvocationReconciliation | KindAwareReconciliation;
20
71
 
21
72
  export type PromptDeadlineOutcome = Extract<SdkPromptTerminalOutcome, { kind: "failed" }> & {
@@ -49,6 +100,12 @@ export class PromptDeadlineManager {
49
100
  readonly #getMaxMs: () => number;
50
101
  readonly #now: () => number;
51
102
  readonly #onExpired?: (correlation: InvocationCorrelation, outcome?: PromptDeadlineOutcome) => void;
103
+ readonly #onDeadlineExceeded?: (
104
+ correlation: InvocationCorrelation,
105
+ signal: AbortSignal,
106
+ isCurrent?: () => boolean,
107
+ ) => void | Promise<void>;
108
+ readonly #deadlineFlushTimeoutMs: number;
52
109
 
53
110
  constructor(options: {
54
111
  reconciliation: DeadlineReconciliation;
@@ -56,12 +113,55 @@ export class PromptDeadlineManager {
56
113
  getMaxMs: () => number;
57
114
  now?: () => number;
58
115
  onExpired?: (correlation: InvocationCorrelation, outcome?: PromptDeadlineOutcome) => void;
116
+ /**
117
+ * Best-effort durability hook for the single path that genuinely retires a
118
+ * prompt as `prompt_deadline_exceeded` (#5583). Awaited after the durable
119
+ * pending claim but BEFORE the durable terminal, so a crash in that window
120
+ * leaves the record pending and recovery retries the prompt; a
121
+ * rejection is swallowed and never changes the deadline outcome. Not called
122
+ * when a real terminal transition or a real failure won the race, nor when
123
+ * renewed progress supersedes this expiry instance. The hook receives an
124
+ * abort signal that fires when it outruns `deadlineFlushTimeoutMs`, plus a
125
+ * generation fence for irreversible worktree adoption.
126
+ */
127
+ onDeadlineExceeded?: (
128
+ correlation: InvocationCorrelation,
129
+ signal: AbortSignal,
130
+ isCurrent?: () => boolean,
131
+ ) => void | Promise<void>;
132
+ /**
133
+ * Hard bound on `onDeadlineExceeded`. Measured with a real timer, not
134
+ * `now`, because it guards real subprocesses — which is also why it is a
135
+ * constructor option: a fake clock cannot shorten it for tests.
136
+ */
137
+ deadlineFlushTimeoutMs?: number;
59
138
  }) {
60
139
  this.#reconciliation = options.reconciliation;
61
140
  this.#getLeaseMs = options.getLeaseMs;
62
141
  this.#getMaxMs = options.getMaxMs;
63
142
  this.#now = options.now ?? Date.now;
64
143
  this.#onExpired = options.onExpired;
144
+ this.#onDeadlineExceeded = options.onDeadlineExceeded;
145
+ this.#deadlineFlushTimeoutMs = options.deadlineFlushTimeoutMs ?? DEADLINE_FLUSH_TIMEOUT_MS;
146
+ }
147
+
148
+ /** Run the durability hook under the shared bound; see `runBoundedDeadlineFlush`. */
149
+ async #runDeadlineFlush(
150
+ correlation: InvocationCorrelation,
151
+ lease: PromptDeadlineLease,
152
+ generation: number,
153
+ ): Promise<void> {
154
+ const hook = this.#onDeadlineExceeded;
155
+ if (hook === undefined) return;
156
+ const key = leaseKey(correlation);
157
+ await runBoundedDeadlineFlush(
158
+ signal =>
159
+ hook(correlation, signal, () => {
160
+ const current = this.#leases.get(key);
161
+ return current === lease && current.generation === generation;
162
+ }),
163
+ this.#deadlineFlushTimeoutMs,
164
+ );
65
165
  }
66
166
 
67
167
  #clearTimer(key: string): void {
@@ -165,16 +265,48 @@ export class PromptDeadlineManager {
165
265
  provenance: "deadline",
166
266
  evidence: {},
167
267
  }) as PromptDeadlineOutcome;
268
+ let winner: SdkPromptTerminalOutcome = outcome;
168
269
  try {
169
- await this.#reconciliation.claimPendingOutcome("prompt", correlation, outcome);
270
+ const claimed = await this.#reconciliation.claimPendingOutcome("prompt", correlation, outcome);
271
+ if (claimed !== undefined) winner = claimed;
170
272
  } catch {
171
273
  // claim may fail if already claimed (e.g., cancellation won); ignore.
172
274
  }
275
+ // A real terminal may win between lookup and this claim. Its existing
276
+ // pending outcome is authoritative: release this expiry fence without
277
+ // running the deadline-only durability hook or publishing a deadline result.
278
+ if (winner.kind !== "failed" || winner.code !== "prompt_deadline_exceeded" || winner.provenance !== "deadline") {
279
+ this.#expiring.delete(key);
280
+ this.#expiryRetries.delete(key);
281
+ return;
282
+ }
173
283
  // Re-verify the captured lease is still authoritative after the claim
174
284
  // await (exact-head review P2): fresh attributable progress during the
175
285
  // claim must cancel this expiry instance instead of surfacing an exceeded
176
286
  // outcome for a prompt that is demonstrably alive.
177
287
  if (this.#backOffIfSuperseded(key, lease, generation)) return;
288
+ // Durability BEFORE the durable terminal (#5583, #5623 review round 4). The
289
+ // claim above is already the durable pending marker, so a process death
290
+ // anywhere in this window leaves the record PENDING and restart recovery
291
+ // retries the prompt — work that was never autosaved is never reported as
292
+ // finished. Running the flush after `finalizeOutcome` instead made the
293
+ // autosave the one step a crash could silently skip, which is the whole
294
+ // durability guarantee of this change. The cost is that the durable terminal
295
+ // is delayed by at most the flush's bound.
296
+ //
297
+ // The wait is BOUNDED, not just guarded (#5623 review round 2): a hook that
298
+ // never settles — a blocking git lock, a credential prompt — would leave the
299
+ // finalize, `#onExpired` and `clear` below unreachable, stranding the prompt
300
+ // with neither a terminal nor an owner. A try/catch cannot rescue a promise
301
+ // that never settles, so the flush is raced against a real timer and
302
+ // abandoned if it outruns it.
303
+ await this.#runDeadlineFlush(correlation, lease, generation);
304
+ // Fence again AFTER the flush (#5623 review round 2): the flush is an await
305
+ // like any other here, and up to ten seconds long, so progress can land and
306
+ // renew the lease while it runs. A renewed prompt must not be terminalized as
307
+ // deadline-exceeded by this stale pass; `#backOffIfSuperseded` reschedules on
308
+ // the way out, so it keeps a live deadline.
309
+ if (this.#backOffIfSuperseded(key, lease, generation)) return;
178
310
  try {
179
311
  await this.#reconciliation.finalizeOutcome("prompt", correlation, outcome, () => {
180
312
  const current = this.#leases.get(key);
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Bounded wait for an in-flight dispatched tool call to reach its boundary
3
+ * before an expired prompt deadline force-terminates the run (#5637).
4
+ *
5
+ * Terminal fencing aborts the run's cancellation domain FIRST and only proves
6
+ * settlement afterwards (`RunResourceLedger.waitForSettlement` resolves once the
7
+ * run is sealed and its tracked `kind: "tool"` resources have settled), so a
8
+ * tool that was mid-write when the deadline expired observes the aborted signal
9
+ * DURING its write and leaves a torn artifact behind. Waiting for that call's
10
+ * own `tool_execution_end` — under a short, finite grace — turns the kill into a
11
+ * boundary abort. When the grace is exhausted the run is force-terminated
12
+ * exactly as before, and the fact that a tool was still executing is returned as
13
+ * structured evidence rather than dropped.
14
+ *
15
+ * Deliberately dependency-light and clock-injectable: the contended bus module
16
+ * takes only a call, and the behaviour is testable without a live transport.
17
+ */
18
+
19
+ /**
20
+ * Hard bound on how long deadline expiry will wait for an in-flight tool call to
21
+ * reach its boundary before force-terminating. This guards a real subprocess, so
22
+ * it is a real timer rather than the lease clock — and a parameter rather than a
23
+ * bare module constant, so a test may shorten it explicitly instead of a fake
24
+ * clock silently shortening it for production code too.
25
+ */
26
+ export const TOOL_CALL_BOUNDARY_GRACE_MS = 5_000;
27
+
28
+ /**
29
+ * Re-check interval for the pending set while the grace runs.
30
+ *
31
+ * The authoritative source of "is a tool running?" is the run resource ledger,
32
+ * a SYNCHRONOUS snapshot with no completion signal of its own, so the wait has
33
+ * to look again rather than being told. `whenIdle` only wakes the check early
34
+ * when the event-derived view happens to drain first. Bounded by the grace, so
35
+ * this costs at most `graceMs / pollMs` array reads on the rare expiry-with-a-
36
+ * tool-running path and nothing at all on the idle path.
37
+ */
38
+ export const TOOL_CALL_BOUNDARY_POLL_MS = 25;
39
+
40
+ export type ToolBoundaryOutcome = "idle" | "settled" | "forced";
41
+
42
+ export interface ToolBoundaryWaitResult {
43
+ outcome: ToolBoundaryOutcome;
44
+ waitedMs: number;
45
+ /**
46
+ * Non-empty ONLY for "forced": the dispatched tool calls still running when
47
+ * the grace expired. Ids only — never tool arguments, output or paths.
48
+ */
49
+ pendingToolCallIds: string[];
50
+ }
51
+
52
+ /**
53
+ * Shared result for the common case of no dispatched tool running at expiry.
54
+ * Frozen because it is handed to every idle caller: the deadline path must stay
55
+ * byte-identical to its pre-#5637 behaviour, which includes allocating nothing
56
+ * and arming no timer.
57
+ */
58
+ export const IDLE_TOOL_BOUNDARY_RESULT: ToolBoundaryWaitResult = Object.freeze({
59
+ outcome: "idle" as const,
60
+ waitedMs: 0,
61
+ pendingToolCallIds: Object.freeze([]) as unknown as string[],
62
+ });
63
+
64
+ /**
65
+ * Wait for the pending dispatched tool calls to drain, bounded by `graceMs`.
66
+ *
67
+ * Never composed with an abort signal: at the only call site nothing has been
68
+ * aborted yet, and a signal that was already aborted would make this wait
69
+ * unreachable — which is precisely the mid-tool kill being fixed.
70
+ */
71
+ export async function waitForToolCallBoundary(input: {
72
+ pending: () => readonly string[];
73
+ /**
74
+ * Resolves when the event-derived view of the pending set drains. A wake-up
75
+ * HINT only: `pending()` is re-read before the wait is allowed to settle,
76
+ * because the authoritative source may still hold a call this signal knows
77
+ * nothing about. Expected never to reject.
78
+ */
79
+ whenIdle: () => Promise<void>;
80
+ graceMs?: number;
81
+ pollMs?: number;
82
+ now?: () => number;
83
+ }): Promise<ToolBoundaryWaitResult> {
84
+ const now = input.now ?? Date.now;
85
+ // Idle prompts pay nothing: no timer, no allocation, no extra microtask turn
86
+ // beyond the caller's own await.
87
+ if (input.pending().length === 0) return IDLE_TOOL_BOUNDARY_RESULT;
88
+ const graceMs = Math.max(0, input.graceMs ?? TOOL_CALL_BOUNDARY_GRACE_MS);
89
+ const pollMs = Math.max(1, input.pollMs ?? TOOL_CALL_BOUNDARY_POLL_MS);
90
+ const startedAt = now();
91
+ let graceTimer: ReturnType<typeof setTimeout> | undefined;
92
+ let pollTimer: ReturnType<typeof setInterval> | undefined;
93
+ try {
94
+ const settled = new Promise<"settled">(resolve => {
95
+ // `pending()` is the single arbiter of settlement; the idle signal and
96
+ // the poll only decide WHEN it is consulted.
97
+ const check = () => {
98
+ if (input.pending().length === 0) resolve("settled");
99
+ };
100
+ // The loser of the race is abandoned rather than cancelled, so a rejection
101
+ // from it must be swallowed here or it surfaces as an unhandled rejection
102
+ // and takes the host down. A rejected idle simply leaves the poll and the
103
+ // grace timer as the arbiters.
104
+ void input.whenIdle().then(check, () => {});
105
+ pollTimer = setInterval(check, pollMs);
106
+ pollTimer?.unref?.();
107
+ });
108
+ const forced = new Promise<"forced">(resolve => {
109
+ graceTimer = setTimeout(() => resolve("forced"), graceMs);
110
+ // Never hold the process open for a tool that will not come back.
111
+ graceTimer?.unref?.();
112
+ });
113
+ const outcome = await Promise.race([settled, forced]);
114
+ return outcome === "settled"
115
+ ? { outcome: "settled", waitedMs: now() - startedAt, pendingToolCallIds: [] }
116
+ : { outcome: "forced", waitedMs: now() - startedAt, pendingToolCallIds: [...input.pending()] };
117
+ } finally {
118
+ clearTimeout(graceTimer);
119
+ clearInterval(pollTimer);
120
+ }
121
+ }
@@ -2144,6 +2144,17 @@
2144
2144
  "packages/coding-agent/test/sdk-operation-inventory.test.ts"
2145
2145
  ]
2146
2146
  },
2147
+ {
2148
+ "sourceId": "slash_command:mcp",
2149
+ "sourceFile": "packages/coding-agent/src/slash-commands/builtin-registry.ts",
2150
+ "sourceKind": "slash_command",
2151
+ "decision": "exclude",
2152
+ "rationale": "interactive exact-config MCP status and session control command; terminal-only handleTui surface is not dispatched through ACP or the public SDK",
2153
+ "exclusionMetadata": {
2154
+ "adapterMappings": "not_applicable",
2155
+ "testIds": "not_applicable"
2156
+ }
2157
+ },
2147
2158
  {
2148
2159
  "sourceId": "slash_command:agents",
2149
2160
  "sourceFile": "packages/coding-agent/src/slash-commands/builtin-registry.ts",
@@ -2188,6 +2199,24 @@
2188
2199
  "testIds": "not_applicable"
2189
2200
  }
2190
2201
  },
2202
+ {
2203
+ "sourceId": "slash_command:fork",
2204
+ "sourceFile": "packages/coding-agent/src/slash-commands/builtin-registry.ts",
2205
+ "sourceKind": "slash_command",
2206
+ "decision": "include",
2207
+ "sdkId": "session.branch",
2208
+ "adapterMappings": {
2209
+ "telegram": "prohibited",
2210
+ "discord": "prohibited",
2211
+ "slack": "prohibited",
2212
+ "mcp": "prohibited",
2213
+ "acp": "prohibited",
2214
+ "daemonCli": "prohibited"
2215
+ },
2216
+ "testIds": [
2217
+ "packages/coding-agent/test/sdk-operation-inventory.test.ts"
2218
+ ]
2219
+ },
2191
2220
  {
2192
2221
  "sourceId": "slash_command:provider",
2193
2222
  "sourceFile": "packages/coding-agent/src/slash-commands/builtin-registry.ts",
@@ -3202,6 +3231,28 @@
3202
3231
  "packages/coding-agent/test/sdk-operation-inventory.test.ts"
3203
3232
  ]
3204
3233
  },
3234
+ {
3235
+ "sourceId": "agent_session:getExactMcpStatusSnapshot",
3236
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
3237
+ "sourceKind": "agent_session",
3238
+ "decision": "exclude",
3239
+ "rationale": "internal exact-config MCP status accessor used only by the terminal-only /mcp command; its capability is granted only to root interactive --mcp-config sessions, not a public SDK query",
3240
+ "exclusionMetadata": {
3241
+ "adapterMappings": "not_applicable",
3242
+ "testIds": "not_applicable"
3243
+ }
3244
+ },
3245
+ {
3246
+ "sourceId": "agent_session:controlExactMcpServer",
3247
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
3248
+ "sourceKind": "agent_session",
3249
+ "decision": "exclude",
3250
+ "rationale": "internal session-local exact-config MCP suspend/resume/reconnect mutation used only by the terminal-only /mcp command; runtime suppression is not persistent user authority or a public SDK control",
3251
+ "exclusionMetadata": {
3252
+ "adapterMappings": "not_applicable",
3253
+ "testIds": "not_applicable"
3254
+ }
3255
+ },
3205
3256
  {
3206
3257
  "sourceId": "agent_session:getSelectedMCPToolNames",
3207
3258
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -3891,6 +3942,17 @@
3891
3942
  "packages/coding-agent/test/sdk-operation-inventory.test.ts"
3892
3943
  ]
3893
3944
  },
3945
+ {
3946
+ "sourceId": "agent_session:submitUserMessage",
3947
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
3948
+ "sourceKind": "agent_session",
3949
+ "decision": "exclude",
3950
+ "rationale": "public in-process embedder lifecycle API; direct handle surface, not an SDK transport operation",
3951
+ "exclusionMetadata": {
3952
+ "adapterMappings": "not_applicable",
3953
+ "testIds": "not_applicable"
3954
+ }
3955
+ },
3894
3956
  {
3895
3957
  "sourceId": "agent_session:clearQueue",
3896
3958
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -4182,6 +4244,17 @@
4182
4244
  "testIds": "not_applicable"
4183
4245
  }
4184
4246
  },
4247
+ {
4248
+ "sourceId": "agent_session:pendingToolExecutions",
4249
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
4250
+ "sourceKind": "agent_session",
4251
+ "decision": "exclude",
4252
+ "rationale": "internal read-only run-resource-ledger view, threaded via terminalAbortSeams so the prompt deadline can find a tool-call boundary; not a user-facing SDK control seam",
4253
+ "exclusionMetadata": {
4254
+ "adapterMappings": "not_applicable",
4255
+ "testIds": "not_applicable"
4256
+ }
4257
+ },
4185
4258
  {
4186
4259
  "sourceId": "agent_session:abortPromptAndWait",
4187
4260
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -4466,6 +4539,39 @@
4466
4539
  "testIds": "not_applicable"
4467
4540
  }
4468
4541
  },
4542
+ {
4543
+ "sourceId": "agent_session:installRecoveredDefaultFallbackChain",
4544
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
4545
+ "sourceKind": "agent_session",
4546
+ "decision": "exclude",
4547
+ "rationale": "internal recovered fallback-chain installation during session startup, not a user-facing SDK control seam",
4548
+ "exclusionMetadata": {
4549
+ "adapterMappings": "not_applicable",
4550
+ "testIds": "not_applicable"
4551
+ }
4552
+ },
4553
+ {
4554
+ "sourceId": "agent_session:markStartupRecoveryBindingsRequired",
4555
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
4556
+ "sourceKind": "agent_session",
4557
+ "decision": "exclude",
4558
+ "rationale": "internal startup recovery binding marker, not a user-facing SDK control seam",
4559
+ "exclusionMetadata": {
4560
+ "adapterMappings": "not_applicable",
4561
+ "testIds": "not_applicable"
4562
+ }
4563
+ },
4564
+ {
4565
+ "sourceId": "agent_session:hasRecoveredDefaultFallbackChain",
4566
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
4567
+ "sourceKind": "agent_session",
4568
+ "decision": "exclude",
4569
+ "rationale": "internal recovered fallback-chain state query, not a user-facing SDK control seam",
4570
+ "exclusionMetadata": {
4571
+ "adapterMappings": "not_applicable",
4572
+ "testIds": "not_applicable"
4573
+ }
4574
+ },
4469
4575
  {
4470
4576
  "sourceId": "agent_session:seedDefaultFallbackResolution",
4471
4577
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -25,6 +25,7 @@ import {
25
25
  readSdkSessionEndpoint,
26
26
  type SdkSessionEndpoint,
27
27
  } from "../client/discovery";
28
+ import { SESSION_HOST_OBSERVER_CAPABILITY, TURN_STREAM_CAPABILITY } from "../host/host";
28
29
  import {
29
30
  type ActivatedPreparedSession,
30
31
  type PreparedSessionActivationClient,
@@ -286,6 +287,8 @@ export interface SessionRouterOptions {
286
287
  agentDir: string;
287
288
  /** Limits attachment to exact ids selected by a Broker-scoped operation. */
288
289
  sessionIds?: readonly string[];
290
+ /** Marks default SDK clients as notification-only observers; demanding by default. */
291
+ observer?: boolean;
289
292
  deps?: SessionRouterDeps;
290
293
  /** Runtime-specific identity validation; Router supplies a conservative fallback. */
291
294
  correlateFrame?: SessionRouterFrameCorrelator;
@@ -612,6 +615,7 @@ type AdoptedSession = {
612
615
  export class SessionRouter {
613
616
  readonly #agentDir: string;
614
617
  readonly #sessionIds: ReadonlySet<string> | undefined;
618
+ readonly #observer: boolean;
615
619
  readonly #deps: SessionRouterDeps;
616
620
  readonly #correlateFrame: SessionRouterFrameCorrelator;
617
621
  readonly #index: SessionIndex;
@@ -653,6 +657,7 @@ export class SessionRouter {
653
657
  constructor(options: SessionRouterOptions) {
654
658
  this.#agentDir = options.agentDir;
655
659
  this.#sessionIds = options.sessionIds === undefined ? undefined : new Set(options.sessionIds);
660
+ this.#observer = options.observer === true;
656
661
  this.#deps = options.deps ?? {};
657
662
  this.#correlateFrame = options.correlateFrame ?? fallbackCorrelation;
658
663
  this.#index = this.#deps.createIndex?.(options.agentDir) ?? new DefaultSessionIndex(options.agentDir);
@@ -1519,7 +1524,10 @@ export class SessionRouter {
1519
1524
  endpointMtimeMs,
1520
1525
  });
1521
1526
  } else {
1522
- const defaultClient = new SdkClient(endpoint.url, endpoint.token, { ...ACP_SESSION_RECONNECT });
1527
+ const defaultClient = new SdkClient(endpoint.url, endpoint.token, {
1528
+ ...ACP_SESSION_RECONNECT,
1529
+ ...(this.#observer ? { capabilities: [SESSION_HOST_OBSERVER_CAPABILITY, TURN_STREAM_CAPABILITY] } : {}),
1530
+ });
1523
1531
  transport = defaultClient;
1524
1532
  connection = defaultClient.connect().then(() => defaultClient);
1525
1533
  }