@gajae-code/coding-agent 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (610) hide show
  1. package/CHANGELOG.md +215 -8
  2. package/README.md +2 -0
  3. package/bin/gajaessi.js +4 -0
  4. package/dist/types/async/job-manager.d.ts +55 -2
  5. package/dist/types/async/support.d.ts +14 -0
  6. package/dist/types/capability/mcp.d.ts +6 -0
  7. package/dist/types/capability/types.d.ts +6 -0
  8. package/dist/types/cli/accounts-cli.d.ts +19 -0
  9. package/dist/types/cli/args.d.ts +3 -0
  10. package/dist/types/cli/config-cli.d.ts +6 -0
  11. package/dist/types/cli/crash-cli.d.ts +10 -0
  12. package/dist/types/cli/customize-doctor.d.ts +145 -0
  13. package/dist/types/cli/daemon-cli.d.ts +3 -1
  14. package/dist/types/cli/mcp-cli.d.ts +11 -0
  15. package/dist/types/cli/notify-cli.d.ts +1 -1
  16. package/dist/types/cli/root-flags.d.ts +12 -0
  17. package/dist/types/cli/setup-cli.d.ts +3 -1
  18. package/dist/types/cli/skills-cli.d.ts +2 -1
  19. package/dist/types/cli/update-cli.d.ts +19 -1
  20. package/dist/types/cli.d.ts +6 -0
  21. package/dist/types/commands/accounts.d.ts +40 -0
  22. package/dist/types/commands/crash.d.ts +24 -0
  23. package/dist/types/commands/customize.d.ts +22 -0
  24. package/dist/types/commands/daemon.d.ts +1 -1
  25. package/dist/types/commands/launch.d.ts +6 -0
  26. package/dist/types/commands/setup.d.ts +6 -0
  27. package/dist/types/commands/skills.d.ts +6 -1
  28. package/dist/types/commands/update.d.ts +7 -0
  29. package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
  30. package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
  31. package/dist/types/config/config-schema-version.d.ts +10 -0
  32. package/dist/types/config/file-lock.d.ts +18 -0
  33. package/dist/types/config/model-profile-activation.d.ts +3 -1
  34. package/dist/types/config/model-registry.d.ts +10 -1
  35. package/dist/types/config/models-config-schema.d.ts +2 -0
  36. package/dist/types/config/settings-schema.d.ts +73 -9
  37. package/dist/types/config/settings.d.ts +63 -0
  38. package/dist/types/config/skill-settings-defaults.d.ts +26 -0
  39. package/dist/types/config/task-delegation.d.ts +39 -0
  40. package/dist/types/config/update-channel.d.ts +10 -0
  41. package/dist/types/coordinator-mcp/server.d.ts +5 -1
  42. package/dist/types/crash/index-store.d.ts +87 -0
  43. package/dist/types/crash/nudge.d.ts +50 -0
  44. package/dist/types/crash/record-loader.d.ts +17 -0
  45. package/dist/types/crash/report.d.ts +134 -0
  46. package/dist/types/crash/sanitize.d.ts +25 -0
  47. package/dist/types/cursor.d.ts +13 -2
  48. package/dist/types/customization/import.d.ts +37 -0
  49. package/dist/types/customization/index.d.ts +4 -0
  50. package/dist/types/customization/inventory.d.ts +25 -0
  51. package/dist/types/customization/mutations.d.ts +32 -0
  52. package/dist/types/customization/types.d.ts +115 -0
  53. package/dist/types/daemon/control-types.d.ts +8 -1
  54. package/dist/types/daemon/operator-contract.d.ts +4 -4
  55. package/dist/types/discovery/claude.d.ts +39 -1
  56. package/dist/types/discovery/codex.d.ts +39 -1
  57. package/dist/types/discovery/index.d.ts +2 -0
  58. package/dist/types/discovery/mcp-compat.d.ts +30 -0
  59. package/dist/types/edit/renderer.d.ts +23 -0
  60. package/dist/types/extensibility/extensions/runner.d.ts +3 -0
  61. package/dist/types/extensibility/extensions/types.d.ts +21 -4
  62. package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
  63. package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
  64. package/dist/types/extensibility/hooks/loader.d.ts +19 -5
  65. package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
  66. package/dist/types/extensibility/skill-management.d.ts +107 -0
  67. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
  68. package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
  69. package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
  70. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
  71. package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
  72. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
  73. package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
  74. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
  75. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
  76. package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
  77. package/dist/types/hooks/events.d.ts +60 -0
  78. package/dist/types/hooks/normalize.d.ts +83 -0
  79. package/dist/types/hooks/skill-state.d.ts +9 -2
  80. package/dist/types/main.d.ts +2 -1
  81. package/dist/types/modes/acp/abort-scope.d.ts +13 -0
  82. package/dist/types/modes/acp/acp-agent.d.ts +7 -4
  83. package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
  84. package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
  85. package/dist/types/modes/components/customization/index.d.ts +1 -0
  86. package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
  87. package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
  88. package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
  89. package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
  90. package/dist/types/modes/components/oauth-selector.d.ts +10 -4
  91. package/dist/types/modes/components/pet-capability.d.ts +7 -21
  92. package/dist/types/modes/components/settings-selector.d.ts +5 -0
  93. package/dist/types/modes/components/status-line/gh.d.ts +6 -2
  94. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  95. package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
  96. package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
  97. package/dist/types/modes/interactive-mode.d.ts +1 -0
  98. package/dist/types/modes/theme/defaults/index.d.ts +118 -0
  99. package/dist/types/modes/types.d.ts +1 -0
  100. package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
  101. package/dist/types/runtime-mcp/config.d.ts +9 -0
  102. package/dist/types/runtime-mcp/manager.d.ts +26 -1
  103. package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
  104. package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
  105. package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
  106. package/dist/types/runtime-mcp/protocol.d.ts +278 -0
  107. package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
  108. package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
  109. package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
  110. package/dist/types/runtime-mcp/types.d.ts +102 -10
  111. package/dist/types/sdk/acp/adapter.d.ts +26 -5
  112. package/dist/types/sdk/broker/broker.d.ts +3 -55
  113. package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
  114. package/dist/types/sdk/broker/session-index.d.ts +14 -5
  115. package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
  116. package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
  117. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
  118. package/dist/types/sdk/bus/config.d.ts +11 -0
  119. package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
  120. package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
  121. package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
  122. package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
  123. package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
  124. package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
  125. package/dist/types/sdk/bus/index.d.ts +85 -99
  126. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
  127. package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
  128. package/dist/types/sdk/bus/notification-service.d.ts +52 -0
  129. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
  130. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
  131. package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
  132. package/dist/types/sdk/bus/session-control.d.ts +25 -1
  133. package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
  134. package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
  135. package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
  136. package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
  137. package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
  138. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
  139. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
  140. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
  141. package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
  142. package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
  143. package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
  144. package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
  145. package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
  146. package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
  147. package/dist/types/sdk/cli/rows.d.ts +2 -11
  148. package/dist/types/sdk/cli/session-cli.d.ts +15 -25
  149. package/dist/types/sdk/client/client.d.ts +97 -1
  150. package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
  151. package/dist/types/sdk/host/control/index.d.ts +1 -1
  152. package/dist/types/sdk/host/control/operations.d.ts +18 -5
  153. package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
  154. package/dist/types/sdk/host/host.d.ts +15 -1
  155. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  156. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  157. package/dist/types/sdk/host/session-runtime.d.ts +127 -7
  158. package/dist/types/sdk/host/types.d.ts +1 -1
  159. package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
  160. package/dist/types/sdk/index.d.ts +2 -1
  161. package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
  162. package/dist/types/sdk/lifecycle/client.d.ts +59 -0
  163. package/dist/types/sdk/lifecycle/index.d.ts +3 -0
  164. package/dist/types/sdk/lifecycle/service.d.ts +232 -0
  165. package/dist/types/sdk/mcp/server.d.ts +9 -6
  166. package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
  167. package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
  168. package/dist/types/sdk/prompt-status.d.ts +10 -3
  169. package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
  170. package/dist/types/sdk/receipt-state.d.ts +17 -0
  171. package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
  172. package/dist/types/sdk/router/index.d.ts +1 -0
  173. package/dist/types/sdk/router/session-router.d.ts +152 -0
  174. package/dist/types/sdk/session-list.d.ts +22 -0
  175. package/dist/types/sdk/session-reconnect.d.ts +43 -1
  176. package/dist/types/sdk/session.d.ts +34 -1
  177. package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
  178. package/dist/types/session/account-inventory.d.ts +86 -0
  179. package/dist/types/session/agent-session.d.ts +145 -6
  180. package/dist/types/session/agent-storage.d.ts +10 -0
  181. package/dist/types/session/coordinator-tool-label.d.ts +28 -0
  182. package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
  183. package/dist/types/session/messages.d.ts +1 -1
  184. package/dist/types/session/secure-token-file.d.ts +3 -0
  185. package/dist/types/session/session-manager.d.ts +47 -1
  186. package/dist/types/session/startup-auth-config.d.ts +44 -0
  187. package/dist/types/session/terminal-abort.d.ts +378 -0
  188. package/dist/types/session/yield-queue.d.ts +7 -0
  189. package/dist/types/session-import/claude.d.ts +26 -0
  190. package/dist/types/session-import/codex.d.ts +88 -0
  191. package/dist/types/session-import/command.d.ts +35 -0
  192. package/dist/types/session-import/detect.d.ts +22 -0
  193. package/dist/types/session-import/index.d.ts +7 -0
  194. package/dist/types/session-import/provider-codex.d.ts +22 -0
  195. package/dist/types/session-import/provider-service.d.ts +38 -0
  196. package/dist/types/session-import/redact.d.ts +23 -0
  197. package/dist/types/session-import/service.d.ts +47 -0
  198. package/dist/types/session-import/types.d.ts +120 -0
  199. package/dist/types/setup/paseo/check.d.ts +16 -0
  200. package/dist/types/setup/paseo/install-saga.d.ts +115 -0
  201. package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
  202. package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
  203. package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
  204. package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
  205. package/dist/types/setup/paseo/provider-config.d.ts +35 -0
  206. package/dist/types/setup/paseo/remove.d.ts +14 -0
  207. package/dist/types/setup/paseo/result-types.d.ts +59 -0
  208. package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
  209. package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
  210. package/dist/types/skill-state/active-state.d.ts +5 -1
  211. package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
  212. package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
  213. package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
  214. package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
  215. package/dist/types/slash-commands/types.d.ts +7 -1
  216. package/dist/types/task/executor.d.ts +10 -0
  217. package/dist/types/task/index.d.ts +3 -1
  218. package/dist/types/tools/ask-answer-registry.d.ts +6 -3
  219. package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
  220. package/dist/types/tools/bash.d.ts +2 -6
  221. package/dist/types/tools/browser/attach.d.ts +11 -0
  222. package/dist/types/tools/browser/launch.d.ts +20 -0
  223. package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
  224. package/dist/types/tools/browser/render.d.ts +1 -0
  225. package/dist/types/tools/browser.d.ts +3 -1
  226. package/dist/types/tools/image-gen.d.ts +10 -2
  227. package/dist/types/tools/index.d.ts +8 -0
  228. package/dist/types/tools/monitor.d.ts +1 -1
  229. package/dist/types/tools/skill-discovery.d.ts +8 -1
  230. package/dist/types/tools/subagent.d.ts +2 -0
  231. package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
  232. package/dist/types/utils/herdr-pane.d.ts +76 -0
  233. package/package.json +19 -9
  234. package/scripts/build-binary.ts +2 -1
  235. package/scripts/build-sdk-package-smoke.ts +2 -13
  236. package/scripts/capture-sticky-viewport-showcase.ts +0 -1
  237. package/scripts/compile-args.ts +2 -0
  238. package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
  239. package/scripts/generate-sdk-operation-inventory.ts +28 -0
  240. package/scripts/generate-telegram-baseline-manifest.ts +1 -0
  241. package/scripts/generate-tool-catalog.ts +6 -4
  242. package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
  243. package/src/async/job-manager.ts +352 -17
  244. package/src/async/support.ts +25 -0
  245. package/src/autoresearch/dashboard.ts +28 -13
  246. package/src/capability/index.ts +3 -1
  247. package/src/capability/mcp.ts +6 -0
  248. package/src/capability/types.ts +6 -0
  249. package/src/cli/accounts-cli.ts +395 -0
  250. package/src/cli/args.ts +23 -0
  251. package/src/cli/auth-broker-cli.ts +136 -66
  252. package/src/cli/auth-gateway-cli.ts +94 -70
  253. package/src/cli/config-cli.ts +27 -2
  254. package/src/cli/crash-cli.ts +78 -0
  255. package/src/cli/customize-doctor.ts +1605 -0
  256. package/src/cli/daemon-cli.ts +12 -3
  257. package/src/cli/fast-help.ts +1 -0
  258. package/src/cli/mcp-cli.ts +128 -60
  259. package/src/cli/notify-cli.ts +8 -14
  260. package/src/cli/root-flags.ts +8 -0
  261. package/src/cli/setup-cli.ts +145 -0
  262. package/src/cli/skills-cli.ts +38 -2
  263. package/src/cli/update-cli.ts +167 -12
  264. package/src/cli.ts +4 -0
  265. package/src/commands/accounts.ts +71 -0
  266. package/src/commands/crash.ts +35 -0
  267. package/src/commands/customize.ts +84 -0
  268. package/src/commands/daemon.ts +2 -2
  269. package/src/commands/deep-interview.ts +2 -0
  270. package/src/commands/launch.ts +1 -0
  271. package/src/commands/mcp.ts +12 -7
  272. package/src/commands/ralplan.ts +2 -0
  273. package/src/commands/sdk.ts +65 -32
  274. package/src/commands/setup.ts +5 -0
  275. package/src/commands/skills.ts +14 -4
  276. package/src/commands/ultragoal.ts +10 -1
  277. package/src/commands/update.ts +26 -15
  278. package/src/config/atomic-yaml-patch-worker.ts +57 -0
  279. package/src/config/atomic-yaml-patch.ts +769 -29
  280. package/src/config/config-schema-version.ts +10 -0
  281. package/src/config/file-lock.ts +70 -1
  282. package/src/config/mcp-schema.json +52 -14
  283. package/src/config/model-profile-activation.ts +23 -2
  284. package/src/config/model-profiles.ts +88 -21
  285. package/src/config/model-registry.ts +147 -21
  286. package/src/config/models-config-schema.ts +1 -1
  287. package/src/config/settings-schema.ts +77 -7
  288. package/src/config/settings.ts +4038 -199
  289. package/src/config/skill-settings-defaults.ts +41 -3
  290. package/src/config/task-delegation.ts +87 -0
  291. package/src/config/update-channel.ts +23 -0
  292. package/src/coordinator-mcp/server.ts +377 -308
  293. package/src/crash/index-store.ts +723 -0
  294. package/src/crash/nudge.ts +89 -0
  295. package/src/crash/record-loader.ts +149 -0
  296. package/src/crash/report.ts +551 -0
  297. package/src/crash/sanitize.ts +129 -0
  298. package/src/cursor.ts +36 -10
  299. package/src/customization/import.ts +946 -0
  300. package/src/customization/index.ts +4 -0
  301. package/src/customization/inventory.ts +335 -0
  302. package/src/customization/mutations.ts +141 -0
  303. package/src/customization/types.ts +223 -0
  304. package/src/daemon/control-types.ts +8 -1
  305. package/src/daemon/operator-contract.ts +6 -6
  306. package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
  307. package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
  308. package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
  309. package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
  310. package/src/discovery/claude-hooks.ts +38 -0
  311. package/src/discovery/claude.ts +142 -209
  312. package/src/discovery/codex-hooks.ts +38 -0
  313. package/src/discovery/codex.ts +132 -198
  314. package/src/discovery/helpers.ts +8 -1
  315. package/src/discovery/index.ts +2 -0
  316. package/src/discovery/mcp-compat.ts +234 -0
  317. package/src/discovery/mcp-json.ts +6 -0
  318. package/src/edit/renderer.ts +40 -0
  319. package/src/edit/streaming.ts +4 -2
  320. package/src/exec/bash-executor.ts +24 -20
  321. package/src/export/html/index.ts +51 -2
  322. package/src/extensibility/extensions/loader.ts +9 -1
  323. package/src/extensibility/extensions/runner.ts +17 -4
  324. package/src/extensibility/extensions/types.ts +31 -6
  325. package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
  326. package/src/extensibility/gjc-plugins/installer.ts +9 -5
  327. package/src/extensibility/gjc-plugins/observability.ts +8 -2
  328. package/src/extensibility/gjc-plugins/registry.ts +13 -2
  329. package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
  330. package/src/extensibility/gjc-plugins/schema.ts +222 -39
  331. package/src/extensibility/hooks/loader.ts +154 -10
  332. package/src/extensibility/runtime-skill-discovery.ts +257 -60
  333. package/src/extensibility/skill-management.ts +368 -0
  334. package/src/extensibility/skills.ts +52 -16
  335. package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
  336. package/src/gjc-runtime/launch-worktree.ts +56 -2
  337. package/src/gjc-runtime/linux-proc.ts +7 -1
  338. package/src/gjc-runtime/ralplan-runtime.ts +100 -164
  339. package/src/gjc-runtime/session-state-lock.ts +992 -0
  340. package/src/gjc-runtime/session-state-sidecar.ts +644 -142
  341. package/src/gjc-runtime/state-writer.ts +39 -14
  342. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
  343. package/src/gjc-runtime/ultragoal-guard.ts +11 -4
  344. package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
  345. package/src/gjc-runtime/workflow-settings.ts +596 -0
  346. package/src/goals/tools/goal-tool.ts +6 -1
  347. package/src/hooks/events.ts +291 -0
  348. package/src/hooks/native-skill-hook.ts +4 -0
  349. package/src/hooks/normalize.ts +369 -0
  350. package/src/hooks/skill-state.ts +165 -46
  351. package/src/internal-urls/docs-index.generated.ts +41 -32
  352. package/src/main.ts +36 -5
  353. package/src/migrate/mcp-mapper.ts +25 -2
  354. package/src/modes/acp/abort-scope.ts +29 -0
  355. package/src/modes/acp/acp-agent.ts +423 -98
  356. package/src/modes/components/assistant-message.ts +6 -1
  357. package/src/modes/components/chrome.ts +4 -3
  358. package/src/modes/components/customization/customization-dashboard.ts +443 -0
  359. package/src/modes/components/customization/import-wizard.ts +372 -0
  360. package/src/modes/components/customization/index.ts +1 -0
  361. package/src/modes/components/dynamic-theme-text.ts +22 -0
  362. package/src/modes/components/gajae-pet-widget.ts +607 -193
  363. package/src/modes/components/irc-sidebar.ts +11 -0
  364. package/src/modes/components/iterm-pet-transport.ts +585 -0
  365. package/src/modes/components/model-selector.ts +1 -6
  366. package/src/modes/components/oauth-selector.ts +277 -86
  367. package/src/modes/components/pet-capability.ts +35 -31
  368. package/src/modes/components/settings-selector.ts +29 -5
  369. package/src/modes/components/status-line/gh.ts +45 -1
  370. package/src/modes/components/status-line/segments.ts +19 -4
  371. package/src/modes/components/tool-status-header.ts +13 -3
  372. package/src/modes/controllers/command-controller.ts +20 -8
  373. package/src/modes/controllers/extension-ui-controller.ts +56 -257
  374. package/src/modes/controllers/input-controller.ts +10 -0
  375. package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
  376. package/src/modes/controllers/selector-controller.ts +238 -77
  377. package/src/modes/controllers/stt-controller.ts +3 -3
  378. package/src/modes/interactive-mode.ts +88 -16
  379. package/src/modes/print-mode.ts +35 -6
  380. package/src/modes/runtime-init.ts +21 -68
  381. package/src/modes/theme/defaults/index.ts +2 -0
  382. package/src/modes/theme/defaults/ouroboros.json +118 -0
  383. package/src/modes/types.ts +1 -0
  384. package/src/modes/utils/injected-user-submission.ts +25 -0
  385. package/src/modes/utils/terminal-bell.ts +15 -1
  386. package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
  387. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  388. package/src/prompts/agents/critic.md +1 -1
  389. package/src/prompts/system/rlm-research.md +1 -1
  390. package/src/prompts/system/system-prompt.md +0 -2
  391. package/src/prompts/tools/bash.md +7 -1
  392. package/src/prompts/tools/browser.md +1 -1
  393. package/src/prompts/tools/cron.md +6 -6
  394. package/src/prompts/tools/read.md +0 -2
  395. package/src/prompts/tools/skill-discovery.md +4 -2
  396. package/src/runtime-mcp/client.ts +427 -23
  397. package/src/runtime-mcp/config.ts +37 -5
  398. package/src/runtime-mcp/manager-pool.test.ts +56 -0
  399. package/src/runtime-mcp/manager.ts +52 -2
  400. package/src/runtime-mcp/oauth-discovery.ts +13 -0
  401. package/src/runtime-mcp/oauth-flow.ts +46 -1
  402. package/src/runtime-mcp/pool-key.ts +5 -1
  403. package/src/runtime-mcp/pool.test.ts +9 -0
  404. package/src/runtime-mcp/protocol.test.ts +353 -0
  405. package/src/runtime-mcp/protocol.ts +624 -0
  406. package/src/runtime-mcp/scope-config.ts +78 -0
  407. package/src/runtime-mcp/tool-bridge.ts +44 -10
  408. package/src/runtime-mcp/transports/http.ts +84 -13
  409. package/src/runtime-mcp/types.ts +123 -12
  410. package/src/sdk/acp/adapter.ts +328 -97
  411. package/src/sdk/broker/broker.ts +160 -741
  412. package/src/sdk/broker/ensure.ts +9 -1
  413. package/src/sdk/broker/lifecycle.ts +510 -116
  414. package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
  415. package/src/sdk/broker/process-incarnation.ts +19 -0
  416. package/src/sdk/broker/session-index.ts +516 -117
  417. package/src/sdk/broker/startup-failure.ts +28 -5
  418. package/src/sdk/broker/transport.ts +1 -13
  419. package/src/sdk/bus/chat-daemon-cli.ts +4 -2
  420. package/src/sdk/bus/chat-daemon-control.ts +67 -6
  421. package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
  422. package/src/sdk/bus/config.ts +13 -0
  423. package/src/sdk/bus/conversation-store.ts +59 -171
  424. package/src/sdk/bus/daemon-paths.ts +20 -0
  425. package/src/sdk/bus/discord-conversation.ts +2 -0
  426. package/src/sdk/bus/discord-daemon.ts +524 -126
  427. package/src/sdk/bus/discord-live-provider.ts +206 -79
  428. package/src/sdk/bus/existing-thread-readiness.ts +4 -97
  429. package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
  430. package/src/sdk/bus/index.ts +2480 -456
  431. package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
  432. package/src/sdk/bus/lifecycle-commands.ts +2 -2
  433. package/src/sdk/bus/managed-daemon.ts +2 -145
  434. package/src/sdk/bus/notification-service.ts +196 -0
  435. package/src/sdk/bus/operator-runtime.ts +1 -1
  436. package/src/sdk/bus/prompt-reconciliation.ts +24 -15
  437. package/src/sdk/bus/reconciliation-store.ts +553 -24
  438. package/src/sdk/bus/session-control.ts +49 -3
  439. package/src/sdk/bus/slack-conversation.ts +4 -0
  440. package/src/sdk/bus/slack-daemon.ts +733 -134
  441. package/src/sdk/bus/slack-live-provider.ts +65 -15
  442. package/src/sdk/bus/slack-provider.ts +4 -0
  443. package/src/sdk/bus/slack-thread-binding.ts +9 -104
  444. package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
  445. package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
  446. package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
  447. package/src/sdk/bus/telegram-daemon-control.ts +3 -13
  448. package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
  449. package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
  450. package/src/sdk/bus/telegram-daemon.ts +2552 -2280
  451. package/src/sdk/bus/telegram-reference.ts +1 -226
  452. package/src/sdk/bus/telegram-setup.ts +2 -2
  453. package/src/sdk/bus/threaded-render.ts +1 -0
  454. package/src/sdk/bus/topic-registry.ts +279 -146
  455. package/src/sdk/cli/rows.ts +2 -35
  456. package/src/sdk/cli/session-cli.ts +776 -700
  457. package/src/sdk/client/client.ts +892 -1
  458. package/src/sdk/host/control/dispatch.ts +93 -58
  459. package/src/sdk/host/control/index.ts +1 -1
  460. package/src/sdk/host/control/operations.ts +18 -10
  461. package/src/sdk/host/control/runtime-gate.ts +40 -0
  462. package/src/sdk/host/host.ts +63 -12
  463. package/src/sdk/host/query/handlers.ts +66 -7
  464. package/src/sdk/host/reverse-leases.ts +2 -2
  465. package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
  466. package/src/sdk/host/session-runtime.test.ts +2787 -34
  467. package/src/sdk/host/session-runtime.ts +1489 -101
  468. package/src/sdk/host/surface-policy.ts +12 -8
  469. package/src/sdk/host/types.ts +1 -1
  470. package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
  471. package/src/sdk/host/websocket-transport.ts +85 -50
  472. package/src/sdk/index.ts +2 -1
  473. package/src/sdk/lifecycle/broker-client.ts +53 -0
  474. package/src/sdk/lifecycle/client.ts +234 -0
  475. package/src/sdk/lifecycle/index.ts +3 -0
  476. package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
  477. package/src/sdk/lifecycle/service.ts +720 -0
  478. package/src/sdk/mcp/server.ts +226 -188
  479. package/src/sdk/prompt-deadline-lease.ts +55 -0
  480. package/src/sdk/prompt-deadline-manager.ts +148 -0
  481. package/src/sdk/prompt-status.ts +11 -3
  482. package/src/sdk/protocol/operation-inventory.generated.json +272 -129
  483. package/src/sdk/protocol/operation-registry.ts +71 -8
  484. package/src/sdk/receipt-state.ts +43 -0
  485. package/src/sdk/reconciliation-extensions.ts +14 -0
  486. package/src/sdk/router/index.ts +1 -0
  487. package/src/sdk/router/session-router.ts +1658 -0
  488. package/src/sdk/session-list.ts +93 -0
  489. package/src/sdk/session-reconnect.ts +45 -1
  490. package/src/sdk/session.ts +716 -120
  491. package/src/sdk/transport/serve-cli.ts +18 -34
  492. package/src/session/account-inventory.ts +603 -0
  493. package/src/session/agent-session.ts +2873 -559
  494. package/src/session/agent-storage.ts +35 -0
  495. package/src/session/blob-store.ts +32 -1
  496. package/src/session/coordinator-tool-label.ts +40 -0
  497. package/src/session/internal/managed-session-scope.ts +4 -0
  498. package/src/session/internal/managed-session-storage.ts +199 -31
  499. package/src/session/messages.ts +1 -1
  500. package/src/session/secure-token-file.ts +80 -0
  501. package/src/session/session-manager.ts +757 -57
  502. package/src/session/session-storage.ts +25 -16
  503. package/src/session/startup-auth-config.ts +297 -0
  504. package/src/session/terminal-abort.ts +1253 -0
  505. package/src/session/yield-queue.ts +57 -15
  506. package/src/session-import/claude.ts +334 -0
  507. package/src/session-import/codex.ts +1033 -0
  508. package/src/session-import/command.ts +77 -0
  509. package/src/session-import/detect.ts +133 -0
  510. package/src/session-import/index.ts +7 -0
  511. package/src/session-import/provider-codex.ts +327 -0
  512. package/src/session-import/provider-service.ts +457 -0
  513. package/src/session-import/redact.ts +128 -0
  514. package/src/session-import/service.ts +1264 -0
  515. package/src/session-import/types.ts +148 -0
  516. package/src/setup/paseo/check.ts +213 -0
  517. package/src/setup/paseo/install-saga.ts +293 -0
  518. package/src/setup/paseo/json-publisher.ts +263 -0
  519. package/src/setup/paseo/orchestration-preferences.ts +86 -0
  520. package/src/setup/paseo/paseo-ownership.ts +224 -0
  521. package/src/setup/paseo/paseo-setup.ts +253 -0
  522. package/src/setup/paseo/provider-config.ts +139 -0
  523. package/src/setup/paseo/remove.ts +183 -0
  524. package/src/setup/paseo/result-types.ts +79 -0
  525. package/src/setup/paseo/setup-deps.ts +175 -0
  526. package/src/setup/paseo/skills-bridge.ts +260 -0
  527. package/src/skill-state/active-state.ts +21 -11
  528. package/src/slash-commands/acp-builtins.ts +9 -1
  529. package/src/slash-commands/builtin-registry.ts +117 -19
  530. package/src/slash-commands/helpers/credential-switch.ts +143 -0
  531. package/src/slash-commands/helpers/mcp.ts +9 -3
  532. package/src/slash-commands/helpers/usage-report.ts +61 -56
  533. package/src/slash-commands/types.ts +7 -2
  534. package/src/task/executor.ts +30 -11
  535. package/src/task/index.ts +66 -7
  536. package/src/task/render.ts +23 -9
  537. package/src/tools/ask-answer-registry.ts +23 -7
  538. package/src/tools/ask.ts +8 -4
  539. package/src/tools/bash-sleep-advisory.ts +115 -0
  540. package/src/tools/bash.ts +98 -18
  541. package/src/tools/browser/attach.ts +71 -3
  542. package/src/tools/browser/launch.ts +86 -13
  543. package/src/tools/browser/profile-discovery.ts +57 -7
  544. package/src/tools/browser/render.ts +8 -1
  545. package/src/tools/browser.ts +130 -21
  546. package/src/tools/computer.enforcement.test.ts +1 -1
  547. package/src/tools/computer.ts +3 -2
  548. package/src/tools/cron.ts +12 -1
  549. package/src/tools/image-gen.ts +349 -142
  550. package/src/tools/index.ts +8 -0
  551. package/src/tools/job.ts +33 -6
  552. package/src/tools/monitor.ts +41 -2
  553. package/src/tools/skill-discovery.ts +21 -29
  554. package/src/tools/subagent.ts +142 -24
  555. package/src/tools/todo-contract.ts +55 -3
  556. package/src/tools/todo-write.ts +4 -3
  557. package/src/tools/tool-catalog.generated.ts +6 -6
  558. package/src/tools/ultragoal-ask-guard.ts +10 -3
  559. package/src/utils/herdr-pane.ts +345 -0
  560. package/src/utils/title-generator.ts +2 -0
  561. package/src/web/scrapers/index.ts +6 -4
  562. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  563. package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
  564. package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
  565. package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
  566. package/dist/types/runtime/lazy-service.test.d.ts +0 -1
  567. package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
  568. package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
  569. package/dist/types/runtime-mcp/config.test.d.ts +0 -1
  570. package/dist/types/runtime-mcp/http.test.d.ts +0 -1
  571. package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
  572. package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
  573. package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
  574. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
  575. package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
  576. package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
  577. package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
  578. package/dist/types/sdk/elevation/audit.d.ts +0 -93
  579. package/dist/types/sdk/elevation/capability.d.ts +0 -3
  580. package/dist/types/sdk/elevation/digest.d.ts +0 -72
  581. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
  582. package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
  583. package/dist/types/sdk/elevation/owner.d.ts +0 -48
  584. package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
  585. package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
  586. package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
  587. package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
  588. package/dist/types/session/auth-broker-config.d.ts +0 -13
  589. package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
  590. package/dist/types/skills/skills.test.d.ts +0 -1
  591. package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
  592. package/dist/types/task/token-log.test.d.ts +0 -1
  593. package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
  594. package/dist/types/tools/descriptors.test.d.ts +0 -1
  595. package/scripts/g005-daemon-smoke.ts +0 -180
  596. package/scripts/g011-daemon-path-smoke.ts +0 -153
  597. package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
  598. package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
  599. package/src/sdk/bus/telegram-cli.ts +0 -212
  600. package/src/sdk/elevation/allowlist.ts +0 -54
  601. package/src/sdk/elevation/audit.ts +0 -208
  602. package/src/sdk/elevation/capability.ts +0 -41
  603. package/src/sdk/elevation/digest.ts +0 -129
  604. package/src/sdk/elevation/dispatch-receipt.ts +0 -184
  605. package/src/sdk/elevation/grant-ledger.ts +0 -1142
  606. package/src/sdk/elevation/owner.ts +0 -109
  607. package/src/session/auth-broker-config.ts +0 -109
  608. /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
  609. /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
  610. /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
@@ -1,13 +1,18 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { lifecycleRequestTimeoutMs } from "../broker/startup-budget";
3
- import { SdkClient, SdkClientError, type SdkFrame, type SdkSentRecord } from "../client";
3
+ import { type SdkClient, SdkClientError } from "../client";
4
+ import type { AbortScope } from "../host/control/operations";
4
5
  import { assertReverseResponseFrame, ReverseLeaseError } from "../host/reverse-leases";
5
6
  import { validateAdapterControl, validateAdapterSecretFields } from "../protocol/adapter-validation";
6
7
  import { OPERATIONS } from "../protocol/operation-registry";
7
- import { ACP_SESSION_RECONNECT } from "../session-reconnect";
8
+ import { type SessionAttachment, type SessionRouter, SessionRouterError } from "../router";
9
+ import { ACP_SESSION_RECONNECT, SESSION_ABORT_TIMEOUT_MS } from "../session-reconnect";
8
10
  import type { SessionLifecycleMcpServer } from "./mcp";
9
11
 
10
12
  type JsonObject = Record<string, unknown>;
13
+ function object(value: unknown): JsonObject | undefined {
14
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? (value as JsonObject) : undefined;
15
+ }
11
16
 
12
17
  /** The small agent-side ACP surface used for reverse requests. */
13
18
  export interface AcpReverseConnection {
@@ -21,9 +26,11 @@ export interface AcpProviderRegistration {
21
26
  }
22
27
 
23
28
  export interface AcpSdkAdapterOptions {
24
- url: string;
25
- token: string;
29
+ /** Broker lifecycle transport only. Live session work requires `router` plus an opaque attachment. */
26
30
  client?: SdkClient;
31
+ router?: SessionRouter;
32
+ attachment?: SessionAttachment;
33
+ sessionId?: string;
27
34
  connection?: AcpReverseConnection;
28
35
  providers?: AcpProviderRegistration[];
29
36
  /** Lease IDs persisted by the ACP host across a WebSocket reconnect. */
@@ -41,6 +48,17 @@ export class AcpSdkAdapterError extends Error {
41
48
  }
42
49
  }
43
50
 
51
+ function credentialFreeLifecycleResult(value: unknown): unknown {
52
+ if (Array.isArray(value)) return value.map(credentialFreeLifecycleResult);
53
+ if (value === null || typeof value !== "object") return value;
54
+ const output: Record<string, unknown> = {};
55
+ for (const [key, nested] of Object.entries(value as Record<string, unknown>)) {
56
+ if (key === "endpoint" || key === "token" || key === "url") continue;
57
+ output[key] = credentialFreeLifecycleResult(nested);
58
+ }
59
+ return output;
60
+ }
61
+
44
62
  /**
45
63
  * Lifecycle failures the ACP MCP launch wrapper must report verbatim. Everything else
46
64
  * is re-attributed to the configured MCP servers, which is the useful answer for a
@@ -76,7 +94,8 @@ export function acpMcpLaunchFailure(error: unknown, mcpServers: SessionLifecycle
76
94
  }
77
95
 
78
96
  export type AcpReconnectFailedHandler = (error: SdkClientError) => void;
79
- export type AcpFrameHandler = (frame: SdkFrame) => void;
97
+ export type AcpFrameHandler = (frame: Record<string, unknown>) => void;
98
+
80
99
  type ReverseRequest = {
81
100
  state: "pending" | "cancelled";
82
101
  controller?: AbortController;
@@ -109,7 +128,10 @@ function isLifecycleOperation(operation: string): boolean {
109
128
  * ACP bridge: all session work is performed through authenticated v3 frames.
110
129
  */
111
130
  export class AcpSdkAdapter {
112
- readonly #client: SdkClient;
131
+ readonly #client?: SdkClient;
132
+ readonly #router?: SessionRouter;
133
+ #attachment?: SessionAttachment;
134
+ readonly #sessionId?: string;
113
135
  readonly #connection?: AcpReverseConnection;
114
136
  readonly #providers: AcpProviderRegistration[];
115
137
  readonly #heartbeatMs: number;
@@ -118,17 +140,33 @@ export class AcpSdkAdapter {
118
140
  #unsubscribeReconnectFailed?: () => void;
119
141
  #heartbeat?: NodeJS.Timeout;
120
142
  #connectionId?: string;
143
+ /** Router transport identity captured before reverse provider activation. */
144
+ #routerConnectionReady = false;
145
+
121
146
  #leases = new Map<string, string>();
122
147
  #reclaiming?: Promise<void>;
148
+ #providerActivation?: Promise<void>;
149
+ #providersActivated = false;
123
150
  #reverseRequests = new Map<string, ReverseRequest>();
124
151
  #reconnectFailedHandlers = new Set<AcpReconnectFailedHandler>();
125
152
  #frameHandlers = new Set<AcpFrameHandler>();
126
153
 
127
154
  #reverseCancelTtlMs: number;
128
155
  #closed = false;
129
-
156
+ #started = false;
130
157
  constructor(options: AcpSdkAdapterOptions) {
131
- this.#client = options.client ?? new SdkClient(options.url, options.token, { ...ACP_SESSION_RECONNECT });
158
+ if ((options.client === undefined) === (options.router === undefined))
159
+ throw new AcpSdkAdapterError(
160
+ "invalid_input",
161
+ "ACP adapter requires exactly one Broker client or SessionRouter.",
162
+ );
163
+ const sessionId = options.sessionId ?? options.attachment?.sessionId;
164
+ if (options.router && (!options.attachment || !sessionId || options.attachment.sessionId !== sessionId))
165
+ throw new AcpSdkAdapterError("invalid_input", "ACP session adapters require an exact SessionAttachment.");
166
+ this.#client = options.client;
167
+ this.#router = options.router;
168
+ this.#attachment = options.attachment;
169
+ this.#sessionId = sessionId;
132
170
  this.#connection = options.connection;
133
171
  this.#providers = options.providers ?? [];
134
172
  for (const [capability, leaseId] of Object.entries(options.expectedLeaseIds ?? {}))
@@ -138,13 +176,46 @@ export class AcpSdkAdapter {
138
176
  }
139
177
 
140
178
  static async connect(options: AcpSdkAdapterOptions): Promise<AcpSdkAdapter> {
141
- const client =
142
- options.client ?? (await SdkClient.connect(options.url, options.token, { ...ACP_SESSION_RECONNECT }));
143
- const adapter = new AcpSdkAdapter({ ...options, client });
179
+ const adapter = new AcpSdkAdapter(options);
144
180
  await adapter.start();
145
181
  return adapter;
146
182
  }
147
183
 
184
+ acceptAttachment(attachment: SessionAttachment): void {
185
+ if (!this.#router || attachment.sessionId !== this.#sessionId)
186
+ throw new AcpSdkAdapterError("invalid_input", "ACP attachment does not match this session adapter.");
187
+ this.#abortActiveReverseRequests();
188
+ this.#attachment = attachment;
189
+ this.#connectionId = undefined;
190
+ this.#routerConnectionReady = false;
191
+ this.#providersActivated = false;
192
+ if (attachment.isCurrent()) void this.#activateProviders().catch(error => this.#reportReconnectFailure(error));
193
+ }
194
+
195
+ revokeAttachment(attachment: SessionAttachment): void {
196
+ if (this.#attachment !== attachment) return;
197
+ this.#abortActiveReverseRequests();
198
+ this.#attachment = undefined;
199
+ this.#connectionId = undefined;
200
+ this.#routerConnectionReady = false;
201
+ this.#providersActivated = false;
202
+ }
203
+
204
+ async attachmentReady(attachment: SessionAttachment): Promise<void> {
205
+ if (this.#attachment !== attachment) this.acceptAttachment(attachment);
206
+ else {
207
+ this.#abortActiveReverseRequests();
208
+ this.#connectionId = undefined;
209
+ this.#routerConnectionReady = false;
210
+ this.#providersActivated = false;
211
+ }
212
+ if (!attachment.isCurrent()) throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
213
+ await this.#activateProviders();
214
+ }
215
+
216
+ acceptFrame(frame: Record<string, unknown>): void {
217
+ void this.#onFrame(frame);
218
+ }
148
219
  get leaseIds(): ReadonlyMap<string, string> {
149
220
  return this.#leases;
150
221
  }
@@ -164,15 +235,26 @@ export class AcpSdkAdapter {
164
235
 
165
236
  async start(): Promise<void> {
166
237
  if (this.#closed) throw new AcpSdkAdapterError("connection_closed");
167
- this.#unsubscribe ??= this.#client.onFrame(frame => void this.#onFrame(frame));
168
- this.#unsubscribeReconnect ??= this.#client.onReconnect(
169
- () => void this.#reclaimProviders().catch(error => this.#reportReconnectFailure(error)),
170
- );
171
- this.#unsubscribeReconnectFailed ??= this.#client.onReconnectFailed(error => this.#reportReconnectFailure(error));
172
- await this.#client.connect();
173
- this.#connectionId = this.#client.connectionId;
174
- if (this.#providers.length > 0 && !this.#connectionId) this.#connectionId = await this.#waitForConnectionId();
175
- for (const provider of this.#providers) await this.registerProvider(provider);
238
+ if (!this.#started) {
239
+ this.#started = true;
240
+ if (this.#client) {
241
+ this.#unsubscribe ??= this.#client.onFrame(frame => void this.#onFrame(frame));
242
+ this.#unsubscribeReconnect ??= this.#client.onReconnect(
243
+ () => void this.#reclaimProviders().catch(error => this.#reportReconnectFailure(error)),
244
+ );
245
+ this.#unsubscribeReconnectFailed ??= this.#client.onReconnectFailed(error =>
246
+ this.#reportReconnectFailure(error),
247
+ );
248
+ await this.#client.connect();
249
+ this.#connectionId = this.#client.connectionId;
250
+ }
251
+ }
252
+ if (this.#router) {
253
+ if (!this.#attachment?.isCurrent()) return;
254
+ await this.#activateProviders();
255
+ } else {
256
+ await this.#activateProviders();
257
+ }
176
258
  this.#heartbeat ??= setInterval(
177
259
  () => void this.#heartbeatLeases().catch(error => this.#reportReconnectFailure(error)),
178
260
  this.#heartbeatMs,
@@ -191,57 +273,134 @@ export class AcpSdkAdapter {
191
273
  this.#unsubscribe?.();
192
274
  this.#unsubscribeReconnect?.();
193
275
  this.#unsubscribeReconnectFailed?.();
194
- await this.#client.close();
276
+ if (this.#client) await this.#client.close();
195
277
  }
196
278
 
197
279
  async prompt(params: JsonObject | string): Promise<unknown> {
198
280
  const text = typeof params === "string" ? params : String(params.prompt ?? params.text ?? "");
199
- return await this.#client.control("turn.prompt", { ...(typeof params === "object" ? params : {}), text });
281
+ return await this.#requestSession({
282
+ type: "control_request",
283
+ operation: "turn.prompt",
284
+ input: { ...(typeof params === "object" ? params : {}), text },
285
+ });
200
286
  }
201
- async cancel(): Promise<unknown> {
202
- return await this.#client.control("turn.abort", {});
287
+ /**
288
+ * Ends the active turn with a C04 terminal abort. The default `scope:"turn"`
289
+ * only stops the current turn, matching the SDK `turn.abort` default and
290
+ * other ACP clients' cancel behavior; `scope:"owned"` additionally stops
291
+ * exact causal owned work (background Bash/task jobs, detached subagents) so
292
+ * an external client can terminate everything a turn spawned. Paseo keeps
293
+ * owned cancels through its provider config env
294
+ * (`GJC_ACP_ABORT_SCOPE=owned`) without source changes. A fresh bounded
295
+ * idempotency key per call keeps terminal-abort replay deterministic across
296
+ * retries.
297
+ */
298
+ async cancel(scope: AbortScope = "turn"): Promise<unknown> {
299
+ return await this.control("turn.abort", { mode: "terminal", scope, idempotencyKey: randomUUID() });
203
300
  }
204
301
  async setModel(params: JsonObject | string): Promise<unknown> {
205
302
  const id = typeof params === "string" ? params : String(params.modelId ?? params.id ?? "");
206
- return await this.#client.control("model.set", { id });
303
+ return await this.#requestSession({ type: "control_request", operation: "model.set", input: { id } });
207
304
  }
208
305
 
209
306
  async control(operation: string, input: JsonObject = {}): Promise<unknown> {
210
307
  this.#assertGenericDisposition("control", operation);
211
- const { confirm, ...payload } = input;
308
+ // `confirm` and `idempotencyKey` are envelope concerns, not control input:
309
+ // extract them so the payload passes the control validator and the bounded
310
+ // key reaches the control envelope — terminal abort requires it, and
311
+ // without it every {mode:"terminal"} control is rejected (review
312
+ // thread P1).
313
+ const { confirm, idempotencyKey, ...payload } = input;
212
314
  const secretError = validateAdapterSecretFields(operation, payload);
213
315
  if (secretError) throw new AcpSdkAdapterError(secretError.code, secretError.message);
214
316
 
215
317
  const invalid = validateAdapterControl(operation, payload);
216
318
  if (invalid) throw new AcpSdkAdapterError(invalid.code, invalid.message);
217
- return await this.#client.control(operation, payload, { confirm: confirm === true });
319
+ return await this.#requestSession(
320
+ {
321
+ type: "control_request",
322
+ operation,
323
+ input: payload,
324
+ ...(confirm === undefined ? {} : { confirm: confirm === true }),
325
+ ...(typeof idempotencyKey === "string" && idempotencyKey ? { idempotencyKey } : {}),
326
+ },
327
+ false,
328
+ // A cancel must not inherit the Router's wide session reply budget: the
329
+ // caller awaits this acknowledgement before any settlement path can bound
330
+ // the turn, so a wedged host would stretch cancellation by that budget.
331
+ operation === "turn.abort" ? { timeoutMs: SESSION_ABORT_TIMEOUT_MS } : undefined,
332
+ );
218
333
  }
219
334
  async query(query: string, input: JsonObject = {}, cursor?: string): Promise<unknown> {
220
- return await this.#client.query(query, input, cursor);
335
+ return await this.#requestSession({
336
+ type: "query_request",
337
+ query,
338
+ input,
339
+ ...(cursor === undefined ? {} : { cursor }),
340
+ });
341
+ }
342
+
343
+ #unwrapSessionResponse(response: unknown): unknown {
344
+ const envelope = object(response);
345
+ if (envelope?.ok === false) {
346
+ const error = object(envelope.error);
347
+ throw new AcpSdkAdapterError(
348
+ typeof error?.code === "string" ? error.code : "request_failed",
349
+ typeof error?.message === "string" ? error.message : "SDK session request failed.",
350
+ );
351
+ }
352
+ return envelope?.result ?? response;
353
+ }
354
+
355
+ async #requestSession(frame: JsonObject, raw = false, options?: { timeoutMs: number }): Promise<unknown> {
356
+ const router = this.#router;
357
+ if (!router)
358
+ throw new AcpSdkAdapterError(
359
+ "operation_prohibited",
360
+ "Live session controls and queries require the current Router attachment.",
361
+ );
362
+ const attachment = this.#attachment;
363
+ const sessionId = this.#sessionId;
364
+ if (!attachment || !sessionId || !attachment.isCurrent())
365
+ throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
366
+ const response = await router.request(
367
+ sessionId,
368
+ { ...frame, id: randomUUID() },
369
+ attachment.generation,
370
+ attachment,
371
+ options,
372
+ );
373
+ if (!attachment.isCurrent())
374
+ throw new SessionRouterError("ambiguous", "SDK session attachment changed while awaiting command response.");
375
+ return raw ? response : this.#unwrapSessionResponse(response);
221
376
  }
222
377
  async global(operation: string, input: JsonObject = {}, idempotencyKey?: string): Promise<unknown> {
378
+ const result = await this.#lifecycleRequest(operation, input, idempotencyKey);
379
+ return isLifecycleOperation(operation) ? credentialFreeLifecycleResult(result) : result;
380
+ }
381
+ /** Uses lifecycle endpoint credentials only inside the ACP session owner. */
382
+ async lifecycle(operation: string, input: JsonObject = {}, idempotencyKey?: string): Promise<unknown> {
383
+ if (!isLifecycleOperation(operation))
384
+ throw new AcpSdkAdapterError("invalid_input", "ACP lifecycle requests must use a lifecycle operation.");
385
+ return await this.#lifecycleRequest(operation, input, idempotencyKey);
386
+ }
387
+ async #lifecycleRequest(operation: string, input: JsonObject, idempotencyKey?: string): Promise<unknown> {
223
388
  this.#assertGenericDisposition("global", operation);
224
389
  if (isLifecycleOperation(operation) && !idempotencyKey)
225
390
  throw new AcpSdkAdapterError("invalid_input", "idempotencyKey is required for lifecycle operations.");
391
+ if (!this.#client)
392
+ throw new AcpSdkAdapterError("operation_prohibited", "Lifecycle operations require the Broker connection.");
226
393
  // The broker may hold a startup in its admission queue before the readiness
227
- // clock starts, so the caller deadline covers the queue wait too.
394
+ // clock even starts, so the caller deadline covers the queue wait too; sizing
395
+ // it on readiness alone times out requests the broker is still running. A
396
+ // request that named no readiness budget is queued for the default one, so it
397
+ // needs the same extension rather than the client's generic request deadline.
228
398
  const timeoutMs = lifecycleRequestTimeoutMs(operation, input);
229
- try {
230
- return await this.#client.global(operation, input, {
231
- idempotencyKey,
232
- ...(timeoutMs === undefined ? {} : { timeoutMs }),
233
- });
234
- } catch (error) {
235
- if (
236
- isLifecycleOperation(operation) &&
237
- error instanceof SdkClientError &&
238
- error.code === "uncertain_after_send" &&
239
- error.details &&
240
- typeof error.details === "object"
241
- )
242
- return await this.#client.lookupLifecycle(error.details as SdkSentRecord);
243
- throw error;
244
- }
399
+ const response = await this.#client.global(operation, input, {
400
+ idempotencyKey,
401
+ ...(timeoutMs === undefined ? {} : { timeoutMs }),
402
+ });
403
+ return response;
245
404
  }
246
405
 
247
406
  async sdkControl(params: { operation: string; input?: JsonObject }): Promise<unknown> {
@@ -281,21 +440,64 @@ export class AcpSdkAdapter {
281
440
  }
282
441
 
283
442
  async registerProvider(provider: AcpProviderRegistration): Promise<void> {
284
- const connectionId = this.#connectionId ?? (await this.#waitForConnectionId());
443
+ if (!this.#router)
444
+ throw new AcpSdkAdapterError(
445
+ "operation_prohibited",
446
+ "Provider registration requires the current Router attachment.",
447
+ );
448
+ const attachment = this.#attachment;
449
+ if (!attachment?.isCurrent()) throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
450
+ this.#captureRouterConnection(attachment);
285
451
  const previousLeaseId = this.#leases.get(provider.capability);
286
- const result = await this.#client.request({
287
- type: "register_provider",
288
- connectionId,
289
- capability: provider.capability,
290
- definitions: provider.definitions,
291
- idempotencyKey: randomUUID(),
292
- ...(previousLeaseId ? { expectedLeaseId: previousLeaseId } : {}),
293
- });
452
+ const response = await this.#requestSession(
453
+ {
454
+ type: "register_provider",
455
+ capability: provider.capability,
456
+ definitions: provider.definitions,
457
+ idempotencyKey: randomUUID(),
458
+ ...(previousLeaseId ? { expectedLeaseId: previousLeaseId } : {}),
459
+ },
460
+ true,
461
+ );
462
+ const result = object(object(response)?.result) ?? object(response) ?? {};
294
463
  if (typeof result.leaseId !== "string")
295
464
  throw new AcpSdkAdapterError("invalid_reverse_frame", "Provider registration omitted leaseId.");
296
465
  this.#leases.set(provider.capability, result.leaseId);
297
466
  }
298
467
 
468
+ async #activateProviders(): Promise<void> {
469
+ if (this.#providersActivated || this.#providers.length === 0) return;
470
+ if (this.#providerActivation) return await this.#providerActivation;
471
+ const activation = (async () => {
472
+ for (;;) {
473
+ const attachment = this.#attachment;
474
+ const connectionId = attachment?.connectionId;
475
+ try {
476
+ for (const provider of this.#providers) await this.registerProvider(provider);
477
+ if (this.#router && (attachment !== this.#attachment || attachment?.connectionId !== connectionId)) {
478
+ this.#abortActiveReverseRequests();
479
+ this.#providersActivated = false;
480
+ continue;
481
+ }
482
+ this.#providersActivated = true;
483
+ return;
484
+ } catch (error) {
485
+ if (this.#router && attachment !== this.#attachment && !this.#closed) {
486
+ this.#providersActivated = false;
487
+ continue;
488
+ }
489
+ throw error;
490
+ }
491
+ }
492
+ })();
493
+ this.#providerActivation = activation;
494
+ try {
495
+ await activation;
496
+ } finally {
497
+ if (this.#providerActivation === activation) this.#providerActivation = undefined;
498
+ }
499
+ }
500
+
299
501
  #assertGenericDisposition(kind: "control" | "global", sdkId: string): void {
300
502
  const operation = OPERATIONS.find(candidate => candidate.kind === kind && candidate.sdkId === sdkId);
301
503
  if (!operation) throw new AcpSdkAdapterError("unknown_operation", `Unknown SDK ${kind}: ${sdkId}`);
@@ -319,9 +521,13 @@ export class AcpSdkAdapter {
319
521
  if (this.#reclaiming) return await this.#reclaiming;
320
522
  this.#reclaiming = (async () => {
321
523
  this.#abortActiveReverseRequests();
322
- this.#connectionId = this.#client.connectionId;
323
- if (!this.#connectionId) this.#connectionId = await this.#waitForConnectionId();
324
- for (const provider of this.#providers) await this.registerProvider(provider);
524
+ if (!this.#router)
525
+ throw new AcpSdkAdapterError(
526
+ "operation_prohibited",
527
+ "Provider reactivation requires the current Router attachment.",
528
+ );
529
+ this.#providersActivated = false;
530
+ await this.#activateProviders();
325
531
  })();
326
532
  try {
327
533
  await this.#reclaiming;
@@ -330,7 +536,25 @@ export class AcpSdkAdapter {
330
536
  }
331
537
  }
332
538
 
539
+ #captureRouterConnection(attachment: SessionAttachment): void {
540
+ const connectionId = attachment.connectionId;
541
+ if (typeof connectionId !== "string" || connectionId.length === 0) {
542
+ this.#connectionId = undefined;
543
+ this.#routerConnectionReady = false;
544
+ this.#providersActivated = false;
545
+ return;
546
+ }
547
+ const changed = this.#connectionId !== undefined && this.#connectionId !== connectionId;
548
+ this.#connectionId = connectionId;
549
+ this.#routerConnectionReady = true;
550
+ if (changed) {
551
+ this.#providersActivated = false;
552
+ this.#abortActiveReverseRequests();
553
+ }
554
+ }
555
+
333
556
  #reportReconnectFailure(error: unknown): void {
557
+ if (error instanceof SessionRouterError) return;
334
558
  const typed =
335
559
  error instanceof SdkClientError
336
560
  ? error
@@ -342,40 +566,33 @@ export class AcpSdkAdapter {
342
566
  for (const handler of this.#reconnectFailedHandlers) handler(typed);
343
567
  }
344
568
 
345
- async #waitForConnectionId(): Promise<string> {
346
- if (this.#connectionId) return this.#connectionId;
347
- return await new Promise<string>((resolve, reject) => {
348
- const timeout = setTimeout(
349
- () => reject(new AcpSdkAdapterError("unavailable", "SDK server did not provide a connection id.")),
350
- 10_000,
569
+ async #sendSession(frame: Record<string, unknown>): Promise<void> {
570
+ if (!this.#router)
571
+ throw new AcpSdkAdapterError(
572
+ "operation_prohibited",
573
+ "Live session sends require the current Router attachment.",
351
574
  );
352
- const unsubscribe = this.#client.onFrame(frame => {
353
- if ((frame.type === "hello" || frame.type === "server_hello") && typeof frame.connectionId === "string") {
354
- clearTimeout(timeout);
355
- unsubscribe();
356
- this.#connectionId = frame.connectionId;
357
- resolve(frame.connectionId);
358
- }
359
- });
360
- });
575
+ const attachment = this.#attachment;
576
+ if (!attachment?.isCurrent()) throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
577
+ await Promise.resolve(attachment.send(frame));
361
578
  }
362
579
 
363
580
  async #heartbeatLeases(): Promise<void> {
364
581
  if (this.#closed) return;
365
582
  try {
366
- await this.#client.awaitHello();
367
- this.#connectionId ??= this.#client.connectionId;
368
- if (!this.#connectionId) return;
369
- for (const leaseId of this.#leases.values())
370
- this.#client.send({ type: "provider_heartbeat", connectionId: this.#connectionId, leaseId });
583
+ if (!this.#router) return;
584
+ if (!this.#attachment?.isCurrent()) return;
585
+ for (const leaseId of this.#leases.values()) await this.#sendSession({ type: "provider_heartbeat", leaseId });
371
586
  } catch (error) {
587
+ if (error instanceof SessionRouterError && error.phase === "pre_send") return;
372
588
  this.#reportReconnectFailure(error);
373
589
  }
374
590
  }
375
591
 
376
- async #onFrame(frame: SdkFrame): Promise<void> {
592
+ async #onFrame(frame: Record<string, unknown>): Promise<void> {
377
593
  for (const handler of this.#frameHandlers) handler(frame);
378
594
  if ((frame.type === "hello" || frame.type === "server_hello") && typeof frame.connectionId === "string") {
595
+ if (this.#router) return;
379
596
  const changed = this.#connectionId !== undefined && this.#connectionId !== frame.connectionId;
380
597
  this.#connectionId = frame.connectionId;
381
598
  if (changed) void this.#reclaimProviders().catch(error => this.#reportReconnectFailure(error));
@@ -391,20 +608,24 @@ export class AcpSdkAdapter {
391
608
  return;
392
609
  }
393
610
 
394
- if (frame.type !== "reverse_request") return;
611
+ if (frame.type !== "reverse_request" || !this.#router) return;
395
612
  const id = typeof frame.id === "string" ? frame.id : "";
396
613
  const connectionId = typeof frame.connectionId === "string" ? frame.connectionId : "";
397
614
  const capability = typeof frame.capability === "string" ? frame.capability : "";
398
615
  const leaseId = typeof frame.leaseId === "string" ? frame.leaseId : "";
399
- if (
400
- !id ||
401
- !connectionId ||
402
- !capability ||
403
- !leaseId ||
404
- this.#reverseRequests.has(id) ||
405
- !this.#ownsReverseLease(connectionId, capability, leaseId)
406
- )
616
+ if (!id || !connectionId || !capability || !leaseId || this.#reverseRequests.has(id)) return;
617
+ if (this.#connectionId === undefined) {
618
+ this.#connectionId = connectionId;
619
+ this.#routerConnectionReady = true;
620
+ } else if (this.#connectionId !== connectionId) {
621
+ this.#connectionId = connectionId;
622
+ this.#routerConnectionReady = true;
623
+ this.#providersActivated = false;
624
+ this.#abortActiveReverseRequests();
625
+ void this.#reclaimProviders().catch(error => this.#reportReconnectFailure(error));
407
626
  return;
627
+ }
628
+ if (!this.#ownsReverseLease(connectionId, capability, leaseId)) return;
408
629
  const controller = new AbortController();
409
630
  const active: ReverseRequest = { state: "pending", controller };
410
631
  this.#reverseRequests.set(id, active);
@@ -417,7 +638,7 @@ export class AcpSdkAdapter {
417
638
 
418
639
  const response = { type: "reverse_response", id, connectionId, leaseId, ok: true, result };
419
640
  assertReverseResponseFrame(response);
420
- this.#client.send(response);
641
+ await this.#sendSession(response);
421
642
  } catch (error) {
422
643
  if (!this.#canRespondToReverse(id, active, connectionId, capability, leaseId)) return;
423
644
 
@@ -430,21 +651,31 @@ export class AcpSdkAdapter {
430
651
  "acp_reverse_failed",
431
652
  error instanceof Error ? error.message : "ACP reverse request failed.",
432
653
  );
433
- this.#client.send({
434
- type: "reverse_response",
435
- id,
436
- connectionId,
437
- leaseId,
438
- ok: false,
439
- error: { code: typed.code, message: typed.message },
440
- });
654
+ try {
655
+ await this.#sendSession({
656
+ type: "reverse_response",
657
+ id,
658
+ connectionId,
659
+ leaseId,
660
+ ok: false,
661
+ error: { code: typed.code, message: typed.message },
662
+ });
663
+ } catch (sendError) {
664
+ this.#reportReconnectFailure(sendError);
665
+ }
441
666
  } finally {
442
667
  this.#finishReverse(id, active);
443
668
  }
444
669
  }
445
670
 
446
671
  #ownsReverseLease(connectionId: string, capability: string, leaseId: string): boolean {
447
- return this.#connectionId === connectionId && this.#leases.get(capability) === leaseId;
672
+ return (
673
+ this.#router !== undefined &&
674
+ this.#routerConnectionReady &&
675
+ this.#providersActivated &&
676
+ this.#connectionId === connectionId &&
677
+ this.#leases.get(capability) === leaseId
678
+ );
448
679
  }
449
680
 
450
681
  #canRespondToReverse(