@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
@@ -1,3 +1,4 @@
1
+ import * as path from "node:path";
1
2
  import {
2
3
  Agent,
3
4
  type AgentEvent,
@@ -6,7 +7,7 @@ import {
6
7
  type AgentTool,
7
8
  type AppendOnlyContextManager,
8
9
  INTENT_FIELD,
9
- type ThinkingLevel,
10
+ ThinkingLevel,
10
11
  } from "@gajae-code/agent-core";
11
12
  import {
12
13
  type AuthCredentialSelector,
@@ -36,34 +37,34 @@ import {
36
37
  createAppendOnlyContextManager,
37
38
  providerSupportsAppendOnlyAuto,
38
39
  resolveAppendOnlyMode,
39
- } from "./append-only-mode";
40
- import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled, jobElapsedMs } from "./async";
41
- import { loadCapability } from "./capability";
42
- import { type Rule, ruleCapability, setActiveRules } from "./capability/rule";
43
- import { kNoAuth, ModelRegistry } from "./config/model-registry";
40
+ } from "../append-only-mode";
41
+ import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled, jobElapsedMs } from "../async";
42
+ import { loadCapability } from "../capability";
43
+ import { type Rule, ruleCapability, setActiveRules } from "../capability/rule";
44
+ import { kNoAuth, ModelRegistry } from "../config/model-registry";
44
45
  import {
45
46
  formatModelString,
46
47
  parseModelPattern,
47
- parseModelString,
48
48
  resolveAllowedModels,
49
+ resolveModelChainWithAuth,
49
50
  resolveModelRoleValue,
50
51
  type ScopedModelSelection,
51
- } from "./config/model-resolver";
52
- import { loadPromptTemplates as loadPromptTemplatesInternal, type PromptTemplate } from "./config/prompt-templates";
53
- import { Settings, type SkillsSettings } from "./config/settings";
54
- import { CursorExecHandlers } from "./cursor";
55
- import type { BashRestrictionProfile } from "./tools/bash-allowed-prefixes";
56
- import "./discovery";
57
- import { resolveConfigValue } from "./config/resolve-config-value";
58
- import { getEmbeddedDefaultGjcSkills } from "./defaults/gjc-defaults";
59
- import { BUNDLED_GROK_BUILD_EXTENSION_ID, getBundledGrokBuildExtensionFactory } from "./defaults/gjc-grok-cli";
60
- import { initializeWithSettings } from "./discovery";
61
- import { disposeAllVmContexts, disposeVmContextsByOwner } from "./eval/js/context-manager";
62
- import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "./eval/py/executor";
63
- import { TtsrManager } from "./export/ttsr";
64
- import type { CustomCommandsLoadResult, LoadedCustomCommand } from "./extensibility/custom-commands";
65
- import type { CustomTool, CustomToolContext, CustomToolSessionEvent } from "./extensibility/custom-tools/types";
66
- import { CustomToolAdapter } from "./extensibility/custom-tools/wrapper";
52
+ } from "../config/model-resolver";
53
+ import { loadPromptTemplates as loadPromptTemplatesInternal, type PromptTemplate } from "../config/prompt-templates";
54
+ import { Settings, type SkillsSettings } from "../config/settings";
55
+ import { CursorExecHandlers } from "../cursor";
56
+ import type { BashRestrictionProfile } from "../tools/bash-allowed-prefixes";
57
+ import "../discovery";
58
+ import { resolveConfigValue } from "../config/resolve-config-value";
59
+ import { getEmbeddedDefaultGjcSkills } from "../defaults/gjc-defaults";
60
+ import { BUNDLED_GROK_BUILD_EXTENSION_ID, getBundledGrokBuildExtensionFactory } from "../defaults/gjc-grok-cli";
61
+ import { initializeWithSettings } from "../discovery";
62
+ import { disposeAllVmContexts, disposeVmContextsByOwner } from "../eval/js/context-manager";
63
+ import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "../eval/py/executor";
64
+ import { TtsrManager } from "../export/ttsr";
65
+ import type { CustomCommandsLoadResult, LoadedCustomCommand } from "../extensibility/custom-commands";
66
+ import type { CustomTool, CustomToolContext, CustomToolSessionEvent } from "../extensibility/custom-tools/types";
67
+ import { CustomToolAdapter } from "../extensibility/custom-tools/wrapper";
67
68
  import {
68
69
  type ExtensionContext,
69
70
  type ExtensionFactory,
@@ -74,61 +75,63 @@ import {
74
75
  loadExtensionFromFactory,
75
76
  type ToolDefinition,
76
77
  wrapRegisteredTools,
77
- } from "./extensibility/extensions";
78
- import { ExtensionRuntime } from "./extensibility/extensions/loader";
79
- import { type ConstrainedPluginHook, loadConstrainedPluginHooks } from "./extensibility/gjc-plugins/constrained-hooks";
80
- import { resolveCurrentPhaseForParent } from "./extensibility/gjc-plugins/injection";
78
+ } from "../extensibility/extensions";
79
+ import { ExtensionRuntime } from "../extensibility/extensions/loader";
80
+ import { type ConstrainedPluginHook, loadConstrainedPluginHooks } from "../extensibility/gjc-plugins/constrained-hooks";
81
+ import { resolveCurrentPhaseForParent } from "../extensibility/gjc-plugins/injection";
81
82
  import {
82
83
  buildPluginMcpConfigs,
83
84
  loadAlwaysOnPluginTools,
84
85
  renderAlwaysOnSystemAppendices,
85
- } from "./extensibility/gjc-plugins/runtime-adapters";
86
- import { loadActiveSubskillTools } from "./extensibility/gjc-plugins/tools";
87
- import { loadSkills, type Skill, type SkillWarning, setActiveSkills } from "./extensibility/skills";
88
- import type { FileSlashCommand } from "./extensibility/slash-commands";
89
- import type { HindsightSessionState } from "./hindsight/state";
90
- import { LocalProtocolHandler, type LocalProtocolOptions } from "./internal-urls";
91
- import { LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "./lsp/startup-events";
92
- import { resolveMemoryBackend } from "./memory-backend";
93
- import { createNotificationsExtension } from "./notifications";
86
+ } from "../extensibility/gjc-plugins/runtime-adapters";
87
+ import { loadActiveSubskillTools } from "../extensibility/gjc-plugins/tools";
88
+ import { loadSkills, type Skill, type SkillWarning, setActiveSkills } from "../extensibility/skills";
89
+ import type { FileSlashCommand } from "../extensibility/slash-commands";
90
+ import type { HindsightSessionState } from "../hindsight/state";
91
+ import { LocalProtocolHandler, type LocalProtocolOptions } from "../internal-urls";
92
+ import { resolveMemoryBackend } from "../memory-backend";
93
+ import asyncResultTemplate from "../prompts/tools/async-result.md" with { type: "text" };
94
+ import { AgentRegistry, MAIN_AGENT_ID } from "../registry/agent-registry";
95
+ import { MCPManager } from "../runtime-mcp";
96
+ import { createNotificationsExtension } from "../sdk/bus";
94
97
  import {
95
98
  getNotificationConfig,
99
+ isNotificationHostEligible,
96
100
  type NotificationConfig,
97
101
  SPAWN_PROVENANCE_ENV,
98
102
  shouldRegisterNotificationsExtension,
99
- } from "./notifications/config";
100
- import asyncResultTemplate from "./prompts/tools/async-result.md" with { type: "text" };
101
- import { AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
102
- import { MCPManager } from "./runtime-mcp";
103
+ } from "../sdk/bus/config";
104
+ import { NotificationSessionController } from "../sdk/bus/session-control";
105
+ import { shouldHostSdk } from "../sdk/host";
103
106
  import {
104
107
  collectEnvSecrets,
105
108
  deobfuscateSessionContext,
106
109
  loadSecrets,
107
110
  obfuscateMessages,
108
111
  SecretObfuscator,
109
- } from "./secrets";
110
- import { AgentSession, type ForkContextSeed } from "./session/agent-session";
111
- import { resolveAuthBrokerConfig } from "./session/auth-broker-config";
112
- import { AuthBrokerClient, AuthStorage, RemoteAuthCredentialStore } from "./session/auth-storage";
113
- import { type CustomMessage, convertToLlm } from "./session/messages";
114
- import { SessionManager } from "./session/session-manager";
115
- import { formatNoModelsAvailableFallback } from "./setup/model-onboarding-guidance";
116
- import { closeAllConnections } from "./ssh/connection-manager";
117
- import { unmountAll } from "./ssh/sshfs-mount";
112
+ } from "../secrets";
113
+ import { AgentSession, type ForkContextSeed } from "../session/agent-session";
114
+ import { resolveAuthBrokerConfig } from "../session/auth-broker-config";
115
+ import { AuthBrokerClient, AuthStorage, RemoteAuthCredentialStore } from "../session/auth-storage";
116
+ import { type CustomMessage, convertToLlm } from "../session/messages";
117
+ import { SessionManager } from "../session/session-manager";
118
+ import { formatNoModelsAvailableFallback } from "../setup/model-onboarding-guidance";
119
+ import { closeAllConnections } from "../ssh/connection-manager";
120
+ import { unmountAll } from "../ssh/sshfs-mount";
118
121
  import {
119
122
  type BuildSystemPromptResult,
120
123
  buildSystemPrompt as buildSystemPromptInternal,
121
124
  buildSystemPromptToolMetadata,
122
125
  loadProjectContextFiles as loadContextFilesInternal,
123
- } from "./system-prompt";
124
- import { AgentOutputManager } from "./task/output-manager";
125
- import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } from "./thinking";
126
+ } from "../system-prompt";
127
+ import { AgentOutputManager } from "../task/output-manager";
128
+ import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } from "../thinking";
126
129
  import {
127
130
  collectDiscoverableTools,
128
131
  type DiscoverableTool,
129
132
  isMCPBridgeTool,
130
133
  isMCPToolName,
131
- } from "./tool-discovery/tool-index";
134
+ } from "../tool-discovery/tool-index";
132
135
  import {
133
136
  applyConfiguredSearchTimeout,
134
137
  BashTool,
@@ -156,15 +159,19 @@ import {
156
159
  type ToolSession,
157
160
  WebSearchTool,
158
161
  WriteTool,
159
- warmupLspServers,
160
- } from "./tools";
161
- import { ToolContextStore } from "./tools/context";
162
- import { getImageGenTools } from "./tools/image-gen";
163
- import { wrapToolWithMetaNotice } from "./tools/output-meta";
164
- import { guardToolForUltragoalAsk } from "./tools/ultragoal-ask-guard";
165
- import { EventBus } from "./utils/event-bus";
166
- import { buildNamedToolChoice, buildNamedToolChoiceResult } from "./utils/tool-choice";
167
- import { buildWorkspaceTree, type WorkspaceTree } from "./workspace-tree";
162
+ } from "../tools";
163
+ import { ToolContextStore } from "../tools/context";
164
+ import { getImageGenTools } from "../tools/image-gen";
165
+ import { wrapToolWithMetaNotice } from "../tools/output-meta";
166
+ import { guardToolForUltragoalAsk } from "../tools/ultragoal-ask-guard";
167
+ import { EventBus } from "../utils/event-bus";
168
+ import { buildNamedToolChoice, buildNamedToolChoiceResult } from "../utils/tool-choice";
169
+ import { buildWorkspaceTree, type WorkspaceTree } from "../workspace-tree";
170
+ import {
171
+ attachLifecycleStartupCapability,
172
+ lifecycleStartupCapabilityOption,
173
+ type SdkStartupCapability,
174
+ } from "./startup-capability";
168
175
 
169
176
  type AsyncResultEntry = {
170
177
  jobId: string;
@@ -333,8 +340,12 @@ export interface CreateAgentSessionOptions {
333
340
 
334
341
  /** @deprecated MCP runtime discovery is quarantined and ignored. */
335
342
  enableMCP?: boolean;
336
- /** Existing MCP manager to reuse (skips discovery, propagates to toolSession). */
343
+ /** Existing MCP manager to reuse (skips discovery, propagates to toolSession).
344
+ * Mutually exclusive with mcpConfigPath. */
337
345
  mcpManager?: MCPManager;
346
+ /** Load MCP tools for a top-level session only from this caller-owned absolute config file path.
347
+ * Mutually exclusive with mcpManager. */
348
+ mcpConfigPath?: string;
338
349
 
339
350
  /** Enable LSP integration (tool, formatting, diagnostics, warmup). Default: true */
340
351
  enableLsp?: boolean;
@@ -383,6 +394,8 @@ export interface CreateAgentSessionOptions {
383
394
 
384
395
  /** Whether UI is available (enables interactive tools like ask). Default: false */
385
396
  hasUI?: boolean;
397
+ /** Whether this host mode can own a notification session endpoint. Default: true. */
398
+ notificationHostModeSupported?: boolean;
386
399
 
387
400
  /**
388
401
  * Opt-in OpenTelemetry instrumentation forwarded to the underlying Agent.
@@ -410,11 +423,11 @@ export interface CreateAgentSessionResult {
410
423
  extensionsResult: LoadExtensionsResult;
411
424
  /** Update tool UI context (interactive mode) */
412
425
  setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
413
- /** MCP manager for server lifecycle management (undefined if MCP disabled) */
426
+ /** MCP manager for server lifecycle management (undefined if MCP disabled or an exact tools-only config is session-owned) */
414
427
  mcpManager?: MCPManager;
415
428
  /** Warning if session was restored with a different model than saved */
416
429
  modelFallbackMessage?: string;
417
- /** LSP servers detected for startup; warmup may continue in the background */
430
+ /** LSP servers configured for lazy startup in interactive mode */
418
431
  lspServers?: LspStartupServerInfo[];
419
432
  /** Shared event bus for tool/extension communication */
420
433
  eventBus: EventBus;
@@ -422,15 +435,15 @@ export interface CreateAgentSessionResult {
422
435
 
423
436
  // Re-exports
424
437
 
425
- export type { PromptTemplate } from "./config/prompt-templates";
426
- export { Settings, type SkillsSettings } from "./config/settings";
427
- export type { CustomCommand, CustomCommandFactory } from "./extensibility/custom-commands/types";
428
- export type { CustomTool, CustomToolFactory } from "./extensibility/custom-tools/types";
429
- export type * from "./extensibility/extensions";
430
- export type { Skill } from "./extensibility/skills";
431
- export type { FileSlashCommand } from "./extensibility/slash-commands";
432
- export type { Tool } from "./tools";
433
- export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "./workspace-tree";
438
+ export type { PromptTemplate } from "../config/prompt-templates";
439
+ export { Settings, type SkillsSettings } from "../config/settings";
440
+ export type { CustomCommand, CustomCommandFactory } from "../extensibility/custom-commands/types";
441
+ export type { CustomTool, CustomToolFactory } from "../extensibility/custom-tools/types";
442
+ export type * from "../extensibility/extensions";
443
+ export type { Skill } from "../extensibility/skills";
444
+ export type { FileSlashCommand } from "../extensibility/slash-commands";
445
+ export type { Tool } from "../tools";
446
+ export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "../workspace-tree";
434
447
 
435
448
  export {
436
449
  // Individual tool classes (for custom usage)
@@ -896,7 +909,62 @@ export function resolveIntentTracingEnabled(intentTracingSetting: boolean | unde
896
909
  return (!!intentTracingSetting || $flag("PI_INTENT_TRACING")) && hasUI;
897
910
  }
898
911
 
912
+ const MCP_CONFIG_PATH_AND_MANAGER_ERROR = "mcpConfigPath and mcpManager are mutually exclusive";
913
+ const MCP_CONFIG_PATH_ABSOLUTE_ERROR = "mcpConfigPath requires an absolute path";
914
+ const MCP_TOOLS_ONLY_MANAGER_SUBSESSION_ERROR = "tools-only MCP managers cannot be reused in sub-sessions";
915
+ const MCP_CONFIG_PATH_SUBSESSION_ERROR = "mcpConfigPath cannot be used in sub-sessions";
916
+ const MAX_EXACT_MCP_TOOL_COLLISION_NAMES = 10;
917
+ const MAX_EXACT_MCP_TOOL_NAME_LENGTH = 100;
918
+
919
+ class ExactMcpToolNameCollisionError extends Error {
920
+ constructor(toolNames: Iterable<string>) {
921
+ const names = [...new Set(toolNames)]
922
+ .sort()
923
+ .slice(0, MAX_EXACT_MCP_TOOL_COLLISION_NAMES)
924
+ .map(name => name.slice(0, MAX_EXACT_MCP_TOOL_NAME_LENGTH));
925
+ super(`Exact MCP tool name collision: ${names.join(", ")}`);
926
+ }
927
+ }
928
+
929
+ function findExactMcpToolNameCollisions(
930
+ exactMcpToolNames: readonly string[],
931
+ catalogToolNames: Iterable<string>,
932
+ ): string[] {
933
+ const exactMcpToolNameCounts = new Map<string, number>();
934
+ for (const toolName of exactMcpToolNames) {
935
+ exactMcpToolNameCounts.set(toolName, (exactMcpToolNameCounts.get(toolName) ?? 0) + 1);
936
+ }
937
+ const catalogToolNameCounts = new Map<string, number>();
938
+ for (const toolName of catalogToolNames) {
939
+ catalogToolNameCounts.set(toolName, (catalogToolNameCounts.get(toolName) ?? 0) + 1);
940
+ }
941
+ const collisions: string[] = [];
942
+ for (const [toolName, exactMcpToolNameCount] of exactMcpToolNameCounts) {
943
+ if (exactMcpToolNameCount > 1 || (catalogToolNameCounts.get(toolName) ?? 0) > 1) {
944
+ collisions.push(toolName);
945
+ }
946
+ }
947
+ return collisions;
948
+ }
949
+
899
950
  export async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {
951
+ const lifecycleStartupCapability = (
952
+ options as CreateAgentSessionOptions & { [lifecycleStartupCapabilityOption]?: SdkStartupCapability }
953
+ )[lifecycleStartupCapabilityOption];
954
+ const isCanonicalSubSession =
955
+ (options.taskDepth ?? 0) > 0 || Boolean(options.parentTaskPrefix) || Boolean(options.currentAgentType);
956
+ if (isCanonicalSubSession && options.mcpConfigPath !== undefined) {
957
+ throw new Error(MCP_CONFIG_PATH_SUBSESSION_ERROR);
958
+ }
959
+ if (options.mcpConfigPath !== undefined && options.mcpManager !== undefined) {
960
+ throw new Error(MCP_CONFIG_PATH_AND_MANAGER_ERROR);
961
+ }
962
+ if (options.mcpConfigPath !== undefined && !path.isAbsolute(options.mcpConfigPath)) {
963
+ throw new Error(MCP_CONFIG_PATH_ABSOLUTE_ERROR);
964
+ }
965
+ if (isCanonicalSubSession && options.mcpManager?.isToolsOnly()) {
966
+ throw new Error(MCP_TOOLS_ONLY_MANAGER_SUBSESSION_ERROR);
967
+ }
900
968
  const cwd = options.cwd ?? getProjectDir();
901
969
  const agentDir = options.agentDir ?? getDefaultAgentDir();
902
970
  const eventBus = options.eventBus ?? new EventBus();
@@ -1077,21 +1145,26 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1077
1145
  );
1078
1146
  let model = options.model;
1079
1147
  let modelFallbackMessage: string | undefined;
1080
- // If session has data, try to restore model from it.
1081
- // Skip restore when an explicit model was requested.
1082
- const defaultModelStr = existingSession.models.default;
1083
- if (!hasExplicitModel && !model && hasExistingSession && defaultModelStr) {
1148
+ const persistedDefaultChain = existingSession.configuredModelChains.default?.entries;
1149
+ const defaultModelEntries =
1150
+ persistedDefaultChain && persistedDefaultChain.length > 0
1151
+ ? persistedDefaultChain
1152
+ : existingSession.models.default
1153
+ ? [existingSession.models.default]
1154
+ : [];
1155
+ // If session has data, restore its configured default chain rather than the
1156
+ // scalar runtime model, which may be a stale fallback from the prior run.
1157
+ if (!hasExplicitModel && !model && hasExistingSession && defaultModelEntries.length > 0) {
1084
1158
  await logger.time("restoreSessionModel", async () => {
1085
- const parsedModel = parseModelString(defaultModelStr);
1086
- if (parsedModel) {
1087
- const restoredModel = modelRegistry.find(parsedModel.provider, parsedModel.id);
1088
- if (restoredModel && (await hasModelApiKey(restoredModel))) {
1089
- model = restoredModel;
1090
- }
1091
- }
1092
- if (!model) {
1093
- modelFallbackMessage = `Could not restore model ${defaultModelStr}`;
1094
- }
1159
+ const restoredDefaultResolution = await resolveModelChainWithAuth(
1160
+ defaultModelEntries,
1161
+ modelRegistry,
1162
+ settings,
1163
+ providerSessionId,
1164
+ { managedFallback: defaultModelEntries.length > 1 },
1165
+ );
1166
+ model = restoredDefaultResolution.model;
1167
+ if (!model) modelFallbackMessage = `Could not restore model ${defaultModelEntries.join(" -> ")}`;
1095
1168
  });
1096
1169
  }
1097
1170
 
@@ -1112,12 +1185,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1112
1185
  const hasExplicitDefaultThinkingLevel = settings.has("defaultThinkingLevel");
1113
1186
  let thinkingLevelFromSchemaDefault = false;
1114
1187
 
1115
- // If session has data and includes a thinking entry, restore it
1116
- if (thinkingLevel === undefined && hasExistingSession && hasThinkingEntry) {
1117
- thinkingLevel = parseThinkingLevel(existingSession.thinkingLevel);
1188
+ // If session has data and includes a thinking entry, restore an explicit session
1189
+ // override. A persisted inherit marker deliberately re-enters the normal
1190
+ // default-role/global/model resolution path instead of resolving to `undefined`.
1191
+ const restoredThinkingLevel =
1192
+ hasExistingSession && hasThinkingEntry ? parseThinkingLevel(existingSession.thinkingLevel) : undefined;
1193
+ if (thinkingLevel === undefined && restoredThinkingLevel !== ThinkingLevel.Inherit) {
1194
+ thinkingLevel = restoredThinkingLevel;
1118
1195
  }
1119
1196
 
1120
- if (thinkingLevel === undefined && !hasExplicitModel && !hasThinkingEntry && defaultRoleSpec.explicitThinkingLevel) {
1197
+ if (thinkingLevel === undefined && !hasExplicitModel && defaultRoleSpec.explicitThinkingLevel) {
1121
1198
  thinkingLevel = defaultRoleSpec.thinkingLevel;
1122
1199
  }
1123
1200
 
@@ -1145,8 +1222,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1145
1222
  // with the rest of session setup (extension/skill load, tool registry,
1146
1223
  // system prompt build). Without this, the first `fetch(...)` pays the
1147
1224
  // full handshake serially — 100–300 ms transcontinental for
1148
- // api.anthropic.com from a residential IP. Every mode benefits
1149
- // (interactive, print, rpc, acp).
1225
+ // api.anthropic.com from a residential IP. Every session frontend benefits
1226
+ // (interactive, print, SDK, ACP).
1150
1227
  preconnectModelHost(model.baseUrl);
1151
1228
  }
1152
1229
 
@@ -1243,6 +1320,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1243
1320
  let session!: AgentSession;
1244
1321
  let hasSession = false;
1245
1322
  let hasRegistered = false;
1323
+ let cleanupOwnedMcpManager: (() => Promise<void>) | undefined;
1246
1324
  const enableLsp = options.enableLsp ?? true;
1247
1325
  const backgroundJobsEnabled = isBackgroundJobSupportEnabled(settings);
1248
1326
  const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ?? 100));
@@ -1294,8 +1372,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1294
1372
 
1295
1373
  const agentRegistry = options.agentRegistry ?? AgentRegistry.global();
1296
1374
  const resolvedAgentId = options.agentId ?? options.parentTaskPrefix ?? MAIN_AGENT_ID;
1297
- const isSubSession = taskDepth > 0 || Boolean(options.parentTaskPrefix) || Boolean(options.currentAgentType);
1298
- const resolvedAgentDisplayName = options.agentDisplayName ?? (isSubSession ? "sub" : "main");
1375
+ const resolvedAgentDisplayName = options.agentDisplayName ?? (isCanonicalSubSession ? "sub" : "main");
1299
1376
  const resolvedAgentRosterLabel = resolveAgentRosterLabel(
1300
1377
  options.agentRosterLabel,
1301
1378
  resolvedAgentId,
@@ -1311,8 +1388,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1311
1388
  };
1312
1389
 
1313
1390
  try {
1391
+ let promptMetadataModel: Model | undefined;
1314
1392
  const getActiveModelString = (): string | undefined => {
1315
- const activeModel = agent?.state.model;
1393
+ const activeModel = promptMetadataModel ?? agent?.state.model;
1316
1394
  if (activeModel) return formatModelString(activeModel);
1317
1395
  if (model) return formatModelString(model);
1318
1396
  return undefined;
@@ -1449,15 +1527,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1449
1527
  // Create built-in tools (already wrapped with meta notice formatting)
1450
1528
  const builtinTools = await logger.time("createAllTools", createTools, toolSession, options.toolNames);
1451
1529
 
1452
- // MCP runtime discovery is quarantined for the GJC surface. Keep an
1453
- // explicitly supplied manager only for legacy in-process callers that own
1454
- // lifecycle themselves; never discover project/user MCP configs here. The
1455
- // owned manager for always-on plugin-bundle MCP servers is created further
1456
- // below, after `customTools` is populated, so its tools can be surfaced as
1457
- // always-on tools per the plugin product contract.
1530
+ // MCP runtime discovery is quarantined for the GJC surface. A top-level
1531
+ // session may load only a caller-supplied exact config; project and user
1532
+ // MCP configs are never discovered here. Existing managers remain available
1533
+ // for legacy in-process callers, and plugin-bundle managers are created
1534
+ // below after `customTools` is populated.
1458
1535
  let mcpManager: MCPManager | undefined = options.mcpManager;
1459
1536
  let ownsMcpManager = false;
1537
+ const explicitMcpConfigPath = !isCanonicalSubSession && !options.mcpManager ? options.mcpConfigPath : undefined;
1460
1538
  const customTools: CustomTool[] = [];
1539
+ const exactMcpToolNames: string[] = [];
1461
1540
 
1462
1541
  // Add image tools when the active model or configured image providers can generate images.
1463
1542
  const imageGenTools = await logger.time("getImageGenTools", () => getImageGenTools(modelRegistry, model));
@@ -1527,12 +1606,26 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1527
1606
  logger.warn("Failed to load always-on GJC plugin tools", { error });
1528
1607
  }
1529
1608
 
1530
- // Always-on GJC plugin-bundle MCP servers. Top-level sessions own a manager
1531
- // and connect the validated servers; subagents inherit the parent's manager
1532
- // via options.mcpManager and never spawn their own (prevents duplicate
1533
- // processes and leaks). Per the plugin product contract, connected MCP tools
1534
- // are surfaced as always-on tools rather than gated behind MCP selection.
1535
- if (!mcpManager && !options.parentTaskPrefix) {
1609
+ const preExactCustomToolNames = customTools.map(tool => tool.name);
1610
+ if (explicitMcpConfigPath !== undefined) {
1611
+ const owned = new MCPManager(cwd, null, { toolsOnly: true });
1612
+ owned.setAuthStorage(authStorage);
1613
+ mcpManager = owned;
1614
+ ownsMcpManager = true;
1615
+ cleanupOwnedMcpManager = () => owned.disconnectAll();
1616
+ const result = await owned.discoverAndConnect({ configPath: explicitMcpConfigPath });
1617
+ const resultTools = result.tools as CustomTool[];
1618
+ exactMcpToolNames.push(...resultTools.map(tool => tool.name));
1619
+ customTools.push(...resultTools);
1620
+ if (result.errors.size > 0 || result.tools.length === 0) {
1621
+ logger.warn("MCP tools could not be loaded.");
1622
+ }
1623
+ } else if (!mcpManager && !isCanonicalSubSession) {
1624
+ // Always-on GJC plugin-bundle MCP servers. Top-level sessions own a manager
1625
+ // and connect the validated servers; subagents inherit the parent's manager
1626
+ // via options.mcpManager and never spawn their own (prevents duplicate
1627
+ // processes and leaks). Per the plugin product contract, connected MCP tools
1628
+ // are surfaced as always-on tools rather than gated behind MCP selection.
1536
1629
  try {
1537
1630
  const { configs, quarantine } = await buildPluginMcpConfigs({ cwd });
1538
1631
  for (const q of quarantine) {
@@ -1567,13 +1660,14 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1567
1660
  } catch (error) {
1568
1661
  logger.warn("Failed to wire GJC plugin MCP servers", { error });
1569
1662
  }
1570
- } else if (options.parentTaskPrefix) {
1663
+ } else if (isCanonicalSubSession) {
1571
1664
  // Subagent: inherit the parent's always-on plugin MCP tools WITHOUT
1572
1665
  // owning the manager (no connect, no callbacks, no disposal). The
1573
1666
  // top-level session installed its manager as the process-global
1574
1667
  // instance; reading getTools() surfaces the same always-on tools so the
1575
1668
  // product decision holds for subagent sessions too.
1576
- const inherited = mcpManager ?? MCPManager.instance();
1669
+ const singleton = MCPManager.instance();
1670
+ const inherited = mcpManager ?? (singleton?.isToolsOnly() ? undefined : singleton);
1577
1671
  if (inherited) {
1578
1672
  try {
1579
1673
  const inheritedTools = inherited.getTools();
@@ -1583,11 +1677,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1583
1677
  }
1584
1678
  }
1585
1679
  }
1586
- // Only top-level sessions own the global MCPManager. Subagents already
1587
- // receive the parent's manager via options.mcpManager; reassigning the
1588
- // singleton to the same value is a no-op. Keep the gate explicit to mirror
1589
- // the AsyncJobManager ownership rule.
1590
- if (mcpManager && !options.parentTaskPrefix) MCPManager.setInstance(mcpManager);
1680
+ // Exact-config managers are session-local. Plugin managers keep their
1681
+ // existing top-level singleton behavior for bundled runtime surfaces.
1682
+ if (mcpManager && !mcpManager.isToolsOnly() && !isCanonicalSubSession && explicitMcpConfigPath === undefined) {
1683
+ MCPManager.setInstance(mcpManager);
1684
+ }
1591
1685
 
1592
1686
  // Custom tool and extension discovery is quarantined from the public GJC utility surface.
1593
1687
  // Explicit SDK extension factories are still honored; callers use them to
@@ -1616,16 +1710,31 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1616
1710
  } catch {
1617
1711
  notificationCfg = undefined;
1618
1712
  }
1713
+ const isTopLevelSdkSession = !isCanonicalSubSession;
1619
1714
  // Consume the GJC spawn-provenance marker: read it once, then remove it
1620
1715
  // from this process's env so it is never re-inherited by children this
1621
1716
  // session later spawns (marker is per-spawn, not dynastic — each GJC child
1622
1717
  // spawn site sets it explicitly). Suppression under `sessionScope=primary`
1623
- // keeps auto-spawned children (team workers, harness RPC owners) silent
1624
- // while explicit `/session_create` opt-in (GJC_NOTIFICATIONS=1) still wins.
1718
+ // keeps auto-spawned children (team workers, harness owners) silent while
1719
+ // explicit SDK session opt-in (GJC_NOTIFICATIONS=1) still wins.
1625
1720
  const spawnProvenance = process.env[SPAWN_PROVENANCE_ENV];
1626
1721
  const spawnedByGjc = typeof spawnProvenance === "string" && spawnProvenance.trim().length > 0;
1627
1722
  delete process.env[SPAWN_PROVENANCE_ENV];
1723
+ const notificationHostEligible = isNotificationHostEligible({
1724
+ env: process.env,
1725
+ hostModeSupported: options.notificationHostModeSupported ?? true,
1726
+ taskDepth,
1727
+ parentTaskPrefix: options.parentTaskPrefix,
1728
+ currentAgentType: options.currentAgentType,
1729
+ sessionScope: notificationCfg?.sessionScope,
1730
+ spawnedByGjc,
1731
+ });
1732
+ const notificationSessionController = new NotificationSessionController({
1733
+ eligible: notificationHostEligible,
1734
+ getConfig: () => getNotificationConfig(settings),
1735
+ });
1628
1736
  if (
1737
+ lifecycleStartupCapability ||
1629
1738
  shouldRegisterNotificationsExtension({
1630
1739
  env: process.env,
1631
1740
  cfg: notificationCfg,
@@ -1633,9 +1742,26 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1633
1742
  parentTaskPrefix: options.parentTaskPrefix,
1634
1743
  currentAgentType: options.currentAgentType,
1635
1744
  spawnedByGjc,
1636
- })
1745
+ }) ||
1746
+ shouldHostSdk(notificationCfg, isTopLevelSdkSession)
1637
1747
  ) {
1638
- inlineExtensions.push(api => createNotificationsExtension(api, { settings }));
1748
+ inlineExtensions.push(async api => {
1749
+ try {
1750
+ if (lifecycleStartupCapability) attachLifecycleStartupCapability(api, lifecycleStartupCapability);
1751
+ if (lifecycleStartupCapability && process.env.GJC_SDK_TEST_FACTORY_FAILURE === cwd)
1752
+ throw new Error(process.env.GJC_SDK_TEST_FACTORY_SECRET ?? "Lifecycle factory test failure.");
1753
+ createNotificationsExtension(api, {
1754
+ settings,
1755
+ controller: notificationSessionController,
1756
+ spawnedByGjc,
1757
+ });
1758
+ } catch (error) {
1759
+ lifecycleStartupCapability?.settleFailure(
1760
+ lifecycleStartupCapability.normalizeFailure("registration", "factory_absent", error),
1761
+ );
1762
+ throw error;
1763
+ }
1764
+ });
1639
1765
  }
1640
1766
 
1641
1767
  // Extension/module discovery is quarantined; retain only the private
@@ -1760,7 +1886,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1760
1886
  sessionManager,
1761
1887
  modelRegistry,
1762
1888
  {
1763
- kind: isSubSession ? "sub" : "main",
1889
+ kind: isCanonicalSubSession ? "sub" : "main",
1764
1890
  taskDepth,
1765
1891
  ...(options.parentTaskPrefix ? { parentTaskPrefix: options.parentTaskPrefix } : {}),
1766
1892
  ...(options.currentAgentType ? { currentAgentType: options.currentAgentType } : {}),
@@ -1827,6 +1953,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1827
1953
 
1828
1954
  // All built-in tools are active (conditional tools like git/ask return null from factory if disabled)
1829
1955
  const toolRegistry = new Map<string, Tool>();
1956
+ let builtinCandidateTools = [...builtinTools];
1830
1957
  for (const tool of builtinTools) {
1831
1958
  toolRegistry.set(tool.name, tool);
1832
1959
  }
@@ -1836,7 +1963,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1836
1963
  if (toolRegistry.has(name)) continue;
1837
1964
  const goalStateTool = await logger.time(`createTools:${name}:session`, BUILTIN_TOOLS[name], toolSession);
1838
1965
  if (goalStateTool) {
1839
- toolRegistry.set(goalStateTool.name, wrapToolWithMetaNotice(goalStateTool));
1966
+ const wrappedGoalStateTool = wrapToolWithMetaNotice(goalStateTool);
1967
+ builtinCandidateTools.push(wrappedGoalStateTool);
1968
+ toolRegistry.set(wrappedGoalStateTool.name, wrappedGoalStateTool);
1840
1969
  }
1841
1970
  }
1842
1971
  }
@@ -1850,6 +1979,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1850
1979
  }
1851
1980
  if (model?.provider === "cursor") {
1852
1981
  toolRegistry.delete("edit");
1982
+ builtinCandidateTools = builtinCandidateTools.filter(tool => tool.name !== "edit");
1853
1983
  }
1854
1984
 
1855
1985
  const hasDeferrableTools = Array.from(toolRegistry.values()).some(tool => tool.deferrable === true);
@@ -1858,7 +1988,22 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1858
1988
  } else if (!toolRegistry.has("resolve")) {
1859
1989
  const resolveTool = await logger.time("createTools:resolve:session", HIDDEN_TOOLS.resolve, toolSession);
1860
1990
  if (resolveTool) {
1861
- toolRegistry.set(resolveTool.name, wrapToolWithMetaNotice(resolveTool));
1991
+ const wrappedResolveTool = wrapToolWithMetaNotice(resolveTool);
1992
+ builtinCandidateTools.push(wrappedResolveTool);
1993
+ toolRegistry.set(wrappedResolveTool.name, wrappedResolveTool);
1994
+ }
1995
+ }
1996
+ // Exact-config MCP tools cannot claim a name already represented by the final candidate catalog.
1997
+ // Other catalog collisions retain their legacy override behavior.
1998
+ if (exactMcpToolNames.length > 0) {
1999
+ const catalogToolNames = [
2000
+ ...builtinCandidateTools.map(tool => tool.name),
2001
+ ...preExactCustomToolNames,
2002
+ ...wrappedExtensionTools.map(tool => tool.name),
2003
+ ];
2004
+ const collidingToolNames = findExactMcpToolNameCollisions(exactMcpToolNames, catalogToolNames);
2005
+ if (collidingToolNames.length > 0) {
2006
+ throw new ExactMcpToolNameCollisionError(collidingToolNames);
1862
2007
  }
1863
2008
  }
1864
2009
 
@@ -1892,30 +2037,43 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1892
2037
  const rebuildSystemPrompt = async (
1893
2038
  toolNames: string[],
1894
2039
  tools: Map<string, AgentTool>,
2040
+ candidateModel?: Model,
1895
2041
  ): Promise<BuildSystemPromptResult> => {
1896
2042
  toolContextStore.setToolNames(toolNames);
1897
- const activeToolNames = new Set(toolNames);
1898
- const discoverableBuiltinTools: DiscoverableTool[] =
1899
- effectiveDiscoveryMode === "all"
1900
- ? collectDiscoverableTools(
1901
- Array.from(tools.values()).filter(
1902
- tool => tool.loadMode === "discoverable" && !activeToolNames.has(tool.name),
1903
- ),
1904
- { source: "builtin" },
1905
- )
1906
- : [];
1907
- const discoverableMCPTools: DiscoverableTool[] = mcpDiscoveryEnabled
1908
- ? collectDiscoverableTools(
1909
- Array.from(tools.values()).filter(
1910
- tool => isMCPToolName(tool.name) && !activeToolNames.has(tool.name),
1911
- ),
1912
- { source: "mcp" },
1913
- )
1914
- : [];
1915
- const discoverableToolsForDesc: DiscoverableTool[] = [...discoverableBuiltinTools, ...discoverableMCPTools];
1916
- const promptTools = buildSystemPromptToolMetadata(tools, {
1917
- search_tool_bm25: { description: renderSearchToolBm25Description(discoverableToolsForDesc) },
1918
- });
2043
+ const { discoverableBuiltinTools, discoverableMCPTools, promptTools } = (() => {
2044
+ const previousPromptMetadataModel = promptMetadataModel;
2045
+ promptMetadataModel = candidateModel;
2046
+ try {
2047
+ const activeToolNames = new Set(toolNames);
2048
+ const discoverableBuiltinTools: DiscoverableTool[] =
2049
+ effectiveDiscoveryMode === "all"
2050
+ ? collectDiscoverableTools(
2051
+ Array.from(tools.values()).filter(
2052
+ tool => tool.loadMode === "discoverable" && !activeToolNames.has(tool.name),
2053
+ ),
2054
+ { source: "builtin" },
2055
+ )
2056
+ : [];
2057
+ const discoverableMCPTools: DiscoverableTool[] = mcpDiscoveryEnabled
2058
+ ? collectDiscoverableTools(
2059
+ Array.from(tools.values()).filter(
2060
+ tool => isMCPToolName(tool.name) && !activeToolNames.has(tool.name),
2061
+ ),
2062
+ { source: "mcp" },
2063
+ )
2064
+ : [];
2065
+ const discoverableToolsForDesc: DiscoverableTool[] = [
2066
+ ...discoverableBuiltinTools,
2067
+ ...discoverableMCPTools,
2068
+ ];
2069
+ const promptTools = buildSystemPromptToolMetadata(tools, {
2070
+ search_tool_bm25: { description: renderSearchToolBm25Description(discoverableToolsForDesc) },
2071
+ });
2072
+ return { discoverableBuiltinTools, discoverableMCPTools, promptTools };
2073
+ } finally {
2074
+ promptMetadataModel = previousPromptMetadataModel;
2075
+ }
2076
+ })();
1919
2077
  const memoryInstructions = await resolveMemoryBackend(settings).buildDeveloperInstructions(
1920
2078
  agentDir,
1921
2079
  settings,
@@ -1923,7 +2081,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1923
2081
  );
1924
2082
 
1925
2083
  // Build combined append prompt: memory instructions + MCP server instructions
1926
- const serverInstructions = mcpManager?.getServerInstructions();
2084
+ const serverInstructions =
2085
+ explicitMcpConfigPath === undefined ? mcpManager?.getServerInstructions() : undefined;
1927
2086
  let appendPrompt: string | undefined = memoryInstructions ?? undefined;
1928
2087
  if (serverInstructions && serverInstructions.size > 0) {
1929
2088
  const parts: string[] = [];
@@ -2086,7 +2245,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2086
2245
  id: resolvedAgentId,
2087
2246
  displayName: resolvedAgentDisplayName,
2088
2247
  rosterLabel: resolvedAgentRosterLabel,
2089
- kind: isSubSession ? "sub" : "main",
2248
+ kind: isCanonicalSubSession ? "sub" : "main",
2090
2249
  parentId: options.parentTaskPrefix,
2091
2250
  session: null,
2092
2251
  sessionFile: sessionManager.getSessionFile() ?? null,
@@ -2326,7 +2485,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2326
2485
  : undefined,
2327
2486
  );
2328
2487
  }
2329
- sessionManager.appendThinkingLevelChange(thinkingLevel);
2488
+ sessionManager.appendThinkingLevelChange(options.thinkingLevel ?? ThinkingLevel.Inherit);
2330
2489
  if (initialServiceTier) {
2331
2490
  sessionManager.appendServiceTierChange(initialServiceTier);
2332
2491
  }
@@ -2337,14 +2496,15 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2337
2496
  thinkingLevel,
2338
2497
  sessionManager,
2339
2498
  settings,
2499
+ notificationSessionController,
2340
2500
  evalKernelOwnerId,
2341
2501
  // Defined only for top-level sessions (creation is gated above).
2342
2502
  // AgentSession uses this to decide whether it may dispose the global
2343
2503
  // AsyncJobManager on teardown; subagents inherit the parent's and
2344
2504
  // **MUST NOT** tear it down.
2345
2505
  ownedAsyncJobManager: asyncJobManager,
2346
- // Only the owned plugin-bundle MCP manager is torn down on dispose;
2347
- // subagents/callers that merely observe the global must not (see
2506
+ // Only an MCP manager owned by this session is torn down on dispose;
2507
+ // subagents and callers that merely observe a manager must not (see
2348
2508
  // AgentSession.dispose).
2349
2509
  ownedMcpManager: ownsMcpManager ? mcpManager : undefined,
2350
2510
  scopedModels: options.scopedModels,
@@ -2368,20 +2528,23 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2368
2528
  reloadSshTool,
2369
2529
  requestedToolNames: requestedToolNameSet,
2370
2530
  discoverableToolAllowedNames: options.discoverableToolAllowedNames,
2371
- getMcpServerInstructions: mcpManager
2372
- ? () => {
2373
- const raw = mcpManager.getServerInstructions();
2374
- if (!raw || raw.size === 0) return raw;
2375
- const out = new Map<string, string>();
2376
- for (const [name, text] of raw) {
2377
- out.set(
2378
- name,
2379
- text.length > MAX_MCP_INSTRUCTIONS_LENGTH ? text.slice(0, MAX_MCP_INSTRUCTIONS_LENGTH) : text,
2380
- );
2531
+ getMcpServerInstructions:
2532
+ mcpManager && explicitMcpConfigPath === undefined
2533
+ ? () => {
2534
+ const raw = mcpManager.getServerInstructions();
2535
+ if (!raw || raw.size === 0) return raw;
2536
+ const out = new Map<string, string>();
2537
+ for (const [name, text] of raw) {
2538
+ out.set(
2539
+ name,
2540
+ text.length > MAX_MCP_INSTRUCTIONS_LENGTH
2541
+ ? text.slice(0, MAX_MCP_INSTRUCTIONS_LENGTH)
2542
+ : text,
2543
+ );
2544
+ }
2545
+ return out;
2381
2546
  }
2382
- return out;
2383
- }
2384
- : undefined,
2547
+ : undefined,
2385
2548
  mcpDiscoveryEnabled,
2386
2549
  initialSelectedMCPToolNames,
2387
2550
  defaultSelectedMCPToolNames,
@@ -2455,47 +2618,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2455
2618
  }
2456
2619
  }
2457
2620
 
2458
- // Start LSP warmup in the background so startup does not block on language server initialization.
2459
- // Print/script invocations (`hasUI=false`) don't render the warmup status indicator AND typically
2460
- // finish before LSP servers would have stabilized — warming them just spends CPU parsing big
2461
- // `initialize` responses concurrently with the LLM stream consumer, jittering perceived latency.
2462
- // Tools that need an LSP server still spin one up on demand through `getOrCreateClient`.
2463
- let lspServers: CreateAgentSessionResult["lspServers"];
2464
- if (enableLsp && options.hasUI && settings.get("lsp.diagnosticsOnWrite")) {
2465
- lspServers = discoverStartupLspServers(cwd);
2466
- if (lspServers.length > 0) {
2467
- void (async () => {
2468
- try {
2469
- const result = await logger.time("warmupLspServers", warmupLspServers, cwd);
2470
- const serversByName = new Map(result.servers.map(server => [server.name, server] as const));
2471
- for (const server of lspServers ?? []) {
2472
- const next = serversByName.get(server.name);
2473
- if (!next) continue;
2474
- server.status = next.status;
2475
- server.fileTypes = next.fileTypes;
2476
- server.error = next.error;
2477
- }
2478
- const event: LspStartupEvent = {
2479
- type: "completed",
2480
- servers: result.servers,
2481
- };
2482
- eventBus.emit(LSP_STARTUP_EVENT_CHANNEL, event);
2483
- } catch (error) {
2484
- const errorMessage = error instanceof Error ? error.message : String(error);
2485
- logger.warn("LSP server warmup failed", { cwd, error: errorMessage });
2486
- for (const server of lspServers ?? []) {
2487
- server.status = "error";
2488
- server.error = errorMessage;
2489
- }
2490
- const event: LspStartupEvent = {
2491
- type: "failed",
2492
- error: errorMessage,
2493
- };
2494
- eventBus.emit(LSP_STARTUP_EVENT_CHANNEL, event);
2495
- }
2496
- })();
2497
- }
2498
- }
2621
+ // Discover configured LSP servers for the interactive status display without starting them.
2622
+ // LSP-backed write operations create clients on demand through `getOrCreateClient`.
2623
+ const lspServers =
2624
+ enableLsp && options.hasUI && settings.get("lsp.diagnosticsOnWrite")
2625
+ ? discoverStartupLspServers(cwd)
2626
+ : undefined;
2499
2627
 
2500
2628
  logger.time("startMemoryStartupTask", () =>
2501
2629
  Promise.resolve(
@@ -2510,9 +2638,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2510
2638
  ),
2511
2639
  );
2512
2640
 
2513
- // Wire MCP manager callbacks to session for reactive tool updates.
2514
- // Skip when reusing a parent's manager — the parent owns the callbacks.
2515
- if (mcpManager && !options.mcpManager) {
2641
+ // Exact-config managers do not receive reactive callbacks; their tools are
2642
+ // registered once in the session-owned catalog.
2643
+ if (mcpManager && !options.mcpManager && explicitMcpConfigPath === undefined) {
2516
2644
  // The owned plugin-bundle manager surfaces its tools as always-on custom
2517
2645
  // tools (registered above), so it must NOT drive refreshMCPTools — that
2518
2646
  // path strips MCP bridge tools and re-gates them behind MCP selection,
@@ -2562,7 +2690,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2562
2690
  session,
2563
2691
  extensionsResult,
2564
2692
  setToolUIContext,
2565
- mcpManager,
2693
+ mcpManager: ownsMcpManager && mcpManager?.isToolsOnly() ? undefined : mcpManager,
2566
2694
  modelFallbackMessage,
2567
2695
  lspServers,
2568
2696
  eventBus,
@@ -2577,13 +2705,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2577
2705
  await session.dispose();
2578
2706
  } else {
2579
2707
  if (hasRegistered) agentRegistry.unregister(resolvedAgentId);
2708
+ await cleanupOwnedMcpManager?.();
2580
2709
  await disposeKernelSessionsByOwner(evalKernelOwnerId);
2581
2710
  await disposeVmContextsByOwner(evalKernelOwnerId);
2582
2711
  }
2583
- } catch (cleanupError) {
2584
- logger.warn("Failed to clean up createAgentSession resources after startup error", {
2585
- error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError),
2586
- });
2712
+ } catch {
2713
+ logger.warn("Failed to clean up createAgentSession resources after startup error");
2587
2714
  } finally {
2588
2715
  releaseLocalProtocolOverride();
2589
2716
  }