@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,125 @@
1
+ import { createHash, timingSafeEqual } from "node:crypto";
2
+ import type { ServerWebSocket } from "bun";
3
+ import type { Broker } from "./broker";
4
+
5
+ const PROTOCOL_VERSION = 3;
6
+ /** Maximum UTF-8 byte length accepted for a single broker JSON frame. */
7
+ const MAX_BROKER_JSON_FRAME_BYTES = 4 * 1024 * 1024;
8
+
9
+ const BROKER_OPERATIONS = new Set([
10
+ "session.list",
11
+ "session.get_endpoint",
12
+ "session.create",
13
+ "session.fork",
14
+ "session.resume",
15
+ "session.close",
16
+ "session.delete",
17
+ ]);
18
+ type RequestInput = Record<string, unknown>;
19
+ type BrokerRequest = {
20
+ type: "broker_request";
21
+ id?: string;
22
+ operation?: string;
23
+ input?: RequestInput;
24
+ idempotencyKey?: string;
25
+ };
26
+ function digest(value: string): Buffer {
27
+ return createHash("sha256").update(value).digest();
28
+ }
29
+ function tokenMatches(expected: string, actual: string | null): boolean {
30
+ return actual !== null && timingSafeEqual(digest(expected), digest(actual));
31
+ }
32
+ function isInput(value: unknown): value is RequestInput {
33
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34
+ }
35
+ function send(socket: ServerWebSocket<unknown>, frame: Record<string, unknown>): void {
36
+ socket.send(JSON.stringify(frame));
37
+ }
38
+ function sendError(socket: ServerWebSocket<unknown>, id: string | undefined, code: string, message: string): void {
39
+ send(socket, { type: "broker_response", ...(id === undefined ? {} : { id }), ok: false, error: { code, message } });
40
+ }
41
+ /** Loopback-only WebSocket transport for the agent-global SDK broker. */
42
+ export class BrokerTransport {
43
+ readonly #broker: Broker;
44
+ readonly #token: string;
45
+ readonly #requestedPort: number;
46
+ #server: ReturnType<typeof Bun.serve> | null = null;
47
+ #port = 0;
48
+ constructor(broker: Broker, token: string, port = 0) {
49
+ this.#broker = broker;
50
+ this.#token = token;
51
+ this.#requestedPort = port;
52
+ }
53
+ get port(): number {
54
+ if (!this.#server) throw new Error("Broker transport is not running");
55
+ return this.#port;
56
+ }
57
+ async start(): Promise<number> {
58
+ if (this.#server) return this.#port;
59
+ this.#server = Bun.serve({
60
+ hostname: "127.0.0.1",
61
+ port: this.#requestedPort,
62
+ fetch: request => {
63
+ const url = new URL(request.url);
64
+ if (request.headers.get("upgrade")?.toLowerCase() !== "websocket")
65
+ return new Response("Upgrade Required", { status: 426 });
66
+ if (!tokenMatches(this.#token, url.searchParams.get("token")))
67
+ return new Response("Unauthorized", { status: 401 });
68
+ if (!this.#server?.upgrade(request, { data: undefined }))
69
+ return new Response("WebSocket upgrade failed", { status: 400 });
70
+ return undefined;
71
+ },
72
+ websocket: {
73
+ maxPayloadLength: MAX_BROKER_JSON_FRAME_BYTES * 2,
74
+ open: socket => send(socket, { type: "broker_hello", protocolVersion: PROTOCOL_VERSION }),
75
+ message: (socket, message) => void this.#handleMessage(socket, message),
76
+ },
77
+ });
78
+ this.#port = this.#server.port ?? 0;
79
+ return this.#port;
80
+ }
81
+ async stop(): Promise<void> {
82
+ const server = this.#server;
83
+ this.#server = null;
84
+ if (server) await server.stop(true);
85
+ }
86
+ async #handleMessage(socket: ServerWebSocket<unknown>, raw: string | Buffer): Promise<void> {
87
+ if (Buffer.byteLength(raw) > MAX_BROKER_JSON_FRAME_BYTES) {
88
+ sendError(socket, undefined, "payload_too_large", "broker JSON frame exceeds 4 MiB limit");
89
+ return;
90
+ }
91
+ let frame: BrokerRequest;
92
+ try {
93
+ frame = JSON.parse(raw.toString()) as BrokerRequest;
94
+ } catch {
95
+ sendError(socket, undefined, "invalid_input", "malformed JSON");
96
+ return;
97
+ }
98
+ if (frame?.type !== "broker_request") {
99
+ sendError(socket, undefined, "invalid_input", "invalid broker frame");
100
+ return;
101
+ }
102
+ if (typeof frame.id !== "string" || !frame.id) {
103
+ sendError(socket, frame.id, "invalid_input", "request id is required");
104
+ return;
105
+ }
106
+ if (typeof frame.operation !== "string" || !BROKER_OPERATIONS.has(frame.operation)) {
107
+ sendError(socket, frame.id, "unknown_operation", "unknown broker operation");
108
+ return;
109
+ }
110
+ if (frame.input === undefined || !isInput(frame.input)) {
111
+ sendError(socket, frame.id, "invalid_input", "request input must be an object");
112
+ return;
113
+ }
114
+ if (frame.idempotencyKey !== undefined && typeof frame.idempotencyKey !== "string") {
115
+ sendError(socket, frame.id, "invalid_input", "idempotencyKey must be a string");
116
+ return;
117
+ }
118
+ try {
119
+ const result = await this.#broker.handleRequest(frame.operation, frame.input, frame.idempotencyKey);
120
+ send(socket, { type: "broker_response", id: frame.id, ...result });
121
+ } catch {
122
+ sendError(socket, frame.id, "unavailable", "broker request failed");
123
+ }
124
+ }
125
+ }
@@ -0,0 +1,107 @@
1
+ import { validateAdapterSecretFields } from "../protocol/adapter-validation";
2
+ import { type Adapter, OPERATIONS, type Operation, type OperationKind } from "../protocol/operation-registry";
3
+
4
+ export type ChatTransport = Extract<Adapter, "telegram" | "discord" | "slack">;
5
+ export type ChatOperationDisposition = "allowed" | "unsupported_on_chat";
6
+
7
+ export interface ChatCommandError {
8
+ code: "unsupported_on_chat" | "secret_input_forbidden";
9
+ message: string;
10
+ }
11
+
12
+ export type ChatCommandDecision = { ok: true } | { ok: false; error: ChatCommandError };
13
+
14
+ export interface ChatOperationRequest {
15
+ kind: OperationKind;
16
+ operation: string;
17
+ input?: unknown;
18
+ }
19
+
20
+ const EXPLICITLY_PROHIBITED_OPERATION_IDS = new Set(["C25", "C39", "C40", "G02"]);
21
+
22
+ function isAllowedOnChat(transport: ChatTransport, operation: Operation): boolean {
23
+ return (
24
+ !EXPLICITLY_PROHIBITED_OPERATION_IDS.has(operation.id) &&
25
+ (operation.adapterDispositions[transport] === "generic_safe" ||
26
+ operation.adapterDispositions[transport] === "native_alias")
27
+ );
28
+ }
29
+
30
+ function buildChatOperationPolicy(transport: ChatTransport): Readonly<Record<string, ChatOperationDisposition>> {
31
+ const policy: Record<string, ChatOperationDisposition> = {};
32
+ for (const operation of OPERATIONS)
33
+ policy[operation.id] = isAllowedOnChat(transport, operation) ? "allowed" : "unsupported_on_chat";
34
+ return policy;
35
+ }
36
+
37
+ /**
38
+ * Chat authorization follows each transport's canonical registry disposition.
39
+ * Explicit policy prohibitions remain as defense in depth for shell execution,
40
+ * callback-provider registration, and endpoint credentials.
41
+ */
42
+ export const CHAT_OPERATION_POLICY: Readonly<
43
+ Record<ChatTransport, Readonly<Record<string, ChatOperationDisposition>>>
44
+ > = {
45
+ telegram: buildChatOperationPolicy("telegram"),
46
+ discord: buildChatOperationPolicy("discord"),
47
+ slack: buildChatOperationPolicy("slack"),
48
+ };
49
+
50
+ function unsupported(): ChatCommandDecision {
51
+ return { ok: false, error: { code: "unsupported_on_chat", message: "This operation is not supported on chat." } };
52
+ }
53
+
54
+ /** Reject unsafe or unknown commands before their SDK request can be sent. */
55
+ export function authorizeChatOperation(transport: ChatTransport, request: ChatOperationRequest): ChatCommandDecision {
56
+ const operation = OPERATIONS.find(
57
+ candidate => candidate.kind === request.kind && candidate.sdkId === request.operation,
58
+ );
59
+ if (!operation) return unsupported();
60
+ if (validateAdapterSecretFields(operation.sdkId, (request.input ?? {}) as Record<string, unknown>)) {
61
+ return {
62
+ ok: false,
63
+ error: { code: "secret_input_forbidden", message: "Secret configuration input is forbidden on chat." },
64
+ };
65
+ }
66
+ return CHAT_OPERATION_POLICY[transport][operation.id] === "allowed" ? { ok: true } : unsupported();
67
+ }
68
+
69
+ /** Execute only an authorized command, ensuring rejected payloads produce no SDK send. */
70
+ export async function sendAuthorizedChatOperation<T>(
71
+ transport: ChatTransport,
72
+ request: ChatOperationRequest,
73
+ send: () => Promise<T>,
74
+ ): Promise<{ ok: true; result: T } | { ok: false; error: ChatCommandError }> {
75
+ const decision = authorizeChatOperation(transport, request);
76
+ if (!decision.ok) return decision;
77
+ return { ok: true, result: await send() };
78
+ }
79
+
80
+ const BODY_BEARING_QUERY_OPERATIONS = new Set([
81
+ "transcript.body",
82
+ "context.get",
83
+ "diff.read_hunk",
84
+ "session.last_assistant",
85
+ "resource.body",
86
+ "artifact.read",
87
+ ]);
88
+
89
+ export type ChatCommandOutcome =
90
+ | { ok: true; result: unknown }
91
+ | { ok: false; error: { code: string; message: string } };
92
+
93
+ /**
94
+ * The chat transport is an untrusted presentation surface, not a general SDK
95
+ * result renderer. Never serialize SDK result bodies or provider error text.
96
+ */
97
+ export function projectChatCommandOutcome(
98
+ request: Pick<ChatOperationRequest, "kind" | "operation">,
99
+ outcome: ChatCommandOutcome,
100
+ ): Record<string, unknown> {
101
+ if (!outcome.ok)
102
+ return { ok: false, error: { code: outcome.error.code, message: "Command could not be completed." } };
103
+ if (request.kind === "query" && BODY_BEARING_QUERY_OPERATIONS.has(request.operation)) {
104
+ return { ok: true, result: { operation: request.operation, status: "content_withheld" } };
105
+ }
106
+ return { ok: true, result: { operation: request.operation, status: "completed" } };
107
+ }
@@ -0,0 +1,214 @@
1
+ import * as crypto from "node:crypto";
2
+ import * as path from "node:path";
3
+ import {
4
+ acquireChatDaemonOwnership,
5
+ type ChatDaemonKind,
6
+ clearChatDaemonControlRequest,
7
+ readChatDaemonControlRequest,
8
+ readChatDaemonState,
9
+ releaseChatDaemonOwnership,
10
+ renewChatDaemonHeartbeat,
11
+ } from "./chat-daemon-control";
12
+ import { type ChatDaemonRuntimeConfig, ChatDaemonRuntime as DefaultChatDaemonRuntime } from "./chat-daemon-runtime";
13
+ import {
14
+ isDiscordConfigured,
15
+ isSlackConfigured,
16
+ loadNotificationConfigFile,
17
+ notificationConfigFromFile,
18
+ } from "./config";
19
+
20
+ export interface ChatDaemonRuntimeHandle {
21
+ start(): Promise<void>;
22
+ stop(): Promise<void>;
23
+ transportHealthy?(): boolean;
24
+ }
25
+
26
+ export interface RunChatDaemonInternalDeps {
27
+ processPid?: number;
28
+ pidAlive?: (pid: number) => boolean;
29
+ createRuntime?: (input: {
30
+ kind: ChatDaemonKind;
31
+ agentDir: string;
32
+ config: ChatDaemonConfig;
33
+ }) => Promise<ChatDaemonRuntimeHandle> | ChatDaemonRuntimeHandle;
34
+ setInterval?: typeof setInterval;
35
+ clearInterval?: typeof clearInterval;
36
+ }
37
+
38
+ export type ChatDaemonConfig = ChatDaemonRuntimeConfig;
39
+
40
+ function argValue(argv: string[], name: string): string | undefined {
41
+ const index = argv.indexOf(name);
42
+ return index >= 0 ? argv[index + 1] : undefined;
43
+ }
44
+
45
+ function defaultPidAlive(pid: number): boolean {
46
+ try {
47
+ process.kill(pid, 0);
48
+ return true;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ async function loadConfig(agentDir: string, kind: ChatDaemonKind): Promise<ChatDaemonConfig | undefined> {
55
+ const loaded = loadNotificationConfigFile(agentDir);
56
+ if (loaded.status === "not-found") return undefined;
57
+ if (loaded.status === "error") throw loaded.error;
58
+ const config = notificationConfigFromFile(loaded.value);
59
+ if (!config.enabled) return undefined;
60
+ if (kind === "discord") {
61
+ if (
62
+ !isDiscordConfigured({
63
+ ...config,
64
+ sessionScope: "all",
65
+ idleTimeoutMs: 60_000,
66
+ rich: { enabled: true },
67
+ richDraft: { enabled: false },
68
+ topics: { nameTemplate: undefined },
69
+ })
70
+ ) {
71
+ throw new Error("Discord notifications are enabled but configuration is incomplete");
72
+ }
73
+ const discord = config.discord as {
74
+ botToken: string;
75
+ applicationId: string;
76
+ guildId: string;
77
+ parentChannelId: string;
78
+ };
79
+ const { botToken, applicationId, guildId, parentChannelId } = discord;
80
+ const identity = crypto
81
+ .createHash("sha256")
82
+ .update(
83
+ [botToken, applicationId, guildId, parentChannelId, String(config.redact), config.verbosity].join("\0"),
84
+ )
85
+ .digest("hex")
86
+ .slice(0, 16);
87
+ return {
88
+ identity,
89
+ notifications: { discord: { botToken, applicationId, guildId, parentChannelId } },
90
+ presentation: { redact: config.redact, verbosity: config.verbosity },
91
+ };
92
+ }
93
+ if (
94
+ !isSlackConfigured({
95
+ ...config,
96
+ sessionScope: "all",
97
+ idleTimeoutMs: 60_000,
98
+ rich: { enabled: true },
99
+ richDraft: { enabled: false },
100
+ topics: { nameTemplate: undefined },
101
+ })
102
+ ) {
103
+ throw new Error("Slack notifications are enabled but configuration is incomplete");
104
+ }
105
+ const slack = config.slack as {
106
+ botToken: string;
107
+ appToken: string;
108
+ workspaceId: string;
109
+ channelId: string;
110
+ authorizedUserId?: string;
111
+ };
112
+ const { botToken, appToken, workspaceId, channelId, authorizedUserId } = slack;
113
+ const identity = crypto
114
+ .createHash("sha256")
115
+ .update(
116
+ [
117
+ botToken,
118
+ appToken,
119
+ workspaceId,
120
+ channelId,
121
+ authorizedUserId ?? "",
122
+ String(config.redact),
123
+ config.verbosity,
124
+ ].join("\0"),
125
+ )
126
+ .digest("hex")
127
+ .slice(0, 16);
128
+ return {
129
+ identity,
130
+ notifications: { slack: { botToken, appToken, workspaceId, channelId, authorizedUserId } },
131
+ presentation: { redact: config.redact, verbosity: config.verbosity },
132
+ };
133
+ }
134
+
135
+ function ownerPid(ownerId: string): number | undefined {
136
+ const match = /^(\d+)(?:-|$)/.exec(ownerId);
137
+ const pid = Number(match?.[1]);
138
+ return Number.isSafeInteger(pid) && pid > 0 ? pid : undefined;
139
+ }
140
+
141
+ function defaultRuntime(input: {
142
+ kind: ChatDaemonKind;
143
+ agentDir: string;
144
+ config: ChatDaemonConfig;
145
+ }): ChatDaemonRuntimeHandle {
146
+ return new DefaultChatDaemonRuntime(input);
147
+ }
148
+
149
+ /** Hidden worker entrypoint. It owns only lock/state/control lifecycle; transport creation remains injectable. */
150
+ export async function runChatDaemonInternal(
151
+ kind: ChatDaemonKind,
152
+ argv: string[],
153
+ deps: RunChatDaemonInternalDeps = {},
154
+ ): Promise<void> {
155
+ const agentDir =
156
+ argValue(argv, "--agent-dir") ?? process.env.GJC_CODING_AGENT_DIR ?? path.join(process.cwd(), ".gjc", "agent");
157
+ const ownerId = argValue(argv, "--owner-id");
158
+ if (!ownerId) throw new Error("missing --owner-id");
159
+ const pid = ownerPid(ownerId);
160
+ if (pid !== undefined && !(deps.pidAlive ?? defaultPidAlive)(pid)) return;
161
+ const config = await loadConfig(agentDir, kind);
162
+ if (!config) return;
163
+ if (
164
+ !(await acquireChatDaemonOwnership({ agentDir, kind, ownerId, pid: deps.processPid, identity: config.identity }))
165
+ )
166
+ return;
167
+
168
+ let incarnation: string | undefined;
169
+ let runtime: ChatDaemonRuntimeHandle | undefined;
170
+ let interval: ReturnType<typeof setInterval> | undefined;
171
+ let stopping = false;
172
+ const stop = (): void => {
173
+ stopping = true;
174
+ };
175
+ try {
176
+ incarnation = (await readChatDaemonState(agentDir, kind))?.incarnation;
177
+ if (!incarnation) throw new Error("chat daemon ownership state is missing an incarnation");
178
+ runtime = await (deps.createRuntime?.({ kind, agentDir, config }) ?? defaultRuntime({ kind, agentDir, config }));
179
+ const renewHeartbeat = async (): Promise<void> => {
180
+ await renewChatDaemonHeartbeat({
181
+ agentDir,
182
+ kind,
183
+ ownerId,
184
+ pid: deps.processPid,
185
+ incarnation,
186
+ transportHealthy: runtime?.transportHealthy?.() ?? true,
187
+ });
188
+ };
189
+ process.once("SIGTERM", stop);
190
+ process.once("SIGINT", stop);
191
+ interval = (deps.setInterval ?? setInterval)(() => {
192
+ void renewHeartbeat();
193
+ }, 5_000);
194
+ await runtime.start();
195
+ await renewHeartbeat();
196
+ while (!stopping) {
197
+ const request = await readChatDaemonControlRequest(agentDir, kind);
198
+ if (request?.ownerId === ownerId && request.incarnation === incarnation) {
199
+ await clearChatDaemonControlRequest(agentDir, kind, request.requestId);
200
+ break;
201
+ }
202
+ await new Promise(resolve => setTimeout(resolve, 100));
203
+ }
204
+ } finally {
205
+ if (interval !== undefined) (deps.clearInterval ?? clearInterval)(interval);
206
+ process.off("SIGTERM", stop);
207
+ process.off("SIGINT", stop);
208
+ try {
209
+ await runtime?.stop();
210
+ } finally {
211
+ await releaseChatDaemonOwnership({ agentDir, kind, ownerId, pid: deps.processPid, incarnation });
212
+ }
213
+ }
214
+ }