@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,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
- }