@gajae-code/coding-agent 0.10.2 → 0.11.1

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 (476) hide show
  1. package/CHANGELOG.md +58 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/async/job-manager.d.ts +46 -7
  4. package/dist/types/cli/args.d.ts +4 -5
  5. package/dist/types/cli/daemon-cli.d.ts +12 -1
  6. package/dist/types/cli/notify-cli.d.ts +21 -1
  7. package/dist/types/cli.d.ts +3 -0
  8. package/dist/types/commands/daemon.d.ts +39 -0
  9. package/dist/types/commands/launch.d.ts +3 -0
  10. package/dist/types/commands/notify.d.ts +28 -1
  11. package/dist/types/commands/sdk.d.ts +33 -0
  12. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  13. package/dist/types/config/model-profile-activation.d.ts +35 -15
  14. package/dist/types/config/model-profiles.d.ts +11 -5
  15. package/dist/types/config/model-registry.d.ts +3 -3
  16. package/dist/types/config/model-resolver.d.ts +39 -6
  17. package/dist/types/config/model-selector-value.d.ts +17 -0
  18. package/dist/types/config/models-config-schema.d.ts +10 -6
  19. package/dist/types/config/settings-schema.d.ts +133 -6
  20. package/dist/types/config/settings.d.ts +63 -35
  21. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  22. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  23. package/dist/types/daemon/builtin.d.ts +6 -5
  24. package/dist/types/daemon/control-types.d.ts +1 -1
  25. package/dist/types/discovery/mcp-json.d.ts +12 -1
  26. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  27. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  28. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  29. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  30. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  31. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  32. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  33. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  34. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  35. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  36. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  37. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  38. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  39. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
  40. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  41. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  42. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  43. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  44. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  45. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  46. package/dist/types/harness-control-plane/types.d.ts +3 -4
  47. package/dist/types/lsp/index.d.ts +1 -1
  48. package/dist/types/main.d.ts +32 -38
  49. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  50. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  51. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  52. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  53. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  54. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  55. package/dist/types/modes/components/model-selector.d.ts +1 -0
  56. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  57. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  58. package/dist/types/modes/components/welcome.d.ts +1 -1
  59. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  60. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
  61. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  62. package/dist/types/modes/index.d.ts +0 -4
  63. package/dist/types/modes/interactive-mode.d.ts +5 -2
  64. package/dist/types/modes/runtime-init.d.ts +2 -2
  65. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  66. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  67. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  68. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  69. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +170 -30
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  72. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  73. package/dist/types/modes/types.d.ts +7 -2
  74. package/dist/types/runtime-mcp/client.d.ts +2 -0
  75. package/dist/types/runtime-mcp/config.d.ts +5 -1
  76. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  77. package/dist/types/runtime-mcp/types.d.ts +4 -0
  78. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  79. package/dist/types/sdk/acp/index.d.ts +2 -0
  80. package/dist/types/sdk/broker/broker.d.ts +53 -0
  81. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  82. package/dist/types/sdk/broker/ensure.d.ts +42 -0
  83. package/dist/types/sdk/broker/identity.d.ts +3 -0
  84. package/dist/types/sdk/broker/index.d.ts +8 -0
  85. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  86. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  87. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  88. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  89. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  90. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  91. package/dist/types/sdk/broker/transport.d.ts +9 -0
  92. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  93. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  94. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  95. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  96. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  97. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  98. package/dist/types/sdk/bus/config.d.ts +274 -0
  99. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  100. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  101. package/dist/types/sdk/bus/discord-daemon.d.ts +50 -0
  102. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  103. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  104. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  105. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  107. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  108. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  109. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  110. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  111. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  112. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  113. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  114. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  115. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  116. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  117. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  118. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  119. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  121. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +78 -17
  122. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  123. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  124. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  125. package/dist/types/sdk/cli/index.d.ts +1 -0
  126. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  127. package/dist/types/sdk/client/client.d.ts +1 -0
  128. package/dist/types/sdk/client/discovery.d.ts +27 -0
  129. package/dist/types/sdk/client/index.d.ts +2 -0
  130. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  131. package/dist/types/sdk/host/control/index.d.ts +2 -0
  132. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  133. package/dist/types/sdk/host/events.d.ts +35 -0
  134. package/dist/types/sdk/host/host.d.ts +35 -0
  135. package/dist/types/sdk/host/index.d.ts +4 -0
  136. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  137. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  138. package/dist/types/sdk/host/query/index.d.ts +3 -0
  139. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  140. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  141. package/dist/types/sdk/host/types.d.ts +32 -0
  142. package/dist/types/sdk/index.d.ts +6 -0
  143. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  144. package/dist/types/sdk/mcp/index.d.ts +1 -0
  145. package/dist/types/sdk/mcp/server.d.ts +37 -0
  146. package/dist/types/sdk/models.d.ts +44 -0
  147. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  148. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  149. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  150. package/dist/types/sdk/startup-capability.d.ts +50 -0
  151. package/dist/types/session/agent-session.d.ts +114 -21
  152. package/dist/types/session/default-model-selection.d.ts +25 -0
  153. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  154. package/dist/types/session/session-manager.d.ts +58 -1
  155. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  156. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  157. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  158. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  159. package/dist/types/tools/browser/launch.d.ts +22 -0
  160. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  161. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  162. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  163. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  164. package/dist/types/tools/browser/registry.d.ts +19 -0
  165. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  166. package/dist/types/tools/index.d.ts +8 -8
  167. package/dist/types/tools/subagent-render.d.ts +1 -0
  168. package/dist/types/tools/subagent.d.ts +6 -1
  169. package/package.json +34 -13
  170. package/scripts/build-sdk-package-smoke.ts +99 -0
  171. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  172. package/scripts/compile-args.ts +4 -2
  173. package/scripts/g005-daemon-smoke.ts +4 -5
  174. package/scripts/g011-daemon-path-smoke.ts +5 -5
  175. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  176. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  177. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  178. package/scripts/manifest-schema.ts +124 -0
  179. package/scripts/run-test-manifest.ts +153 -0
  180. package/scripts/run-threat-model-check.ts +157 -0
  181. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  182. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  183. package/src/append-only-mode.ts +1 -1
  184. package/src/async/job-manager.ts +406 -63
  185. package/src/cli/args.ts +43 -12
  186. package/src/cli/auth-gateway-cli.ts +2 -2
  187. package/src/cli/config-cli.ts +2 -1
  188. package/src/cli/daemon-cli.ts +63 -14
  189. package/src/cli/list-models.ts +1 -1
  190. package/src/cli/notify-cli.ts +288 -286
  191. package/src/cli.ts +21 -2
  192. package/src/commands/daemon.ts +50 -6
  193. package/src/commands/harness.ts +93 -36
  194. package/src/commands/launch.ts +5 -2
  195. package/src/commands/mcp-serve.ts +19 -12
  196. package/src/commands/notify.ts +36 -3
  197. package/src/commands/sdk.ts +426 -0
  198. package/src/commit/agentic/agent.ts +1 -0
  199. package/src/config/atomic-yaml-patch.ts +423 -0
  200. package/src/config/model-profile-activation.ts +240 -89
  201. package/src/config/model-profiles.ts +18 -15
  202. package/src/config/model-registry.ts +51 -26
  203. package/src/config/model-resolver.ts +138 -51
  204. package/src/config/model-selector-value.ts +50 -0
  205. package/src/config/models-config-schema.ts +14 -21
  206. package/src/config/settings-schema.ts +128 -10
  207. package/src/config/settings.ts +1120 -158
  208. package/src/coordinator-mcp/model-preset.ts +74 -20
  209. package/src/coordinator-mcp/server.ts +1597 -3052
  210. package/src/daemon/builtin.ts +8 -5
  211. package/src/daemon/control-types.ts +1 -1
  212. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  213. package/src/discovery/mcp-json.ts +327 -20
  214. package/src/extensibility/custom-tools/types.ts +1 -1
  215. package/src/extensibility/extensions/compact-handler.ts +3 -3
  216. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  217. package/src/extensibility/extensions/loader.ts +69 -5
  218. package/src/extensibility/extensions/runner.ts +112 -4
  219. package/src/extensibility/extensions/types.ts +176 -17
  220. package/src/extensibility/hooks/types.ts +1 -1
  221. package/src/gjc-runtime/launch-tmux.ts +170 -86
  222. package/src/gjc-runtime/psmux-detect.ts +82 -4
  223. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  224. package/src/gjc-runtime/team-runtime.ts +54 -35
  225. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  226. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  227. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  228. package/src/gjc-runtime/ultragoal-guard.ts +108 -14
  229. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
  230. package/src/gjc-runtime/ultragoal-runtime.ts +227 -11
  231. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  232. package/src/harness-control-plane/operate.ts +9 -9
  233. package/src/harness-control-plane/owner.ts +283 -39
  234. package/src/harness-control-plane/receipts.ts +0 -1
  235. package/src/harness-control-plane/sdk-transport.ts +395 -0
  236. package/src/harness-control-plane/session-transport.ts +94 -0
  237. package/src/harness-control-plane/types.ts +1 -1
  238. package/src/internal-urls/docs-index.generated.ts +34 -35
  239. package/src/lsp/client.ts +42 -6
  240. package/src/lsp/index.ts +2 -2
  241. package/src/main.ts +299 -204
  242. package/src/modes/DESIGN.md +258 -0
  243. package/src/modes/acp/acp-agent.ts +1228 -2612
  244. package/src/modes/acp/acp-client-bridge.ts +2 -20
  245. package/src/modes/acp/acp-event-mapper.ts +18 -2
  246. package/src/modes/acp/acp-mode.ts +8 -36
  247. package/src/modes/acp/permission-mode.ts +25 -0
  248. package/src/modes/acp/startup-options.ts +6 -0
  249. package/src/modes/components/agent-dashboard.ts +37 -17
  250. package/src/modes/components/model-selector.ts +93 -35
  251. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  252. package/src/modes/components/settings-selector.ts +60 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +10 -17
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +396 -28
  257. package/src/modes/controllers/selector-controller.ts +674 -36
  258. package/src/modes/index.ts +0 -22
  259. package/src/modes/interactive-mode.ts +87 -36
  260. package/src/modes/runtime-init.ts +298 -6
  261. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  262. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  263. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  264. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  265. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  266. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1258 -87
  267. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  268. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  269. package/src/modes/types.ts +7 -2
  270. package/src/runtime-mcp/client.ts +94 -19
  271. package/src/runtime-mcp/config.ts +27 -15
  272. package/src/runtime-mcp/manager.ts +343 -105
  273. package/src/runtime-mcp/oauth-flow.ts +42 -12
  274. package/src/runtime-mcp/transports/http.ts +49 -19
  275. package/src/runtime-mcp/transports/stdio.ts +47 -28
  276. package/src/runtime-mcp/types.ts +10 -0
  277. package/src/sdk/acp/adapter.ts +418 -0
  278. package/src/sdk/acp/index.ts +2 -0
  279. package/src/sdk/broker/broker.ts +642 -0
  280. package/src/sdk/broker/discovery.ts +113 -0
  281. package/src/sdk/broker/ensure.ts +307 -0
  282. package/src/sdk/broker/identity.ts +42 -0
  283. package/src/sdk/broker/index.ts +8 -0
  284. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  285. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  286. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  287. package/src/sdk/broker/lifecycle.ts +2157 -0
  288. package/src/sdk/broker/process-incarnation.ts +159 -0
  289. package/src/sdk/broker/runtime.ts +164 -0
  290. package/src/sdk/broker/session-index.ts +318 -0
  291. package/src/sdk/broker/state-version.ts +23 -0
  292. package/src/sdk/broker/transport.ts +125 -0
  293. package/src/sdk/bus/chat-command-policy.ts +107 -0
  294. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  295. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  296. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  297. package/src/sdk/bus/chat-effect-journal.ts +355 -0
  298. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  299. package/src/sdk/bus/config.ts +433 -0
  300. package/src/sdk/bus/conversation-store.ts +391 -0
  301. package/src/sdk/bus/discord-conversation.ts +85 -0
  302. package/src/sdk/bus/discord-daemon.ts +2292 -0
  303. package/src/sdk/bus/discord-live-provider.ts +521 -0
  304. package/src/sdk/bus/discord-provider.ts +56 -0
  305. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  306. package/src/sdk/bus/index.ts +3979 -0
  307. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  309. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  310. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  311. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  312. package/src/sdk/bus/natives-augment.d.ts +38 -0
  313. package/src/sdk/bus/notification-orchestration.ts +535 -0
  314. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  315. package/src/sdk/bus/session-control.ts +333 -0
  316. package/src/sdk/bus/slack-conversation.ts +74 -0
  317. package/src/sdk/bus/slack-daemon.ts +2144 -0
  318. package/src/sdk/bus/slack-live-provider.ts +380 -0
  319. package/src/sdk/bus/slack-provider.ts +76 -0
  320. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  321. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  322. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  323. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  324. package/src/{notifications → sdk/bus}/telegram-daemon.ts +603 -63
  325. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  326. package/src/sdk/bus/telegram-setup.ts +663 -0
  327. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  328. package/src/sdk/cli/index.ts +1 -0
  329. package/src/sdk/cli/session-cli.ts +275 -0
  330. package/src/sdk/client/client.ts +1 -0
  331. package/src/sdk/client/discovery.ts +108 -0
  332. package/src/sdk/client/index.ts +2 -0
  333. package/src/sdk/host/control/dispatch.ts +367 -0
  334. package/src/sdk/host/control/index.ts +10 -0
  335. package/src/sdk/host/control/operations.ts +63 -0
  336. package/src/sdk/host/events.ts +91 -0
  337. package/src/sdk/host/host.ts +296 -0
  338. package/src/sdk/host/index.ts +4 -0
  339. package/src/sdk/host/query/cursor.ts +189 -0
  340. package/src/sdk/host/query/handlers.ts +533 -0
  341. package/src/sdk/host/query/index.ts +3 -0
  342. package/src/sdk/host/query/revision-store.ts +1126 -0
  343. package/src/sdk/host/reverse-leases.ts +325 -0
  344. package/src/sdk/host/types.ts +29 -0
  345. package/src/sdk/index.ts +13 -0
  346. package/src/sdk/lifecycle-session.ts +39 -0
  347. package/src/sdk/mcp/index.ts +1 -0
  348. package/src/sdk/mcp/server.ts +332 -0
  349. package/src/sdk/models.ts +168 -0
  350. package/src/sdk/protocol/adapter-validation.ts +48 -0
  351. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  352. package/src/sdk/protocol/operation-registry.ts +312 -0
  353. package/src/{sdk.ts → sdk/session.ts} +339 -212
  354. package/src/sdk/startup-capability.ts +189 -0
  355. package/src/session/agent-session.ts +2650 -944
  356. package/src/session/default-model-selection.ts +93 -0
  357. package/src/session/fallback-chain-controller.ts +136 -0
  358. package/src/session/session-manager.ts +438 -11
  359. package/src/session/session-storage.ts +8 -1
  360. package/src/setup/credential-auto-import.ts +290 -35
  361. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  362. package/src/slash-commands/builtin-registry.ts +2 -1
  363. package/src/task/executor.ts +62 -13
  364. package/src/task/index.ts +26 -16
  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/subagent-render.ts +19 -8
  384. package/src/tools/subagent.ts +84 -32
  385. package/src/tools/telegram-send.ts +2 -2
  386. package/vendor/insane-search/MANIFEST.json +2 -1
  387. package/vendor/insane-search/engine/bias_check.py +4 -1
  388. package/vendor/insane-search/engine/phase0.py +26 -1
  389. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  390. package/dist/types/modes/bridge/auth.d.ts +0 -12
  391. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  392. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  393. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  394. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  395. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  396. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  397. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  398. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  399. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  400. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  401. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  402. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  403. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  404. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  405. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  406. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  407. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  408. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  409. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  410. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  411. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  412. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  413. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  414. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  415. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  416. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  417. package/dist/types/notifications/config.d.ts +0 -132
  418. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  419. package/src/modes/bridge/auth.ts +0 -41
  420. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  421. package/src/modes/bridge/bridge-mode.ts +0 -675
  422. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  423. package/src/modes/bridge/event-stream.ts +0 -70
  424. package/src/modes/rpc/host-tools.ts +0 -1
  425. package/src/modes/rpc/host-uris.ts +0 -1
  426. package/src/modes/rpc/rpc-client.ts +0 -1166
  427. package/src/modes/rpc/rpc-mode.ts +0 -1029
  428. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  429. package/src/modes/rpc/rpc-types.ts +0 -637
  430. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  431. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  432. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  433. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  434. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  435. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  436. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  437. package/src/modes/shared/agent-wire/responses.ts +0 -17
  438. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  439. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  440. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  441. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  442. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  443. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  444. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  445. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  446. package/src/notifications/config.ts +0 -219
  447. package/src/notifications/index.ts +0 -1835
  448. package/src/notifications/telegram-daemon-cli.ts +0 -243
  449. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  450. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  462. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  463. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  475. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  476. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -1,127 +0,0 @@
1
- /**
2
- * Session-level unattended control plane (#323 / G011 emission side).
3
- *
4
- * Bridges the gate EMISSION side (skill runtimes / ask tool emitting gates) to
5
- * the gate ANSWER side (the external agent's `workflow_gate_response` over RPC):
6
- *
7
- * - `emitGate(input)` opens a gate on the durable broker, emits the gate frame
8
- * to the transport, and returns a promise that resolves with the agent's
9
- * answer once it arrives.
10
- * - `resolveGate(response)` (called from RPC dispatch) validates + resolves the
11
- * gate on the broker; the broker's `advance` hook resolves the pending
12
- * `emitGate` promise with the answer.
13
- *
14
- * Also implements the dispatch-facing {@link RpcUnattendedControlPlane} so the
15
- * RPC server can route `negotiate_unattended` + `workflow_gate_response` here.
16
- */
17
- import type { Model } from "@gajae-code/ai";
18
- import type { AskSelectedAckOutcome } from "../../../tools";
19
- import type { RpcCommand, RpcUnattendedAccepted, RpcUnattendedDeclaration, RpcWorkflowGate, RpcWorkflowGateResolution, RpcWorkflowGateResponse } from "../../rpc/rpc-types";
20
- import type { RpcUnattendedControlPlane } from "./command-dispatch";
21
- import { type UnattendedAbortHooks, type UnattendedAuditEvent, UnattendedRunController } from "./unattended-run-controller";
22
- import { type GateStore, type OpenGateInput } from "./workflow-gate-broker";
23
- export interface WorkflowGateTerminalController {
24
- completeGateInteractions(gateId: string): void | Promise<void>;
25
- cancelGateInteractions(gateId: string, reason: string): void | Promise<void>;
26
- }
27
- export interface WorkflowGateTerminalEvent {
28
- gateId: string;
29
- kind: "accepted" | "cancelled";
30
- origin?: "rpc" | "bridge" | "other" | "telegram_notification";
31
- reason?: string;
32
- }
33
- export interface NotificationGateResolutionOptions {
34
- interactionActionId: string;
35
- replyReceiptId: string;
36
- answerJson: string;
37
- idempotencyKey?: string;
38
- requestSelectedAck(input: {
39
- replyReceiptId: string;
40
- actionId: string;
41
- commitKey: string;
42
- daemonDeadlineAt: number;
43
- hostTimeoutMs: number;
44
- }): Promise<AskSelectedAckOutcome>;
45
- resolveClaim(): void;
46
- closeClaimInvalid(reason: string): void;
47
- }
48
- export interface AskSelectedAckRecoveryParticipant {
49
- requestRecoveredAskSelectedAck(input: {
50
- sessionId: string;
51
- actionId: string;
52
- commitKey: string;
53
- deadlineAt: number;
54
- hostTimeoutMs: number;
55
- }): Promise<AskSelectedAckOutcome>;
56
- }
57
- /**
58
- * Derive an explicit `providerSupportsTokenCostMetrics` capability from the
59
- * active model so unattended negotiation fails closed when token/cost usage
60
- * cannot be accounted for (#606). Callers that omit a model — or whose model is
61
- * configured to suppress streaming usage (`compat.supportsUsageInStreaming:
62
- * false`) — get `false`, which the controller refuses with
63
- * `unsupported_budget_metric`.
64
- */
65
- export declare function modelSupportsTokenCostMetrics(model: Model | undefined): boolean;
66
- /** Minimal surface a skill runtime / ask tool uses to emit a gate and await its answer. */
67
- export interface WorkflowGateEmitter {
68
- /** True only when unattended mode has been negotiated. */
69
- isUnattended(): boolean;
70
- /** Open + emit a gate; resolves with the agent's answer (from workflow_gate_response). */
71
- emitGate(input: OpenGateInput): Promise<unknown>;
72
- /**
73
- * Optional bridge surface (present on {@link UnattendedSessionControlPlane}) that
74
- * lets an in-process extension observe emitted gates and answer them — used by
75
- * the notifications SDK to resolve a real ask gate from a remote reply.
76
- */
77
- onGateEmitted?(listener: (gate: RpcWorkflowGate) => void): () => void;
78
- resolveGate?(response: RpcWorkflowGateResponse): Promise<RpcWorkflowGateResolution>;
79
- resolveGateFromNotification?(response: RpcWorkflowGateResponse, options: NotificationGateResolutionOptions): Promise<RpcWorkflowGateResolution>;
80
- registerGateTerminalController?(controller: WorkflowGateTerminalController): () => void;
81
- listPendingGates?(): RpcWorkflowGate[];
82
- setAckRecoveryParticipant?(participant: AskSelectedAckRecoveryParticipant | null): void;
83
- }
84
- export interface UnattendedSessionOptions {
85
- runId: string;
86
- sessionId?: string;
87
- /** Emit a workflow_gate frame to the transport so the agent receives it. */
88
- emitFrame: (gate: RpcWorkflowGate) => void;
89
- /** Durable gate store; defaults to in-memory. */
90
- store?: GateStore;
91
- /** Audit sink for controller + gate events. */
92
- audit?: (event: UnattendedAuditEvent | {
93
- event: string;
94
- [k: string]: unknown;
95
- }) => void;
96
- abortHooks?: UnattendedAbortHooks;
97
- /** Whether the active provider reports token/cost usage (fail-closed when false/omitted). */
98
- providerSupportsTokenCostMetrics?: boolean;
99
- /** Snapshot live cumulative usage after a dispatch or turn, for budget reconciliation. */
100
- getUsageSnapshot?: () => {
101
- tokens?: number;
102
- costUsd?: number;
103
- };
104
- }
105
- export declare class UnattendedSessionControlPlane implements RpcUnattendedControlPlane, WorkflowGateEmitter {
106
- #private;
107
- private readonly opts;
108
- constructor(opts: UnattendedSessionOptions);
109
- isUnattended(): boolean;
110
- /** Observe every emitted gate (e.g. so an extension can map an ask to its gate_id). */
111
- onGateEmitted(listener: (gate: RpcWorkflowGate) => void): () => void;
112
- get controller(): UnattendedRunController | undefined;
113
- registerGateTerminalController(controller: WorkflowGateTerminalController): () => void;
114
- setAckRecoveryParticipant(participant: AskSelectedAckRecoveryParticipant | null): void;
115
- negotiate(declaration: RpcUnattendedDeclaration): RpcUnattendedAccepted;
116
- preflightCommand(command: RpcCommand): void;
117
- reconcileUsage(phase?: string): void;
118
- resolveGate(response: RpcWorkflowGateResponse): Promise<RpcWorkflowGateResolution>;
119
- resolveGateFromNotification(response: RpcWorkflowGateResponse, options: NotificationGateResolutionOptions): Promise<RpcWorkflowGateResolution>;
120
- startRecoveryOnce(options?: {
121
- participantGraceMs?: number;
122
- }): Promise<void>;
123
- dispose(reason?: string): void;
124
- listPendingGates(): import("../../rpc/rpc-types").RpcWorkflowGate[];
125
- emitGate(input: OpenGateInput): Promise<unknown>;
126
- recover(): Promise<void>;
127
- }
@@ -1,132 +0,0 @@
1
- import type { Settings } from "../config/settings";
2
- /**
3
- * Env marker set by GJC's own programmatic separate-process child spawn sites
4
- * (team workers, harness RPC owners) and carrying the spawning session id.
5
- *
6
- * Presence — not the value — marks a session as GJC-spawned. It is consumed
7
- * (read once, then deleted from the child's own env) at startup so it is
8
- * per-spawn rather than dynastic: a grandchild is marked only if its own spawn
9
- * site marks it, never by inheriting a marked ancestor's environment.
10
- */
11
- export declare const SPAWN_PROVENANCE_ENV = "GJC_SPAWNED_BY_SESSION";
12
- export interface NotificationConfig {
13
- enabled: boolean;
14
- botToken?: string;
15
- chatId?: string;
16
- discord: {
17
- botToken?: string;
18
- channelId?: string;
19
- };
20
- slack: {
21
- botToken?: string;
22
- channelId?: string;
23
- };
24
- redact: boolean;
25
- verbosity: "lean" | "verbose";
26
- /**
27
- * Which sessions may register a notification endpoint. `all` (default)
28
- * preserves historical behavior; `primary` suppresses GJC-spawned children
29
- * (those carrying {@link SPAWN_PROVENANCE_ENV}) unless they explicitly opt in.
30
- */
31
- sessionScope: "all" | "primary";
32
- idleTimeoutMs: number;
33
- rich: {
34
- enabled: boolean;
35
- };
36
- richDraft: {
37
- enabled: boolean;
38
- };
39
- topics: {
40
- /**
41
- * Optional Telegram forum-topic name template with `{repo}`, `{branch}`,
42
- * and `{title}` placeholders. Unset preserves the built-in
43
- * `{repo}/{branch} - {title}` composition (with its title/repo/branch
44
- * fallbacks).
45
- */
46
- nameTemplate?: string;
47
- };
48
- }
49
- /** Read typed config from Settings. */
50
- export declare function getNotificationConfig(settings: Settings): NotificationConfig;
51
- export declare function hasNonBlankValue(value: string | undefined): boolean;
52
- /** Is Telegram configured with usable non-blank boundary credentials? */
53
- export declare function isTelegramConfigured(cfg: NotificationConfig): cfg is NotificationConfig & {
54
- botToken: string;
55
- chatId: string;
56
- };
57
- /** Is global config sufficient for auto-on (enabled + at least one configured adapter)? */
58
- export declare function isGloballyConfigured(cfg: NotificationConfig): boolean;
59
- /**
60
- * Per-run opt-out for completion notifications, honored before settings lookups.
61
- *
62
- * `GJC_NOTIFY=off` (also `0` / `false`, case-insensitive) suppresses the
63
- * completion notification surface for this process only. `config.yml` is
64
- * untouched and child processes inherit the env var, which lets non-interactive
65
- * fleet runs (`gjc -p --no-session`) stay silent even when a user-level/global
66
- * completion notification configuration is enabled.
67
- */
68
- export declare function completionNotifyDisabledByEnv(env: NodeJS.ProcessEnv): boolean;
69
- /** Resolve whether the notifications extension should be registered at SDK startup. */
70
- export declare function shouldRegisterNotificationsExtension(input: {
71
- env: NodeJS.ProcessEnv;
72
- cfg?: NotificationConfig;
73
- /** Task recursion depth; helper/subagent sessions must not spawn remote surfaces. */
74
- taskDepth?: number;
75
- /** Parent subagent id/prefix; present for helper/subagent sessions even when depth is omitted. */
76
- parentTaskPrefix?: string;
77
- /** Role-agent type/name; present for task sessions even if depth metadata is lost. */
78
- currentAgentType?: string;
79
- /**
80
- * True when this session was launched by one of GJC's own programmatic
81
- * separate-process child spawn sites (marked via {@link SPAWN_PROVENANCE_ENV}).
82
- * Under `notifications.sessionScope = "primary"` such children are suppressed
83
- * unless they explicitly opt in, so an interactive parent that fans out work
84
- * does not flood the paired chat with topics for children the user never
85
- * asked for. User-opened sessions (CLI/tmux/headless) never carry the marker.
86
- */
87
- spawnedByGjc?: boolean;
88
- }): boolean;
89
- /**
90
- * Resolve whether THIS session should run notifications.
91
- * Precedence (highest first):
92
- * 1) env.GJC_NOTIFICATIONS === "0" -> false (hard opt-out)
93
- * 2) sessionDisabled === true -> false (local /notify off)
94
- * 3) env.GJC_NOTIFICATIONS === "1" || env.GJC_NOTIFICATIONS_TOKEN present -> true (legacy explicit)
95
- * 4) isGloballyConfigured(cfg) -> true (global auto-on)
96
- * 5) otherwise false
97
- */
98
- export declare function isSessionNotificationsEnabled(input: {
99
- cfg: NotificationConfig;
100
- env: NodeJS.ProcessEnv;
101
- sessionDisabled: boolean;
102
- }): boolean;
103
- /** Mask a bot token for display: first 4 chars + "…" + "(len N)"; "(unset)" when undefined/empty. Never reveal full token. */
104
- export declare function maskToken(token: string | undefined): string;
105
- /** Stable non-reversible fingerprint of a token: sha256 hex, first 12 chars. */
106
- export declare function tokenFingerprint(token: string): string;
107
- /** Short session tag for display, e.g. last 6 chars of sessionId. */
108
- export declare function sessionTag(sessionId: string): string;
109
- export interface RedactableAction {
110
- id: string;
111
- kind: string;
112
- sessionId: string;
113
- question?: string;
114
- options?: string[];
115
- summary?: string;
116
- }
117
- /**
118
- * When redact is true, strip sensitive content for remote delivery:
119
- * - ask: NOT redacted. An ask is an interactive prompt the human must read and
120
- * answer on the remote surface; redacting its question/options would make it
121
- * unanswerable, defeating remote answering. Asks are returned unchanged.
122
- * - idle: summary removed, (no question/options).
123
- * When redact is false, return the action unchanged.
124
- *
125
- * Redaction still applies to streamed content frames (turn_stream, context_update,
126
- * image_attachment) which are suppressed at their emit sites, not here. Explicit
127
- * `telegram_send` file attachments are rejected before the file is read or forwarded.
128
- */
129
- export declare function buildRedactedAction(action: RedactableAction, opts: {
130
- redact: boolean;
131
- sessionTag: string;
132
- }): RedactableAction;
@@ -1,290 +0,0 @@
1
- /**
2
- * gajae-code RPC adapter + single-flight acceptance.
3
- *
4
- * The gajae-code harness is driven via `gjc --mode rpc` (see docs/rpc.md). Acceptance
5
- * is a PROTOCOL FACT, not an echo: a prompt is `accepted` only when the RPC command is
6
- * acked AND the next `agent_start` event arrives after the pre-submit cursor within the
7
- * timeout, with an idle + empty-queue pre-state. Ack alone never means accepted.
8
- *
9
- * The acceptance logic ({@link singleFlightAccept}) is decoupled from the transport via
10
- * the {@link HarnessRpc} interface so it is unit-testable with a fake, while
11
- * {@link GajaeCodeRpc} provides the real `gjc --mode rpc` subprocess implementation
12
- * (exercised by the M10 e2e suite).
13
- */
14
- import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process";
15
- import { randomUUID } from "node:crypto";
16
-
17
- export interface RpcStateSnapshot {
18
- isStreaming: boolean;
19
- steeringQueueDepth: number;
20
- followupQueueDepth: number;
21
- }
22
-
23
- /** Abstract handle to a live gajae-code RPC session. */
24
- export interface HarnessRpc {
25
- getState(): Promise<RpcStateSnapshot>;
26
- /** Send a prompt; resolves with the RPC command id and whether it was acked. Does NOT await agent_start. */
27
- sendPrompt(prompt: string): Promise<{ commandId: string; ack: boolean }>;
28
- /** Monotonic count of events observed so far (the acceptance cursor). */
29
- eventCursor(): number;
30
- /** Resolve when an `agent_start` event arrives strictly after `afterCursor`, else null on timeout. */
31
- waitForAgentStart(afterCursor: number, timeoutMs: number): Promise<{ cursor: number } | null>;
32
- close(): Promise<void>;
33
- /** Subscribe to parsed event frames (non-ready, non-response), fired AFTER the cursor advances. Returns unsubscribe. */
34
- onEventFrame?(listener: (frame: Record<string, unknown>) => void): () => void;
35
- /** Whether the underlying RPC subprocess is still alive. */
36
- isLive?(): boolean;
37
- /** ISO timestamp of the last observed event frame, or null. */
38
- lastFrameAt?(): string | null;
39
- /** Final assistant text from the live session (for review-verdict extraction); null when unavailable. */
40
- getLastAssistantText?(): Promise<string | null>;
41
- }
42
-
43
- export interface AcceptanceResult {
44
- accepted: boolean;
45
- reason: string;
46
- commandId: string | null;
47
- preSubmitCursor: number;
48
- agentStartCursor: number | null;
49
- preSubmitState: RpcStateSnapshot;
50
- }
51
-
52
- /**
53
- * Single-flight acceptance: idle + empty-queue pre-state, ack, then the NEXT
54
- * `agent_start` after the pre-submit cursor within `timeoutMs`.
55
- */
56
- export async function singleFlightAccept(
57
- rpc: HarnessRpc,
58
- prompt: string,
59
- timeoutMs: number,
60
- ): Promise<AcceptanceResult> {
61
- const pre = await rpc.getState();
62
- const preSubmitCursor = rpc.eventCursor();
63
- if (pre.isStreaming || pre.steeringQueueDepth > 0 || pre.followupQueueDepth > 0) {
64
- return {
65
- accepted: false,
66
- reason: "pre-state-not-idle",
67
- commandId: null,
68
- preSubmitCursor,
69
- agentStartCursor: null,
70
- preSubmitState: pre,
71
- };
72
- }
73
- const { commandId, ack } = await rpc.sendPrompt(prompt);
74
- if (!ack) {
75
- return {
76
- accepted: false,
77
- reason: "no-ack",
78
- commandId,
79
- preSubmitCursor,
80
- agentStartCursor: null,
81
- preSubmitState: pre,
82
- };
83
- }
84
- const started = await rpc.waitForAgentStart(preSubmitCursor, timeoutMs);
85
- if (!started) {
86
- return {
87
- accepted: false,
88
- reason: "no-agent-start-within-timeout",
89
- commandId,
90
- preSubmitCursor,
91
- agentStartCursor: null,
92
- preSubmitState: pre,
93
- };
94
- }
95
- return {
96
- accepted: true,
97
- reason: "protocol-ack-single-flight",
98
- commandId,
99
- preSubmitCursor,
100
- agentStartCursor: started.cursor,
101
- preSubmitState: pre,
102
- };
103
- }
104
-
105
- interface PendingResponse {
106
- resolve: (value: Record<string, unknown>) => void;
107
- reject: (error: Error) => void;
108
- }
109
-
110
- /**
111
- * Real adapter: spawns `gjc --mode rpc --session-dir <dir>` and speaks the JSONL
112
- * protocol from docs/rpc.md. Verified end-to-end in the M10 suite.
113
- */
114
- export class GajaeCodeRpc implements HarnessRpc {
115
- #proc: ChildProcessWithoutNullStreams;
116
- #buffer = "";
117
- #cursor = 0;
118
- #pending = new Map<string, PendingResponse>();
119
- #agentStartCursors: number[] = [];
120
- #waiters: {
121
- afterCursor: number;
122
- resolve: (v: { cursor: number } | null) => void;
123
- timer: NodeJS.Timeout;
124
- }[] = [];
125
- #frameListeners: ((frame: Record<string, unknown>) => void)[] = [];
126
- #lastFrameAt: string | null = null;
127
- #alive = true;
128
-
129
- constructor(opts: { sessionDir: string; command?: string[]; cwd?: string; env?: NodeJS.ProcessEnv }) {
130
- const base = opts.command ?? ["gjc", "--mode", "rpc"];
131
- const args = [...base.slice(1), "--session-dir", opts.sessionDir];
132
- this.#proc = spawn(base[0], args, {
133
- cwd: opts.cwd,
134
- env: opts.env ?? process.env,
135
- stdio: ["pipe", "pipe", "pipe"],
136
- }) as ChildProcessWithoutNullStreams;
137
- this.#proc.stdout.setEncoding("utf8");
138
- this.#proc.stdout.on("data", chunk => this.#onData(chunk as string));
139
- this.#proc.on("exit", () => {
140
- this.#alive = false;
141
- });
142
- this.#proc.on("error", () => {
143
- this.#alive = false;
144
- });
145
- }
146
-
147
- #onData(chunk: string): void {
148
- this.#buffer += chunk;
149
- let idx = this.#buffer.indexOf("\n");
150
- while (idx >= 0) {
151
- const line = this.#buffer.slice(0, idx).trim();
152
- this.#buffer = this.#buffer.slice(idx + 1);
153
- if (line) this.#onFrame(line);
154
- idx = this.#buffer.indexOf("\n");
155
- }
156
- }
157
-
158
- #onFrame(line: string): void {
159
- let frame: Record<string, unknown>;
160
- try {
161
- frame = JSON.parse(line) as Record<string, unknown>;
162
- } catch {
163
- return;
164
- }
165
- const type = frame.type;
166
- if (type === "response") {
167
- const id = typeof frame.id === "string" ? frame.id : undefined;
168
- if (id && this.#pending.has(id)) {
169
- const pending = this.#pending.get(id);
170
- this.#pending.delete(id);
171
- pending?.resolve(frame);
172
- }
173
- return;
174
- }
175
- if (type === "ready") return;
176
- // Any other frame is a session/agent event: advance the cursor.
177
- this.#cursor += 1;
178
- this.#lastFrameAt = new Date().toISOString();
179
- // Session events arrive as canonical `event` frames: the agent event type
180
- // lives in `payload.event_type`. Non-event frames keep their flat `type`.
181
- const effectiveType =
182
- type === "event" && frame.payload && typeof frame.payload === "object"
183
- ? (frame.payload as { event_type?: unknown }).event_type
184
- : type;
185
- if (effectiveType === "agent_start") {
186
- const cursor = this.#cursor;
187
- this.#agentStartCursors.push(cursor);
188
- this.#waiters = this.#waiters.filter(w => {
189
- if (cursor > w.afterCursor) {
190
- clearTimeout(w.timer);
191
- w.resolve({ cursor });
192
- return false;
193
- }
194
- return true;
195
- });
196
- }
197
- // Fire-and-forget frame listeners (owner maps + emits). Never await; never let a listener kill the reader.
198
- for (const listener of this.#frameListeners) {
199
- try {
200
- listener(frame);
201
- } catch {
202
- // swallow listener errors
203
- }
204
- }
205
- }
206
-
207
- #send(command: Record<string, unknown>): Promise<Record<string, unknown>> {
208
- const id = randomUUID();
209
- return new Promise((resolve, reject) => {
210
- this.#pending.set(id, { resolve, reject });
211
- this.#proc.stdin.write(`${JSON.stringify({ id, ...command })}\n`, err => {
212
- if (err) {
213
- this.#pending.delete(id);
214
- reject(err);
215
- }
216
- });
217
- });
218
- }
219
-
220
- onEventFrame(listener: (frame: Record<string, unknown>) => void): () => void {
221
- this.#frameListeners.push(listener);
222
- return () => {
223
- this.#frameListeners = this.#frameListeners.filter(l => l !== listener);
224
- };
225
- }
226
-
227
- isLive(): boolean {
228
- return this.#alive;
229
- }
230
-
231
- lastFrameAt(): string | null {
232
- return this.#lastFrameAt;
233
- }
234
-
235
- async getState(): Promise<RpcStateSnapshot> {
236
- const res = await this.#send({ type: "get_state" });
237
- const data = (res.data ?? {}) as Record<string, unknown>;
238
- return {
239
- isStreaming: Boolean(data.isStreaming),
240
- steeringQueueDepth: typeof data.queuedMessageCount === "number" ? data.queuedMessageCount : 0,
241
- followupQueueDepth: 0,
242
- };
243
- }
244
-
245
- async getLastAssistantText(): Promise<string | null> {
246
- const res = await this.#send({ type: "get_last_assistant_text" });
247
- const data = (res.data ?? {}) as Record<string, unknown>;
248
- return typeof data.text === "string" ? data.text : null;
249
- }
250
-
251
- async sendPrompt(prompt: string): Promise<{ commandId: string; ack: boolean }> {
252
- const id = randomUUID();
253
- const ackPromise = new Promise<Record<string, unknown>>((resolve, reject) => {
254
- this.#pending.set(id, { resolve, reject });
255
- this.#proc.stdin.write(`${JSON.stringify({ id, type: "prompt", message: prompt })}\n`, err => {
256
- if (err) {
257
- this.#pending.delete(id);
258
- reject(err);
259
- }
260
- });
261
- });
262
- const res = await ackPromise;
263
- return { commandId: id, ack: res.success === true };
264
- }
265
-
266
- eventCursor(): number {
267
- return this.#cursor;
268
- }
269
-
270
- waitForAgentStart(afterCursor: number, timeoutMs: number): Promise<{ cursor: number } | null> {
271
- const existing = this.#agentStartCursors.find(c => c > afterCursor);
272
- if (existing !== undefined) return Promise.resolve({ cursor: existing });
273
- return new Promise(resolve => {
274
- const timer = setTimeout(() => {
275
- this.#waiters = this.#waiters.filter(w => w.timer !== timer);
276
- resolve(null);
277
- }, timeoutMs);
278
- this.#waiters.push({ afterCursor, resolve, timer });
279
- });
280
- }
281
-
282
- async close(): Promise<void> {
283
- try {
284
- this.#proc.stdin.end();
285
- } catch {
286
- // ignore
287
- }
288
- this.#proc.kill();
289
- }
290
- }
@@ -1,41 +0,0 @@
1
- import * as crypto from "node:crypto";
2
-
3
- export interface BridgeAuthConfig {
4
- token: string;
5
- }
6
-
7
- export interface BridgeBindConfig {
8
- hostname: string;
9
- port: number;
10
- tlsConfigured: boolean;
11
- }
12
-
13
- export function extractBearerToken(authorization: string | null | undefined): string | undefined {
14
- if (!authorization) return undefined;
15
- const trimmed = authorization.trim();
16
- const match = /^Bearer\s+(.+)$/i.exec(trimmed);
17
- const token = match?.[1]?.trim();
18
- return token ? token : undefined;
19
- }
20
-
21
- export function isBridgeTokenAuthorized(authorization: string | null | undefined, config: BridgeAuthConfig): boolean {
22
- const candidate = extractBearerToken(authorization);
23
- if (candidate === undefined) return false;
24
- const candidateBytes = Buffer.from(candidate, "utf8");
25
- const expectedBytes = Buffer.from(config.token, "utf8");
26
- return candidateBytes.length === expectedBytes.length && crypto.timingSafeEqual(candidateBytes, expectedBytes);
27
- }
28
-
29
- export function isLoopbackHost(hostname: string): boolean {
30
- const normalized = hostname.trim().toLowerCase();
31
- return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1" || normalized === "[::1]";
32
- }
33
-
34
- export function assertSafeBridgeBind(config: BridgeBindConfig): void {
35
- if (!config.tlsConfigured) {
36
- throw new Error(
37
- `Refusing to start bridge on ${config.hostname}:${config.port} without TLS configured. ` +
38
- "Set GJC_BRIDGE_TLS_CERT and GJC_BRIDGE_TLS_KEY.",
39
- );
40
- }
41
- }
@@ -1,47 +0,0 @@
1
- import type {
2
- ClientBridge,
3
- ClientBridgePermissionOption,
4
- ClientBridgePermissionOutcome,
5
- ClientBridgePermissionToolCall,
6
- } from "../../session/client-bridge";
7
- import type { UiRequestBroker, UiRequestCancelled, UiRequestResolution } from "../shared/agent-wire/ui-request-broker";
8
-
9
- export interface BridgePermissionRequestPayload {
10
- kind: "permission";
11
- toolCall: ClientBridgePermissionToolCall;
12
- options: ClientBridgePermissionOption[];
13
- }
14
-
15
- export type BridgePermissionBroker = UiRequestBroker<BridgePermissionRequestPayload, ClientBridgePermissionOutcome>;
16
- function isUiRequestCancelled(
17
- resolution: UiRequestResolution<ClientBridgePermissionOutcome>,
18
- ): resolution is UiRequestCancelled {
19
- return "status" in resolution && resolution.status === "cancelled";
20
- }
21
-
22
- function toPermissionOutcome(
23
- resolution: UiRequestResolution<ClientBridgePermissionOutcome>,
24
- ): ClientBridgePermissionOutcome {
25
- if (isUiRequestCancelled(resolution)) {
26
- return { outcome: "cancelled" };
27
- }
28
- return resolution;
29
- }
30
-
31
- export function createBridgeClientBridge(broker: BridgePermissionBroker): ClientBridge {
32
- return {
33
- capabilities: { requestPermission: true },
34
- deferAgentInitiatedTurns: true,
35
- async requestPermission(toolCall, options, signal) {
36
- return toPermissionOutcome(
37
- await broker.request(
38
- { kind: "permission", toolCall, options },
39
- {
40
- correlationId: toolCall.toolCallId,
41
- signal,
42
- },
43
- ),
44
- );
45
- },
46
- };
47
- }