@gajae-code/coding-agent 0.10.2 → 0.11.0

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