@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
@@ -12,10 +12,10 @@
12
12
  * swapped in later without changing callers.
13
13
  */
14
14
  import { createHash } from "node:crypto";
15
- import type { RpcJsonSchema, RpcWorkflowGateValidationError } from "../../rpc/rpc-types";
15
+ import type { JsonSchema, WorkflowGateValidationError } from "./workflow-gate-types";
16
16
 
17
17
  /** Keywords this wrapper understands. Any other keyword is rejected. */
18
- const SUPPORTED_KEYWORDS = new Set<keyof RpcJsonSchema>([
18
+ const SUPPORTED_KEYWORDS = new Set<keyof JsonSchema>([
19
19
  "type",
20
20
  "enum",
21
21
  "const",
@@ -65,7 +65,7 @@ export function canonicalJson(value: unknown): string {
65
65
  return `{${entries.join(",")}}`;
66
66
  }
67
67
 
68
- export function schemaHash(schema: RpcJsonSchema): string {
68
+ export function schemaHash(schema: JsonSchema): string {
69
69
  return createHash("sha256").update(canonicalJson(schema)).digest("hex");
70
70
  }
71
71
 
@@ -74,7 +74,7 @@ function answerHashOf(answer: unknown): string {
74
74
  }
75
75
 
76
76
  /** Validate the schema *shape*. Throws WorkflowGateSchemaError on any problem. */
77
- export function assertSupportedGateSchema(schema: RpcJsonSchema): void {
77
+ export function assertSupportedGateSchema(schema: JsonSchema): void {
78
78
  const serialized = canonicalJson(schema);
79
79
  if (Buffer.byteLength(serialized, "utf8") > GATE_SCHEMA_LIMITS.maxSchemaBytes) {
80
80
  throw new WorkflowGateSchemaError(`schema exceeds ${GATE_SCHEMA_LIMITS.maxSchemaBytes} bytes`);
@@ -82,7 +82,7 @@ export function assertSupportedGateSchema(schema: RpcJsonSchema): void {
82
82
  walkSchema(schema, 0, "#");
83
83
  }
84
84
 
85
- function walkSchema(schema: RpcJsonSchema, depth: number, path: string): void {
85
+ function walkSchema(schema: JsonSchema, depth: number, path: string): void {
86
86
  if (depth > GATE_SCHEMA_LIMITS.maxDepth) {
87
87
  throw new WorkflowGateSchemaError(`schema nesting exceeds depth ${GATE_SCHEMA_LIMITS.maxDepth} at ${path}`);
88
88
  }
@@ -90,7 +90,7 @@ function walkSchema(schema: RpcJsonSchema, depth: number, path: string): void {
90
90
  throw new WorkflowGateSchemaError(`schema node at ${path} must be an object`);
91
91
  }
92
92
  for (const key of Object.keys(schema)) {
93
- if (!SUPPORTED_KEYWORDS.has(key as keyof RpcJsonSchema)) {
93
+ if (!SUPPORTED_KEYWORDS.has(key as keyof JsonSchema)) {
94
94
  throw new WorkflowGateSchemaError(`unsupported keyword "${key}" at ${path}`);
95
95
  }
96
96
  }
@@ -148,7 +148,7 @@ function walkSchema(schema: RpcJsonSchema, depth: number, path: string): void {
148
148
  if (propKeys.length > GATE_SCHEMA_LIMITS.maxProperties) {
149
149
  throw new WorkflowGateSchemaError(`properties at ${path} exceed ${GATE_SCHEMA_LIMITS.maxProperties}`);
150
150
  }
151
- for (const k of propKeys) walkSchema(schema.properties[k] as RpcJsonSchema, depth + 1, `${path}/properties/${k}`);
151
+ for (const k of propKeys) walkSchema(schema.properties[k] as JsonSchema, depth + 1, `${path}/properties/${k}`);
152
152
  }
153
153
  if (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== "boolean") {
154
154
  if (
@@ -166,7 +166,7 @@ function walkSchema(schema: RpcJsonSchema, depth: number, path: string): void {
166
166
  if (branches !== undefined) {
167
167
  if (!Array.isArray(branches)) throw new WorkflowGateSchemaError(`${combiner} at ${path} must be an array`);
168
168
  for (let i = 0; i < branches.length; i++)
169
- walkSchema(branches[i] as RpcJsonSchema, depth + 1, `${path}/${combiner}/${i}`);
169
+ walkSchema(branches[i] as JsonSchema, depth + 1, `${path}/${combiner}/${i}`);
170
170
  }
171
171
  }
172
172
  }
@@ -175,7 +175,7 @@ type SchemaError = { path: string; keyword: string; message: string; expected?:
175
175
 
176
176
  /** A compiled, cached validator for one schema. */
177
177
  export interface CompiledGateSchema {
178
- readonly schema: RpcJsonSchema;
178
+ readonly schema: JsonSchema;
179
179
  readonly hash: string;
180
180
  validate(answer: unknown): SchemaError[];
181
181
  }
@@ -183,7 +183,7 @@ export interface CompiledGateSchema {
183
183
  const compileCache = new Map<string, CompiledGateSchema>();
184
184
 
185
185
  /** Compile (and cache) a validator for a schema. Asserts shape on first compile. */
186
- export function compileGateSchema(schema: RpcJsonSchema): CompiledGateSchema {
186
+ export function compileGateSchema(schema: JsonSchema): CompiledGateSchema {
187
187
  const hash = schemaHash(schema);
188
188
  const cached = compileCache.get(hash);
189
189
  if (cached) return cached;
@@ -206,7 +206,7 @@ export function compileGateSchema(schema: RpcJsonSchema): CompiledGateSchema {
206
206
  return compiled;
207
207
  }
208
208
 
209
- function typeMatches(type: NonNullable<RpcJsonSchema["type"]>, value: unknown): boolean {
209
+ function typeMatches(type: NonNullable<JsonSchema["type"]>, value: unknown): boolean {
210
210
  switch (type) {
211
211
  case "string":
212
212
  return typeof value === "string";
@@ -225,7 +225,7 @@ function typeMatches(type: NonNullable<RpcJsonSchema["type"]>, value: unknown):
225
225
  }
226
226
  }
227
227
 
228
- function validateValue(schema: RpcJsonSchema, value: unknown, path: string, errors: SchemaError[]): void {
228
+ function validateValue(schema: JsonSchema, value: unknown, path: string, errors: SchemaError[]): void {
229
229
  if (schema.type !== undefined && !typeMatches(schema.type, value)) {
230
230
  errors.push({ path, keyword: "type", message: `expected ${schema.type}`, expected: schema.type });
231
231
  return;
@@ -318,7 +318,7 @@ function validateValue(schema: RpcJsonSchema, value: unknown, path: string, erro
318
318
  }
319
319
  if (schema.items) {
320
320
  for (let i = 0; i < value.length; i++)
321
- validateValue(schema.items as RpcJsonSchema, value[i], `${path}/${i}`, errors);
321
+ validateValue(schema.items as JsonSchema, value[i], `${path}/${i}`, errors);
322
322
  }
323
323
  }
324
324
  for (const combiner of ["oneOf", "anyOf"] as const) {
@@ -336,13 +336,13 @@ function validateValue(schema: RpcJsonSchema, value: unknown, path: string, erro
336
336
 
337
337
  /**
338
338
  * Validate an answer against a compiled gate schema. Returns `null` on success
339
- * or a typed {@link RpcWorkflowGateValidationError} on mismatch.
339
+ * or a typed {@link WorkflowGateValidationError} on mismatch.
340
340
  */
341
341
  export function validateGateAnswer(
342
342
  compiled: CompiledGateSchema,
343
343
  gateId: string,
344
344
  answer: unknown,
345
- ): RpcWorkflowGateValidationError | null {
345
+ ): WorkflowGateValidationError | null {
346
346
  const errors = compiled.validate(answer);
347
347
  if (errors.length === 0) return null;
348
348
  return { code: "invalid_workflow_gate_answer", gate_id: gateId, schema_hash: compiled.hash, errors };
@@ -0,0 +1,113 @@
1
+ /** Transport-neutral workflow gate contract used by SDK workflow coordination. */
2
+
3
+ /** Lifecycle stages that emit machine-addressable SDK workflow gates. */
4
+ export type WorkflowStage = "deep-interview" | "ralplan" | "ultragoal";
5
+
6
+ /** Reserved stage names that are explicitly not part of the v1 contract. */
7
+ export const RESERVED_WORKFLOW_STAGES: readonly string[] = ["team"];
8
+
9
+ export type WorkflowGateKind = "question" | "approval" | "execution";
10
+
11
+ /** The documented JSON Schema 2020-12 subset supported by the gate validator. */
12
+ export interface JsonSchema {
13
+ type?: "string" | "number" | "integer" | "boolean" | "object" | "array" | "null";
14
+ enum?: unknown[];
15
+ const?: unknown;
16
+ properties?: Record<string, JsonSchema>;
17
+ required?: string[];
18
+ additionalProperties?: boolean | JsonSchema;
19
+ items?: JsonSchema;
20
+ minLength?: number;
21
+ maxLength?: number;
22
+ pattern?: string;
23
+ minItems?: number;
24
+ maxItems?: number;
25
+ uniqueItems?: boolean;
26
+ minimum?: number;
27
+ maximum?: number;
28
+ title?: string;
29
+ description?: string;
30
+ oneOf?: JsonSchema[];
31
+ anyOf?: JsonSchema[];
32
+ }
33
+
34
+ export interface WorkflowGateOption {
35
+ value: unknown;
36
+ label: string;
37
+ description?: string;
38
+ }
39
+
40
+ export interface WorkflowGateContext {
41
+ title?: string;
42
+ plan?: string;
43
+ source?: string;
44
+ prompt?: string;
45
+ summary?: string;
46
+ stage_state?: Record<string, unknown>;
47
+ artifact_refs?: Array<{ kind: string; path?: string; sha256?: string }>;
48
+ language?: string;
49
+ }
50
+
51
+ /** Outbound event: a machine-addressable workflow gate awaiting an answer. */
52
+ export interface WorkflowGate {
53
+ type: "workflow_gate";
54
+ gate_id: string;
55
+ stage: WorkflowStage;
56
+ kind: WorkflowGateKind;
57
+ schema: JsonSchema;
58
+ schema_hash: string;
59
+ options?: WorkflowGateOption[];
60
+ context: WorkflowGateContext;
61
+ created_at: string;
62
+ required: true;
63
+ }
64
+
65
+ /** Non-actionable durable-gate state retained for restart diagnostics. */
66
+ export interface WorkflowGateLifecycle {
67
+ state: "quarantined";
68
+ reason:
69
+ | "orphaned_after_process_restart"
70
+ | "accepted_unadvanced_after_process_restart"
71
+ | "continuation_owner_lost"
72
+ | "opened_without_continuation"
73
+ | "finalization_failed"
74
+ | "advance_failed";
75
+ quarantinedAt: string;
76
+ supersededByGateId?: string;
77
+ }
78
+
79
+ /** A quarantined gate is diagnostic-only and must never be presented or answered. */
80
+ export interface WorkflowGateDiagnostic extends WorkflowGate {
81
+ id: string;
82
+ tag: "quarantined";
83
+ lifecycle: WorkflowGateLifecycle;
84
+ }
85
+
86
+ /** Stable Q12 row preserving the root WorkflowGate shape. */
87
+ export type WorkflowGateQueryRecord =
88
+ | (WorkflowGate & { id: string; tag: "pending"; lifecycle?: undefined })
89
+ | WorkflowGateDiagnostic;
90
+
91
+ /** Inbound: the agent's answer to a workflow gate. */
92
+ export interface WorkflowGateResponse {
93
+ gate_id: string;
94
+ answer: unknown;
95
+ idempotency_key?: string;
96
+ }
97
+
98
+ /** Outcome of resolving a gate, surfaced back to the answering client. */
99
+ export interface WorkflowGateResolution {
100
+ gate_id: string;
101
+ status: "accepted" | "rejected";
102
+ answer_hash: string;
103
+ resolved_at: string;
104
+ error?: WorkflowGateValidationError;
105
+ }
106
+
107
+ /** Typed error shape for schema validation failures. */
108
+ export interface WorkflowGateValidationError {
109
+ code: "invalid_workflow_gate_answer";
110
+ gate_id: string;
111
+ schema_hash: string;
112
+ errors: Array<{ path: string; keyword: string; message: string; expected?: unknown }>;
113
+ }
@@ -14,6 +14,7 @@ import type { CompactOptions } from "../extensibility/extensions/types";
14
14
  import type { Skill } from "../extensibility/skills";
15
15
  import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
16
16
  import type { MCPManager } from "../runtime-mcp";
17
+ import type { NotificationSessionReconcileResult, NotificationSessionStatus } from "../sdk/bus/session-control";
17
18
  import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
18
19
  import type { HistoryStorage } from "../session/history-storage";
19
20
  import type { SessionContext, SessionManager } from "../session/session-manager";
@@ -96,6 +97,10 @@ export interface InteractiveModeContext {
96
97
  mcpManager?: MCPManager;
97
98
  lspServers?: LspStartupServerInfo[];
98
99
 
100
+ /** Shared controller query; absent in ACP/lightweight test contexts. */
101
+ getCurrentSessionNotificationStatus?(): NotificationSessionStatus | undefined;
102
+ /** Toggle only the current session; absent in ACP/lightweight test contexts. */
103
+ setCurrentSessionNotificationsEnabled?(enabled: boolean): Promise<NotificationSessionReconcileResult | undefined>;
99
104
  readonly ircLedger: IrcObservationLedger;
100
105
  // State
101
106
  isInitialized: boolean;
@@ -35,6 +35,7 @@ import type {
35
35
  MCPToolsListResult,
36
36
  MCPTransport,
37
37
  } from "./types";
38
+ import { MCPExpectedFailure } from "./types";
38
39
 
39
40
  /** MCP protocol version we support */
40
41
  const PROTOCOL_VERSION = "2025-03-26";
@@ -47,6 +48,66 @@ const CLIENT_INFO = {
47
48
  name: "gjc-coding-agent",
48
49
  version: "1.0.0",
49
50
  };
51
+ function isRecord(value: unknown): value is Record<string, unknown> {
52
+ return typeof value === "object" && value !== null && !Array.isArray(value);
53
+ }
54
+
55
+ function decodeInitializeResult(value: unknown): MCPInitializeResult {
56
+ if (
57
+ !isRecord(value) ||
58
+ typeof value.protocolVersion !== "string" ||
59
+ !isRecord(value.capabilities) ||
60
+ !isRecord(value.serverInfo) ||
61
+ typeof value.serverInfo.name !== "string" ||
62
+ typeof value.serverInfo.version !== "string" ||
63
+ (value.instructions !== undefined && typeof value.instructions !== "string")
64
+ ) {
65
+ throw new MCPExpectedFailure();
66
+ }
67
+
68
+ return {
69
+ protocolVersion: value.protocolVersion,
70
+ capabilities: value.capabilities as MCPServerCapabilities,
71
+ serverInfo: {
72
+ name: value.serverInfo.name,
73
+ version: value.serverInfo.version,
74
+ },
75
+ ...(value.instructions === undefined ? {} : { instructions: value.instructions }),
76
+ };
77
+ }
78
+
79
+ function decodeToolsListResult(value: unknown): MCPToolsListResult {
80
+ if (
81
+ !isRecord(value) ||
82
+ !Array.isArray(value.tools) ||
83
+ (value.nextCursor !== undefined && typeof value.nextCursor !== "string")
84
+ ) {
85
+ throw new MCPExpectedFailure();
86
+ }
87
+
88
+ const tools = value.tools.map(tool => {
89
+ if (
90
+ !isRecord(tool) ||
91
+ typeof tool.name !== "string" ||
92
+ !isRecord(tool.inputSchema) ||
93
+ tool.inputSchema.type !== "object" ||
94
+ (tool.inputSchema.properties !== undefined && !isRecord(tool.inputSchema.properties)) ||
95
+ (tool.inputSchema.required !== undefined &&
96
+ (!Array.isArray(tool.inputSchema.required) ||
97
+ !tool.inputSchema.required.every(item => typeof item === "string"))) ||
98
+ (tool.description !== undefined && typeof tool.description !== "string")
99
+ ) {
100
+ throw new MCPExpectedFailure();
101
+ }
102
+ return {
103
+ name: tool.name,
104
+ inputSchema: { ...tool.inputSchema, type: "object" as const },
105
+ ...(tool.description === undefined ? {} : { description: tool.description }),
106
+ };
107
+ });
108
+
109
+ return value.nextCursor === undefined ? { tools } : { tools, nextCursor: value.nextCursor };
110
+ }
50
111
 
51
112
  /**
52
113
  * Default handler for standard MCP server-to-client requests.
@@ -93,22 +154,22 @@ async function initializeConnection(
93
154
  transport: MCPTransport,
94
155
  options?: {
95
156
  signal?: AbortSignal;
157
+ /** Whether to advertise the roots/list capability (default: true). */
158
+ advertiseRoots?: boolean;
96
159
  /** Called after the initialize response (which sets the session ID) but before notifications/initialized. */
97
160
  onInitialized?: () => void | Promise<void>;
98
161
  },
99
162
  ): Promise<MCPInitializeResult> {
100
163
  const params: MCPInitializeParams = {
101
164
  protocolVersion: PROTOCOL_VERSION,
102
- capabilities: {
103
- roots: { listChanged: false },
104
- },
165
+ capabilities: options?.advertiseRoots === false ? {} : { roots: { listChanged: false } },
105
166
  clientInfo: CLIENT_INFO,
106
167
  };
107
168
 
108
- const result = await transport.request<MCPInitializeResult>(
109
- "initialize",
110
- params as unknown as Record<string, unknown>,
111
- { signal: options?.signal },
169
+ const result = decodeInitializeResult(
170
+ await transport.request<unknown>("initialize", params as unknown as Record<string, unknown>, {
171
+ signal: options?.signal,
172
+ }),
112
173
  );
113
174
 
114
175
  if (options?.signal?.aborted) {
@@ -135,6 +196,8 @@ export async function connectToServer(
135
196
  config: MCPServerConfig,
136
197
  options?: {
137
198
  signal?: AbortSignal;
199
+ /** Whether to advertise the roots/list capability (default: true). */
200
+ advertiseRoots?: boolean;
138
201
  onNotification?: (method: string, params: unknown) => void;
139
202
  onRequest?: (method: string, params: unknown) => Promise<unknown>;
140
203
  },
@@ -150,14 +213,14 @@ export async function connectToServer(
150
213
  transport.onNotification = options.onNotification;
151
214
  }
152
215
 
153
- // Always handle standard MCP server-to-client requests (ping, roots/list).
154
- // The initialize request declares roots capability, so we must respond to
155
- // roots/list — even for short-lived test connections.
216
+ // Always install a handler for standard MCP server-to-client requests.
217
+ // Callers that do not advertise roots can reject roots/list via onRequest.
156
218
  transport.onRequest = options?.onRequest ?? defaultRequestHandler;
157
219
 
158
220
  try {
159
221
  const initResult = await initializeConnection(transport, {
160
222
  signal: connectSignal,
223
+ advertiseRoots: options?.advertiseRoots,
161
224
  async onInitialized() {
162
225
  // Open the SSE stream before sending initialized, so server-to-client
163
226
  // requests triggered by on_initialized (e.g. roots/list) are delivered.
@@ -176,24 +239,36 @@ export async function connectToServer(
176
239
  instructions: initResult.instructions,
177
240
  };
178
241
  } catch (error) {
179
- await transport.close();
242
+ try {
243
+ await transport.close();
244
+ } catch {
245
+ // Preserve the initialization failure when cleanup also fails.
246
+ }
180
247
  throw error;
181
248
  }
182
249
  };
183
250
 
251
+ const connectionTimeoutMessage = `Connection to MCP server "${name}" timed out after ${timeoutMs}ms`;
252
+
184
253
  try {
185
- return await withTimeout(
186
- connect(),
187
- timeoutMs,
188
- `Connection to MCP server "${name}" timed out after ${timeoutMs}ms`,
189
- connectSignal,
190
- );
254
+ return await withTimeout(connect(), timeoutMs, connectionTimeoutMessage, connectSignal);
191
255
  } catch (error) {
192
256
  // If withTimeout rejected (timeout/abort) while connect() was still pending,
193
257
  // abort initialization and wait for transport cleanup before returning.
258
+ const aborted = options?.signal?.aborted === true;
194
259
  connectAbort.abort(error);
195
260
  if (transport) {
196
- await transport.close().catch(() => {});
261
+ try {
262
+ await transport.close();
263
+ } catch {
264
+ // Preserve the primary connection failure when cleanup also fails.
265
+ }
266
+ }
267
+ if (error instanceof MCPExpectedFailure) {
268
+ throw error;
269
+ }
270
+ if (aborted || (error instanceof Error && error.message === connectionTimeoutMessage)) {
271
+ throw new MCPExpectedFailure(error);
197
272
  }
198
273
  throw error;
199
274
  }
@@ -225,7 +300,7 @@ export async function listTools(
225
300
  params.cursor = cursor;
226
301
  }
227
302
 
228
- const result = await connection.transport.request<MCPToolsListResult>("tools/list", params, options);
303
+ const result = decodeToolsListResult(await connection.transport.request<unknown>("tools/list", params, options));
229
304
  allTools.push(...result.tools);
230
305
  cursor = result.nextCursor;
231
306
  } while (cursor);
@@ -9,6 +9,7 @@ import { mcpCapability } from "../capability/mcp";
9
9
  import type { SourceMeta } from "../capability/types";
10
10
  import type { MCPServer } from "../discovery";
11
11
  import { loadCapability } from "../discovery";
12
+ import { loadMCPJsonFile } from "../discovery/mcp-json";
12
13
  import { readDisabledServers } from "./config-writer";
13
14
  import type { MCPServerConfig } from "./types";
14
15
 
@@ -20,8 +21,10 @@ export interface LoadMCPConfigsOptions {
20
21
  filterExa?: boolean;
21
22
  /** Whether to filter out browser MCP servers when builtin browser tool is enabled (default: false) */
22
23
  filterBrowser?: boolean;
23
- /** Only include servers eligible for startup connection, i.e. autoload !== false (default: false) */
24
+ /** Only include startup-eligible servers; exact-config sessions always enforce autoload !== false. */
24
25
  autoloadOnly?: boolean;
26
+ /** Load only this explicit MCP config file. */
27
+ configPath?: string;
25
28
  }
26
29
 
27
30
  /** Result of loading MCP configs */
@@ -32,6 +35,8 @@ export interface LoadMCPConfigsResult {
32
35
  exaApiKeys: string[];
33
36
  /** Source metadata for each server */
34
37
  sources: Record<string, SourceMeta>;
38
+ /** Whether the explicit configuration was unavailable or contained invalid entries. */
39
+ configurationWarning: boolean;
35
40
  }
36
41
 
37
42
  /**
@@ -97,21 +102,28 @@ function convertToLegacyConfig(server: MCPServer): MCPServerConfig {
97
102
  * @param options Load options
98
103
  */
99
104
  export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOptions): Promise<LoadMCPConfigsResult> {
105
+ const exactConfig = options?.configPath !== undefined;
100
106
  const enableProjectConfig = options?.enableProjectConfig ?? true;
101
- const filterExa = options?.filterExa ?? true;
102
- const filterBrowser = options?.filterBrowser ?? false;
103
- const autoloadOnly = options?.autoloadOnly ?? false;
104
-
105
- // Load MCP servers via capability system
106
- const result = await loadCapability<MCPServer>(mcpCapability.id, { cwd });
107
-
108
- // Filter out project-level configs if disabled
109
- const servers = enableProjectConfig
110
- ? result.items
111
- : result.items.filter(server => server._source.level !== "project");
107
+ const filterExa = exactConfig ? false : (options?.filterExa ?? true);
108
+ const filterBrowser = exactConfig ? false : (options?.filterBrowser ?? false);
109
+ const autoloadOnly = exactConfig || (options?.autoloadOnly ?? false);
110
+
111
+ let servers: MCPServer[];
112
+ let disabledServers: Set<string>;
113
+ let configurationWarning = false;
114
+ if (exactConfig) {
115
+ const result = await loadMCPJsonFile(options.configPath!, "project", { quiet: true });
116
+ servers = result.items;
117
+ disabledServers = new Set(result.disabledServers);
118
+ configurationWarning = (result.warnings?.length ?? 0) > 0;
119
+ } else {
120
+ // Load MCP servers via capability system
121
+ const result = await loadCapability<MCPServer>(mcpCapability.id, { cwd });
122
+ // Filter out project-level configs if disabled
123
+ servers = enableProjectConfig ? result.items : result.items.filter(server => server._source.level !== "project");
124
+ disabledServers = new Set(await readDisabledServers(getMCPConfigPath("user", cwd)));
125
+ }
112
126
 
113
- // Load user-level disabled servers list
114
- const disabledServers = new Set(await readDisabledServers(getMCPConfigPath("user", cwd)));
115
127
  // Convert to legacy format and preserve source metadata
116
128
  let configs: Record<string, MCPServerConfig> = {};
117
129
  let sources: Record<string, SourceMeta> = {};
@@ -142,7 +154,7 @@ export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOpt
142
154
  sources = browserResult.sources;
143
155
  }
144
156
 
145
- return { configs, exaApiKeys, sources };
157
+ return { configs, exaApiKeys, sources, configurationWarning };
146
158
  }
147
159
 
148
160
  /** Pattern to match Exa MCP servers */