@gajae-code/coding-agent 0.10.2 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (476) hide show
  1. package/CHANGELOG.md +58 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/async/job-manager.d.ts +46 -7
  4. package/dist/types/cli/args.d.ts +4 -5
  5. package/dist/types/cli/daemon-cli.d.ts +12 -1
  6. package/dist/types/cli/notify-cli.d.ts +21 -1
  7. package/dist/types/cli.d.ts +3 -0
  8. package/dist/types/commands/daemon.d.ts +39 -0
  9. package/dist/types/commands/launch.d.ts +3 -0
  10. package/dist/types/commands/notify.d.ts +28 -1
  11. package/dist/types/commands/sdk.d.ts +33 -0
  12. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  13. package/dist/types/config/model-profile-activation.d.ts +35 -15
  14. package/dist/types/config/model-profiles.d.ts +11 -5
  15. package/dist/types/config/model-registry.d.ts +3 -3
  16. package/dist/types/config/model-resolver.d.ts +39 -6
  17. package/dist/types/config/model-selector-value.d.ts +17 -0
  18. package/dist/types/config/models-config-schema.d.ts +10 -6
  19. package/dist/types/config/settings-schema.d.ts +133 -6
  20. package/dist/types/config/settings.d.ts +63 -35
  21. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  22. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  23. package/dist/types/daemon/builtin.d.ts +6 -5
  24. package/dist/types/daemon/control-types.d.ts +1 -1
  25. package/dist/types/discovery/mcp-json.d.ts +12 -1
  26. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  27. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  28. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  29. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  30. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  31. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  32. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  33. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  34. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  35. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  36. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  37. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  38. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  39. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
  40. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  41. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  42. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  43. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  44. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  45. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  46. package/dist/types/harness-control-plane/types.d.ts +3 -4
  47. package/dist/types/lsp/index.d.ts +1 -1
  48. package/dist/types/main.d.ts +32 -38
  49. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  50. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  51. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  52. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  53. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  54. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  55. package/dist/types/modes/components/model-selector.d.ts +1 -0
  56. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  57. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  58. package/dist/types/modes/components/welcome.d.ts +1 -1
  59. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  60. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
  61. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  62. package/dist/types/modes/index.d.ts +0 -4
  63. package/dist/types/modes/interactive-mode.d.ts +5 -2
  64. package/dist/types/modes/runtime-init.d.ts +2 -2
  65. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  66. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  67. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  68. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  69. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +170 -30
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  72. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  73. package/dist/types/modes/types.d.ts +7 -2
  74. package/dist/types/runtime-mcp/client.d.ts +2 -0
  75. package/dist/types/runtime-mcp/config.d.ts +5 -1
  76. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  77. package/dist/types/runtime-mcp/types.d.ts +4 -0
  78. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  79. package/dist/types/sdk/acp/index.d.ts +2 -0
  80. package/dist/types/sdk/broker/broker.d.ts +53 -0
  81. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  82. package/dist/types/sdk/broker/ensure.d.ts +42 -0
  83. package/dist/types/sdk/broker/identity.d.ts +3 -0
  84. package/dist/types/sdk/broker/index.d.ts +8 -0
  85. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  86. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  87. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  88. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  89. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  90. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  91. package/dist/types/sdk/broker/transport.d.ts +9 -0
  92. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  93. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  94. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  95. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  96. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  97. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  98. package/dist/types/sdk/bus/config.d.ts +274 -0
  99. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  100. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  101. package/dist/types/sdk/bus/discord-daemon.d.ts +50 -0
  102. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  103. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  104. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  105. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  107. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  108. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  109. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  110. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  111. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  112. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  113. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  114. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  115. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  116. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  117. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  118. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  119. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  121. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +78 -17
  122. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  123. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  124. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  125. package/dist/types/sdk/cli/index.d.ts +1 -0
  126. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  127. package/dist/types/sdk/client/client.d.ts +1 -0
  128. package/dist/types/sdk/client/discovery.d.ts +27 -0
  129. package/dist/types/sdk/client/index.d.ts +2 -0
  130. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  131. package/dist/types/sdk/host/control/index.d.ts +2 -0
  132. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  133. package/dist/types/sdk/host/events.d.ts +35 -0
  134. package/dist/types/sdk/host/host.d.ts +35 -0
  135. package/dist/types/sdk/host/index.d.ts +4 -0
  136. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  137. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  138. package/dist/types/sdk/host/query/index.d.ts +3 -0
  139. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  140. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  141. package/dist/types/sdk/host/types.d.ts +32 -0
  142. package/dist/types/sdk/index.d.ts +6 -0
  143. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  144. package/dist/types/sdk/mcp/index.d.ts +1 -0
  145. package/dist/types/sdk/mcp/server.d.ts +37 -0
  146. package/dist/types/sdk/models.d.ts +44 -0
  147. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  148. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  149. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  150. package/dist/types/sdk/startup-capability.d.ts +50 -0
  151. package/dist/types/session/agent-session.d.ts +114 -21
  152. package/dist/types/session/default-model-selection.d.ts +25 -0
  153. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  154. package/dist/types/session/session-manager.d.ts +58 -1
  155. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  156. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  157. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  158. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  159. package/dist/types/tools/browser/launch.d.ts +22 -0
  160. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  161. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  162. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  163. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  164. package/dist/types/tools/browser/registry.d.ts +19 -0
  165. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  166. package/dist/types/tools/index.d.ts +8 -8
  167. package/dist/types/tools/subagent-render.d.ts +1 -0
  168. package/dist/types/tools/subagent.d.ts +6 -1
  169. package/package.json +34 -13
  170. package/scripts/build-sdk-package-smoke.ts +99 -0
  171. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  172. package/scripts/compile-args.ts +4 -2
  173. package/scripts/g005-daemon-smoke.ts +4 -5
  174. package/scripts/g011-daemon-path-smoke.ts +5 -5
  175. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  176. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  177. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  178. package/scripts/manifest-schema.ts +124 -0
  179. package/scripts/run-test-manifest.ts +153 -0
  180. package/scripts/run-threat-model-check.ts +157 -0
  181. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  182. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  183. package/src/append-only-mode.ts +1 -1
  184. package/src/async/job-manager.ts +406 -63
  185. package/src/cli/args.ts +43 -12
  186. package/src/cli/auth-gateway-cli.ts +2 -2
  187. package/src/cli/config-cli.ts +2 -1
  188. package/src/cli/daemon-cli.ts +63 -14
  189. package/src/cli/list-models.ts +1 -1
  190. package/src/cli/notify-cli.ts +288 -286
  191. package/src/cli.ts +21 -2
  192. package/src/commands/daemon.ts +50 -6
  193. package/src/commands/harness.ts +93 -36
  194. package/src/commands/launch.ts +5 -2
  195. package/src/commands/mcp-serve.ts +19 -12
  196. package/src/commands/notify.ts +36 -3
  197. package/src/commands/sdk.ts +426 -0
  198. package/src/commit/agentic/agent.ts +1 -0
  199. package/src/config/atomic-yaml-patch.ts +423 -0
  200. package/src/config/model-profile-activation.ts +240 -89
  201. package/src/config/model-profiles.ts +18 -15
  202. package/src/config/model-registry.ts +51 -26
  203. package/src/config/model-resolver.ts +138 -51
  204. package/src/config/model-selector-value.ts +50 -0
  205. package/src/config/models-config-schema.ts +14 -21
  206. package/src/config/settings-schema.ts +128 -10
  207. package/src/config/settings.ts +1120 -158
  208. package/src/coordinator-mcp/model-preset.ts +74 -20
  209. package/src/coordinator-mcp/server.ts +1597 -3052
  210. package/src/daemon/builtin.ts +8 -5
  211. package/src/daemon/control-types.ts +1 -1
  212. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  213. package/src/discovery/mcp-json.ts +327 -20
  214. package/src/extensibility/custom-tools/types.ts +1 -1
  215. package/src/extensibility/extensions/compact-handler.ts +3 -3
  216. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  217. package/src/extensibility/extensions/loader.ts +69 -5
  218. package/src/extensibility/extensions/runner.ts +112 -4
  219. package/src/extensibility/extensions/types.ts +176 -17
  220. package/src/extensibility/hooks/types.ts +1 -1
  221. package/src/gjc-runtime/launch-tmux.ts +170 -86
  222. package/src/gjc-runtime/psmux-detect.ts +82 -4
  223. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  224. package/src/gjc-runtime/team-runtime.ts +54 -35
  225. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  226. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  227. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  228. package/src/gjc-runtime/ultragoal-guard.ts +108 -14
  229. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
  230. package/src/gjc-runtime/ultragoal-runtime.ts +227 -11
  231. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  232. package/src/harness-control-plane/operate.ts +9 -9
  233. package/src/harness-control-plane/owner.ts +283 -39
  234. package/src/harness-control-plane/receipts.ts +0 -1
  235. package/src/harness-control-plane/sdk-transport.ts +395 -0
  236. package/src/harness-control-plane/session-transport.ts +94 -0
  237. package/src/harness-control-plane/types.ts +1 -1
  238. package/src/internal-urls/docs-index.generated.ts +34 -35
  239. package/src/lsp/client.ts +42 -6
  240. package/src/lsp/index.ts +2 -2
  241. package/src/main.ts +299 -204
  242. package/src/modes/DESIGN.md +258 -0
  243. package/src/modes/acp/acp-agent.ts +1228 -2612
  244. package/src/modes/acp/acp-client-bridge.ts +2 -20
  245. package/src/modes/acp/acp-event-mapper.ts +18 -2
  246. package/src/modes/acp/acp-mode.ts +8 -36
  247. package/src/modes/acp/permission-mode.ts +25 -0
  248. package/src/modes/acp/startup-options.ts +6 -0
  249. package/src/modes/components/agent-dashboard.ts +37 -17
  250. package/src/modes/components/model-selector.ts +93 -35
  251. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  252. package/src/modes/components/settings-selector.ts +60 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +10 -17
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +396 -28
  257. package/src/modes/controllers/selector-controller.ts +674 -36
  258. package/src/modes/index.ts +0 -22
  259. package/src/modes/interactive-mode.ts +87 -36
  260. package/src/modes/runtime-init.ts +298 -6
  261. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  262. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  263. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  264. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  265. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  266. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1258 -87
  267. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  268. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  269. package/src/modes/types.ts +7 -2
  270. package/src/runtime-mcp/client.ts +94 -19
  271. package/src/runtime-mcp/config.ts +27 -15
  272. package/src/runtime-mcp/manager.ts +343 -105
  273. package/src/runtime-mcp/oauth-flow.ts +42 -12
  274. package/src/runtime-mcp/transports/http.ts +49 -19
  275. package/src/runtime-mcp/transports/stdio.ts +47 -28
  276. package/src/runtime-mcp/types.ts +10 -0
  277. package/src/sdk/acp/adapter.ts +418 -0
  278. package/src/sdk/acp/index.ts +2 -0
  279. package/src/sdk/broker/broker.ts +642 -0
  280. package/src/sdk/broker/discovery.ts +113 -0
  281. package/src/sdk/broker/ensure.ts +307 -0
  282. package/src/sdk/broker/identity.ts +42 -0
  283. package/src/sdk/broker/index.ts +8 -0
  284. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  285. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  286. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  287. package/src/sdk/broker/lifecycle.ts +2157 -0
  288. package/src/sdk/broker/process-incarnation.ts +159 -0
  289. package/src/sdk/broker/runtime.ts +164 -0
  290. package/src/sdk/broker/session-index.ts +318 -0
  291. package/src/sdk/broker/state-version.ts +23 -0
  292. package/src/sdk/broker/transport.ts +125 -0
  293. package/src/sdk/bus/chat-command-policy.ts +107 -0
  294. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  295. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  296. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  297. package/src/sdk/bus/chat-effect-journal.ts +355 -0
  298. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  299. package/src/sdk/bus/config.ts +433 -0
  300. package/src/sdk/bus/conversation-store.ts +391 -0
  301. package/src/sdk/bus/discord-conversation.ts +85 -0
  302. package/src/sdk/bus/discord-daemon.ts +2292 -0
  303. package/src/sdk/bus/discord-live-provider.ts +521 -0
  304. package/src/sdk/bus/discord-provider.ts +56 -0
  305. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  306. package/src/sdk/bus/index.ts +3979 -0
  307. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  309. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  310. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  311. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  312. package/src/sdk/bus/natives-augment.d.ts +38 -0
  313. package/src/sdk/bus/notification-orchestration.ts +535 -0
  314. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  315. package/src/sdk/bus/session-control.ts +333 -0
  316. package/src/sdk/bus/slack-conversation.ts +74 -0
  317. package/src/sdk/bus/slack-daemon.ts +2144 -0
  318. package/src/sdk/bus/slack-live-provider.ts +380 -0
  319. package/src/sdk/bus/slack-provider.ts +76 -0
  320. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  321. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  322. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  323. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  324. package/src/{notifications → sdk/bus}/telegram-daemon.ts +603 -63
  325. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  326. package/src/sdk/bus/telegram-setup.ts +663 -0
  327. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  328. package/src/sdk/cli/index.ts +1 -0
  329. package/src/sdk/cli/session-cli.ts +275 -0
  330. package/src/sdk/client/client.ts +1 -0
  331. package/src/sdk/client/discovery.ts +108 -0
  332. package/src/sdk/client/index.ts +2 -0
  333. package/src/sdk/host/control/dispatch.ts +367 -0
  334. package/src/sdk/host/control/index.ts +10 -0
  335. package/src/sdk/host/control/operations.ts +63 -0
  336. package/src/sdk/host/events.ts +91 -0
  337. package/src/sdk/host/host.ts +296 -0
  338. package/src/sdk/host/index.ts +4 -0
  339. package/src/sdk/host/query/cursor.ts +189 -0
  340. package/src/sdk/host/query/handlers.ts +533 -0
  341. package/src/sdk/host/query/index.ts +3 -0
  342. package/src/sdk/host/query/revision-store.ts +1126 -0
  343. package/src/sdk/host/reverse-leases.ts +325 -0
  344. package/src/sdk/host/types.ts +29 -0
  345. package/src/sdk/index.ts +13 -0
  346. package/src/sdk/lifecycle-session.ts +39 -0
  347. package/src/sdk/mcp/index.ts +1 -0
  348. package/src/sdk/mcp/server.ts +332 -0
  349. package/src/sdk/models.ts +168 -0
  350. package/src/sdk/protocol/adapter-validation.ts +48 -0
  351. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  352. package/src/sdk/protocol/operation-registry.ts +312 -0
  353. package/src/{sdk.ts → sdk/session.ts} +339 -212
  354. package/src/sdk/startup-capability.ts +189 -0
  355. package/src/session/agent-session.ts +2650 -944
  356. package/src/session/default-model-selection.ts +93 -0
  357. package/src/session/fallback-chain-controller.ts +136 -0
  358. package/src/session/session-manager.ts +438 -11
  359. package/src/session/session-storage.ts +8 -1
  360. package/src/setup/credential-auto-import.ts +290 -35
  361. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  362. package/src/slash-commands/builtin-registry.ts +2 -1
  363. package/src/task/executor.ts +62 -13
  364. package/src/task/index.ts +26 -16
  365. package/src/tools/ask-answer-registry.ts +1 -1
  366. package/src/tools/ask.ts +13 -8
  367. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  368. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  369. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  370. package/src/tools/browser/launch.ts +124 -19
  371. package/src/tools/browser/profile-discovery.ts +63 -0
  372. package/src/tools/browser/profile-posture.ts +59 -0
  373. package/src/tools/browser/profile-reuse.ts +102 -0
  374. package/src/tools/browser/profile-warmup.ts +109 -0
  375. package/src/tools/browser/registry.ts +87 -11
  376. package/src/tools/browser/tab-protocol.ts +1 -0
  377. package/src/tools/browser/tab-supervisor.ts +1 -0
  378. package/src/tools/browser/tab-worker.ts +1 -1
  379. package/src/tools/browser.ts +6 -0
  380. package/src/tools/index.ts +8 -8
  381. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  382. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  383. package/src/tools/subagent-render.ts +19 -8
  384. package/src/tools/subagent.ts +84 -32
  385. package/src/tools/telegram-send.ts +2 -2
  386. package/vendor/insane-search/MANIFEST.json +2 -1
  387. package/vendor/insane-search/engine/bias_check.py +4 -1
  388. package/vendor/insane-search/engine/phase0.py +26 -1
  389. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  390. package/dist/types/modes/bridge/auth.d.ts +0 -12
  391. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  392. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  393. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  394. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  395. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  396. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  397. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  398. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  399. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  400. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  401. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  402. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  403. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  404. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  405. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  406. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  407. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  408. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  409. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  410. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  411. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  412. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  413. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  414. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  415. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  416. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  417. package/dist/types/notifications/config.d.ts +0 -132
  418. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  419. package/src/modes/bridge/auth.ts +0 -41
  420. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  421. package/src/modes/bridge/bridge-mode.ts +0 -675
  422. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  423. package/src/modes/bridge/event-stream.ts +0 -70
  424. package/src/modes/rpc/host-tools.ts +0 -1
  425. package/src/modes/rpc/host-uris.ts +0 -1
  426. package/src/modes/rpc/rpc-client.ts +0 -1166
  427. package/src/modes/rpc/rpc-mode.ts +0 -1029
  428. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  429. package/src/modes/rpc/rpc-types.ts +0 -637
  430. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  431. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  432. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  433. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  434. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  435. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  436. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  437. package/src/modes/shared/agent-wire/responses.ts +0 -17
  438. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  439. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  440. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  441. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  442. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  443. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  444. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  445. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  446. package/src/notifications/config.ts +0 -219
  447. package/src/notifications/index.ts +0 -1835
  448. package/src/notifications/telegram-daemon-cli.ts +0 -243
  449. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  450. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  462. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  463. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  475. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  476. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
package/src/cli.ts CHANGED
@@ -9,6 +9,7 @@ import { Args, type CliConfig, Command, type CommandEntry, Flags, run } from "@g
9
9
  import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION, VERSION } from "@gajae-code/utils/dirs";
10
10
  import { runFixtureReport } from "./cli/fixture-report";
11
11
  import { isTmuxOwnerIsolationCliArgv, runTmuxOwnerIsolationCliFromStdin } from "./gjc-runtime/tmux-owner-isolation-cli";
12
+ import { runChatDaemonInternal } from "./sdk/bus/chat-daemon-cli";
12
13
 
13
14
  if (Bun.semver.order(Bun.version, MIN_BUN_VERSION) < 0) {
14
15
  process.stderr.write(
@@ -41,6 +42,7 @@ export const commands: CommandEntry[] = [
41
42
  { name: "config", load: () => import("./commands/config").then(m => m.default) },
42
43
  { name: "stats", load: () => import("./commands/stats").then(m => m.default) },
43
44
  { name: "notify", load: () => import("./commands/notify").then(m => m.default) },
45
+ { name: "sdk", load: () => import("./commands/sdk").then(m => m.default) },
44
46
  { name: "daemon", load: () => import("./commands/daemon").then(m => m.default) },
45
47
  { name: "web-search", aliases: ["q"], load: () => import("./commands/web-search").then(m => m.default) },
46
48
  { name: "local-provider", load: () => import("./commands/local-provider").then(m => m.default) },
@@ -123,6 +125,18 @@ async function runNotifyDaemonInternalFastPath(argv: string[]): Promise<void> {
123
125
  await runNotifyCommand(cmd);
124
126
  }
125
127
 
128
+ function isChatDaemonInternalFastPath(argv: string[]): boolean {
129
+ return argv[0] === "daemon" && (argv[1] === "discord-internal" || argv[1] === "slack-internal");
130
+ }
131
+
132
+ async function runChatDaemonInternalFastPath(argv: string[]): Promise<void> {
133
+ const action = argv[1];
134
+ if (action !== "discord-internal" && action !== "slack-internal") {
135
+ throw new Error("invalid chat daemon internal fast path");
136
+ }
137
+ await runChatDaemonInternal(action === "discord-internal" ? "discord" : "slack", argv.slice(2));
138
+ }
139
+
126
140
  function rootFixtureArg(argv: string[]): { present: boolean; id: string | undefined } {
127
141
  for (let i = 0; i < argv.length; i++) {
128
142
  const arg = argv[i];
@@ -175,10 +189,11 @@ export class RootHelpCommand extends Command {
175
189
  }),
176
190
  "system-prompt": Flags.string({ description: "System prompt (default: coding assistant prompt)" }),
177
191
  "append-system-prompt": Flags.string({ description: "Append text or file contents to the system prompt" }),
192
+ "mcp-config": Flags.string({ description: "Tools-only MCP config file (absolute path)" }),
178
193
  "allow-home": Flags.boolean({ description: "Allow starting in ~ without auto-switching to a temp dir" }),
179
194
  mode: Flags.string({
180
- description: "Output mode: text (default), json, rpc, acp, rpc-ui, or bridge",
181
- options: ["text", "json", "rpc", "acp", "rpc-ui", "bridge"],
195
+ description: "Output mode: text (default), json, or acp",
196
+ options: ["text", "json", "acp"],
182
197
  }),
183
198
  print: Flags.boolean({ char: "p", description: "Non-interactive mode: process prompt and exit" }),
184
199
  continue: Flags.boolean({ char: "c", description: "Continue previous session" }),
@@ -313,6 +328,10 @@ export async function runCli(argv: string[]): Promise<void> {
313
328
  await runNotifyDaemonInternalFastPath(argv);
314
329
  return;
315
330
  }
331
+ if (isChatDaemonInternalFastPath(argv)) {
332
+ await runChatDaemonInternalFastPath(argv);
333
+ return;
334
+ }
316
335
  if (argv[0] === "--smoke-test") {
317
336
  await runSmokeTest();
318
337
  return;
@@ -2,14 +2,22 @@
2
2
  * Manage GJC background daemons (status/list/stop/reload).
3
3
  */
4
4
  import { Args, Command, Flags } from "@gajae-code/utils/cli";
5
- import { type DaemonCliAction, type DaemonCommandArgs, runDaemonCommand } from "../cli/daemon-cli";
5
+ import {
6
+ type DaemonCommandAction,
7
+ type DaemonCommandArgs,
8
+ isDaemonInternalAction,
9
+ runDaemonCommand,
10
+ } from "../cli/daemon-cli";
6
11
  import type { DaemonKind } from "../daemon/control-types";
7
12
  import { DAEMON_ACTION_TOKENS, resolveDaemonAction } from "../daemon/operator-contract";
8
13
  import { initTheme } from "../modes/theme/theme";
14
+ import { runSdkSessionCli } from "../sdk/cli";
15
+
16
+ const ACTIONS = [...DAEMON_ACTION_TOKENS, "discord-internal", "slack-internal", "session"] as const;
9
17
 
10
18
  export default class Daemon extends Command {
11
19
  static description =
12
- "Manage GJC background daemons. Routine use: `gjc daemon status` to check, `gjc daemon restart` to reload (spawns one if none is running). `stop`/`list` and the escalation flags below are advanced primitives.";
20
+ "Manage GJC background daemons and SDK sessions. Routine use: `gjc daemon status` to check, `gjc daemon restart` to reload (spawns one if none is running). `stop`/`list` and the escalation flags below are advanced primitives.";
13
21
 
14
22
  static examples = [
15
23
  "# Check the daemon (concise per-daemon result)\n gjc daemon status",
@@ -23,7 +31,7 @@ export default class Daemon extends Command {
23
31
  action: Args.string({
24
32
  description: "Daemon action (status, restart, reload, stop, list)",
25
33
  required: false,
26
- options: DAEMON_ACTION_TOKENS as string[],
34
+ options: [...ACTIONS] as string[],
27
35
  }),
28
36
  kind: Args.string({ description: "Daemon kind(s) to target", required: false, multiple: true }),
29
37
  };
@@ -36,13 +44,46 @@ export default class Daemon extends Command {
36
44
  "graceful-timeout-ms": Flags.integer({ description: "Cooperative stop timeout before escalation" }),
37
45
  "kill-timeout-ms": Flags.integer({ description: "Wait for old pid death after SIGKILL" }),
38
46
  "spawn-if-stopped": Flags.boolean({ description: "On reload, spawn even when no daemon is running" }),
47
+ smoke: Flags.boolean({ description: "Internal: run worker smoke without configuration or network" }),
48
+ "owner-id": Flags.string({ description: "Internal: daemon owner id" }),
49
+ "agent-dir": Flags.string({ description: "Internal: daemon state directory" }),
50
+ op: Flags.string({ description: "SDK control or global operation" }),
51
+ "idempotency-key": Flags.string({ description: "Caller idempotency key required for SDK lifecycle globals" }),
52
+ "json-input": Flags.string({ description: "SDK request JSON object" }),
53
+ "json-input-file": Flags.string({ description: "Read SDK request JSON from a 0600 file" }),
54
+ "json-input-stdin": Flags.boolean({ description: "Read SDK request JSON from standard input" }),
55
+ confirm: Flags.boolean({ description: "Confirm a destructive SDK control operation" }),
56
+ query: Flags.string({ description: "SDK query name" }),
57
+ cursor: Flags.string({ description: "SDK query continuation cursor" }),
58
+ "show-endpoint-credential": Flags.boolean({ description: "Allow session.get_endpoint secret output" }),
59
+ yes: Flags.boolean({ description: "Confirm endpoint credential output on a TTY" }),
39
60
  };
40
61
 
41
62
  async run(): Promise<void> {
42
63
  const { args, flags } = await this.parse(Daemon);
43
- const action = (resolveDaemonAction(args.action) ?? "status") as DaemonCliAction;
44
- const kinds = (Array.isArray(args.kind) ? args.kind : args.kind ? [args.kind] : []) as DaemonKind[];
64
+ const rawAction = args.action ?? "status";
65
+ const positional = Array.isArray(args.kind) ? args.kind : args.kind ? [args.kind] : [];
45
66
  const flagRec = flags as Record<string, unknown>;
67
+ if (rawAction === "session") {
68
+ await runSdkSessionCli({
69
+ action: positional[0],
70
+ sessionId: positional[1],
71
+ operation: flagRec.op as string | undefined,
72
+ query: flagRec.query as string | undefined,
73
+ jsonInput: flagRec["json-input"] as string | undefined,
74
+ jsonInputFile: flagRec["json-input-file"] as string | undefined,
75
+ jsonInputStdin: Boolean(flagRec["json-input-stdin"]),
76
+ confirm: Boolean(flagRec.confirm),
77
+ idempotencyKey: flagRec["idempotency-key"] as string | undefined,
78
+ cursor: flagRec.cursor as string | undefined,
79
+ showEndpointCredential: Boolean(flagRec["show-endpoint-credential"]),
80
+ yes: Boolean(flagRec.yes),
81
+ agentDir: flagRec["agent-dir"] as string | undefined,
82
+ });
83
+ return;
84
+ }
85
+ const action = (resolveDaemonAction(rawAction) ?? rawAction) as DaemonCommandAction;
86
+ const kinds = positional as DaemonKind[];
46
87
  const cmd: DaemonCommandArgs = {
47
88
  action,
48
89
  kinds,
@@ -53,9 +94,12 @@ export default class Daemon extends Command {
53
94
  gracefulTimeoutMs: flagRec["graceful-timeout-ms"] as number | undefined,
54
95
  killTimeoutMs: flagRec["kill-timeout-ms"] as number | undefined,
55
96
  spawnIfStopped: flagRec["spawn-if-stopped"] as boolean | undefined,
97
+ smoke: Boolean(flags.smoke),
98
+ ownerId: flagRec["owner-id"] as string | undefined,
99
+ agentDir: flagRec["agent-dir"] as string | undefined,
56
100
  };
57
101
 
58
- await initTheme();
102
+ if (!isDaemonInternalAction(action)) await initTheme();
59
103
  await runDaemonCommand(cmd);
60
104
  }
61
105
  }
@@ -39,7 +39,7 @@ import { type ResolvedOwner, RuntimeOwner, resolveOwner, resolveOwnerLive } from
39
39
  import { preserveDirtyWorktree } from "../harness-control-plane/preserve";
40
40
  import { RECEIPT_SPOOL_DIR_ENV } from "../harness-control-plane/receipt-spool";
41
41
  import { buildReceipt, requiresVanishBeforeAction, type VanishEvidence } from "../harness-control-plane/receipts";
42
- import { GajaeCodeRpc } from "../harness-control-plane/rpc-adapter";
42
+ import { createSdkSessionTransport, spawnNormalHarnessSession } from "../harness-control-plane/sdk-transport";
43
43
  import { classifyLeaseStatus, readLease } from "../harness-control-plane/session-lease";
44
44
  import { buildResponse, buildStateView, submitUnavailableReason } from "../harness-control-plane/state-machine";
45
45
  import {
@@ -50,7 +50,6 @@ import {
50
50
  rememberHarnessSessionRoot,
51
51
  resolveHarnessRoot,
52
52
  resolveHarnessSessionRoot,
53
- sessionPaths,
54
53
  writeReceiptImmutable,
55
54
  writeSessionState,
56
55
  } from "../harness-control-plane/storage";
@@ -66,7 +65,7 @@ import {
66
65
  type SessionHandle,
67
66
  type SessionState,
68
67
  } from "../harness-control-plane/types";
69
- import { SPAWN_PROVENANCE_ENV } from "../notifications/config";
68
+ import { SPAWN_PROVENANCE_ENV } from "../sdk/bus/config";
70
69
 
71
70
  const PRIVATE_OWNER_CONTROL_FIELDS = new Set([
72
71
  "socket_key",
@@ -546,6 +545,8 @@ interface OwnerSpawnResult {
546
545
  socketKey: string | null;
547
546
  fallbackReason: string | null;
548
547
  blockerReason: string | null;
548
+ /** Exact-PID reap proof for a direct detached-owner child declared not-live (no orphan). */
549
+ detachedOwnerReaped?: { pid: number; verified: boolean } | null;
549
550
  }
550
551
 
551
552
  function shellQuote(value: string): string {
@@ -630,6 +631,12 @@ function scopedBootstrapReceipt(stdout: Uint8Array): ScopedBootstrapReceipt | nu
630
631
  }
631
632
  }
632
633
 
634
+ function ownerIsolationPlatform(): NodeJS.Platform {
635
+ return process.platform === "linux" || process.env.GJC_HARNESS_TEST_ASSUME_LINUX_OWNER_ISOLATION !== "1"
636
+ ? process.platform
637
+ : "linux";
638
+ }
639
+
633
640
  function portableProcessStartTime(pid: number): string | null {
634
641
  if (process.platform === "linux") return null;
635
642
  const configured = process.env.GJC_HARNESS_PROCESS_START_COMMAND;
@@ -644,7 +651,11 @@ function portableProcessStartTime(pid: number): string | null {
644
651
  return null;
645
652
  }
646
653
  }
647
- const result = Bun.spawnSync([...command, String(pid)], { stdout: "pipe", stderr: "ignore" });
654
+ const result = Bun.spawnSync([...command, String(pid)], {
655
+ stdout: "pipe",
656
+ stderr: "ignore",
657
+ env: { ...process.env, LC_ALL: "C", LANG: "C" },
658
+ });
648
659
  if (result.exitCode !== 0) return null;
649
660
  const value = result.stdout.toString();
650
661
  const line = value.endsWith("\n") ? value.slice(0, -1) : value;
@@ -801,36 +812,40 @@ export default class Harness extends Command {
801
812
  /** Detached owner daemon (spawned by `start --detach`). Runs until retired or signalled. */
802
813
  async #runOwner(root: string, input: Record<string, unknown>, flagSession: string | undefined): Promise<void> {
803
814
  const sessionId = requireSessionId(input, flagSession);
804
- const sessionDir = sessionPaths(root, sessionId).gjcSessionDir;
805
- // Optional rpc command override (tests / non-default hosts); defaults to `gjc --mode rpc`.
806
- const override = process.env.GJC_HARNESS_RPC_COMMAND;
807
- const command = override ? (JSON.parse(override) as string[]) : undefined;
808
- // Mark the RPC owner as a GJC-spawned child (canonical provenance marker)
809
- // so `notifications.sessionScope = "primary"` suppresses its notification
810
- // endpoint/topic; default `all` preserves historical auto-on behavior.
811
- const rpc = new GajaeCodeRpc({
812
- sessionDir,
813
- command,
814
- env: { ...process.env, [SPAWN_PROVENANCE_ENV]: sessionId },
815
- });
816
- const owner = new RuntimeOwner({ root, sessionId, rpc });
815
+ const state = await loadState(root, sessionId);
816
+ const previousSpawnProvenance = process.env[SPAWN_PROVENANCE_ENV];
817
+ process.env[SPAWN_PROVENANCE_ENV] = sessionId;
818
+ let transport: Awaited<ReturnType<typeof createSdkSessionTransport>>;
819
+ try {
820
+ transport = await createSdkSessionTransport({
821
+ repo: state.handle.workspace,
822
+ sessionId,
823
+ spawn: () => spawnNormalHarnessSession(state.handle.workspace, sessionId),
824
+ });
825
+ } finally {
826
+ if (previousSpawnProvenance === undefined) delete process.env[SPAWN_PROVENANCE_ENV];
827
+ else process.env[SPAWN_PROVENANCE_ENV] = previousSpawnProvenance;
828
+ }
829
+ const owner = new RuntimeOwner({ root, sessionId, transport });
817
830
  const info = await owner.start();
818
831
  writeJson({ ok: true, owner: info });
819
832
  await new Promise<void>(resolve => {
820
833
  const stop = (): void => {
821
834
  clearInterval(timer);
835
+ process.removeListener("SIGTERM", stop);
836
+ process.removeListener("SIGINT", stop);
822
837
  resolve();
823
838
  };
824
- const timer = setInterval(async () => {
825
- const resolved = await resolveOwner(root, sessionId);
826
- if (!resolved.live) stop();
839
+ const timer = setInterval(() => {
840
+ void resolveOwner(root, sessionId).then(resolved => {
841
+ if (!resolved.live) stop();
842
+ });
827
843
  }, 500);
828
844
  timer.unref?.();
829
845
  process.on("SIGTERM", stop);
830
846
  process.on("SIGINT", stop);
831
847
  });
832
848
  await owner.stop();
833
- process.exit(0);
834
849
  }
835
850
 
836
851
  #buildOwnerCommand(sessionId: string): string[] {
@@ -841,7 +856,7 @@ export default class Harness extends Command {
841
856
  }
842
857
 
843
858
  async #waitForOwner(root: string, sessionId: string): Promise<boolean> {
844
- for (let i = 0; i < 100; i++) {
859
+ for (let i = 0; i < 160; i++) {
845
860
  const owner = await resolveOwner(root, sessionId);
846
861
  if (owner.live && owner.socketPath) {
847
862
  try {
@@ -855,6 +870,38 @@ export default class Harness extends Command {
855
870
  }
856
871
  return false;
857
872
  }
873
+ /**
874
+ * Reap an exact detached-owner child the parent spawned but declared not-live. The parent
875
+ * owns this PID's lifecycle (it spawned it), so shutdown is exact-owner scoped: SIGTERM, a
876
+ * bounded grace wait, then SIGKILL, then verify the SAME PID exited via its exit promise.
877
+ * Never name-based — the spawned Subprocess pins the exact owner identity, so a not-live
878
+ * declaration must not orphan a daemon the parent brought into being.
879
+ */
880
+ async #reapDetachedOwner(
881
+ child: Bun.Subprocess<"ignore", "ignore", "ignore">,
882
+ ): Promise<{ pid: number; verified: boolean }> {
883
+ // A resolved exit promise proves the PID is gone; a rejection is NOT proof of exit (it may
884
+ // surface an error observing the subprocess), so map it to false and let the SIGKILL
885
+ // escalation + cleanup-uncertain surfacing handle the uncertainty.
886
+ const exited = child.exited.then(
887
+ () => true,
888
+ () => false,
889
+ );
890
+ const send = (signal: NodeJS.Signals): void => {
891
+ try {
892
+ child.kill(signal);
893
+ } catch {
894
+ // Kill may fail if the child already exited; the exited race below is authoritative.
895
+ }
896
+ };
897
+ send("SIGTERM");
898
+ let verified = await Promise.race([exited, Bun.sleep(2000).then(() => false)]);
899
+ if (!verified) {
900
+ send("SIGKILL");
901
+ verified = await Promise.race([exited, Bun.sleep(1000).then(() => false)]);
902
+ }
903
+ return { pid: child.pid, verified };
904
+ }
858
905
 
859
906
  async #harnessOwnerIsolationProbe(tmuxCommand: string): Promise<OwnerIsolationProbe> {
860
907
  return {
@@ -862,6 +909,7 @@ export default class Harness extends Command {
862
909
  process.env.GJC_HARNESS_TEST_CALLER_CGROUP ??
863
910
  (await fs.readFile("/proc/self/cgroup", "utf8").catch(() => null)),
864
911
  probeServer: async (socketKey, tmuxControlArgv): Promise<TmuxServerProof> => {
912
+ const platform = ownerIsolationPlatform();
865
913
  if (!socketKey || socketKey.length > 128) return { state: "unverifiable" };
866
914
  const controlArgv = tmuxControlArgv ?? [tmuxCommand, "-L", socketKey];
867
915
  if (controlArgv.length < 3 || controlArgv[0] !== tmuxCommand || !controlArgv.includes("-L")) {
@@ -878,20 +926,16 @@ export default class Harness extends Command {
878
926
  if (!Number.isSafeInteger(pid) || pid <= 0) return { state: "unverifiable" };
879
927
  const cgroupText =
880
928
  process.env.GJC_HARNESS_TEST_SERVER_CGROUP ??
881
- (process.platform === "linux"
882
- ? await fs.readFile(`/proc/${pid}/cgroup`, "utf8").catch(() => null)
883
- : null);
929
+ (platform === "linux" ? await fs.readFile(`/proc/${pid}/cgroup`, "utf8").catch(() => null) : null);
884
930
  const testStartTime = process.env.GJC_HARNESS_TEST_SERVER_START_TIME;
885
931
  const stat =
886
- testStartTime || process.platform !== "linux"
932
+ testStartTime || platform !== "linux"
887
933
  ? null
888
934
  : await fs.readFile(`/proc/${pid}/stat`, "utf8").catch(() => null);
889
- const cgroup = classifyCgroup({ platform: process.platform, cgroupText });
935
+ const cgroup = classifyCgroup({ platform, cgroupText });
890
936
  const startTime =
891
937
  testStartTime ??
892
- (process.platform === "linux"
893
- ? ownerProcessStartTime(process.platform, stat)
894
- : portableProcessStartTime(pid));
938
+ (platform === "linux" ? ownerProcessStartTime(platform, stat) : portableProcessStartTime(pid));
895
939
  if (!startTime) return { state: "unverifiable", pid, cgroup };
896
940
  return {
897
941
  state:
@@ -996,7 +1040,8 @@ export default class Harness extends Command {
996
1040
  } catch {
997
1041
  return { started: false, sessionName, socketKey, reason: "tmux-owner-generation_unverifiable" };
998
1042
  }
999
- if (process.platform !== "linux" && !portableProcessStartTime(process.pid))
1043
+ const platform = ownerIsolationPlatform();
1044
+ if (platform !== "linux" && !portableProcessStartTime(process.pid))
1000
1045
  return { started: false, sessionName, socketKey, reason: "tmux-owner-generation_unverifiable" };
1001
1046
  await fs.mkdir(path.join(ownerStateDir, sessionId, "owner-lifecycle"), { recursive: true, mode: 0o700 });
1002
1047
  const ownerGeneration = randomUUID();
@@ -1008,10 +1053,10 @@ export default class Harness extends Command {
1008
1053
  ];
1009
1054
  if (process.env[RECEIPT_SPOOL_DIR_ENV])
1010
1055
  envAssignments.push(`${RECEIPT_SPOOL_DIR_ENV}=${shellQuote(process.env[RECEIPT_SPOOL_DIR_ENV])}`);
1011
- if (process.env.GJC_HARNESS_RPC_COMMAND)
1012
- envAssignments.push(`GJC_HARNESS_RPC_COMMAND=${shellQuote(process.env.GJC_HARNESS_RPC_COMMAND)}`);
1013
1056
  if (process.env.GJC_HARNESS_TEST_NODE_MODULES)
1014
1057
  envAssignments.push(`GJC_HARNESS_TEST_NODE_MODULES=${shellQuote(process.env.GJC_HARNESS_TEST_NODE_MODULES)}`);
1058
+ if (process.env.GJC_SDK_DISABLE)
1059
+ envAssignments.push(`GJC_SDK_DISABLE=${shellQuote(process.env.GJC_SDK_DISABLE)}`);
1015
1060
  const shellCommand = `exec env ${envAssignments.join(" ")} ${this.#buildOwnerCommand(sessionId).map(shellQuote).join(" ")}`;
1016
1061
  const probe = await this.#harnessOwnerIsolationProbe(tmuxCommand);
1017
1062
  const probeServer = probe.probeServer;
@@ -1036,7 +1081,7 @@ export default class Harness extends Command {
1036
1081
  {
1037
1082
  schema_version: 1,
1038
1083
  op: "plan",
1039
- platform: process.platform,
1084
+ platform,
1040
1085
  session_id: sessionId,
1041
1086
  owner_generation: ownerGeneration,
1042
1087
  baseline,
@@ -1216,6 +1261,7 @@ export default class Harness extends Command {
1216
1261
  ...(process.env.GJC_HARNESS_TEST_NODE_MODULES
1217
1262
  ? { GJC_HARNESS_TEST_NODE_MODULES: process.env.GJC_HARNESS_TEST_NODE_MODULES }
1218
1263
  : {}),
1264
+ ...(process.env.GJC_SDK_DISABLE ? { GJC_SDK_DISABLE: process.env.GJC_SDK_DISABLE } : {}),
1219
1265
  },
1220
1266
  stdout: "ignore",
1221
1267
  stderr: "ignore",
@@ -1223,6 +1269,7 @@ export default class Harness extends Command {
1223
1269
  });
1224
1270
  child.unref();
1225
1271
  const live = await this.#waitForOwner(root, sessionId);
1272
+ const detachedOwnerReaped = live ? null : await this.#reapDetachedOwner(child);
1226
1273
  return {
1227
1274
  live,
1228
1275
  runtime: "detached",
@@ -1230,6 +1277,7 @@ export default class Harness extends Command {
1230
1277
  socketKey: null,
1231
1278
  fallbackReason,
1232
1279
  blockerReason: live ? null : "detached-owner-not-live",
1280
+ ...(detachedOwnerReaped ? { detachedOwnerReaped } : {}),
1233
1281
  };
1234
1282
  }
1235
1283
 
@@ -1274,7 +1322,7 @@ export default class Harness extends Command {
1274
1322
  base: typeof input.base === "string" ? input.base : null,
1275
1323
  issueOrPr: preflight.normalizedIssueOrPr,
1276
1324
  processHandle: { kind: "runtime-owner", ownerId: null, pid: null },
1277
- rpcHandle: { kind: "rpc-subprocess", pid: null, sessionDir: `${root}/sessions/${sessionId}/gjc-session` },
1325
+ sdkHandle: { kind: "sdk-session-endpoint", sessionId },
1278
1326
  ownerHandle: { leasePath, endpoint: null, heartbeatAt: null },
1279
1327
  routerHandle: { kind: "default-in-owner", policy: "default-fallback", eventsPath },
1280
1328
  viewportHandle: { kind: "event-monitor", tmuxSessionName: null, viewOnly: true },
@@ -1299,6 +1347,7 @@ export default class Harness extends Command {
1299
1347
  let ownerFallbackReason: string | null = null;
1300
1348
  let ownerBlockerReason: string | null = null;
1301
1349
  let ownerSocketKey: string | null = null;
1350
+ let ownerDetachedReaped: { pid: number; verified: boolean } | null = null;
1302
1351
  if (input.detach === true) {
1303
1352
  const ownerSpawn = await this.#spawnDetachedOwner(root, sessionId, workspace);
1304
1353
  ownerLive = ownerSpawn.live;
@@ -1306,6 +1355,7 @@ export default class Harness extends Command {
1306
1355
  ownerFallbackReason = ownerSpawn.fallbackReason;
1307
1356
  ownerBlockerReason = ownerSpawn.blockerReason;
1308
1357
  ownerSocketKey = ownerSpawn.socketKey;
1358
+ ownerDetachedReaped = ownerSpawn.detachedOwnerReaped ?? null;
1309
1359
  handle.viewportHandle = {
1310
1360
  kind: "event-monitor",
1311
1361
  tmuxSessionName: ownerSpawn.tmuxSessionName,
@@ -1330,7 +1380,13 @@ export default class Harness extends Command {
1330
1380
  // A live endpoint never proves a failed tmux launch safe: preserve the isolation/provenance blocker.
1331
1381
  if (ownerBlockerReason) {
1332
1382
  state.lifecycle = "blocked";
1333
- state.blockers = [...state.blockers, ownerBlockerReason];
1383
+ // `detached-owner-not-live` is the lifecycle status; an unverified reap (the exact
1384
+ // spawned child never confirmed exit after SIGKILL) is a stronger, distinct signal that
1385
+ // must not be masked by the not-live blocker alone.
1386
+ const ownerBlockers = [ownerBlockerReason];
1387
+ if (ownerDetachedReaped && !ownerDetachedReaped.verified)
1388
+ ownerBlockers.push("detached-owner-cleanup-uncertain");
1389
+ state.blockers = [...state.blockers, ...ownerBlockers];
1334
1390
  state.handle = handle;
1335
1391
  state.updatedAt = nowIso();
1336
1392
  await writeSessionState(root, state);
@@ -1346,6 +1402,7 @@ export default class Harness extends Command {
1346
1402
  ...(ownerSocketKey ? { tmuxOwnerSocketKey: ownerSocketKey } : {}),
1347
1403
  ...(ownerFallbackReason ? { ownerFallbackReason } : {}),
1348
1404
  ...(ownerBlockerReason ? { reason: ownerBlockerReason } : {}),
1405
+ ...(ownerDetachedReaped ? { detachedOwnerReaped: ownerDetachedReaped } : {}),
1349
1406
  },
1350
1407
  !ownerBlockerReason,
1351
1408
  ),
@@ -105,12 +105,15 @@ export default class Index extends Command {
105
105
  "append-system-prompt": Flags.string({
106
106
  description: "Append text or file contents to the system prompt",
107
107
  }),
108
+ "mcp-config": Flags.string({
109
+ description: "Tools-only MCP config file (absolute path)",
110
+ }),
108
111
  "allow-home": Flags.boolean({
109
112
  description: "Allow starting in ~ without auto-switching to a temp dir",
110
113
  }),
111
114
  mode: Flags.string({
112
- description: "Output mode: text (default), json, rpc, acp, rpc-ui, or bridge",
113
- options: ["text", "json", "rpc", "acp", "rpc-ui", "bridge"],
115
+ description: "Output mode: text (default), json, or acp",
116
+ options: ["text", "json", "acp"],
114
117
  }),
115
118
  print: Flags.boolean({
116
119
  char: "p",
@@ -5,13 +5,15 @@ import {
5
5
  COORDINATOR_MCP_TOOL_NAMES,
6
6
  } from "../coordinator/contract";
7
7
  import { runCoordinatorMcpStdio } from "../coordinator-mcp/server";
8
+ import { runSdkMcpStdio, SDK_MCP_TOOL_NAMES } from "../sdk/mcp/server";
8
9
 
9
10
  function writeJson(value: unknown): void {
10
11
  process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
11
12
  }
12
13
 
13
14
  export function validateMcpServeSubcommandForTest(server: string | undefined): void {
14
- if (server !== "coordinator" && server !== "hermes") throw new Error(`unknown_mcp_serve_subcommand:${server ?? ""}`);
15
+ if (server !== "coordinator" && server !== "hermes" && server !== "sdk")
16
+ throw new Error(`unknown_mcp_serve_subcommand:${server ?? ""}`);
15
17
  }
16
18
 
17
19
  export default class McpServe extends Command {
@@ -19,7 +21,7 @@ export default class McpServe extends Command {
19
21
  static strict = false;
20
22
 
21
23
  static args = {
22
- server: Args.string({ description: "MCP server to run (coordinator or hermes alias)", required: false }),
24
+ server: Args.string({ description: "MCP server to run (sdk, coordinator, or hermes alias)", required: false }),
23
25
  };
24
26
 
25
27
  static flags = {
@@ -44,17 +46,22 @@ export default class McpServe extends Command {
44
46
  }
45
47
 
46
48
  if (flags.check) {
47
- const payload = {
48
- ok: true,
49
- server: { name: COORDINATOR_MCP_SERVER_NAME, protocolVersion: COORDINATOR_MCP_PROTOCOL_VERSION },
50
- readOnly: true,
51
- tools: [...COORDINATOR_MCP_TOOL_NAMES],
52
- };
49
+ const payload =
50
+ server === "sdk"
51
+ ? { ok: true, server: { name: "gjc-sdk-mcp" }, readOnly: false, tools: [...SDK_MCP_TOOL_NAMES] }
52
+ : {
53
+ ok: true,
54
+ server: { name: COORDINATOR_MCP_SERVER_NAME, protocolVersion: COORDINATOR_MCP_PROTOCOL_VERSION },
55
+ readOnly: true,
56
+ tools: [...COORDINATOR_MCP_TOOL_NAMES],
57
+ };
53
58
  if (flags.json) writeJson(payload);
54
- else
55
- process.stdout.write(
56
- `server: ${payload.server.name}\nprotocol: ${payload.server.protocolVersion}\ntools: ${payload.tools.length}\n`,
57
- );
59
+ else process.stdout.write(`server: ${payload.server.name}\ntools: ${payload.tools.length}\n`);
60
+ return;
61
+ }
62
+
63
+ if (server === "sdk") {
64
+ await runSdkMcpStdio();
58
65
  return;
59
66
  }
60
67
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Configure Telegram notifications.
2
+ * Configure Telegram, Discord, or Slack notifications.
3
3
  */
4
4
  import { Args, Command, Flags } from "@gajae-code/utils/cli";
5
5
  import { type NotifyAction, type NotifyCommandArgs, runNotifyCliCommand } from "../cli/notify-cli";
@@ -8,7 +8,7 @@ import { initTheme } from "../modes/theme/theme";
8
8
  const ACTIONS: NotifyAction[] = ["setup", "status", "health", "test", "recovery", "daemon-internal"];
9
9
 
10
10
  export default class Notify extends Command {
11
- static description = "Configure Telegram notifications";
11
+ static description = "Configure Telegram, Discord, or Slack notifications";
12
12
 
13
13
  static args = {
14
14
  action: Args.string({
@@ -17,7 +17,7 @@ export default class Notify extends Command {
17
17
  options: ACTIONS,
18
18
  }),
19
19
  extra: Args.string({
20
- description: "Additional internal args",
20
+ description: "Provider or additional internal args",
21
21
  required: false,
22
22
  multiple: true,
23
23
  }),
@@ -27,6 +27,19 @@ export default class Notify extends Command {
27
27
  smoke: Flags.boolean({ description: "Run hidden daemon smoke" }),
28
28
  token: Flags.string({ description: "Telegram bot token (non-interactive setup)" }),
29
29
  "chat-id": Flags.string({ description: "Telegram chat id to pair (non-interactive setup)" }),
30
+ "discord-bot-token": Flags.string({ description: "Discord bot token (non-interactive Discord setup)" }),
31
+ "discord-application-id": Flags.string({ description: "Discord application id (non-interactive Discord setup)" }),
32
+ "discord-guild-id": Flags.string({ description: "Discord guild id (non-interactive Discord setup)" }),
33
+ "discord-parent-channel-id": Flags.string({
34
+ description: "Discord parent channel id (non-interactive Discord setup)",
35
+ }),
36
+ "slack-bot-token": Flags.string({ description: "Slack bot token (non-interactive Slack setup)" }),
37
+ "slack-app-token": Flags.string({ description: "Slack app token (non-interactive Slack setup)" }),
38
+ "slack-workspace-id": Flags.string({ description: "Slack workspace id (non-interactive Slack setup)" }),
39
+ "slack-channel-id": Flags.string({ description: "Slack channel id (non-interactive Slack setup)" }),
40
+ "slack-authorized-user-id": Flags.string({
41
+ description: "Slack user id authorized for inbound replies and commands",
42
+ }),
30
43
  redact: Flags.boolean({ description: "Enable redaction of remote notification content" }),
31
44
  probe: Flags.boolean({ description: "notify health: probe Telegram reachability (getMe)" }),
32
45
  message: Flags.string({ description: "notify test: custom message body" }),
@@ -47,13 +60,33 @@ export default class Notify extends Command {
47
60
  ...(agentDir ? ["--agent-dir", agentDir] : []),
48
61
  ...extra,
49
62
  ];
63
+ const provider = extra[0];
64
+ if (
65
+ action === "setup" &&
66
+ provider !== undefined &&
67
+ provider !== "telegram" &&
68
+ provider !== "discord" &&
69
+ provider !== "slack"
70
+ ) {
71
+ throw new Error(`Unknown notification provider: ${provider}`);
72
+ }
50
73
 
51
74
  const cmd: NotifyCommandArgs = {
52
75
  action,
53
76
  smoke: flags.smoke,
54
77
  rawArgs,
78
+ provider: provider === "telegram" || provider === "discord" || provider === "slack" ? provider : undefined,
55
79
  token: flags.token as string | undefined,
56
80
  chatId: (flags as Record<string, unknown>)["chat-id"] as string | undefined,
81
+ discordBotToken: flagRec["discord-bot-token"] as string | undefined,
82
+ discordApplicationId: flagRec["discord-application-id"] as string | undefined,
83
+ discordGuildId: flagRec["discord-guild-id"] as string | undefined,
84
+ discordParentChannelId: flagRec["discord-parent-channel-id"] as string | undefined,
85
+ slackBotToken: flagRec["slack-bot-token"] as string | undefined,
86
+ slackAppToken: flagRec["slack-app-token"] as string | undefined,
87
+ slackWorkspaceId: flagRec["slack-workspace-id"] as string | undefined,
88
+ slackChannelId: flagRec["slack-channel-id"] as string | undefined,
89
+ slackAuthorizedUserId: flagRec["slack-authorized-user-id"] as string | undefined,
57
90
  redact: Boolean(flags.redact),
58
91
  probe: Boolean(flags.probe),
59
92
  message: flags.message as string | undefined,