@gajae-code/coding-agent 0.10.2 → 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 (465) hide show
  1. package/CHANGELOG.md +50 -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/model-selector.d.ts +1 -0
  54. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  55. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  56. package/dist/types/modes/components/welcome.d.ts +1 -1
  57. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  58. package/dist/types/modes/index.d.ts +0 -4
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/runtime-init.d.ts +2 -2
  61. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  62. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  63. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  64. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  65. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  66. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  67. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  68. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  69. package/dist/types/modes/types.d.ts +5 -0
  70. package/dist/types/runtime-mcp/client.d.ts +2 -0
  71. package/dist/types/runtime-mcp/config.d.ts +5 -1
  72. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  73. package/dist/types/runtime-mcp/types.d.ts +4 -0
  74. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  75. package/dist/types/sdk/acp/index.d.ts +2 -0
  76. package/dist/types/sdk/broker/broker.d.ts +53 -0
  77. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  78. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  79. package/dist/types/sdk/broker/identity.d.ts +3 -0
  80. package/dist/types/sdk/broker/index.d.ts +8 -0
  81. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  82. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  83. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  84. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  85. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  86. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  87. package/dist/types/sdk/broker/transport.d.ts +9 -0
  88. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  89. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  90. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  91. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  92. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  93. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  94. package/dist/types/sdk/bus/config.d.ts +274 -0
  95. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  96. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  97. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  98. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  99. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  100. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  101. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  102. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  103. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  104. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  105. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  106. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  107. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  108. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  109. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  110. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  111. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  112. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  113. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  114. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  115. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  118. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  119. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  120. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  121. package/dist/types/sdk/cli/index.d.ts +1 -0
  122. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  123. package/dist/types/sdk/client/client.d.ts +1 -0
  124. package/dist/types/sdk/client/discovery.d.ts +27 -0
  125. package/dist/types/sdk/client/index.d.ts +2 -0
  126. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  127. package/dist/types/sdk/host/control/index.d.ts +2 -0
  128. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  129. package/dist/types/sdk/host/events.d.ts +35 -0
  130. package/dist/types/sdk/host/host.d.ts +35 -0
  131. package/dist/types/sdk/host/index.d.ts +4 -0
  132. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  133. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  134. package/dist/types/sdk/host/query/index.d.ts +3 -0
  135. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  136. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  137. package/dist/types/sdk/host/types.d.ts +32 -0
  138. package/dist/types/sdk/index.d.ts +6 -0
  139. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  140. package/dist/types/sdk/mcp/index.d.ts +1 -0
  141. package/dist/types/sdk/mcp/server.d.ts +37 -0
  142. package/dist/types/sdk/models.d.ts +44 -0
  143. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  144. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  145. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  146. package/dist/types/sdk/startup-capability.d.ts +50 -0
  147. package/dist/types/session/agent-session.d.ts +114 -21
  148. package/dist/types/session/default-model-selection.d.ts +25 -0
  149. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  150. package/dist/types/session/session-manager.d.ts +58 -1
  151. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  152. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  153. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  154. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  155. package/dist/types/tools/browser/launch.d.ts +22 -0
  156. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  157. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  158. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  159. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  160. package/dist/types/tools/browser/registry.d.ts +19 -0
  161. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  162. package/dist/types/tools/index.d.ts +8 -8
  163. package/package.json +34 -13
  164. package/scripts/build-sdk-package-smoke.ts +94 -0
  165. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  166. package/scripts/compile-args.ts +4 -2
  167. package/scripts/g005-daemon-smoke.ts +4 -5
  168. package/scripts/g011-daemon-path-smoke.ts +5 -5
  169. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  170. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  171. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  172. package/scripts/manifest-schema.ts +124 -0
  173. package/scripts/run-test-manifest.ts +153 -0
  174. package/scripts/run-threat-model-check.ts +157 -0
  175. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  176. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  177. package/src/append-only-mode.ts +1 -1
  178. package/src/cli/args.ts +43 -12
  179. package/src/cli/auth-gateway-cli.ts +2 -2
  180. package/src/cli/config-cli.ts +2 -1
  181. package/src/cli/daemon-cli.ts +63 -14
  182. package/src/cli/list-models.ts +1 -1
  183. package/src/cli/notify-cli.ts +288 -286
  184. package/src/cli.ts +21 -2
  185. package/src/commands/daemon.ts +50 -6
  186. package/src/commands/harness.ts +93 -36
  187. package/src/commands/launch.ts +5 -2
  188. package/src/commands/mcp-serve.ts +19 -12
  189. package/src/commands/notify.ts +36 -3
  190. package/src/commands/sdk.ts +426 -0
  191. package/src/commit/agentic/agent.ts +1 -0
  192. package/src/config/atomic-yaml-patch.ts +423 -0
  193. package/src/config/model-profile-activation.ts +240 -89
  194. package/src/config/model-profiles.ts +18 -15
  195. package/src/config/model-registry.ts +51 -26
  196. package/src/config/model-resolver.ts +138 -51
  197. package/src/config/model-selector-value.ts +50 -0
  198. package/src/config/models-config-schema.ts +14 -21
  199. package/src/config/settings-schema.ts +128 -10
  200. package/src/config/settings.ts +1120 -158
  201. package/src/coordinator-mcp/model-preset.ts +74 -20
  202. package/src/coordinator-mcp/server.ts +1597 -3052
  203. package/src/daemon/builtin.ts +8 -5
  204. package/src/daemon/control-types.ts +1 -1
  205. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  206. package/src/discovery/mcp-json.ts +327 -20
  207. package/src/extensibility/custom-tools/types.ts +1 -1
  208. package/src/extensibility/extensions/compact-handler.ts +3 -3
  209. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  210. package/src/extensibility/extensions/loader.ts +69 -5
  211. package/src/extensibility/extensions/runner.ts +112 -4
  212. package/src/extensibility/extensions/types.ts +176 -17
  213. package/src/extensibility/hooks/types.ts +1 -1
  214. package/src/gjc-runtime/launch-tmux.ts +170 -86
  215. package/src/gjc-runtime/psmux-detect.ts +82 -4
  216. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  217. package/src/gjc-runtime/team-runtime.ts +54 -35
  218. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  219. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  220. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  221. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  222. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  223. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  224. package/src/harness-control-plane/operate.ts +9 -9
  225. package/src/harness-control-plane/owner.ts +283 -39
  226. package/src/harness-control-plane/receipts.ts +0 -1
  227. package/src/harness-control-plane/sdk-transport.ts +395 -0
  228. package/src/harness-control-plane/session-transport.ts +94 -0
  229. package/src/harness-control-plane/types.ts +1 -1
  230. package/src/internal-urls/docs-index.generated.ts +34 -35
  231. package/src/lsp/client.ts +42 -6
  232. package/src/lsp/index.ts +2 -2
  233. package/src/main.ts +299 -204
  234. package/src/modes/DESIGN.md +258 -0
  235. package/src/modes/acp/acp-agent.ts +1228 -2612
  236. package/src/modes/acp/acp-client-bridge.ts +2 -20
  237. package/src/modes/acp/acp-event-mapper.ts +18 -2
  238. package/src/modes/acp/acp-mode.ts +8 -36
  239. package/src/modes/acp/permission-mode.ts +25 -0
  240. package/src/modes/acp/startup-options.ts +6 -0
  241. package/src/modes/components/agent-dashboard.ts +37 -17
  242. package/src/modes/components/model-selector.ts +93 -35
  243. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  244. package/src/modes/components/settings-selector.ts +60 -11
  245. package/src/modes/components/welcome.ts +4 -4
  246. package/src/modes/controllers/command-controller.ts +1 -2
  247. package/src/modes/controllers/event-controller.ts +11 -16
  248. package/src/modes/controllers/extension-ui-controller.ts +348 -4
  249. package/src/modes/controllers/selector-controller.ts +674 -36
  250. package/src/modes/index.ts +0 -22
  251. package/src/modes/interactive-mode.ts +59 -20
  252. package/src/modes/runtime-init.ts +298 -6
  253. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  254. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  255. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  256. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  257. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  258. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  259. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  260. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  261. package/src/modes/types.ts +5 -0
  262. package/src/runtime-mcp/client.ts +94 -19
  263. package/src/runtime-mcp/config.ts +27 -15
  264. package/src/runtime-mcp/manager.ts +343 -105
  265. package/src/runtime-mcp/oauth-flow.ts +42 -12
  266. package/src/runtime-mcp/transports/http.ts +49 -19
  267. package/src/runtime-mcp/transports/stdio.ts +47 -28
  268. package/src/runtime-mcp/types.ts +10 -0
  269. package/src/sdk/acp/adapter.ts +418 -0
  270. package/src/sdk/acp/index.ts +2 -0
  271. package/src/sdk/broker/broker.ts +642 -0
  272. package/src/sdk/broker/discovery.ts +94 -0
  273. package/src/sdk/broker/ensure.ts +249 -0
  274. package/src/sdk/broker/identity.ts +42 -0
  275. package/src/sdk/broker/index.ts +8 -0
  276. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  277. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  278. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  279. package/src/sdk/broker/lifecycle.ts +2157 -0
  280. package/src/sdk/broker/process-incarnation.ts +159 -0
  281. package/src/sdk/broker/runtime.ts +164 -0
  282. package/src/sdk/broker/session-index.ts +318 -0
  283. package/src/sdk/broker/state-version.ts +23 -0
  284. package/src/sdk/broker/transport.ts +125 -0
  285. package/src/sdk/bus/chat-command-policy.ts +107 -0
  286. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  287. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  288. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  289. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  290. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  291. package/src/sdk/bus/config.ts +433 -0
  292. package/src/sdk/bus/conversation-store.ts +391 -0
  293. package/src/sdk/bus/discord-conversation.ts +85 -0
  294. package/src/sdk/bus/discord-daemon.ts +2275 -0
  295. package/src/sdk/bus/discord-live-provider.ts +521 -0
  296. package/src/sdk/bus/discord-provider.ts +56 -0
  297. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  298. package/src/sdk/bus/index.ts +3943 -0
  299. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  300. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  301. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  302. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  303. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  304. package/src/sdk/bus/natives-augment.d.ts +38 -0
  305. package/src/sdk/bus/notification-orchestration.ts +535 -0
  306. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  307. package/src/sdk/bus/session-control.ts +333 -0
  308. package/src/sdk/bus/slack-conversation.ts +74 -0
  309. package/src/sdk/bus/slack-daemon.ts +2144 -0
  310. package/src/sdk/bus/slack-live-provider.ts +380 -0
  311. package/src/sdk/bus/slack-provider.ts +76 -0
  312. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  313. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  314. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  315. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  316. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  317. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  318. package/src/sdk/bus/telegram-setup.ts +663 -0
  319. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  320. package/src/sdk/cli/index.ts +1 -0
  321. package/src/sdk/cli/session-cli.ts +275 -0
  322. package/src/sdk/client/client.ts +1 -0
  323. package/src/sdk/client/discovery.ts +108 -0
  324. package/src/sdk/client/index.ts +2 -0
  325. package/src/sdk/host/control/dispatch.ts +367 -0
  326. package/src/sdk/host/control/index.ts +10 -0
  327. package/src/sdk/host/control/operations.ts +63 -0
  328. package/src/sdk/host/events.ts +91 -0
  329. package/src/sdk/host/host.ts +296 -0
  330. package/src/sdk/host/index.ts +4 -0
  331. package/src/sdk/host/query/cursor.ts +189 -0
  332. package/src/sdk/host/query/handlers.ts +533 -0
  333. package/src/sdk/host/query/index.ts +3 -0
  334. package/src/sdk/host/query/revision-store.ts +1126 -0
  335. package/src/sdk/host/reverse-leases.ts +325 -0
  336. package/src/sdk/host/types.ts +29 -0
  337. package/src/sdk/index.ts +13 -0
  338. package/src/sdk/lifecycle-session.ts +39 -0
  339. package/src/sdk/mcp/index.ts +1 -0
  340. package/src/sdk/mcp/server.ts +332 -0
  341. package/src/sdk/models.ts +168 -0
  342. package/src/sdk/protocol/adapter-validation.ts +48 -0
  343. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  344. package/src/sdk/protocol/operation-registry.ts +312 -0
  345. package/src/{sdk.ts → sdk/session.ts} +339 -212
  346. package/src/sdk/startup-capability.ts +189 -0
  347. package/src/session/agent-session.ts +2453 -894
  348. package/src/session/default-model-selection.ts +93 -0
  349. package/src/session/fallback-chain-controller.ts +136 -0
  350. package/src/session/session-manager.ts +438 -11
  351. package/src/session/session-storage.ts +8 -1
  352. package/src/setup/credential-auto-import.ts +290 -35
  353. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  354. package/src/slash-commands/builtin-registry.ts +2 -1
  355. package/src/task/executor.ts +62 -13
  356. package/src/tools/ask-answer-registry.ts +1 -1
  357. package/src/tools/ask.ts +13 -8
  358. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  359. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  360. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  361. package/src/tools/browser/launch.ts +124 -19
  362. package/src/tools/browser/profile-discovery.ts +63 -0
  363. package/src/tools/browser/profile-posture.ts +59 -0
  364. package/src/tools/browser/profile-reuse.ts +102 -0
  365. package/src/tools/browser/profile-warmup.ts +109 -0
  366. package/src/tools/browser/registry.ts +87 -11
  367. package/src/tools/browser/tab-protocol.ts +1 -0
  368. package/src/tools/browser/tab-supervisor.ts +1 -0
  369. package/src/tools/browser/tab-worker.ts +1 -1
  370. package/src/tools/browser.ts +6 -0
  371. package/src/tools/index.ts +8 -8
  372. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  373. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  374. package/src/tools/telegram-send.ts +2 -2
  375. package/vendor/insane-search/MANIFEST.json +2 -1
  376. package/vendor/insane-search/engine/bias_check.py +4 -1
  377. package/vendor/insane-search/engine/phase0.py +26 -1
  378. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  379. package/dist/types/modes/bridge/auth.d.ts +0 -12
  380. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  381. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  382. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  383. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  384. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  385. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  386. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  387. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  388. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  389. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  390. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  391. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  392. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  393. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  394. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  395. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  396. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  397. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  398. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  399. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  400. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  401. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  402. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  403. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  404. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  405. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  406. package/dist/types/notifications/config.d.ts +0 -132
  407. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  408. package/src/modes/bridge/auth.ts +0 -41
  409. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  410. package/src/modes/bridge/bridge-mode.ts +0 -675
  411. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  412. package/src/modes/bridge/event-stream.ts +0 -70
  413. package/src/modes/rpc/host-tools.ts +0 -1
  414. package/src/modes/rpc/host-uris.ts +0 -1
  415. package/src/modes/rpc/rpc-client.ts +0 -1166
  416. package/src/modes/rpc/rpc-mode.ts +0 -1029
  417. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  418. package/src/modes/rpc/rpc-types.ts +0 -637
  419. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  420. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  421. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  422. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  423. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  424. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  425. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  426. package/src/modes/shared/agent-wire/responses.ts +0 -17
  427. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  428. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  429. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  430. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  431. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  432. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  433. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  434. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  435. package/src/notifications/config.ts +0 -219
  436. package/src/notifications/index.ts +0 -1835
  437. package/src/notifications/telegram-daemon-cli.ts +0 -243
  438. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  439. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  440. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  441. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  442. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  443. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  444. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  445. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  446. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  447. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  448. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  453. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  454. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  455. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  456. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  457. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  458. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  459. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  460. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  461. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -1,528 +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 {
20
- RpcCommand,
21
- RpcUnattendedAccepted,
22
- RpcUnattendedDeclaration,
23
- RpcWorkflowGate,
24
- RpcWorkflowGateResolution,
25
- RpcWorkflowGateResponse,
26
- } from "../../rpc/rpc-types";
27
- import type { RpcUnattendedControlPlane } from "./command-dispatch";
28
- import { scopeForRpcCommand } from "./scopes";
29
- import {
30
- type UnattendedAbortHooks,
31
- type UnattendedAuditEvent,
32
- UnattendedRunController,
33
- } from "./unattended-run-controller";
34
- import {
35
- type GateStore,
36
- MemoryGateStore,
37
- type OpenGateInput,
38
- type PersistedAckPolicy,
39
- type PersistedGate,
40
- type PersistedSemanticDisposition,
41
- WorkflowGateBroker,
42
- } from "./workflow-gate-broker";
43
-
44
- export interface WorkflowGateTerminalController {
45
- completeGateInteractions(gateId: string): void | Promise<void>;
46
- cancelGateInteractions(gateId: string, reason: string): void | Promise<void>;
47
- }
48
-
49
- export interface WorkflowGateTerminalEvent {
50
- gateId: string;
51
- kind: "accepted" | "cancelled";
52
- origin?: "rpc" | "bridge" | "other" | "telegram_notification";
53
- reason?: string;
54
- }
55
-
56
- export interface NotificationGateResolutionOptions {
57
- interactionActionId: string;
58
- replyReceiptId: string;
59
- answerJson: string;
60
- idempotencyKey?: string;
61
- requestSelectedAck(input: {
62
- replyReceiptId: string;
63
- actionId: string;
64
- commitKey: string;
65
- daemonDeadlineAt: number;
66
- hostTimeoutMs: number;
67
- }): Promise<AskSelectedAckOutcome>;
68
- resolveClaim(): void;
69
- closeClaimInvalid(reason: string): void;
70
- }
71
-
72
- export interface AskSelectedAckRecoveryParticipant {
73
- requestRecoveredAskSelectedAck(input: {
74
- sessionId: string;
75
- actionId: string;
76
- commitKey: string;
77
- deadlineAt: number;
78
- hostTimeoutMs: number;
79
- }): Promise<AskSelectedAckOutcome>;
80
- }
81
-
82
- /**
83
- * RPC commands that perform agent/tool work and therefore consume one unit of the
84
- * `max_tool_calls` budget. Read-only/control/cancellation commands are wall-time-bounded
85
- * and scope-checked but must NOT charge the tool-call budget (issue 04).
86
- */
87
- const CHARGED_COMMAND_TYPES = new Set<RpcCommand["type"]>(["bash", "prompt", "steer", "follow_up", "abort_and_prompt"]);
88
-
89
- /**
90
- * Derive an explicit `providerSupportsTokenCostMetrics` capability from the
91
- * active model so unattended negotiation fails closed when token/cost usage
92
- * cannot be accounted for (#606). Callers that omit a model — or whose model is
93
- * configured to suppress streaming usage (`compat.supportsUsageInStreaming:
94
- * false`) — get `false`, which the controller refuses with
95
- * `unsupported_budget_metric`.
96
- */
97
- export function modelSupportsTokenCostMetrics(model: Model | undefined): boolean {
98
- if (!model) return false;
99
- const compat = model.compat as { supportsUsageInStreaming?: boolean } | undefined;
100
- return compat?.supportsUsageInStreaming !== false;
101
- }
102
-
103
- /** Minimal surface a skill runtime / ask tool uses to emit a gate and await its answer. */
104
- export interface WorkflowGateEmitter {
105
- /** True only when unattended mode has been negotiated. */
106
- isUnattended(): boolean;
107
- /** Open + emit a gate; resolves with the agent's answer (from workflow_gate_response). */
108
- emitGate(input: OpenGateInput): Promise<unknown>;
109
- /**
110
- * Optional bridge surface (present on {@link UnattendedSessionControlPlane}) that
111
- * lets an in-process extension observe emitted gates and answer them — used by
112
- * the notifications SDK to resolve a real ask gate from a remote reply.
113
- */
114
- onGateEmitted?(listener: (gate: RpcWorkflowGate) => void): () => void;
115
- resolveGate?(response: RpcWorkflowGateResponse): Promise<RpcWorkflowGateResolution>;
116
- resolveGateFromNotification?(
117
- response: RpcWorkflowGateResponse,
118
- options: NotificationGateResolutionOptions,
119
- ): Promise<RpcWorkflowGateResolution>;
120
- registerGateTerminalController?(controller: WorkflowGateTerminalController): () => void;
121
- listPendingGates?(): RpcWorkflowGate[];
122
- setAckRecoveryParticipant?(participant: AskSelectedAckRecoveryParticipant | null): void;
123
- }
124
-
125
- export interface UnattendedSessionOptions {
126
- runId: string;
127
- sessionId?: string;
128
- /** Emit a workflow_gate frame to the transport so the agent receives it. */
129
- emitFrame: (gate: RpcWorkflowGate) => void;
130
- /** Durable gate store; defaults to in-memory. */
131
- store?: GateStore;
132
- /** Audit sink for controller + gate events. */
133
- audit?: (event: UnattendedAuditEvent | { event: string; [k: string]: unknown }) => void;
134
- abortHooks?: UnattendedAbortHooks;
135
- /** Whether the active provider reports token/cost usage (fail-closed when false/omitted). */
136
- providerSupportsTokenCostMetrics?: boolean;
137
- /** Snapshot live cumulative usage after a dispatch or turn, for budget reconciliation. */
138
- getUsageSnapshot?: () => { tokens?: number; costUsd?: number };
139
- }
140
-
141
- export class UnattendedSessionControlPlane implements RpcUnattendedControlPlane, WorkflowGateEmitter {
142
- #controller: UnattendedRunController | undefined;
143
- #broker: WorkflowGateBroker | undefined;
144
- readonly #pending = new Map<string, { resolve: (answer: unknown) => void; reject: (err: Error) => void }>();
145
- readonly #earlyAnswers = new Map<string, unknown>();
146
- readonly #gateListeners = new Set<(gate: RpcWorkflowGate) => void>();
147
- #terminalController: WorkflowGateTerminalController | undefined;
148
- #brokerReady = false;
149
- #recoveryPromise: Promise<void> | undefined;
150
- #disposed = false;
151
- #recoveryParticipant: AskSelectedAckRecoveryParticipant | undefined;
152
- #participantReady = Promise.withResolvers<void>();
153
-
154
- constructor(private readonly opts: UnattendedSessionOptions) {}
155
-
156
- isUnattended(): boolean {
157
- return this.#controller !== undefined;
158
- }
159
-
160
- /** Observe every emitted gate (e.g. so an extension can map an ask to its gate_id). */
161
- onGateEmitted(listener: (gate: RpcWorkflowGate) => void): () => void {
162
- this.#gateListeners.add(listener);
163
- return () => this.#gateListeners.delete(listener);
164
- }
165
-
166
- get controller(): UnattendedRunController | undefined {
167
- return this.#controller;
168
- }
169
-
170
- registerGateTerminalController(controller: WorkflowGateTerminalController): () => void {
171
- if (this.#terminalController && this.#terminalController !== controller) {
172
- throw new Error("a workflow gate terminal controller is already registered");
173
- }
174
- this.#terminalController = controller;
175
- return () => {
176
- if (this.#terminalController === controller) this.#terminalController = undefined;
177
- };
178
- }
179
-
180
- setAckRecoveryParticipant(participant: AskSelectedAckRecoveryParticipant | null): void {
181
- this.#recoveryParticipant = participant ?? undefined;
182
- if (participant) this.#participantReady.resolve();
183
- void this.startRecoveryOnce();
184
- }
185
-
186
- async #completeGateInteractions(gateId: string): Promise<void> {
187
- try {
188
- await this.#terminalController?.completeGateInteractions(gateId);
189
- } catch (error) {
190
- this.opts.audit?.({ event: "gate_interaction_completion_failed", gate_id: gateId, error: String(error) });
191
- }
192
- }
193
-
194
- async #cancelGateInteractions(gateId: string, reason: string): Promise<void> {
195
- try {
196
- await this.#terminalController?.cancelGateInteractions(gateId, reason);
197
- } catch (error) {
198
- this.opts.audit?.({ event: "gate_interaction_cancellation_failed", gate_id: gateId, error: String(error) });
199
- }
200
- }
201
-
202
- negotiate(declaration: RpcUnattendedDeclaration): RpcUnattendedAccepted {
203
- const controller = UnattendedRunController.negotiate(declaration, {
204
- runId: this.opts.runId,
205
- sessionId: this.opts.sessionId,
206
- audit: this.opts.audit,
207
- abortHooks: {
208
- ...this.opts.abortHooks,
209
- // On abort (e.g. wall-time / budget breach) reject any gate still
210
- // awaiting an answer, so emitGate cannot hang forever.
211
- stopWorkflow: async reason => {
212
- await this.opts.abortHooks?.stopWorkflow?.(reason);
213
- this.#rejectAllPending(new Error(`unattended run aborted: ${reason}`));
214
- },
215
- },
216
- providerSupportsTokenCostMetrics: this.opts.providerSupportsTokenCostMetrics,
217
- });
218
- this.#controller = controller;
219
- this.#broker = new WorkflowGateBroker(this.opts.runId, this.opts.store ?? new MemoryGateStore(), {
220
- emit: gate => this.opts.emitFrame(gate),
221
- audit: e => this.opts.audit?.(e),
222
- advance: (gate, answer) => {
223
- const pending = this.#pending.get(gate.gate_id);
224
- if (pending) {
225
- this.#pending.delete(gate.gate_id);
226
- pending.resolve(answer);
227
- return;
228
- }
229
- // A controller may answer synchronously while emitFrame is still on the
230
- // stack. Keep the accepted answer so emitGate can still resolve after
231
- // openGate returns and the caller starts awaiting.
232
- this.#earlyAnswers.set(gate.gate_id, answer);
233
- },
234
- finalizeAccepted: record => this.#finalizeAcceptedGate(record),
235
- });
236
- this.#brokerReady = true;
237
- void this.startRecoveryOnce();
238
-
239
- return {
240
- run_id: this.opts.runId,
241
- actor: controller.actor,
242
- budget: controller.budget,
243
- scopes: [...controller.scopes],
244
- action_allowlist: [...controller.actionAllowlist],
245
- accepted_at: new Date().toISOString(),
246
- };
247
- }
248
-
249
- preflightCommand(command: RpcCommand): void {
250
- if (!this.#controller) return;
251
- const phase = `${command.type} preflight`;
252
- // Always enforce wall-time; only charge the tool-call budget for commands that perform
253
- // agent/tool work (issue 04). Read-only/control/cancellation commands must not consume
254
- // max_tool_calls, but remain wall-time-bounded and scope/action-checked.
255
- if (CHARGED_COMMAND_TYPES.has(command.type)) {
256
- this.#controller.preflightToolCall(phase);
257
- } else {
258
- this.#controller.checkWallTime(phase);
259
- }
260
- if (command.type === "bash") {
261
- this.#controller.authorizeBash(command.command);
262
- return;
263
- }
264
- const scope = scopeForRpcCommand(command.type);
265
- this.#controller.authorizeScope(scope);
266
- this.#controller.authorizeAction(UnattendedRunController.actionClassForScope(scope));
267
- }
268
-
269
- reconcileUsage(phase = "unattended usage reconciliation"): void {
270
- const controller = this.#controller;
271
- if (!controller) return;
272
- controller.checkWallTime(phase);
273
- const snapshot = this.opts.getUsageSnapshot?.();
274
- if (!snapshot) return;
275
- const current = controller.usageSnapshot();
276
- const tokens = snapshot.tokens;
277
- const costUsd = snapshot.costUsd;
278
- controller.reconcile(
279
- {
280
- tokens: tokens !== undefined ? Math.max(0, tokens - current.tokens) : undefined,
281
- costUsd: costUsd !== undefined ? Math.max(0, costUsd - current.costUsd) : undefined,
282
- },
283
- phase,
284
- );
285
- }
286
-
287
- resolveGate(response: RpcWorkflowGateResponse): Promise<RpcWorkflowGateResolution> {
288
- if (this.#disposed) return Promise.reject(new Error("unattended session is disposed"));
289
- if (!this.#broker) {
290
- return Promise.reject(new Error("workflow gates are not available until unattended mode is negotiated"));
291
- }
292
- return this.#broker.resolve(response);
293
- }
294
-
295
- async resolveGateFromNotification(
296
- response: RpcWorkflowGateResponse,
297
- options: NotificationGateResolutionOptions,
298
- ): Promise<RpcWorkflowGateResolution> {
299
- let claimSettled = false;
300
- const resolveClaim = () => {
301
- if (claimSettled) return;
302
- claimSettled = true;
303
- try {
304
- options.resolveClaim();
305
- } catch (error) {
306
- this.opts.audit?.({
307
- event: "notification_claim_resolution_failed",
308
- gate_id: response.gate_id,
309
- error: String(error),
310
- });
311
- }
312
- };
313
- const closeClaimInvalid = (reason: string) => {
314
- if (claimSettled) return;
315
- claimSettled = true;
316
- try {
317
- options.closeClaimInvalid(reason);
318
- } catch (error) {
319
- this.opts.audit?.({
320
- event: "notification_claim_close_failed",
321
- gate_id: response.gate_id,
322
- error: String(error),
323
- });
324
- }
325
- };
326
- if (this.#disposed) {
327
- closeClaimInvalid("unattended_session_disposed");
328
- throw new Error("unattended session is disposed");
329
- }
330
- if (!this.#broker) {
331
- closeClaimInvalid("workflow_gate_unavailable");
332
- throw new Error("workflow gates are not available until unattended mode is negotiated");
333
- }
334
- try {
335
- JSON.parse(options.answerJson);
336
- } catch {
337
- closeClaimInvalid("invalid_structured_answer");
338
- return {
339
- gate_id: response.gate_id,
340
- status: "rejected",
341
- answer_hash: "",
342
- resolved_at: new Date().toISOString(),
343
- error: this.#broker.validationError(response.gate_id, "json_parse", "invalid structured answer"),
344
- };
345
- }
346
- let disposition: PersistedSemanticDisposition;
347
- try {
348
- disposition = this.#broker.classifyDisposition(response.gate_id, response.answer);
349
- } catch (error) {
350
- closeClaimInvalid(error instanceof Error ? error.message : "invalid_answer");
351
- return {
352
- gate_id: response.gate_id,
353
- status: "rejected",
354
- answer_hash: "",
355
- resolved_at: new Date().toISOString(),
356
- error: this.#broker.validationError(
357
- response.gate_id,
358
- "semantic_disposition",
359
- error instanceof Error ? error.message : "invalid answer",
360
- ),
361
- };
362
- }
363
-
364
- const commitKey = `${response.gate_id}:${options.idempotencyKey ?? options.replyReceiptId}`;
365
- const ackPolicy: PersistedAckPolicy =
366
- disposition === "commit"
367
- ? {
368
- kind: "telegram_selected_v1",
369
- commitKey,
370
- actionId: options.interactionActionId,
371
- state: "pending",
372
- updatedAt: new Date().toISOString(),
373
- }
374
- : { kind: "none", reason: "semantic_noncommit" };
375
- let resolution: RpcWorkflowGateResolution;
376
- try {
377
- resolution = await this.#broker.resolve(response, {
378
- resolutionOrigin: { kind: "telegram_notification", interactionActionId: options.interactionActionId },
379
- ackPolicy,
380
- semanticDisposition: disposition,
381
-
382
- beforeAdvance: async () => {
383
- if (ackPolicy.kind === "telegram_selected_v1") {
384
- this.#broker?.updateAckPolicy(response.gate_id, {
385
- ...ackPolicy,
386
- state: "attempt_started",
387
- updatedAt: new Date().toISOString(),
388
- });
389
- let outcome: AskSelectedAckOutcome;
390
- try {
391
- outcome = await options.requestSelectedAck({
392
- replyReceiptId: options.replyReceiptId,
393
- actionId: options.interactionActionId,
394
- commitKey,
395
- daemonDeadlineAt: Date.now() + 8_000,
396
- hostTimeoutMs: 10_000,
397
- });
398
- } catch {
399
- outcome = { status: "unknown", reason: "host_timeout" };
400
- }
401
- this.#broker?.updateAckPolicy(response.gate_id, {
402
- ...ackPolicy,
403
- state: outcome.status,
404
- outcome,
405
- updatedAt: new Date().toISOString(),
406
- });
407
- }
408
- resolveClaim();
409
- },
410
- });
411
- } catch (error) {
412
- closeClaimInvalid(error instanceof Error ? error.message : "invalid_answer");
413
- throw error;
414
- }
415
- if (resolution.status === "accepted") resolveClaim();
416
- else closeClaimInvalid(resolution.error?.code ?? "invalid_answer");
417
- return resolution;
418
- }
419
-
420
- async startRecoveryOnce(options: { participantGraceMs?: number } = {}): Promise<void> {
421
- if (this.#disposed || !this.#brokerReady) return;
422
- if (this.#recoveryPromise) return this.#recoveryPromise;
423
- this.#recoveryPromise = (async () => {
424
- if (!this.#recoveryParticipant) {
425
- const grace = options.participantGraceMs ?? 2_000;
426
- await Promise.race([
427
- this.#participantReady.promise,
428
- new Promise<void>(resolve => setTimeout(resolve, grace)),
429
- ]);
430
- }
431
- if (!this.#disposed) await this.#broker?.recover();
432
- })();
433
- return this.#recoveryPromise;
434
- }
435
-
436
- async #finalizeAcceptedGate(record: PersistedGate): Promise<void> {
437
- const policy = record.ackPolicy;
438
- if (policy?.kind === "telegram_selected_v1" && policy.state === "pending") {
439
- let outcome: AskSelectedAckOutcome;
440
- const participant = this.#recoveryParticipant;
441
- if (!participant || !this.opts.sessionId) {
442
- outcome = { status: "failed", reason: "no_participant" };
443
- } else {
444
- this.#broker?.updateAckPolicy(record.gate.gate_id, {
445
- ...policy,
446
- state: "attempt_started",
447
- updatedAt: new Date().toISOString(),
448
- });
449
- try {
450
- outcome = await participant.requestRecoveredAskSelectedAck({
451
- sessionId: this.opts.sessionId,
452
- actionId: policy.actionId,
453
- commitKey: policy.commitKey,
454
- deadlineAt: Date.now() + 8_000,
455
- hostTimeoutMs: 10_000,
456
- });
457
- } catch {
458
- outcome = { status: "unknown", reason: "host_timeout" };
459
- }
460
- }
461
- this.#broker?.updateAckPolicy(record.gate.gate_id, {
462
- ...policy,
463
- state: outcome.status,
464
- outcome,
465
- updatedAt: new Date().toISOString(),
466
- });
467
- }
468
- if (policy?.kind === "telegram_selected_v1" && policy.state === "attempt_started") {
469
- this.#broker?.updateAckPolicy(record.gate.gate_id, {
470
- ...policy,
471
- state: "unknown",
472
- outcome: { status: "unknown", reason: "shutdown" },
473
- updatedAt: new Date().toISOString(),
474
- });
475
- }
476
- await this.#completeGateInteractions(record.gate.gate_id);
477
- }
478
-
479
- dispose(reason = "session_shutdown"): void {
480
- this.#disposed = true;
481
- for (const gateId of this.#pending.keys()) void this.#cancelGateInteractions(gateId, reason);
482
- this.#rejectAllPending(new Error(`unattended session disposed: ${reason}`));
483
- }
484
-
485
- listPendingGates(): import("../../rpc/rpc-types").RpcWorkflowGate[] {
486
- const store = this.opts.store;
487
- if (!store) return [];
488
- return store
489
- .list()
490
- .filter(record => record.status === "pending")
491
- .map(record => record.gate);
492
- }
493
-
494
- emitGate(input: OpenGateInput): Promise<unknown> {
495
- if (this.#disposed) return Promise.reject(new Error("unattended session is disposed"));
496
- if (!this.#broker) {
497
- return Promise.reject(new Error("cannot emit a workflow gate before unattended mode is negotiated"));
498
- }
499
- const gate = this.#broker.openGate(input);
500
- for (const listener of this.#gateListeners) {
501
- try {
502
- listener(gate);
503
- } catch {
504
- // A misbehaving observer must never break gate emission.
505
- }
506
- }
507
- if (this.#earlyAnswers.has(gate.gate_id)) {
508
- const answer = this.#earlyAnswers.get(gate.gate_id);
509
- this.#earlyAnswers.delete(gate.gate_id);
510
- return Promise.resolve(answer);
511
- }
512
- const { promise, resolve, reject } = Promise.withResolvers<unknown>();
513
- this.#pending.set(gate.gate_id, { resolve, reject });
514
- return promise;
515
- }
516
-
517
- async recover(): Promise<void> {
518
- await this.#broker?.recover();
519
- }
520
-
521
- #rejectAllPending(error: Error): void {
522
- this.#earlyAnswers.clear();
523
- for (const [gateId, pending] of this.#pending) {
524
- this.#pending.delete(gateId);
525
- pending.reject(error);
526
- }
527
- }
528
- }