@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
@@ -0,0 +1,380 @@
1
+ import type {
2
+ SlackMessageSearchResult,
3
+ SlackPostedMessage,
4
+ SlackProviderClient,
5
+ SlackSocketEnvelope,
6
+ } from "./slack-provider";
7
+
8
+ const SLACK_API = "https://slack.com/api";
9
+ const DEFAULT_RECONNECT_DELAY_MS = 1_000;
10
+ const MAX_RECONNECT_DELAY_MS = 30_000;
11
+ const MAX_RETRY_AFTER_MS = 60_000;
12
+ const MAX_RATE_LIMIT_RETRIES = 1;
13
+
14
+ export type SlackProviderErrorCode = "connection" | "protocol" | "web_api" | "rate_limited";
15
+
16
+ /** A Slack transport failure whose fields are safe to surface without credentials. */
17
+ export class SlackProviderError extends Error {
18
+ readonly retryable: boolean;
19
+
20
+ constructor(
21
+ readonly code: SlackProviderErrorCode,
22
+ readonly operation: string,
23
+ readonly status?: number,
24
+ readonly retryAfterMs?: number,
25
+ /** The server may have accepted the request before its response became unusable. */
26
+ readonly mayHaveBeenAccepted = false,
27
+ ) {
28
+ super(`${operation} failed (${code})`);
29
+ this.name = "SlackProviderError";
30
+ this.retryable = code === "connection" || code === "rate_limited";
31
+ }
32
+ }
33
+
34
+ export interface SlackWebSocket {
35
+ readonly readyState: number;
36
+ onopen: ((event: Event) => void) | null;
37
+ onmessage: ((event: MessageEvent) => void) | null;
38
+ onclose: ((event: CloseEvent) => void) | null;
39
+ onerror: ((event: Event) => void) | null;
40
+ send(data: string): void;
41
+ close(): void;
42
+ }
43
+
44
+ export interface SlackLiveProviderOptions {
45
+ appToken: string;
46
+ botToken: string;
47
+ fetch?: (input: string, init?: RequestInit) => Promise<Response>;
48
+ webSocket?: (url: string) => SlackWebSocket;
49
+ now?: () => number;
50
+ sleep?: (milliseconds: number) => Promise<void>;
51
+ reconnectDelayMs?: number;
52
+ maxRateLimitRetries?: number;
53
+ maxRetryAfterMs?: number;
54
+ activityTimeoutMs?: number;
55
+ }
56
+
57
+ type SlackApiMessage = {
58
+ channel?: unknown;
59
+ ts?: unknown;
60
+ client_msg_id?: unknown;
61
+ };
62
+
63
+ type SlackApiResponse = {
64
+ ok?: unknown;
65
+ url?: unknown;
66
+ channel?: unknown;
67
+ ts?: unknown;
68
+ client_msg_id?: unknown;
69
+ message?: unknown;
70
+ messages?: unknown;
71
+ retry_after?: unknown;
72
+ };
73
+
74
+ function string(value: unknown): string | undefined {
75
+ return typeof value === "string" && value.length > 0 ? value : undefined;
76
+ }
77
+
78
+ function messages(value: unknown): SlackApiMessage[] {
79
+ return Array.isArray(value)
80
+ ? value.filter((item): item is SlackApiMessage => !!item && typeof item === "object")
81
+ : [];
82
+ }
83
+
84
+ function retryAfterMilliseconds(response: Response, body: SlackApiResponse, maximum: number): number {
85
+ const header = Number(response.headers.get("retry-after"));
86
+ const bodyValue = typeof body.retry_after === "number" ? body.retry_after : Number(body.retry_after);
87
+ const seconds = Number.isFinite(header) && header >= 0 ? header : bodyValue;
88
+ return Math.min(Math.max(0, Number.isFinite(seconds) ? seconds * 1_000 : 1_000), maximum);
89
+ }
90
+
91
+ function socketFromGlobal(url: string): SlackWebSocket {
92
+ return new WebSocket(url);
93
+ }
94
+
95
+ /**
96
+ * Production Socket Mode and Web API client. It keeps all connection state in
97
+ * memory and deliberately never maintains a Slack cursor.
98
+ */
99
+ export class SlackLiveProvider implements SlackProviderClient {
100
+ readonly #appToken: string;
101
+ readonly #botToken: string;
102
+ readonly #fetch: (input: string, init?: RequestInit) => Promise<Response>;
103
+ readonly #webSocket: (url: string) => SlackWebSocket;
104
+ readonly #now: () => number;
105
+ readonly #sleep: (milliseconds: number) => Promise<void>;
106
+ readonly #reconnectDelayMs: number;
107
+ readonly #maxRateLimitRetries: number;
108
+ readonly #maxRetryAfterMs: number;
109
+ readonly #activityTimeoutMs: number;
110
+ #socket: SlackWebSocket | undefined;
111
+ readonly #envelopeSockets = new Map<string, SlackWebSocket>();
112
+ #onEnvelope: ((envelope: SlackSocketEnvelope) => void | Promise<void>) | undefined;
113
+ #lastActivityAt: number | undefined;
114
+ #callbackHealthy = true;
115
+ #deliverySequence = 0;
116
+ #lastCallbackFailure = 0;
117
+ #stopped = true;
118
+ get transportHealthy(): boolean {
119
+ const socket = this.#socket;
120
+ if (this.#stopped || !socket || socket.readyState !== 1 || !this.#callbackHealthy) return false;
121
+ if (this.#lastActivityAt === undefined || this.#now() - this.#lastActivityAt <= this.#activityTimeoutMs)
122
+ return true;
123
+ socket.close();
124
+ return false;
125
+ }
126
+ #reconnectPending = false;
127
+ #lifecycleGeneration = 0;
128
+
129
+ constructor(options: SlackLiveProviderOptions) {
130
+ this.#appToken = options.appToken;
131
+ this.#botToken = options.botToken;
132
+ this.#fetch = options.fetch ?? fetch;
133
+ this.#webSocket = options.webSocket ?? socketFromGlobal;
134
+ this.#now = options.now ?? Date.now;
135
+ this.#sleep =
136
+ options.sleep ?? (async milliseconds => await new Promise<void>(resolve => setTimeout(resolve, milliseconds)));
137
+ this.#reconnectDelayMs = Math.max(0, options.reconnectDelayMs ?? DEFAULT_RECONNECT_DELAY_MS);
138
+ this.#maxRateLimitRetries = Math.max(0, options.maxRateLimitRetries ?? MAX_RATE_LIMIT_RETRIES);
139
+ this.#maxRetryAfterMs = Math.max(0, options.maxRetryAfterMs ?? MAX_RETRY_AFTER_MS);
140
+ this.#activityTimeoutMs = Math.max(1, options.activityTimeoutMs ?? 60_000);
141
+ }
142
+
143
+ async start(onEnvelope: (envelope: SlackSocketEnvelope) => void | Promise<void>): Promise<void> {
144
+ this.#lifecycleGeneration++;
145
+ this.#onEnvelope = onEnvelope;
146
+ this.#stopped = false;
147
+ this.#callbackHealthy = true;
148
+ this.#lastActivityAt = undefined;
149
+ this.#deliverySequence = 0;
150
+ this.#lastCallbackFailure = 0;
151
+ await this.#connect();
152
+ }
153
+
154
+ async stop(): Promise<void> {
155
+ this.#lifecycleGeneration++;
156
+ this.#stopped = true;
157
+ this.#onEnvelope = undefined;
158
+ this.#socket?.close();
159
+ this.#envelopeSockets.clear();
160
+ this.#socket = undefined;
161
+ this.#lastActivityAt = undefined;
162
+ this.#callbackHealthy = false;
163
+ this.#lastCallbackFailure = 0;
164
+ }
165
+
166
+ async ack(envelopeId: string): Promise<void> {
167
+ const socket = this.#envelopeSockets.get(envelopeId) ?? this.#socket;
168
+ if (!envelopeId || !socket || socket.readyState !== 1) {
169
+ throw new SlackProviderError("connection", "socket_ack");
170
+ }
171
+ socket.send(JSON.stringify({ envelope_id: envelopeId }));
172
+ this.#envelopeSockets.delete(envelopeId);
173
+ }
174
+
175
+ async postMessage(input: {
176
+ channel: string;
177
+ text: string;
178
+ threadTs?: string;
179
+ clientMsgId: string;
180
+ }): Promise<SlackPostedMessage> {
181
+ const response = await this.#api("chat.postMessage", {
182
+ channel: input.channel,
183
+ text: input.text,
184
+ thread_ts: input.threadTs,
185
+ client_msg_id: input.clientMsgId,
186
+ });
187
+ const message = this.#message(response);
188
+ // A successful HTTP response without a usable receipt can still represent a
189
+ // remote acceptance. The daemon must reconcile by client_msg_id before retrying.
190
+ if (!message) throw new SlackProviderError("protocol", "chat.postMessage", undefined, undefined, true);
191
+ return message;
192
+ }
193
+
194
+ async findMessageByClientMsgId(input: {
195
+ channel: string;
196
+ clientMsgId: string;
197
+ threadTs?: string;
198
+ }): Promise<SlackMessageSearchResult | null> {
199
+ const response = await this.#api("conversations.history", { channel: input.channel });
200
+ const fromHistory = this.#findMessage(response, input.clientMsgId, input.channel);
201
+ if (fromHistory || !input.threadTs) return fromHistory;
202
+ const replies = await this.#api("conversations.replies", { channel: input.channel, ts: input.threadTs });
203
+ return this.#findMessage(replies, input.clientMsgId, input.channel);
204
+ }
205
+
206
+ async #connect(generation = this.#lifecycleGeneration): Promise<void> {
207
+ const opened = await this.#openSocketUrl();
208
+ if (this.#stopped || generation !== this.#lifecycleGeneration) return;
209
+ await new Promise<void>((resolve, reject) => {
210
+ const socket = this.#webSocket(opened);
211
+ let openedConnection = false;
212
+ this.#socket = socket;
213
+ socket.onopen = () => {
214
+ openedConnection = true;
215
+ this.#lastActivityAt = this.#now();
216
+ this.#callbackHealthy = true;
217
+ this.#lastCallbackFailure = 0;
218
+ resolve();
219
+ };
220
+ socket.onmessage = event => this.#receive(socket, event.data);
221
+ socket.onerror = () => {
222
+ if (!openedConnection) {
223
+ reject(new SlackProviderError("connection", "socket_connect"));
224
+ return;
225
+ }
226
+ this.#callbackHealthy = false;
227
+ socket.close();
228
+ };
229
+ socket.onclose = () => {
230
+ if (this.#socket === socket) this.#socket = undefined;
231
+ if (!openedConnection) {
232
+ reject(new SlackProviderError("connection", "socket_connect"));
233
+ return;
234
+ }
235
+ if (!this.#stopped) void this.#reconnect();
236
+ };
237
+ });
238
+ }
239
+
240
+ async #reconnect(): Promise<void> {
241
+ if (this.#reconnectPending || this.#stopped) return;
242
+ this.#reconnectPending = true;
243
+ const generation = this.#lifecycleGeneration;
244
+ let failures = 0;
245
+ try {
246
+ while (!this.#stopped && generation === this.#lifecycleGeneration) {
247
+ const delay = Math.min(MAX_RECONNECT_DELAY_MS, this.#reconnectDelay(failures));
248
+ await this.#sleep(delay);
249
+ if (this.#stopped || generation !== this.#lifecycleGeneration) return;
250
+ try {
251
+ await this.#connect(generation);
252
+ return;
253
+ } catch {
254
+ // A dropped replacement connection may have accepted the open request.
255
+ // Keep retrying for this worker's lifetime with a bounded delay.
256
+ failures++;
257
+ }
258
+ }
259
+ } finally {
260
+ this.#reconnectPending = false;
261
+ }
262
+ }
263
+ #reconnectDelay(failures: number): number {
264
+ return Math.max(1, this.#reconnectDelayMs * 2 ** Math.min(failures, 30));
265
+ }
266
+
267
+ #receive(socket: SlackWebSocket, data: unknown): void {
268
+ if (typeof data !== "string") return;
269
+ try {
270
+ const decoded: unknown = JSON.parse(data);
271
+ if (!decoded || typeof decoded !== "object") return;
272
+ this.#lastActivityAt = this.#now();
273
+ const candidate = decoded as { envelope_id?: unknown; payload?: unknown };
274
+ const envelopeId = string(candidate.envelope_id);
275
+ if (!envelopeId) return;
276
+ this.#envelopeSockets.set(envelopeId, socket);
277
+ const sequence = ++this.#deliverySequence;
278
+ void this.#deliverEnvelope(socket, sequence, { envelope_id: envelopeId, payload: candidate.payload });
279
+ } catch {
280
+ // Socket Mode can safely ignore malformed frames; Slack redelivers unacknowledged envelopes.
281
+ }
282
+ }
283
+ async #deliverEnvelope(socket: SlackWebSocket, sequence: number, envelope: SlackSocketEnvelope): Promise<void> {
284
+ try {
285
+ await this.#onEnvelope?.(envelope);
286
+ if (this.#socket === socket && sequence > this.#lastCallbackFailure) this.#callbackHealthy = true;
287
+ } catch {
288
+ if (this.#socket !== socket) return;
289
+ // Callback failures are transport failures: retain the unhealthy state until a newer valid delivery or reconnect.
290
+ this.#lastCallbackFailure = sequence;
291
+ this.#callbackHealthy = false;
292
+ }
293
+ }
294
+
295
+ async #openSocketUrl(): Promise<string> {
296
+ const response = await this.#request("apps.connections.open", this.#appToken, {});
297
+ const url = string(response.url);
298
+ if (!url) throw new SlackProviderError("protocol", "apps.connections.open");
299
+ return url;
300
+ }
301
+
302
+ async #api(operation: string, body: Record<string, string | undefined>): Promise<SlackApiResponse> {
303
+ const result = await this.#request(operation, this.#botToken, body, true);
304
+ if (result.ok === true) return result;
305
+ throw new SlackProviderError("web_api", operation);
306
+ }
307
+
308
+ async #request(
309
+ operation: string,
310
+ token: string,
311
+ body: Record<string, string | undefined>,
312
+ retryRateLimit = false,
313
+ ): Promise<SlackApiResponse> {
314
+ for (let attempt = 0; ; attempt++) {
315
+ let response: Response;
316
+ try {
317
+ response = await this.#fetch(`${SLACK_API}/${operation}`, {
318
+ method: "POST",
319
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json; charset=utf-8" },
320
+ body: JSON.stringify(body),
321
+ });
322
+ } catch {
323
+ throw new SlackProviderError("connection", operation);
324
+ }
325
+ let parsed: unknown;
326
+ try {
327
+ parsed = await response.json();
328
+ } catch {
329
+ throw new SlackProviderError(
330
+ "protocol",
331
+ operation,
332
+ response.status,
333
+ undefined,
334
+ operation === "chat.postMessage" && response.ok,
335
+ );
336
+ }
337
+ const result = parsed && typeof parsed === "object" ? (parsed as SlackApiResponse) : {};
338
+ if (response.status !== 429) {
339
+ if (!response.ok) throw new SlackProviderError("web_api", operation, response.status);
340
+ return result;
341
+ }
342
+ const retryAfterMs = retryAfterMilliseconds(response, result, this.#maxRetryAfterMs);
343
+ if (!retryRateLimit || attempt >= this.#maxRateLimitRetries) {
344
+ throw new SlackProviderError("rate_limited", operation, response.status, retryAfterMs);
345
+ }
346
+ const startedAt = this.#now();
347
+ await this.#sleep(retryAfterMs);
348
+ if (this.#now() - startedAt > this.#maxRetryAfterMs) {
349
+ throw new SlackProviderError("rate_limited", operation, response.status, retryAfterMs);
350
+ }
351
+ }
352
+ }
353
+
354
+ #message(response: SlackApiResponse): SlackPostedMessage | undefined {
355
+ const direct: SlackApiMessage = {
356
+ channel: response.channel,
357
+ ts: response.ts,
358
+ client_msg_id: response.client_msg_id,
359
+ };
360
+ const nested = messages(response.message ? [response.message] : response.messages)[0];
361
+ const candidate = string(direct.channel) && string(direct.ts) ? direct : nested;
362
+ const channel = string(candidate?.channel);
363
+ const ts = string(candidate?.ts);
364
+ return channel && ts ? { channel, ts, client_msg_id: string(candidate.client_msg_id) } : undefined;
365
+ }
366
+
367
+ #findMessage(
368
+ response: SlackApiResponse,
369
+ clientMsgId: string,
370
+ requestedChannel: string,
371
+ ): SlackMessageSearchResult | null {
372
+ for (const candidate of messages(response.messages)) {
373
+ const ts = string(candidate.ts);
374
+ if (ts && string(candidate.client_msg_id) === clientMsgId) {
375
+ return { channel: string(candidate.channel) ?? requestedChannel, ts, client_msg_id: clientMsgId };
376
+ }
377
+ }
378
+ return null;
379
+ }
380
+ }
@@ -0,0 +1,76 @@
1
+ export interface SlackSocketEnvelope {
2
+ envelope_id: string;
3
+ payload: unknown;
4
+ }
5
+
6
+ export interface SlackPostedMessage {
7
+ channel: string;
8
+ ts: string;
9
+ client_msg_id?: string;
10
+ }
11
+
12
+ export interface SlackMessageSearchResult {
13
+ channel: string;
14
+ ts: string;
15
+ client_msg_id?: string;
16
+ }
17
+
18
+ /** Minimal Socket Mode + Web API seam. Implementations may wrap the official Slack SDK. */
19
+ export interface SlackProviderClient {
20
+ start(onEnvelope: (envelope: SlackSocketEnvelope) => void | Promise<void>): Promise<void>;
21
+ stop?(): Promise<void>;
22
+ ack(envelopeId: string): Promise<void>;
23
+ postMessage(input: {
24
+ channel: string;
25
+ text: string;
26
+ threadTs?: string;
27
+ clientMsgId: string;
28
+ }): Promise<SlackPostedMessage>;
29
+ findMessageByClientMsgId?(input: {
30
+ channel: string;
31
+ clientMsgId: string;
32
+ threadTs?: string;
33
+ }): Promise<SlackMessageSearchResult | null>;
34
+ readonly transportHealthy?: boolean;
35
+ }
36
+
37
+ /**
38
+ * Transport wrapper deliberately limited to Slack SDK operations. Keeping it injectable
39
+ * makes Socket Mode acknowledgement and Web API failure cases deterministic in tests.
40
+ */
41
+ export class SlackProvider {
42
+ constructor(private readonly client: SlackProviderClient) {}
43
+
44
+ async start(onEnvelope: (envelope: SlackSocketEnvelope) => void | Promise<void>): Promise<void> {
45
+ await this.client.start(onEnvelope);
46
+ }
47
+
48
+ get transportHealthy(): boolean {
49
+ return this.client.transportHealthy ?? true;
50
+ }
51
+
52
+ async stop(): Promise<void> {
53
+ await this.client.stop?.();
54
+ }
55
+
56
+ async ack(envelopeId: string): Promise<void> {
57
+ await this.client.ack(envelopeId);
58
+ }
59
+
60
+ async postMessage(input: {
61
+ channel: string;
62
+ text: string;
63
+ threadTs?: string;
64
+ clientMsgId: string;
65
+ }): Promise<SlackPostedMessage> {
66
+ return await this.client.postMessage(input);
67
+ }
68
+
69
+ async findMessageByClientMsgId(input: {
70
+ channel: string;
71
+ clientMsgId: string;
72
+ threadTs?: string;
73
+ }): Promise<SlackMessageSearchResult | null> {
74
+ return (await this.client.findMessageByClientMsgId?.(input)) ?? null;
75
+ }
76
+ }
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env bun
2
2
  /**
3
- * Reference CLI for the notifications SDK Telegram client.
3
+ * Reference CLI for the Gajae-Code SDK Telegram client.
4
4
  *
5
5
  * Bridges a running GJC session's notification endpoint to a Telegram bot so you
6
6
  * can answer asks / see idle pings from your phone — no RPC mode required. This
7
- * is an EXAMPLE/template (the SDK contract is in `docs/notifications-sdk.md`);
7
+ * is an EXAMPLE/template (the SDK contract is in `docs/sdk.md`);
8
8
  * Discord/Slack clients are written the same way.
9
9
  *
10
10
  * Usage:
11
- * bun run packages/coding-agent/src/notifications/telegram-cli.ts \
11
+ * bun run packages/coding-agent/src/sdk/bus/telegram-cli.ts \
12
12
  * --bot-token <token> [--chat-id <id>] [--endpoint-file <path> | --session-id <id>] [--repo <dir>]
13
13
  *
14
14
  * Env fallbacks: GJC_TG_BOT_TOKEN, GJC_TG_CHAT_ID.
15
15
  * If --chat-id is omitted it is auto-resolved from getUpdates (message the bot once).
16
16
  * If neither --endpoint-file nor --session-id is given, the newest endpoint file
17
- * under <repo>/.gjc/state/notifications/ is used.
17
+ * under <repo>/.gjc/state/sdk/ is used.
18
18
  */
19
19
 
20
20
  import * as fs from "node:fs";
@@ -79,7 +79,7 @@ function printHelpAndExit(): never {
79
79
  " --bot-token <token> Telegram bot token (or env GJC_TG_BOT_TOKEN)",
80
80
  " --chat-id <id> Target chat id (or env GJC_TG_CHAT_ID; auto-resolved if omitted)",
81
81
  " --endpoint-file <path> Session endpoint discovery file",
82
- " --session-id <id> Resolve <repo>/.gjc/state/notifications/<id>.json",
82
+ " --session-id <id> Resolve <repo>/.gjc/state/sdk/<id>.json",
83
83
  " --repo <dir> Repo root for endpoint discovery (default: cwd)",
84
84
  " --api-base <url> Telegram API base (default: https://api.telegram.org)",
85
85
  " --force Bypass active daemon guard (debug only; may cause Telegram 409 conflicts)",
@@ -91,7 +91,7 @@ function printHelpAndExit(): never {
91
91
 
92
92
  /** Find the most recently modified endpoint discovery file under the repo. */
93
93
  function findLatestEndpoint(repo: string): string | undefined {
94
- const dir = path.join(repo, ".gjc", "state", "notifications");
94
+ const dir = path.join(repo, ".gjc", "state", "sdk");
95
95
  let entries: string[];
96
96
  try {
97
97
  entries = fs.readdirSync(dir).filter(f => f.endsWith(".json"));
@@ -166,11 +166,11 @@ async function main(): Promise<void> {
166
166
 
167
167
  const endpointFile =
168
168
  args.endpointFile ??
169
- (args.sessionId ? path.join(args.repo, ".gjc", "state", "notifications", `${args.sessionId}.json`) : undefined) ??
169
+ (args.sessionId ? path.join(args.repo, ".gjc", "state", "sdk", `${args.sessionId}.json`) : undefined) ??
170
170
  findLatestEndpoint(args.repo);
171
171
  if (!endpointFile || !fs.existsSync(endpointFile)) {
172
172
  process.stderr.write(
173
- `error: no endpoint file found (looked under ${args.repo}/.gjc/state/notifications). Start a session with GJC_NOTIFICATIONS=1 first.\n`,
173
+ `error: no endpoint file found (looked under ${args.repo}/.gjc/state/sdk). Start a session with GJC_NOTIFICATIONS=1 first.\n`,
174
174
  );
175
175
  process.exit(2);
176
176
  }