@gajae-code/coding-agent 0.10.1 → 0.11.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 (474) hide show
  1. package/CHANGELOG.md +70 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
  54. package/dist/types/modes/components/model-selector.d.ts +1 -0
  55. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  56. package/dist/types/modes/components/pet-capability.d.ts +37 -0
  57. package/dist/types/modes/components/pet-selector.d.ts +1 -1
  58. package/dist/types/modes/components/settings-selector.d.ts +15 -4
  59. package/dist/types/modes/components/welcome.d.ts +1 -1
  60. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  61. package/dist/types/modes/index.d.ts +0 -4
  62. package/dist/types/modes/interactive-mode.d.ts +5 -1
  63. package/dist/types/modes/runtime-init.d.ts +2 -2
  64. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  65. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  66. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  67. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  68. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  69. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  72. package/dist/types/modes/types.d.ts +16 -1
  73. package/dist/types/runtime-mcp/client.d.ts +2 -0
  74. package/dist/types/runtime-mcp/config.d.ts +5 -1
  75. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  76. package/dist/types/runtime-mcp/types.d.ts +4 -0
  77. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  78. package/dist/types/sdk/acp/index.d.ts +2 -0
  79. package/dist/types/sdk/broker/broker.d.ts +53 -0
  80. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  81. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  82. package/dist/types/sdk/broker/identity.d.ts +3 -0
  83. package/dist/types/sdk/broker/index.d.ts +8 -0
  84. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  85. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  86. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  87. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  88. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  89. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  90. package/dist/types/sdk/broker/transport.d.ts +9 -0
  91. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  92. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  93. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  94. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  95. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  96. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  97. package/dist/types/sdk/bus/config.d.ts +274 -0
  98. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  99. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  100. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  101. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  102. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  103. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  104. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  105. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  107. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  108. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  109. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  110. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  111. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  112. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  113. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  114. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  115. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  118. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  119. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  121. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  122. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  123. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  124. package/dist/types/sdk/cli/index.d.ts +1 -0
  125. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  126. package/dist/types/sdk/client/client.d.ts +1 -0
  127. package/dist/types/sdk/client/discovery.d.ts +27 -0
  128. package/dist/types/sdk/client/index.d.ts +2 -0
  129. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  130. package/dist/types/sdk/host/control/index.d.ts +2 -0
  131. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  132. package/dist/types/sdk/host/events.d.ts +35 -0
  133. package/dist/types/sdk/host/host.d.ts +35 -0
  134. package/dist/types/sdk/host/index.d.ts +4 -0
  135. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  136. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  137. package/dist/types/sdk/host/query/index.d.ts +3 -0
  138. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  139. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  140. package/dist/types/sdk/host/types.d.ts +32 -0
  141. package/dist/types/sdk/index.d.ts +6 -0
  142. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  143. package/dist/types/sdk/mcp/index.d.ts +1 -0
  144. package/dist/types/sdk/mcp/server.d.ts +37 -0
  145. package/dist/types/sdk/models.d.ts +44 -0
  146. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  147. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  148. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  149. package/dist/types/sdk/startup-capability.d.ts +50 -0
  150. package/dist/types/session/agent-session.d.ts +114 -21
  151. package/dist/types/session/default-model-selection.d.ts +25 -0
  152. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  153. package/dist/types/session/session-manager.d.ts +58 -1
  154. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  155. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  156. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  157. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  158. package/dist/types/tools/browser/launch.d.ts +22 -0
  159. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  160. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  161. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  162. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  163. package/dist/types/tools/browser/registry.d.ts +19 -0
  164. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  165. package/dist/types/tools/index.d.ts +8 -8
  166. package/package.json +34 -13
  167. package/scripts/build-sdk-package-smoke.ts +94 -0
  168. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  169. package/scripts/compile-args.ts +4 -2
  170. package/scripts/g005-daemon-smoke.ts +4 -5
  171. package/scripts/g011-daemon-path-smoke.ts +5 -5
  172. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  173. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  174. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  175. package/scripts/manifest-schema.ts +124 -0
  176. package/scripts/run-test-manifest.ts +153 -0
  177. package/scripts/run-threat-model-check.ts +157 -0
  178. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  179. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  180. package/src/append-only-mode.ts +1 -1
  181. package/src/cli/args.ts +43 -12
  182. package/src/cli/auth-gateway-cli.ts +2 -2
  183. package/src/cli/config-cli.ts +2 -1
  184. package/src/cli/daemon-cli.ts +63 -14
  185. package/src/cli/list-models.ts +1 -1
  186. package/src/cli/notify-cli.ts +288 -286
  187. package/src/cli.ts +21 -2
  188. package/src/commands/daemon.ts +50 -6
  189. package/src/commands/harness.ts +93 -36
  190. package/src/commands/launch.ts +5 -2
  191. package/src/commands/mcp-serve.ts +19 -12
  192. package/src/commands/notify.ts +36 -3
  193. package/src/commands/sdk.ts +426 -0
  194. package/src/commit/agentic/agent.ts +1 -0
  195. package/src/config/atomic-yaml-patch.ts +423 -0
  196. package/src/config/model-profile-activation.ts +240 -89
  197. package/src/config/model-profiles.ts +37 -34
  198. package/src/config/model-registry.ts +51 -26
  199. package/src/config/model-resolver.ts +138 -51
  200. package/src/config/model-selector-value.ts +50 -0
  201. package/src/config/models-config-schema.ts +14 -21
  202. package/src/config/settings-schema.ts +128 -10
  203. package/src/config/settings.ts +1120 -158
  204. package/src/coordinator-mcp/model-preset.ts +74 -20
  205. package/src/coordinator-mcp/server.ts +1597 -3052
  206. package/src/daemon/builtin.ts +8 -5
  207. package/src/daemon/control-types.ts +1 -1
  208. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  209. package/src/discovery/mcp-json.ts +327 -20
  210. package/src/extensibility/custom-tools/types.ts +1 -1
  211. package/src/extensibility/extensions/compact-handler.ts +3 -3
  212. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  213. package/src/extensibility/extensions/loader.ts +69 -5
  214. package/src/extensibility/extensions/runner.ts +112 -4
  215. package/src/extensibility/extensions/types.ts +176 -17
  216. package/src/extensibility/hooks/types.ts +1 -1
  217. package/src/extensibility/slash-commands.ts +3 -3
  218. package/src/gjc-runtime/launch-tmux.ts +170 -86
  219. package/src/gjc-runtime/psmux-detect.ts +82 -4
  220. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  221. package/src/gjc-runtime/team-runtime.ts +54 -35
  222. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  223. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
  224. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  225. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  226. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  227. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  228. package/src/harness-control-plane/operate.ts +9 -9
  229. package/src/harness-control-plane/owner.ts +283 -39
  230. package/src/harness-control-plane/receipts.ts +0 -1
  231. package/src/harness-control-plane/sdk-transport.ts +395 -0
  232. package/src/harness-control-plane/session-transport.ts +94 -0
  233. package/src/harness-control-plane/types.ts +1 -1
  234. package/src/internal-urls/docs-index.generated.ts +36 -37
  235. package/src/lsp/client.ts +42 -6
  236. package/src/lsp/index.ts +2 -2
  237. package/src/main.ts +299 -204
  238. package/src/modes/DESIGN.md +258 -0
  239. package/src/modes/acp/acp-agent.ts +1228 -2612
  240. package/src/modes/acp/acp-client-bridge.ts +2 -20
  241. package/src/modes/acp/acp-event-mapper.ts +18 -2
  242. package/src/modes/acp/acp-mode.ts +8 -36
  243. package/src/modes/acp/permission-mode.ts +25 -0
  244. package/src/modes/acp/startup-options.ts +6 -0
  245. package/src/modes/components/agent-dashboard.ts +37 -17
  246. package/src/modes/components/custom-editor.ts +1 -0
  247. package/src/modes/components/gajae-pet-widget.ts +169 -20
  248. package/src/modes/components/model-selector.ts +93 -35
  249. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  250. package/src/modes/components/pet-capability.ts +115 -0
  251. package/src/modes/components/pet-selector.ts +4 -6
  252. package/src/modes/components/settings-selector.ts +86 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +1 -2
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +357 -12
  257. package/src/modes/controllers/input-controller.ts +43 -13
  258. package/src/modes/controllers/selector-controller.ts +671 -44
  259. package/src/modes/index.ts +0 -22
  260. package/src/modes/interactive-mode.ts +108 -24
  261. package/src/modes/runtime-init.ts +298 -6
  262. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  263. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  264. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  265. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  266. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  267. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  268. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  269. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  270. package/src/modes/types.ts +16 -1
  271. package/src/runtime-mcp/client.ts +94 -19
  272. package/src/runtime-mcp/config.ts +27 -15
  273. package/src/runtime-mcp/manager.ts +343 -105
  274. package/src/runtime-mcp/oauth-flow.ts +42 -12
  275. package/src/runtime-mcp/transports/http.ts +49 -19
  276. package/src/runtime-mcp/transports/stdio.ts +47 -28
  277. package/src/runtime-mcp/types.ts +10 -0
  278. package/src/sdk/acp/adapter.ts +418 -0
  279. package/src/sdk/acp/index.ts +2 -0
  280. package/src/sdk/broker/broker.ts +642 -0
  281. package/src/sdk/broker/discovery.ts +94 -0
  282. package/src/sdk/broker/ensure.ts +249 -0
  283. package/src/sdk/broker/identity.ts +42 -0
  284. package/src/sdk/broker/index.ts +8 -0
  285. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  286. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  287. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  288. package/src/sdk/broker/lifecycle.ts +2157 -0
  289. package/src/sdk/broker/process-incarnation.ts +159 -0
  290. package/src/sdk/broker/runtime.ts +164 -0
  291. package/src/sdk/broker/session-index.ts +318 -0
  292. package/src/sdk/broker/state-version.ts +23 -0
  293. package/src/sdk/broker/transport.ts +125 -0
  294. package/src/sdk/bus/chat-command-policy.ts +107 -0
  295. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  296. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  297. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  298. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  299. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  300. package/src/sdk/bus/config.ts +433 -0
  301. package/src/sdk/bus/conversation-store.ts +391 -0
  302. package/src/sdk/bus/discord-conversation.ts +85 -0
  303. package/src/sdk/bus/discord-daemon.ts +2275 -0
  304. package/src/sdk/bus/discord-live-provider.ts +521 -0
  305. package/src/sdk/bus/discord-provider.ts +56 -0
  306. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  307. package/src/sdk/bus/index.ts +3943 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  309. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  310. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  311. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  312. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  313. package/src/sdk/bus/natives-augment.d.ts +38 -0
  314. package/src/sdk/bus/notification-orchestration.ts +535 -0
  315. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  316. package/src/sdk/bus/session-control.ts +333 -0
  317. package/src/sdk/bus/slack-conversation.ts +74 -0
  318. package/src/sdk/bus/slack-daemon.ts +2144 -0
  319. package/src/sdk/bus/slack-live-provider.ts +380 -0
  320. package/src/sdk/bus/slack-provider.ts +76 -0
  321. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  322. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  323. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  324. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  325. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  326. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  327. package/src/sdk/bus/telegram-setup.ts +663 -0
  328. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  329. package/src/sdk/cli/index.ts +1 -0
  330. package/src/sdk/cli/session-cli.ts +275 -0
  331. package/src/sdk/client/client.ts +1 -0
  332. package/src/sdk/client/discovery.ts +108 -0
  333. package/src/sdk/client/index.ts +2 -0
  334. package/src/sdk/host/control/dispatch.ts +367 -0
  335. package/src/sdk/host/control/index.ts +10 -0
  336. package/src/sdk/host/control/operations.ts +63 -0
  337. package/src/sdk/host/events.ts +91 -0
  338. package/src/sdk/host/host.ts +296 -0
  339. package/src/sdk/host/index.ts +4 -0
  340. package/src/sdk/host/query/cursor.ts +189 -0
  341. package/src/sdk/host/query/handlers.ts +533 -0
  342. package/src/sdk/host/query/index.ts +3 -0
  343. package/src/sdk/host/query/revision-store.ts +1126 -0
  344. package/src/sdk/host/reverse-leases.ts +325 -0
  345. package/src/sdk/host/types.ts +29 -0
  346. package/src/sdk/index.ts +13 -0
  347. package/src/sdk/lifecycle-session.ts +39 -0
  348. package/src/sdk/mcp/index.ts +1 -0
  349. package/src/sdk/mcp/server.ts +332 -0
  350. package/src/sdk/models.ts +168 -0
  351. package/src/sdk/protocol/adapter-validation.ts +48 -0
  352. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  353. package/src/sdk/protocol/operation-registry.ts +312 -0
  354. package/src/{sdk.ts → sdk/session.ts} +339 -212
  355. package/src/sdk/startup-capability.ts +189 -0
  356. package/src/session/agent-session.ts +2470 -866
  357. package/src/session/default-model-selection.ts +93 -0
  358. package/src/session/fallback-chain-controller.ts +136 -0
  359. package/src/session/session-manager.ts +447 -13
  360. package/src/session/session-storage.ts +8 -1
  361. package/src/setup/credential-auto-import.ts +290 -35
  362. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  363. package/src/slash-commands/builtin-registry.ts +33 -30
  364. package/src/task/executor.ts +62 -13
  365. package/src/tools/ask-answer-registry.ts +1 -1
  366. package/src/tools/ask.ts +13 -8
  367. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  368. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  369. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  370. package/src/tools/browser/launch.ts +124 -19
  371. package/src/tools/browser/profile-discovery.ts +63 -0
  372. package/src/tools/browser/profile-posture.ts +59 -0
  373. package/src/tools/browser/profile-reuse.ts +102 -0
  374. package/src/tools/browser/profile-warmup.ts +109 -0
  375. package/src/tools/browser/registry.ts +87 -11
  376. package/src/tools/browser/tab-protocol.ts +1 -0
  377. package/src/tools/browser/tab-supervisor.ts +1 -0
  378. package/src/tools/browser/tab-worker.ts +1 -1
  379. package/src/tools/browser.ts +6 -0
  380. package/src/tools/index.ts +8 -8
  381. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  382. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  383. package/src/tools/telegram-send.ts +2 -2
  384. package/vendor/insane-search/MANIFEST.json +2 -1
  385. package/vendor/insane-search/engine/bias_check.py +4 -1
  386. package/vendor/insane-search/engine/phase0.py +26 -1
  387. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  388. package/dist/types/modes/bridge/auth.d.ts +0 -12
  389. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  390. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  391. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  392. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  393. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  394. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  395. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  396. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  397. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  398. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  399. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  400. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  401. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  402. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  403. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  404. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  405. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  406. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  407. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  408. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  409. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  410. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  411. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  412. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  413. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  414. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  415. package/dist/types/notifications/config.d.ts +0 -132
  416. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  417. package/src/modes/bridge/auth.ts +0 -41
  418. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  419. package/src/modes/bridge/bridge-mode.ts +0 -675
  420. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  421. package/src/modes/bridge/event-stream.ts +0 -70
  422. package/src/modes/rpc/host-tools.ts +0 -1
  423. package/src/modes/rpc/host-uris.ts +0 -1
  424. package/src/modes/rpc/rpc-client.ts +0 -1166
  425. package/src/modes/rpc/rpc-mode.ts +0 -1029
  426. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  427. package/src/modes/rpc/rpc-types.ts +0 -637
  428. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  429. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  430. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  431. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  432. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  433. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  434. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  435. package/src/modes/shared/agent-wire/responses.ts +0 -17
  436. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  437. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  438. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  439. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  440. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  441. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  442. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  443. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  444. package/src/notifications/config.ts +0 -219
  445. package/src/notifications/index.ts +0 -1835
  446. package/src/notifications/telegram-daemon-cli.ts +0 -243
  447. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  448. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -1,675 +0,0 @@
1
- import type { ExtensionUIContext } from "../../extensibility/extensions";
2
- import { workflowGatePath } from "../../gjc-runtime/session-layout";
3
- import type { AgentSession } from "../../session/agent-session";
4
- import type { ClientBridgePermissionOutcome } from "../../session/client-bridge";
5
- import type { RpcCommand, RpcResponse, RpcWorkflowGateResponse } from "../rpc/rpc-types";
6
- import { dispatchRpcCommand } from "../shared/agent-wire/command-dispatch";
7
- import { isRpcCommand } from "../shared/agent-wire/command-validation";
8
- import {
9
- BridgeFrameSequencer,
10
- toBridgeEventFrame,
11
- toBridgeWorkflowGateFrame,
12
- } from "../shared/agent-wire/event-envelope";
13
- import type { BridgeCapability } from "../shared/agent-wire/handshake";
14
- import {
15
- type BridgeHandshakeRequest,
16
- isBridgeHandshakeRequest,
17
- negotiateBridgeHandshake,
18
- } from "../shared/agent-wire/handshake";
19
- import { isRpcHostToolResult, isRpcHostToolUpdate, RpcHostToolBridge } from "../shared/agent-wire/host-tool-bridge";
20
- import { isRpcHostUriResult, RpcHostUriBridge } from "../shared/agent-wire/host-uri-bridge";
21
- import type { BridgeFrameType } from "../shared/agent-wire/protocol";
22
- import {
23
- BRIDGE_COMMAND_SCOPES,
24
- type BridgeCommandScope,
25
- isRpcCommandAllowed,
26
- isRpcCommandType,
27
- scopeForRpcCommand,
28
- } from "../shared/agent-wire/scopes";
29
- import { UiRequestBroker } from "../shared/agent-wire/ui-request-broker";
30
- import type { BridgeUiResult } from "../shared/agent-wire/ui-result";
31
- import { defaultAuditPath, UnattendedAuditLog } from "../shared/agent-wire/unattended-audit";
32
- import { modelSupportsTokenCostMetrics, UnattendedSessionControlPlane } from "../shared/agent-wire/unattended-session";
33
- import { FileGateStore } from "../shared/agent-wire/workflow-gate-broker";
34
- import { assertSafeBridgeBind, isBridgeTokenAuthorized } from "./auth";
35
- import { type BridgePermissionRequestPayload, createBridgeClientBridge } from "./bridge-client-bridge";
36
- import { BridgeExtensionUIContext, type BridgeUiRequestPayload } from "./bridge-ui-context";
37
- import { BridgeEventStream } from "./event-stream";
38
-
39
- const DEFAULT_BRIDGE_HOST = "127.0.0.1";
40
- const DEFAULT_BRIDGE_PORT = 4077;
41
-
42
- const SERVER_CAPABILITIES: readonly BridgeCapability[] = [
43
- "events",
44
- "prompt",
45
- "permission",
46
- "elicitation",
47
- "ui.declarative",
48
- "host_tools",
49
- "host_uri",
50
- "workflow_gate",
51
- ];
52
-
53
- const DEFAULT_BRIDGE_SCOPES: readonly BridgeCommandScope[] = ["prompt"];
54
- interface BridgeEndpointMatrix {
55
- events: boolean;
56
- commands: boolean;
57
- control: boolean;
58
- uiResponses: boolean;
59
- hostToolResults: boolean;
60
- hostUriResults: boolean;
61
- }
62
-
63
- const FAIL_CLOSED_BRIDGE_ENDPOINTS: BridgeEndpointMatrix = {
64
- events: false,
65
- commands: false,
66
- control: false,
67
- uiResponses: false,
68
- hostToolResults: false,
69
- hostUriResults: false,
70
- };
71
-
72
- const MAX_IDEMPOTENCY_RECORDS = 1_000;
73
-
74
- const SERVER_FRAME_TYPES: readonly BridgeFrameType[] = [
75
- "ready",
76
- "event",
77
- "response",
78
- "ui_request",
79
- "permission_request",
80
- "host_tool_call",
81
- "host_uri_request",
82
- "reset",
83
- "workflow_gate",
84
- "error",
85
- ];
86
-
87
- interface BridgeFetchHandlerOptions {
88
- sessionId: string;
89
- token: string;
90
- eventStream?: BridgeEventStream;
91
- commandDispatcher?: (command: RpcCommand) => Promise<RpcResponse>;
92
- commandScopes?: readonly BridgeCommandScope[];
93
- idempotencyCache?: BridgeIdempotencyCache;
94
- permissionBroker?: UiRequestBroker<BridgePermissionRequestPayload, ClientBridgePermissionOutcome>;
95
- uiBroker?: UiRequestBroker<BridgeUiRequestPayload, BridgeUiResult<unknown>>;
96
- hostToolBridge?: RpcHostToolBridge;
97
- hostUriBridge?: RpcHostUriBridge;
98
- endpointMatrix?: Partial<BridgeEndpointMatrix>;
99
- unattendedControlPlane?: UnattendedSessionControlPlane;
100
- }
101
-
102
- interface BridgeIdempotencyRecord {
103
- route: string;
104
- ownerToken?: string;
105
- body: string | Promise<string>;
106
- response: unknown | Promise<unknown>;
107
- pending?: boolean;
108
- }
109
-
110
- type BridgeIdempotencyCache = Map<string, BridgeIdempotencyRecord>;
111
-
112
- function idempotencyConflict(): Response {
113
- return jsonResponse(409, { error: "idempotency_conflict" });
114
- }
115
-
116
- function cachedIdempotencyResponse(
117
- cache: BridgeIdempotencyCache | undefined,
118
- key: string | undefined,
119
- record: Omit<BridgeIdempotencyRecord, "response">,
120
- ): Response | Promise<Response> | undefined {
121
- if (!key) return undefined;
122
- const cached = cache?.get(key);
123
- if (!cached) return undefined;
124
- return Promise.resolve(cached.body).then(body => {
125
- if (body !== record.body || cached.route !== record.route) return idempotencyConflict();
126
- if (cached.ownerToken !== record.ownerToken)
127
- return jsonResponse(403, { status: "rejected", code: "not_controller" });
128
- return Promise.resolve(cached.response).then(response => jsonResponse(200, response));
129
- });
130
- }
131
-
132
- function rememberIdempotencyResponse(
133
- cache: BridgeIdempotencyCache | undefined,
134
- key: string | undefined,
135
- record: BridgeIdempotencyRecord,
136
- ): void {
137
- if (!key) return;
138
- cache?.set(key, record);
139
- if (cache && cache.size > MAX_IDEMPOTENCY_RECORDS) {
140
- for (const [candidateKey, candidate] of cache) {
141
- if (!candidate.pending) {
142
- cache.delete(candidateKey);
143
- break;
144
- }
145
- }
146
- }
147
- }
148
-
149
- function jsonResponse(status: number, body: unknown): Response {
150
- return new Response(JSON.stringify(body), {
151
- status,
152
- headers: { "Content-Type": "application/json" },
153
- });
154
- }
155
-
156
- function isBridgeControllerOwner(options: BridgeFetchHandlerOptions, ownerToken: string): boolean {
157
- if (!ownerToken) return false;
158
- const ownerTokens = [options.permissionBroker?.ownerToken, options.uiBroker?.ownerToken].filter(
159
- (token): token is string => typeof token === "string" && token.length > 0,
160
- );
161
- return ownerTokens.length > 0 && ownerTokens.every(token => token === ownerToken);
162
- }
163
-
164
- function parseBridgeScopes(value: string | undefined): readonly BridgeCommandScope[] {
165
- if (!value?.trim()) return DEFAULT_BRIDGE_SCOPES;
166
- const allowed = new Set(BRIDGE_COMMAND_SCOPES);
167
- const scopes = new Set<BridgeCommandScope>(DEFAULT_BRIDGE_SCOPES);
168
- for (const raw of value.split(",")) {
169
- const scope = raw.trim();
170
- if (!scope) continue;
171
- if (!allowed.has(scope as BridgeCommandScope)) throw new Error(`Invalid GJC_BRIDGE_SCOPES entry: ${scope}`);
172
- scopes.add(scope as BridgeCommandScope);
173
- }
174
- return [...scopes];
175
- }
176
-
177
- // Opt-in endpoint enablement via GJC_BRIDGE_ENDPOINTS (default undefined -> fail closed, backward compatible).
178
- // Accepts "all" or a comma list of matrix keys.
179
- export function parseBridgeEndpoints(value: string | undefined): Partial<BridgeEndpointMatrix> | undefined {
180
- if (!value?.trim()) return undefined;
181
- const allowed = new Set<string>(Object.keys(FAIL_CLOSED_BRIDGE_ENDPOINTS));
182
- const matrix: Partial<BridgeEndpointMatrix> = {};
183
- if (value.trim().toLowerCase() === "all") {
184
- for (const key of allowed) matrix[key as keyof BridgeEndpointMatrix] = true;
185
- return matrix;
186
- }
187
- for (const raw of value.split(",")) {
188
- const key = raw.trim();
189
- if (!key) continue;
190
- if (!allowed.has(key)) throw new Error(`Invalid GJC_BRIDGE_ENDPOINTS entry: ${key}`);
191
- matrix[key as keyof BridgeEndpointMatrix] = true;
192
- }
193
- return matrix;
194
- }
195
-
196
- function hasScope(scopes: readonly BridgeCommandScope[] | undefined, scope: BridgeCommandScope): boolean {
197
- return new Set(scopes ?? DEFAULT_BRIDGE_SCOPES).has(scope);
198
- }
199
- function bridgeEndpointMatrix(options: BridgeFetchHandlerOptions): BridgeEndpointMatrix {
200
- return { ...FAIL_CLOSED_BRIDGE_ENDPOINTS, ...options.endpointMatrix };
201
- }
202
-
203
- function disabledEndpointResponse(endpoint: keyof BridgeEndpointMatrix): Response {
204
- return jsonResponse(403, { error: "endpoint_disabled", endpoint });
205
- }
206
-
207
- function bridgeHelpResponse(matrix: BridgeEndpointMatrix): Response {
208
- return jsonResponse(200, {
209
- status: "experimental_gated",
210
- message: "Bridge mode is experimental; session-control endpoints fail closed by default.",
211
- endpoints: matrix,
212
- });
213
- }
214
-
215
- function auditOutcomeFor(event: string): "accepted" | "rejected" | "denied" | "exceeded" | "aborted" | "info" {
216
- if (event.includes("denied")) return "denied";
217
- if (event.includes("exceeded")) return "exceeded";
218
- if (event.includes("abort")) return "aborted";
219
- if (event.includes("rejected") || event.includes("conflict")) return "rejected";
220
- if (event.includes("accepted") || event.includes("negotiated") || event.includes("emitted")) return "accepted";
221
- return "info";
222
- }
223
-
224
- function frameTypeForDispatchOutput(obj: RpcResponse | object): BridgeFrameType {
225
- const type = typeof obj === "object" && obj !== null && "type" in obj ? (obj as { type?: unknown }).type : undefined;
226
- if (type === "host_tool_call" || type === "host_tool_cancel") return "host_tool_call";
227
- if (type === "host_uri_request" || type === "host_uri_cancel") return "host_uri_request";
228
- if (type === "extension_ui_request") return "ui_request";
229
- if (type === "response") return "response";
230
- return "response";
231
- }
232
-
233
- export function createBridgeFetchHandler(options: BridgeFetchHandlerOptions): (request: Request) => Promise<Response> {
234
- return async request => {
235
- const endpointMatrix = bridgeEndpointMatrix(options);
236
- const url = new URL(request.url);
237
- if (request.method === "GET" && url.pathname === "/healthz") {
238
- return jsonResponse(200, { status: "ok" });
239
- }
240
- if (request.method === "GET" && url.pathname === "/v1/help") {
241
- return bridgeHelpResponse(endpointMatrix);
242
- }
243
-
244
- if (request.method === "GET" && url.pathname === `/v1/sessions/${options.sessionId}/events`) {
245
- if (!isBridgeTokenAuthorized(request.headers.get("Authorization"), { token: options.token })) {
246
- return jsonResponse(401, { error: "unauthorized" });
247
- }
248
- if (!endpointMatrix.events) return disabledEndpointResponse("events");
249
- const lastSeqRaw = url.searchParams.get("last_seq");
250
- if (lastSeqRaw !== null && !/^\d+$/.test(lastSeqRaw)) return jsonResponse(400, { error: "invalid_last_seq" });
251
- const lastSeq = lastSeqRaw === null ? 0 : Number.parseInt(lastSeqRaw, 10);
252
- return options.eventStream?.response(lastSeq) ?? jsonResponse(503, { error: "events_unavailable" });
253
- }
254
-
255
- if (!isBridgeTokenAuthorized(request.headers.get("Authorization"), { token: options.token })) {
256
- return jsonResponse(401, { error: "unauthorized" });
257
- }
258
-
259
- if (request.method === "POST" && url.pathname === "/v1/handshake") {
260
- let payload: BridgeHandshakeRequest;
261
- try {
262
- payload = (await request.json()) as BridgeHandshakeRequest;
263
- } catch {
264
- return jsonResponse(400, { error: "invalid_json" });
265
- }
266
- if (!isBridgeHandshakeRequest(payload)) {
267
- return jsonResponse(400, { error: "invalid_request" });
268
- }
269
- let acceptedUnattended = options.unattendedControlPlane?.isUnattended() ? payload.unattended : undefined;
270
- if (
271
- acceptedUnattended === undefined &&
272
- payload.unattended !== undefined &&
273
- endpointMatrix.events &&
274
- options.unattendedControlPlane
275
- ) {
276
- try {
277
- options.unattendedControlPlane.negotiate(payload.unattended);
278
- acceptedUnattended = payload.unattended;
279
- } catch (err) {
280
- const error =
281
- err instanceof Error && "code" in err
282
- ? { code: (err as { code: unknown }).code, message: err.message }
283
- : { error: err instanceof Error ? err.message : String(err) };
284
- return jsonResponse(403, error);
285
- }
286
- }
287
- return jsonResponse(
288
- 200,
289
- negotiateBridgeHandshake(payload, {
290
- sessionId: options.sessionId,
291
- capabilities: endpointMatrix.events ? SERVER_CAPABILITIES : [],
292
- scopes: endpointMatrix.commands ? (options.commandScopes ?? DEFAULT_BRIDGE_SCOPES) : [],
293
- endpoints: {
294
- events: endpointMatrix.events ? `/v1/sessions/${options.sessionId}/events` : "",
295
- commands: endpointMatrix.commands ? `/v1/sessions/${options.sessionId}/commands` : "",
296
- uiResponses: endpointMatrix.uiResponses
297
- ? `/v1/sessions/${options.sessionId}/ui-responses/{correlation_id}`
298
- : "",
299
- claimControl: endpointMatrix.control ? `/v1/sessions/${options.sessionId}/control:claim` : "",
300
- disconnectControl: endpointMatrix.control
301
- ? `/v1/sessions/${options.sessionId}/control:disconnect`
302
- : "",
303
- hostToolResults: endpointMatrix.hostToolResults
304
- ? `/v1/sessions/${options.sessionId}/host-tool-results/{correlation_id}`
305
- : "",
306
- hostUriResults: endpointMatrix.hostUriResults
307
- ? `/v1/sessions/${options.sessionId}/host-uri-results/{correlation_id}`
308
- : "",
309
- },
310
- frameTypes: endpointMatrix.events ? SERVER_FRAME_TYPES : [],
311
- acceptedUnattended,
312
- }),
313
- );
314
- }
315
-
316
- if (request.method === "POST" && url.pathname === `/v1/sessions/${options.sessionId}/commands`) {
317
- if (!endpointMatrix.commands) return disabledEndpointResponse("commands");
318
- if (!options.commandDispatcher) return jsonResponse(503, { error: "commands_unavailable" });
319
- const idempotencyKey = request.headers.get("Idempotency-Key") ?? undefined;
320
- const existingRecord = idempotencyKey ? options.idempotencyCache?.get(idempotencyKey) : undefined;
321
- let body = "";
322
- let payload: unknown;
323
- let pendingResponse: PromiseWithResolvers<unknown> | undefined;
324
- try {
325
- if (existingRecord) {
326
- body = await request.text();
327
- const cached = cachedIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
328
- route: url.pathname,
329
- body,
330
- });
331
- if (cached) return await cached;
332
- } else {
333
- const bodyPromise = request.text();
334
- pendingResponse = Promise.withResolvers<unknown>();
335
- void pendingResponse.promise.catch(() => undefined);
336
- rememberIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
337
- route: url.pathname,
338
- body: bodyPromise,
339
- response: pendingResponse.promise,
340
- pending: true,
341
- });
342
- body = await bodyPromise;
343
- }
344
- payload = JSON.parse(body) as unknown;
345
- } catch {
346
- options.idempotencyCache?.delete(idempotencyKey ?? "");
347
- pendingResponse?.reject(new Error("invalid_json"));
348
- return jsonResponse(400, { error: "invalid_json" });
349
- }
350
- const type =
351
- typeof payload === "object" && payload !== null && "type" in payload
352
- ? (payload as { type?: unknown }).type
353
- : undefined;
354
- if (!isRpcCommandType(type)) {
355
- options.idempotencyCache?.delete(idempotencyKey ?? "");
356
- pendingResponse?.reject(new Error("invalid_command"));
357
- return jsonResponse(400, { error: "invalid_command" });
358
- }
359
- if (!isRpcCommand(payload)) {
360
- options.idempotencyCache?.delete(idempotencyKey ?? "");
361
- pendingResponse?.reject(new Error("invalid_command"));
362
- return jsonResponse(400, { error: "invalid_command" });
363
- }
364
- const scopes = new Set(options.commandScopes ?? DEFAULT_BRIDGE_SCOPES);
365
- if (!isRpcCommandAllowed(type, scopes)) {
366
- options.idempotencyCache?.delete(idempotencyKey ?? "");
367
- pendingResponse?.reject(new Error("scope_denied"));
368
- return jsonResponse(403, { error: "scope_denied", scope: scopeForRpcCommand(type) });
369
- }
370
- try {
371
- const response = await options.commandDispatcher(payload);
372
- pendingResponse?.resolve(response);
373
- const cachedRecord = idempotencyKey ? options.idempotencyCache?.get(idempotencyKey) : undefined;
374
- if (cachedRecord) cachedRecord.pending = false;
375
- return jsonResponse(200, response);
376
- } catch (err) {
377
- options.idempotencyCache?.delete(idempotencyKey ?? "");
378
- pendingResponse?.reject(err);
379
- throw err;
380
- }
381
- }
382
- if (request.method === "POST" && url.pathname === `/v1/sessions/${options.sessionId}/control:claim`) {
383
- if (!endpointMatrix.control) return disabledEndpointResponse("control");
384
- if (!hasScope(options.commandScopes, "control"))
385
- return jsonResponse(403, { error: "scope_denied", scope: "control" });
386
- if (options.permissionBroker?.ownerToken || options.uiBroker?.ownerToken)
387
- return jsonResponse(409, { error: "controller_busy" });
388
- const ownerToken = request.headers.get("X-GJC-Bridge-Owner-Token") ?? crypto.randomUUID();
389
- const permissionClaim = options.permissionBroker?.claimController(ownerToken);
390
- const uiClaim = options.uiBroker?.claimController(ownerToken);
391
- if (permissionClaim?.status === "busy" || uiClaim?.status === "busy")
392
- return jsonResponse(409, { error: "controller_busy" });
393
- return jsonResponse(200, { status: "claimed", ownerToken });
394
- }
395
- if (request.method === "POST" && url.pathname === `/v1/sessions/${options.sessionId}/control:disconnect`) {
396
- if (!endpointMatrix.control) return disabledEndpointResponse("control");
397
- if (!hasScope(options.commandScopes, "control"))
398
- return jsonResponse(403, { error: "scope_denied", scope: "control" });
399
- const ownerToken = request.headers.get("X-GJC-Bridge-Owner-Token") ?? "";
400
- const permissionReleased = options.permissionBroker?.disconnectController(ownerToken) ?? true;
401
- const uiReleased = options.uiBroker?.disconnectController(ownerToken) ?? true;
402
- return permissionReleased && uiReleased
403
- ? jsonResponse(200, { status: "released" })
404
- : jsonResponse(403, { status: "rejected", code: "not_controller" });
405
- }
406
-
407
- const uiResponsePrefix = `/v1/sessions/${options.sessionId}/ui-responses/`;
408
- if (request.method === "POST" && url.pathname.startsWith(uiResponsePrefix)) {
409
- if (!endpointMatrix.uiResponses) return disabledEndpointResponse("uiResponses");
410
- if (!hasScope(options.commandScopes, "control"))
411
- return jsonResponse(403, { error: "scope_denied", scope: "control" });
412
- const correlationId = decodeURIComponent(url.pathname.slice(uiResponsePrefix.length));
413
- const ownerToken = request.headers.get("X-GJC-Bridge-Owner-Token") ?? "";
414
- const idempotencyKey = request.headers.get("Idempotency-Key") ?? undefined;
415
- let body = "";
416
- let payload: unknown;
417
- try {
418
- body = await request.text();
419
- const cached = cachedIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
420
- route: url.pathname,
421
- ownerToken,
422
- body,
423
- });
424
- if (cached) return await cached;
425
- payload = JSON.parse(body) as unknown;
426
- } catch {
427
- return jsonResponse(400, { error: "invalid_json" });
428
- }
429
- if (
430
- payload !== null &&
431
- typeof payload === "object" &&
432
- "gate_id" in payload &&
433
- "answer" in payload &&
434
- (correlationId === (payload as RpcWorkflowGateResponse).gate_id || correlationId.startsWith("wg_"))
435
- ) {
436
- if (!isBridgeControllerOwner(options, ownerToken)) {
437
- return jsonResponse(403, { status: "rejected", code: "not_controller" });
438
- }
439
- try {
440
- const resolution = await options.unattendedControlPlane?.resolveGate({
441
- gate_id: (payload as RpcWorkflowGateResponse).gate_id,
442
- answer: (payload as RpcWorkflowGateResponse).answer,
443
- idempotency_key: (payload as RpcWorkflowGateResponse).idempotency_key ?? idempotencyKey,
444
- });
445
- if (resolution) {
446
- rememberIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
447
- route: url.pathname,
448
- ownerToken,
449
- body,
450
- response: resolution,
451
- });
452
- return jsonResponse(200, resolution);
453
- }
454
- } catch (err) {
455
- const error =
456
- err instanceof Error && "code" in err
457
- ? { code: (err as { code: unknown }).code, message: err.message }
458
- : { error: err instanceof Error ? err.message : String(err) };
459
- return jsonResponse(409, error);
460
- }
461
- }
462
- const permissionResult = options.permissionBroker?.respond(
463
- correlationId,
464
- ownerToken,
465
- payload as ClientBridgePermissionOutcome,
466
- );
467
- if (permissionResult?.status === "accepted") {
468
- rememberIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
469
- route: url.pathname,
470
- ownerToken,
471
- body,
472
- response: permissionResult,
473
- });
474
- return jsonResponse(200, permissionResult);
475
- }
476
- const uiResult = options.uiBroker?.respond(correlationId, ownerToken, payload as BridgeUiResult<unknown>);
477
- if (uiResult?.status === "accepted") {
478
- rememberIdempotencyResponse(options.idempotencyCache, idempotencyKey, {
479
- route: url.pathname,
480
- ownerToken,
481
- body,
482
- response: uiResult,
483
- });
484
- return jsonResponse(200, uiResult);
485
- }
486
- const rejection = uiResult ?? permissionResult ?? { status: "rejected", code: "unknown_request" };
487
- return jsonResponse(
488
- rejection.status === "rejected" && rejection.code === "not_controller" ? 403 : 409,
489
- rejection,
490
- );
491
- }
492
- const hostToolResultPrefix = `/v1/sessions/${options.sessionId}/host-tool-results/`;
493
- if (request.method === "POST" && url.pathname.startsWith(hostToolResultPrefix)) {
494
- if (!endpointMatrix.hostToolResults) return disabledEndpointResponse("hostToolResults");
495
- if (!hasScope(options.commandScopes, "host_tools"))
496
- return jsonResponse(403, { error: "scope_denied", scope: "host_tools" });
497
- if (!options.hostToolBridge) return jsonResponse(503, { error: "host_tools_unavailable" });
498
- const id = decodeURIComponent(url.pathname.slice(hostToolResultPrefix.length));
499
- let payload: unknown;
500
- try {
501
- payload = await request.json();
502
- } catch {
503
- return jsonResponse(400, { error: "invalid_json" });
504
- }
505
- const frame = typeof payload === "object" && payload !== null ? { ...payload, id } : { id };
506
- let handled = false;
507
- if (isRpcHostToolUpdate(frame)) {
508
- handled = options.hostToolBridge.handleUpdate(frame);
509
- } else if (isRpcHostToolResult(frame)) {
510
- handled = options.hostToolBridge.handleResult(frame);
511
- } else {
512
- return jsonResponse(400, { error: "invalid_host_tool_result" });
513
- }
514
- return handled ? jsonResponse(200, { status: "accepted" }) : jsonResponse(404, { error: "unknown_request" });
515
- }
516
-
517
- const hostUriResultPrefix = `/v1/sessions/${options.sessionId}/host-uri-results/`;
518
- if (request.method === "POST" && url.pathname.startsWith(hostUriResultPrefix)) {
519
- if (!endpointMatrix.hostUriResults) return disabledEndpointResponse("hostUriResults");
520
- if (!hasScope(options.commandScopes, "host_uri"))
521
- return jsonResponse(403, { error: "scope_denied", scope: "host_uri" });
522
- if (!options.hostUriBridge) return jsonResponse(503, { error: "host_uri_unavailable" });
523
- const id = decodeURIComponent(url.pathname.slice(hostUriResultPrefix.length));
524
- let payload: unknown;
525
- try {
526
- payload = await request.json();
527
- } catch {
528
- return jsonResponse(400, { error: "invalid_json" });
529
- }
530
- const frame = typeof payload === "object" && payload !== null ? { ...payload, id } : { id };
531
- if (!isRpcHostUriResult(frame)) return jsonResponse(400, { error: "invalid_host_uri_result" });
532
- return options.hostUriBridge.handleResult(frame)
533
- ? jsonResponse(200, { status: "accepted" })
534
- : jsonResponse(404, { error: "unknown_request" });
535
- }
536
- return jsonResponse(404, { error: "not_found" });
537
- };
538
- }
539
-
540
- export async function runBridgeMode(
541
- session: AgentSession,
542
- setToolUIContext?: (uiContext: ExtensionUIContext, hasUI: boolean) => void,
543
- ): Promise<never> {
544
- const token = Bun.env.GJC_BRIDGE_TOKEN;
545
- if (!token) {
546
- throw new Error("GJC_BRIDGE_TOKEN is required for --mode bridge");
547
- }
548
- const hostname = Bun.env.GJC_BRIDGE_HOST ?? DEFAULT_BRIDGE_HOST;
549
- const port = Bun.env.GJC_BRIDGE_PORT ? Number.parseInt(Bun.env.GJC_BRIDGE_PORT, 10) : DEFAULT_BRIDGE_PORT;
550
- if (!Number.isInteger(port) || port <= 0 || port > 65_535) {
551
- throw new Error(`Invalid GJC_BRIDGE_PORT: ${Bun.env.GJC_BRIDGE_PORT}`);
552
- }
553
- const commandScopes = parseBridgeScopes(Bun.env.GJC_BRIDGE_SCOPES);
554
- const endpointMatrix = parseBridgeEndpoints(Bun.env.GJC_BRIDGE_ENDPOINTS);
555
-
556
- const certPath = Bun.env.GJC_BRIDGE_TLS_CERT;
557
- const keyPath = Bun.env.GJC_BRIDGE_TLS_KEY;
558
- const tlsConfigured = Boolean(certPath && keyPath);
559
- assertSafeBridgeBind({ hostname, port, tlsConfigured });
560
-
561
- const tls = tlsConfigured
562
- ? {
563
- cert: await Bun.file(certPath!).text(),
564
- key: await Bun.file(keyPath!).text(),
565
- }
566
- : undefined;
567
-
568
- const eventStream = new BridgeEventStream();
569
- const sequencer = new BridgeFrameSequencer(session.sessionId);
570
- const permissionBroker = new UiRequestBroker<BridgePermissionRequestPayload, ClientBridgePermissionOutcome>({
571
- emitRequest: (correlationId, request) => {
572
- eventStream.publish(sequencer.next("permission_request", request, correlationId));
573
- },
574
- });
575
- const uiBroker = new UiRequestBroker<BridgeUiRequestPayload, BridgeUiResult<unknown>>({
576
- emitRequest: (correlationId, request) => {
577
- eventStream.publish(sequencer.next("ui_request", request, correlationId));
578
- },
579
- });
580
- const uiContext = new BridgeExtensionUIContext({
581
- broker: uiBroker,
582
- emit: payload => eventStream.publish(sequencer.next("ui_request", payload)),
583
- });
584
- setToolUIContext?.(uiContext, true);
585
- session.setClientBridge(createBridgeClientBridge(permissionBroker));
586
- session.subscribe(event => eventStream.publish(toBridgeEventFrame(event, sequencer)));
587
- const output = (obj: RpcResponse | object) => {
588
- eventStream.publish(sequencer.next(frameTypeForDispatchOutput(obj), obj));
589
- };
590
- const hostToolBridge = new RpcHostToolBridge(output);
591
- const hostUriBridge = new RpcHostUriBridge(output);
592
- const idempotencyCache: BridgeIdempotencyCache = new Map();
593
- const auditLog = new UnattendedAuditLog(defaultAuditPath(session.sessionId, session.sessionManager.getCwd()), {
594
- redactAnswers: true,
595
- });
596
- const recordAudit = (event: { event: string; [key: string]: unknown }) => {
597
- const payload =
598
- typeof event.payload === "object" && event.payload !== null
599
- ? (event.payload as Record<string, unknown>)
600
- : undefined;
601
- const gateId =
602
- typeof event.gate_id === "string"
603
- ? event.gate_id
604
- : typeof payload?.gate_id === "string"
605
- ? payload.gate_id
606
- : undefined;
607
- auditLog.record({
608
- run_id: session.sessionId,
609
- session_id: session.sessionId,
610
- actor: typeof event.actor === "string" ? event.actor : undefined,
611
- event: event.event,
612
- outcome: auditOutcomeFor(event.event),
613
- dedupe_key: `${event.event}:${gateId ?? "run"}:${JSON.stringify(payload ?? event)}`,
614
- gate_id: gateId,
615
- stage: typeof event.stage === "string" ? (event.stage as never) : undefined,
616
- kind: typeof event.kind === "string" ? (event.kind as never) : undefined,
617
- scope: typeof payload?.scope === "string" ? payload.scope : undefined,
618
- action: typeof payload?.action === "string" ? payload.action : undefined,
619
- budget: event.event === "budget_exceeded" ? (payload as never) : undefined,
620
- answer_hash: typeof event.answer_hash === "string" ? event.answer_hash : undefined,
621
- error: payload && event.event.endsWith("denied") ? payload : undefined,
622
- });
623
- };
624
- const gateStore = new FileGateStore(
625
- workflowGatePath(session.sessionManager.getCwd(), session.sessionId, session.sessionId),
626
- );
627
- const unattendedControlPlane = new UnattendedSessionControlPlane({
628
- runId: session.sessionId,
629
- sessionId: session.sessionId,
630
- emitFrame: gate => eventStream.publish(toBridgeWorkflowGateFrame(gate, sequencer)),
631
- store: gateStore,
632
- audit: recordAudit,
633
- providerSupportsTokenCostMetrics: modelSupportsTokenCostMetrics(session.model),
634
- getUsageSnapshot: () => {
635
- const stats = session.getSessionStats();
636
- return { tokens: stats.tokens.total, costUsd: stats.cost };
637
- },
638
- });
639
- session.setWorkflowGateEmitter(unattendedControlPlane);
640
- unattendedControlPlane
641
- .recover()
642
- .catch(err =>
643
- eventStream.publish(sequencer.next("error", { error: err instanceof Error ? err.message : String(err) })),
644
- );
645
-
646
- Bun.serve({
647
- hostname,
648
- port,
649
- ...(tls ? { tls } : {}),
650
- fetch: createBridgeFetchHandler({
651
- sessionId: session.sessionId,
652
- token,
653
- eventStream,
654
- idempotencyCache,
655
- permissionBroker,
656
- uiBroker,
657
- hostToolBridge,
658
- hostUriBridge,
659
- commandScopes,
660
- endpointMatrix,
661
- unattendedControlPlane,
662
- commandDispatcher: command =>
663
- dispatchRpcCommand(command, {
664
- session,
665
- output,
666
- hostToolRegistry: hostToolBridge,
667
- hostUriRegistry: hostUriBridge,
668
- createUiContext: () => uiContext,
669
- unattendedControlPlane,
670
- }),
671
- }),
672
- });
673
-
674
- return new Promise<never>(() => {});
675
- }