@gajae-code/coding-agent 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/CHANGELOG.md +70 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
  54. package/dist/types/modes/components/model-selector.d.ts +1 -0
  55. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  56. package/dist/types/modes/components/pet-capability.d.ts +37 -0
  57. package/dist/types/modes/components/pet-selector.d.ts +1 -1
  58. package/dist/types/modes/components/settings-selector.d.ts +15 -4
  59. package/dist/types/modes/components/welcome.d.ts +1 -1
  60. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  61. package/dist/types/modes/index.d.ts +0 -4
  62. package/dist/types/modes/interactive-mode.d.ts +5 -1
  63. package/dist/types/modes/runtime-init.d.ts +2 -2
  64. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  65. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  66. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  67. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  68. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  69. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  72. package/dist/types/modes/types.d.ts +16 -1
  73. package/dist/types/runtime-mcp/client.d.ts +2 -0
  74. package/dist/types/runtime-mcp/config.d.ts +5 -1
  75. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  76. package/dist/types/runtime-mcp/types.d.ts +4 -0
  77. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  78. package/dist/types/sdk/acp/index.d.ts +2 -0
  79. package/dist/types/sdk/broker/broker.d.ts +53 -0
  80. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  81. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  82. package/dist/types/sdk/broker/identity.d.ts +3 -0
  83. package/dist/types/sdk/broker/index.d.ts +8 -0
  84. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  85. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  86. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  87. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  88. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  89. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  90. package/dist/types/sdk/broker/transport.d.ts +9 -0
  91. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  92. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  93. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  94. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  95. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  96. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  97. package/dist/types/sdk/bus/config.d.ts +274 -0
  98. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  99. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  100. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  101. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  102. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  103. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  104. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  105. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  107. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  108. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  109. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  110. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  111. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  112. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  113. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  114. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  115. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  118. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  119. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  121. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  122. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  123. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  124. package/dist/types/sdk/cli/index.d.ts +1 -0
  125. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  126. package/dist/types/sdk/client/client.d.ts +1 -0
  127. package/dist/types/sdk/client/discovery.d.ts +27 -0
  128. package/dist/types/sdk/client/index.d.ts +2 -0
  129. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  130. package/dist/types/sdk/host/control/index.d.ts +2 -0
  131. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  132. package/dist/types/sdk/host/events.d.ts +35 -0
  133. package/dist/types/sdk/host/host.d.ts +35 -0
  134. package/dist/types/sdk/host/index.d.ts +4 -0
  135. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  136. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  137. package/dist/types/sdk/host/query/index.d.ts +3 -0
  138. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  139. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  140. package/dist/types/sdk/host/types.d.ts +32 -0
  141. package/dist/types/sdk/index.d.ts +6 -0
  142. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  143. package/dist/types/sdk/mcp/index.d.ts +1 -0
  144. package/dist/types/sdk/mcp/server.d.ts +37 -0
  145. package/dist/types/sdk/models.d.ts +44 -0
  146. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  147. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  148. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  149. package/dist/types/sdk/startup-capability.d.ts +50 -0
  150. package/dist/types/session/agent-session.d.ts +114 -21
  151. package/dist/types/session/default-model-selection.d.ts +25 -0
  152. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  153. package/dist/types/session/session-manager.d.ts +58 -1
  154. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  155. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  156. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  157. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  158. package/dist/types/tools/browser/launch.d.ts +22 -0
  159. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  160. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  161. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  162. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  163. package/dist/types/tools/browser/registry.d.ts +19 -0
  164. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  165. package/dist/types/tools/index.d.ts +8 -8
  166. package/package.json +34 -13
  167. package/scripts/build-sdk-package-smoke.ts +94 -0
  168. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  169. package/scripts/compile-args.ts +4 -2
  170. package/scripts/g005-daemon-smoke.ts +4 -5
  171. package/scripts/g011-daemon-path-smoke.ts +5 -5
  172. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  173. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  174. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  175. package/scripts/manifest-schema.ts +124 -0
  176. package/scripts/run-test-manifest.ts +153 -0
  177. package/scripts/run-threat-model-check.ts +157 -0
  178. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  179. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  180. package/src/append-only-mode.ts +1 -1
  181. package/src/cli/args.ts +43 -12
  182. package/src/cli/auth-gateway-cli.ts +2 -2
  183. package/src/cli/config-cli.ts +2 -1
  184. package/src/cli/daemon-cli.ts +63 -14
  185. package/src/cli/list-models.ts +1 -1
  186. package/src/cli/notify-cli.ts +288 -286
  187. package/src/cli.ts +21 -2
  188. package/src/commands/daemon.ts +50 -6
  189. package/src/commands/harness.ts +93 -36
  190. package/src/commands/launch.ts +5 -2
  191. package/src/commands/mcp-serve.ts +19 -12
  192. package/src/commands/notify.ts +36 -3
  193. package/src/commands/sdk.ts +426 -0
  194. package/src/commit/agentic/agent.ts +1 -0
  195. package/src/config/atomic-yaml-patch.ts +423 -0
  196. package/src/config/model-profile-activation.ts +240 -89
  197. package/src/config/model-profiles.ts +37 -34
  198. package/src/config/model-registry.ts +51 -26
  199. package/src/config/model-resolver.ts +138 -51
  200. package/src/config/model-selector-value.ts +50 -0
  201. package/src/config/models-config-schema.ts +14 -21
  202. package/src/config/settings-schema.ts +128 -10
  203. package/src/config/settings.ts +1120 -158
  204. package/src/coordinator-mcp/model-preset.ts +74 -20
  205. package/src/coordinator-mcp/server.ts +1597 -3052
  206. package/src/daemon/builtin.ts +8 -5
  207. package/src/daemon/control-types.ts +1 -1
  208. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  209. package/src/discovery/mcp-json.ts +327 -20
  210. package/src/extensibility/custom-tools/types.ts +1 -1
  211. package/src/extensibility/extensions/compact-handler.ts +3 -3
  212. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  213. package/src/extensibility/extensions/loader.ts +69 -5
  214. package/src/extensibility/extensions/runner.ts +112 -4
  215. package/src/extensibility/extensions/types.ts +176 -17
  216. package/src/extensibility/hooks/types.ts +1 -1
  217. package/src/extensibility/slash-commands.ts +3 -3
  218. package/src/gjc-runtime/launch-tmux.ts +170 -86
  219. package/src/gjc-runtime/psmux-detect.ts +82 -4
  220. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  221. package/src/gjc-runtime/team-runtime.ts +54 -35
  222. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  223. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
  224. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  225. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  226. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  227. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  228. package/src/harness-control-plane/operate.ts +9 -9
  229. package/src/harness-control-plane/owner.ts +283 -39
  230. package/src/harness-control-plane/receipts.ts +0 -1
  231. package/src/harness-control-plane/sdk-transport.ts +395 -0
  232. package/src/harness-control-plane/session-transport.ts +94 -0
  233. package/src/harness-control-plane/types.ts +1 -1
  234. package/src/internal-urls/docs-index.generated.ts +36 -37
  235. package/src/lsp/client.ts +42 -6
  236. package/src/lsp/index.ts +2 -2
  237. package/src/main.ts +299 -204
  238. package/src/modes/DESIGN.md +258 -0
  239. package/src/modes/acp/acp-agent.ts +1228 -2612
  240. package/src/modes/acp/acp-client-bridge.ts +2 -20
  241. package/src/modes/acp/acp-event-mapper.ts +18 -2
  242. package/src/modes/acp/acp-mode.ts +8 -36
  243. package/src/modes/acp/permission-mode.ts +25 -0
  244. package/src/modes/acp/startup-options.ts +6 -0
  245. package/src/modes/components/agent-dashboard.ts +37 -17
  246. package/src/modes/components/custom-editor.ts +1 -0
  247. package/src/modes/components/gajae-pet-widget.ts +169 -20
  248. package/src/modes/components/model-selector.ts +93 -35
  249. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  250. package/src/modes/components/pet-capability.ts +115 -0
  251. package/src/modes/components/pet-selector.ts +4 -6
  252. package/src/modes/components/settings-selector.ts +86 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +1 -2
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +357 -12
  257. package/src/modes/controllers/input-controller.ts +43 -13
  258. package/src/modes/controllers/selector-controller.ts +671 -44
  259. package/src/modes/index.ts +0 -22
  260. package/src/modes/interactive-mode.ts +108 -24
  261. package/src/modes/runtime-init.ts +298 -6
  262. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  263. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  264. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  265. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  266. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  267. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  268. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  269. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  270. package/src/modes/types.ts +16 -1
  271. package/src/runtime-mcp/client.ts +94 -19
  272. package/src/runtime-mcp/config.ts +27 -15
  273. package/src/runtime-mcp/manager.ts +343 -105
  274. package/src/runtime-mcp/oauth-flow.ts +42 -12
  275. package/src/runtime-mcp/transports/http.ts +49 -19
  276. package/src/runtime-mcp/transports/stdio.ts +47 -28
  277. package/src/runtime-mcp/types.ts +10 -0
  278. package/src/sdk/acp/adapter.ts +418 -0
  279. package/src/sdk/acp/index.ts +2 -0
  280. package/src/sdk/broker/broker.ts +642 -0
  281. package/src/sdk/broker/discovery.ts +94 -0
  282. package/src/sdk/broker/ensure.ts +249 -0
  283. package/src/sdk/broker/identity.ts +42 -0
  284. package/src/sdk/broker/index.ts +8 -0
  285. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  286. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  287. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  288. package/src/sdk/broker/lifecycle.ts +2157 -0
  289. package/src/sdk/broker/process-incarnation.ts +159 -0
  290. package/src/sdk/broker/runtime.ts +164 -0
  291. package/src/sdk/broker/session-index.ts +318 -0
  292. package/src/sdk/broker/state-version.ts +23 -0
  293. package/src/sdk/broker/transport.ts +125 -0
  294. package/src/sdk/bus/chat-command-policy.ts +107 -0
  295. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  296. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  297. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  298. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  299. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  300. package/src/sdk/bus/config.ts +433 -0
  301. package/src/sdk/bus/conversation-store.ts +391 -0
  302. package/src/sdk/bus/discord-conversation.ts +85 -0
  303. package/src/sdk/bus/discord-daemon.ts +2275 -0
  304. package/src/sdk/bus/discord-live-provider.ts +521 -0
  305. package/src/sdk/bus/discord-provider.ts +56 -0
  306. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  307. package/src/sdk/bus/index.ts +3943 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  309. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  310. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  311. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  312. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  313. package/src/sdk/bus/natives-augment.d.ts +38 -0
  314. package/src/sdk/bus/notification-orchestration.ts +535 -0
  315. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  316. package/src/sdk/bus/session-control.ts +333 -0
  317. package/src/sdk/bus/slack-conversation.ts +74 -0
  318. package/src/sdk/bus/slack-daemon.ts +2144 -0
  319. package/src/sdk/bus/slack-live-provider.ts +380 -0
  320. package/src/sdk/bus/slack-provider.ts +76 -0
  321. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  322. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  323. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  324. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  325. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  326. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  327. package/src/sdk/bus/telegram-setup.ts +663 -0
  328. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  329. package/src/sdk/cli/index.ts +1 -0
  330. package/src/sdk/cli/session-cli.ts +275 -0
  331. package/src/sdk/client/client.ts +1 -0
  332. package/src/sdk/client/discovery.ts +108 -0
  333. package/src/sdk/client/index.ts +2 -0
  334. package/src/sdk/host/control/dispatch.ts +367 -0
  335. package/src/sdk/host/control/index.ts +10 -0
  336. package/src/sdk/host/control/operations.ts +63 -0
  337. package/src/sdk/host/events.ts +91 -0
  338. package/src/sdk/host/host.ts +296 -0
  339. package/src/sdk/host/index.ts +4 -0
  340. package/src/sdk/host/query/cursor.ts +189 -0
  341. package/src/sdk/host/query/handlers.ts +533 -0
  342. package/src/sdk/host/query/index.ts +3 -0
  343. package/src/sdk/host/query/revision-store.ts +1126 -0
  344. package/src/sdk/host/reverse-leases.ts +325 -0
  345. package/src/sdk/host/types.ts +29 -0
  346. package/src/sdk/index.ts +13 -0
  347. package/src/sdk/lifecycle-session.ts +39 -0
  348. package/src/sdk/mcp/index.ts +1 -0
  349. package/src/sdk/mcp/server.ts +332 -0
  350. package/src/sdk/models.ts +168 -0
  351. package/src/sdk/protocol/adapter-validation.ts +48 -0
  352. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  353. package/src/sdk/protocol/operation-registry.ts +312 -0
  354. package/src/{sdk.ts → sdk/session.ts} +339 -212
  355. package/src/sdk/startup-capability.ts +189 -0
  356. package/src/session/agent-session.ts +2470 -866
  357. package/src/session/default-model-selection.ts +93 -0
  358. package/src/session/fallback-chain-controller.ts +136 -0
  359. package/src/session/session-manager.ts +447 -13
  360. package/src/session/session-storage.ts +8 -1
  361. package/src/setup/credential-auto-import.ts +290 -35
  362. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  363. package/src/slash-commands/builtin-registry.ts +33 -30
  364. package/src/task/executor.ts +62 -13
  365. package/src/tools/ask-answer-registry.ts +1 -1
  366. package/src/tools/ask.ts +13 -8
  367. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  368. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  369. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  370. package/src/tools/browser/launch.ts +124 -19
  371. package/src/tools/browser/profile-discovery.ts +63 -0
  372. package/src/tools/browser/profile-posture.ts +59 -0
  373. package/src/tools/browser/profile-reuse.ts +102 -0
  374. package/src/tools/browser/profile-warmup.ts +109 -0
  375. package/src/tools/browser/registry.ts +87 -11
  376. package/src/tools/browser/tab-protocol.ts +1 -0
  377. package/src/tools/browser/tab-supervisor.ts +1 -0
  378. package/src/tools/browser/tab-worker.ts +1 -1
  379. package/src/tools/browser.ts +6 -0
  380. package/src/tools/index.ts +8 -8
  381. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  382. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  383. package/src/tools/telegram-send.ts +2 -2
  384. package/vendor/insane-search/MANIFEST.json +2 -1
  385. package/vendor/insane-search/engine/bias_check.py +4 -1
  386. package/vendor/insane-search/engine/phase0.py +26 -1
  387. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  388. package/dist/types/modes/bridge/auth.d.ts +0 -12
  389. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  390. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  391. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  392. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  393. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  394. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  395. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  396. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  397. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  398. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  399. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  400. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  401. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  402. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  403. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  404. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  405. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  406. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  407. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  408. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  409. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  410. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  411. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  412. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  413. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  414. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  415. package/dist/types/notifications/config.d.ts +0 -132
  416. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  417. package/src/modes/bridge/auth.ts +0 -41
  418. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  419. package/src/modes/bridge/bridge-mode.ts +0 -675
  420. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  421. package/src/modes/bridge/event-stream.ts +0 -70
  422. package/src/modes/rpc/host-tools.ts +0 -1
  423. package/src/modes/rpc/host-uris.ts +0 -1
  424. package/src/modes/rpc/rpc-client.ts +0 -1166
  425. package/src/modes/rpc/rpc-mode.ts +0 -1029
  426. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  427. package/src/modes/rpc/rpc-types.ts +0 -637
  428. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  429. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  430. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  431. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  432. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  433. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  434. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  435. package/src/modes/shared/agent-wire/responses.ts +0 -17
  436. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  437. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  438. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  439. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  440. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  441. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  442. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  443. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  444. package/src/notifications/config.ts +0 -219
  445. package/src/notifications/index.ts +0 -1835
  446. package/src/notifications/telegram-daemon-cli.ts +0 -243
  447. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  448. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -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
  }