@gajae-code/coding-agent 0.18.11 → 0.19.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 (462) hide show
  1. package/CHANGELOG.md +760 -0
  2. package/dist/types/async/job-manager.d.ts +7 -3
  3. package/dist/types/async/result-formatting.d.ts +2 -0
  4. package/dist/types/autoresearch/git.d.ts +1 -1
  5. package/dist/types/capability/fs.d.ts +2 -2
  6. package/dist/types/capability/rule.d.ts +7 -2
  7. package/dist/types/cli/accounts-cli.d.ts +2 -2
  8. package/dist/types/cli/append-system-prompt.d.ts +6 -0
  9. package/dist/types/cli/args.d.ts +7 -2
  10. package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
  11. package/dist/types/cli/customize-doctor.d.ts +4 -3
  12. package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
  13. package/dist/types/cli/install-activation.d.ts +10 -4
  14. package/dist/types/cli/public-command-errors.d.ts +2 -0
  15. package/dist/types/cli/root-flags.d.ts +0 -12
  16. package/dist/types/cli/update-cli.d.ts +21 -3
  17. package/dist/types/cli-main.d.ts +0 -6
  18. package/dist/types/cli-ordinary.d.ts +2 -2
  19. package/dist/types/commands/accounts.d.ts +2 -1
  20. package/dist/types/commands/launch.d.ts +0 -6
  21. package/dist/types/commands/migrate.d.ts +1 -1
  22. package/dist/types/commands/sdk.d.ts +13 -0
  23. package/dist/types/commit/changelog/index.d.ts +1 -0
  24. package/dist/types/commit/map-reduce/index.d.ts +4 -4
  25. package/dist/types/config/autorouting-tier-map.d.ts +53 -1
  26. package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
  27. package/dist/types/config/config-hot-reload.d.ts +44 -0
  28. package/dist/types/config/file-lock.d.ts +52 -3
  29. package/dist/types/config/model-discovery-manager.d.ts +2 -0
  30. package/dist/types/config/model-profile-activation.d.ts +79 -9
  31. package/dist/types/config/model-registry.d.ts +72 -8
  32. package/dist/types/config/model-resolver.d.ts +7 -4
  33. package/dist/types/config/models-config-schema.d.ts +10 -0
  34. package/dist/types/config/settings-schema.d.ts +57 -4
  35. package/dist/types/config/settings.d.ts +33 -1
  36. package/dist/types/coordinator-mcp/server.d.ts +4 -0
  37. package/dist/types/customization/import.d.ts +2 -0
  38. package/dist/types/customization/types.d.ts +1 -1
  39. package/dist/types/dap/config.d.ts +8 -4
  40. package/dist/types/dap/session.d.ts +11 -2
  41. package/dist/types/debug/system-info.d.ts +6 -1
  42. package/dist/types/discovery/helpers.d.ts +7 -2
  43. package/dist/types/discovery/mcp-compat.d.ts +3 -1
  44. package/dist/types/edit/index.d.ts +5 -0
  45. package/dist/types/edit/modes/patch.d.ts +14 -0
  46. package/dist/types/edit/modes/replace.d.ts +3 -0
  47. package/dist/types/eval/py/runtime.d.ts +9 -0
  48. package/dist/types/exec/bash-executor.d.ts +12 -0
  49. package/dist/types/export/ttsr.d.ts +19 -0
  50. package/dist/types/extensibility/extensions/types.d.ts +5 -1
  51. package/dist/types/extensibility/slash-commands.d.ts +1 -0
  52. package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
  53. package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
  54. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
  55. package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
  56. package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
  57. package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
  58. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
  59. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
  60. package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
  61. package/dist/types/hindsight/content.d.ts +5 -6
  62. package/dist/types/internal-urls/types.d.ts +2 -0
  63. package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
  64. package/dist/types/main.d.ts +23 -18
  65. package/dist/types/migrate/action-planner.d.ts +10 -1
  66. package/dist/types/migrate/adapters/codex.d.ts +2 -1
  67. package/dist/types/migrate/adapters/index.d.ts +42 -1
  68. package/dist/types/migrate/executor.d.ts +3 -1
  69. package/dist/types/migrate/hook-module.d.ts +23 -0
  70. package/dist/types/migrate/report.d.ts +2 -1
  71. package/dist/types/migrate/types.d.ts +82 -3
  72. package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
  73. package/dist/types/modes/components/model-selector.d.ts +43 -0
  74. package/dist/types/modes/components/settings-selector.d.ts +6 -0
  75. package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
  76. package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
  77. package/dist/types/modes/theme/theme.d.ts +1 -0
  78. package/dist/types/modes/utils/host-status.d.ts +15 -11
  79. package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
  80. package/dist/types/runtime-mcp/manager.d.ts +7 -0
  81. package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
  82. package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
  83. package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
  84. package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
  85. package/dist/types/sdk/broker/broker.d.ts +29 -2
  86. package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
  87. package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
  88. package/dist/types/sdk/broker/ensure.d.ts +141 -9
  89. package/dist/types/sdk/broker/hop.d.ts +45 -0
  90. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
  91. package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
  92. package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
  93. package/dist/types/sdk/broker/session-index.d.ts +6 -1
  94. package/dist/types/sdk/broker/transport.d.ts +2 -0
  95. package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
  96. package/dist/types/sdk/bus/index.d.ts +44 -0
  97. package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
  98. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
  99. package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
  100. package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
  101. package/dist/types/sdk/cli/session-cli.d.ts +0 -1
  102. package/dist/types/sdk/host/control/operations.d.ts +5 -1
  103. package/dist/types/sdk/host/events.d.ts +4 -0
  104. package/dist/types/sdk/host/host.d.ts +2 -1
  105. package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
  106. package/dist/types/sdk/host/session-runtime.d.ts +40 -8
  107. package/dist/types/sdk/host/surface-policy.d.ts +2 -1
  108. package/dist/types/sdk/lifecycle/service.d.ts +12 -0
  109. package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
  110. package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
  111. package/dist/types/sdk/prompt-status.d.ts +11 -4
  112. package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
  113. package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
  114. package/dist/types/sdk/session-list.d.ts +1 -1
  115. package/dist/types/session/agent-session.d.ts +107 -9
  116. package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
  117. package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
  118. package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
  119. package/dist/types/session/messages.d.ts +5 -1
  120. package/dist/types/session/session-manager.d.ts +29 -3
  121. package/dist/types/session/startup-auth-config.d.ts +24 -2
  122. package/dist/types/session/streaming-output.d.ts +11 -0
  123. package/dist/types/session/terminal-abort.d.ts +3 -1
  124. package/dist/types/session-import/service.d.ts +1 -1
  125. package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
  126. package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
  127. package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
  128. package/dist/types/ssh/ssh-executor.d.ts +8 -1
  129. package/dist/types/system-prompt.d.ts +3 -2
  130. package/dist/types/task/executor.d.ts +19 -2
  131. package/dist/types/task/role-body.d.ts +11 -0
  132. package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
  133. package/dist/types/tools/atomic-file-write.d.ts +9 -7
  134. package/dist/types/tools/awaiting-input.d.ts +28 -0
  135. package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
  136. package/dist/types/tools/bash-skill-urls.d.ts +4 -0
  137. package/dist/types/tools/bash.d.ts +7 -0
  138. package/dist/types/tools/descriptors.d.ts +15 -2
  139. package/dist/types/tools/fetch.d.ts +7 -1
  140. package/dist/types/tools/index.d.ts +2 -0
  141. package/dist/types/tools/irc.d.ts +5 -3
  142. package/dist/types/tools/python.d.ts +1 -1
  143. package/dist/types/tools/report-issue.d.ts +41 -0
  144. package/dist/types/tools/subagent.d.ts +23 -0
  145. package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
  146. package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
  147. package/dist/types/tools/write.d.ts +2 -0
  148. package/dist/types/utils/file-mentions.d.ts +5 -0
  149. package/dist/types/utils/image-limits.d.ts +7 -0
  150. package/dist/types/utils/image-loading.d.ts +0 -1
  151. package/dist/types/utils/open.d.ts +0 -1
  152. package/dist/types/utils/pasted-image-loading.d.ts +1 -5
  153. package/dist/types/utils/prompt-suggestion.d.ts +2 -2
  154. package/dist/types/utils/shell-snapshot.d.ts +2 -0
  155. package/dist/types/utils/title-generator.d.ts +13 -3
  156. package/dist/types/web/scrapers/types.d.ts +8 -1
  157. package/dist/types/web/search/providers/codex.d.ts +6 -7
  158. package/dist/types/web/search/providers/insane.d.ts +7 -1
  159. package/dist/types/web/search/providers/searxng.d.ts +5 -0
  160. package/package.json +10 -9
  161. package/scripts/acp-conformance-agent.ts +12 -2
  162. package/scripts/build-binary.ts +2 -1
  163. package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
  164. package/scripts/generate-docs-index.ts +8 -1
  165. package/scripts/generate-sdk-operation-inventory.ts +38 -4
  166. package/src/async/job-manager.ts +356 -56
  167. package/src/async/result-formatting.ts +40 -0
  168. package/src/autoresearch/git.ts +9 -2
  169. package/src/autoresearch/prompts/prompt-setup.md +1 -1
  170. package/src/capability/fs.ts +58 -22
  171. package/src/capability/index.ts +2 -2
  172. package/src/capability/rule.ts +11 -2
  173. package/src/cli/accounts-cli.ts +176 -8
  174. package/src/cli/append-system-prompt.ts +12 -0
  175. package/src/cli/args.ts +11 -7
  176. package/src/cli/auth-broker-cli.ts +21 -11
  177. package/src/cli/customize-doctor-precedence.ts +31 -0
  178. package/src/cli/customize-doctor.ts +49 -39
  179. package/src/cli/doctor/install-repairs.ts +35 -5
  180. package/src/cli/fast-help.ts +1 -3
  181. package/src/cli/install-activation.ts +47 -4
  182. package/src/cli/migrate-cli.ts +19 -6
  183. package/src/cli/public-command-errors.ts +6 -0
  184. package/src/cli/root-flags.ts +2 -4
  185. package/src/cli/stats-cli.ts +9 -5
  186. package/src/cli/update-cli.ts +471 -13
  187. package/src/cli-ordinary.ts +7 -2
  188. package/src/commands/accounts.ts +10 -5
  189. package/src/commands/harness.ts +25 -15
  190. package/src/commands/migrate.ts +3 -3
  191. package/src/commands/sdk.ts +277 -50
  192. package/src/commands/ultragoal.ts +16 -8
  193. package/src/commit/agentic/agent.ts +6 -6
  194. package/src/commit/analysis/conventional.ts +14 -5
  195. package/src/commit/changelog/index.ts +39 -1
  196. package/src/commit/map-reduce/index.ts +7 -7
  197. package/src/commit/message.ts +10 -3
  198. package/src/commit/pipeline.ts +12 -12
  199. package/src/config/autorouting-tier-map.ts +50 -1
  200. package/src/config/config-file.ts +106 -3
  201. package/src/config/config-hot-reload-trust.ts +148 -0
  202. package/src/config/config-hot-reload.ts +742 -0
  203. package/src/config/file-lock.ts +1615 -328
  204. package/src/config/keybindings.ts +154 -7
  205. package/src/config/model-bindings-applier.ts +85 -47
  206. package/src/config/model-discovery-manager.ts +10 -0
  207. package/src/config/model-profile-activation.ts +889 -148
  208. package/src/config/model-registry.ts +1706 -205
  209. package/src/config/model-resolver.ts +52 -22
  210. package/src/config/models-config-schema.ts +6 -0
  211. package/src/config/settings-schema.ts +73 -4
  212. package/src/config/settings.ts +460 -24
  213. package/src/coordinator-mcp/policy.ts +26 -1
  214. package/src/coordinator-mcp/server.ts +37 -2
  215. package/src/crash/sanitize.ts +7 -1
  216. package/src/customization/import.ts +279 -8
  217. package/src/customization/inventory.ts +24 -8
  218. package/src/customization/types.ts +1 -0
  219. package/src/dap/client.ts +3 -2
  220. package/src/dap/config.ts +31 -11
  221. package/src/dap/defaults.json +1 -1
  222. package/src/dap/session.ts +161 -36
  223. package/src/debug/crash-diagnostics.ts +89 -6
  224. package/src/debug/report-bundle.ts +90 -2
  225. package/src/debug/system-info.ts +8 -3
  226. package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
  227. package/src/discovery/agents-md.ts +1 -1
  228. package/src/discovery/builtin.ts +4 -3
  229. package/src/discovery/helpers.ts +25 -16
  230. package/src/discovery/mcp-compat.ts +120 -17
  231. package/src/edit/apply-patch/index.ts +12 -1
  232. package/src/edit/index.ts +204 -22
  233. package/src/edit/modes/patch.ts +214 -8
  234. package/src/edit/modes/replace.ts +136 -0
  235. package/src/eval/js/context-manager.ts +29 -3
  236. package/src/eval/js/worker-entry.ts +51 -18
  237. package/src/eval/py/executor.ts +14 -4
  238. package/src/eval/py/runner.py +144 -5
  239. package/src/eval/py/runtime.ts +44 -4
  240. package/src/exec/bash-executor.ts +81 -4
  241. package/src/exec/bash-shell-guardian.ts +4 -1
  242. package/src/exec/bash-shell-supervisor.ts +8 -4
  243. package/src/exec/isolated-shell.ts +5 -1
  244. package/src/exec/non-interactive-env.ts +0 -1
  245. package/src/export/html/index.ts +86 -6
  246. package/src/export/ttsr.ts +176 -1
  247. package/src/extensibility/custom-tools/wrapper.ts +3 -1
  248. package/src/extensibility/extensions/loader.ts +10 -1
  249. package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
  250. package/src/extensibility/extensions/types.ts +5 -1
  251. package/src/extensibility/hooks/loader.ts +10 -2
  252. package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
  253. package/src/extensibility/plugins/marketplace/manager.ts +36 -10
  254. package/src/extensibility/slash-commands.ts +5 -0
  255. package/src/gjc-runtime/gc-runtime.ts +37 -7
  256. package/src/gjc-runtime/launch-tmux.ts +30 -15
  257. package/src/gjc-runtime/launch-worktree.test.ts +148 -0
  258. package/src/gjc-runtime/launch-worktree.ts +101 -14
  259. package/src/gjc-runtime/managed-owner-admission.ts +46 -2
  260. package/src/gjc-runtime/ralplan-current-final.ts +294 -0
  261. package/src/gjc-runtime/ralplan-runtime.ts +95 -1
  262. package/src/gjc-runtime/session-resolution.ts +38 -6
  263. package/src/gjc-runtime/session-state-lock.ts +59 -14
  264. package/src/gjc-runtime/state-runtime.ts +23 -19
  265. package/src/gjc-runtime/state-writer.ts +109 -5
  266. package/src/gjc-runtime/tmux-sessions.ts +93 -13
  267. package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
  268. package/src/gjc-runtime/ultragoal-guard.ts +9 -1
  269. package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
  270. package/src/harness-control-plane/finalize.ts +11 -0
  271. package/src/harness-control-plane/receipt-spool.ts +105 -28
  272. package/src/harness-control-plane/storage.ts +124 -6
  273. package/src/hindsight/content.ts +116 -16
  274. package/src/hindsight/mental-models.ts +22 -10
  275. package/src/hindsight/state.ts +7 -4
  276. package/src/hooks/native-skill-hook.ts +17 -12
  277. package/src/internal-urls/artifact-protocol.ts +3 -1
  278. package/src/internal-urls/docs-index.generated.ts +23 -22
  279. package/src/internal-urls/local-protocol.ts +167 -8
  280. package/src/internal-urls/types.ts +2 -0
  281. package/src/lsp/client.ts +2 -1
  282. package/src/lsp/clients/biome-client.ts +2 -0
  283. package/src/lsp/clients/swiftlint-client.ts +2 -0
  284. package/src/lsp/index.ts +29 -0
  285. package/src/lsp/workspace-path.ts +23 -0
  286. package/src/main.ts +330 -92
  287. package/src/memories/index.ts +25 -2
  288. package/src/migrate/action-planner.ts +574 -2
  289. package/src/migrate/adapters/claude-code.ts +162 -5
  290. package/src/migrate/adapters/codex.ts +77 -7
  291. package/src/migrate/adapters/index.ts +258 -5
  292. package/src/migrate/adapters/opencode.ts +10 -1
  293. package/src/migrate/executor.ts +222 -7
  294. package/src/migrate/hook-module.ts +193 -0
  295. package/src/migrate/report.ts +63 -2
  296. package/src/migrate/types.ts +84 -4
  297. package/src/modes/DESIGN.md +51 -0
  298. package/src/modes/acp/acp-agent.ts +10 -1
  299. package/src/modes/acp/permission-mode.ts +18 -1
  300. package/src/modes/components/agent-dashboard.ts +20 -4
  301. package/src/modes/components/assistant-message.ts +55 -1
  302. package/src/modes/components/customization/customization-dashboard.ts +7 -0
  303. package/src/modes/components/customization/import-wizard.ts +29 -3
  304. package/src/modes/components/model-selector.ts +157 -103
  305. package/src/modes/components/settings-selector.ts +103 -37
  306. package/src/modes/components/welcome.ts +3 -1
  307. package/src/modes/controllers/command-controller.ts +300 -9
  308. package/src/modes/controllers/event-controller.ts +1 -1
  309. package/src/modes/controllers/extension-ui-controller.ts +31 -1
  310. package/src/modes/controllers/goal-mode-controller.ts +79 -10
  311. package/src/modes/controllers/input-controller.ts +2 -0
  312. package/src/modes/controllers/plan-mode-controller.ts +66 -11
  313. package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
  314. package/src/modes/controllers/selector-controller.ts +76 -7
  315. package/src/modes/interactive-mode.ts +123 -4
  316. package/src/modes/prompt-suggestion-controller.ts +1 -1
  317. package/src/modes/runtime-init.ts +5 -1
  318. package/src/modes/theme/theme.ts +15 -0
  319. package/src/modes/utils/host-status.ts +21 -10
  320. package/src/prompts/agent-fragments/browser-aside.md +2 -2
  321. package/src/prompts/system/irc-incoming.md +3 -1
  322. package/src/prompts/tools/debug.md +1 -1
  323. package/src/prompts/tools/irc.md +1 -1
  324. package/src/prompts/tools/read.md +1 -1
  325. package/src/prompts/tools/report-issue.md +13 -0
  326. package/src/prompts/tools/task.md +1 -1
  327. package/src/runtime-credential-selector.ts +2 -2
  328. package/src/runtime-mcp/content-limits.ts +7 -0
  329. package/src/runtime-mcp/manager-pool.test.ts +5 -4
  330. package/src/runtime-mcp/manager.ts +40 -3
  331. package/src/runtime-mcp/oauth-flow.ts +32 -6
  332. package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
  333. package/src/runtime-mcp/project-host-values.ts +12 -8
  334. package/src/runtime-mcp/render.ts +16 -1
  335. package/src/runtime-mcp/tool-bridge.ts +194 -21
  336. package/src/runtime-mcp/transports/stdio.ts +2 -1
  337. package/src/sdk/broker/broker-exit.ts +10 -5
  338. package/src/sdk/broker/broker.ts +484 -85
  339. package/src/sdk/broker/daemon-entry.ts +338 -116
  340. package/src/sdk/broker/doctor-restart.ts +2 -1
  341. package/src/sdk/broker/ensure.ts +1214 -268
  342. package/src/sdk/broker/hop.ts +286 -0
  343. package/src/sdk/broker/lifecycle-ledger.ts +38 -11
  344. package/src/sdk/broker/lifecycle.ts +102 -6
  345. package/src/sdk/broker/lock-host-identity.ts +29 -0
  346. package/src/sdk/broker/session-index.ts +91 -16
  347. package/src/sdk/broker/transport.ts +17 -1
  348. package/src/sdk/bus/chat-command-policy.ts +16 -3
  349. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  350. package/src/sdk/bus/index.ts +460 -35
  351. package/src/sdk/bus/reconciliation-store.ts +201 -8
  352. package/src/sdk/bus/session-control.ts +2 -0
  353. package/src/sdk/bus/slack-daemon.ts +105 -9
  354. package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
  355. package/src/sdk/bus/telegram-daemon.ts +10 -2
  356. package/src/sdk/bus/threaded-render.ts +20 -1
  357. package/src/sdk/cli/session-cli.ts +23 -6
  358. package/src/sdk/host/control/dispatch.ts +13 -1
  359. package/src/sdk/host/control/operations.ts +10 -1
  360. package/src/sdk/host/events.ts +67 -4
  361. package/src/sdk/host/host.ts +8 -2
  362. package/src/sdk/host/prompt-image-upload.ts +438 -0
  363. package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
  364. package/src/sdk/host/session-runtime.test.ts +1737 -129
  365. package/src/sdk/host/session-runtime.ts +684 -83
  366. package/src/sdk/host/surface-policy.ts +4 -0
  367. package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
  368. package/src/sdk/host/websocket-transport.ts +19 -7
  369. package/src/sdk/lifecycle/service.ts +15 -1
  370. package/src/sdk/prompt-deadline-flush.ts +78 -5
  371. package/src/sdk/prompt-deadline-manager.ts +68 -14
  372. package/src/sdk/prompt-status.ts +6 -4
  373. package/src/sdk/protocol/adapter-validation.ts +81 -12
  374. package/src/sdk/protocol/operation-inventory.generated.json +261 -2
  375. package/src/sdk/protocol/operation-registry.ts +33 -3
  376. package/src/sdk/reconciliation-extensions.ts +1 -0
  377. package/src/sdk/session-list.ts +1 -0
  378. package/src/sdk/session.ts +237 -97
  379. package/src/session/agent-session.ts +2726 -479
  380. package/src/session/history-storage.ts +182 -12
  381. package/src/session/internal/managed-session-scope.ts +173 -57
  382. package/src/session/internal/managed-session-storage.ts +85 -12
  383. package/src/session/internal/native-publish-outcome.ts +5 -1
  384. package/src/session/messages.ts +47 -6
  385. package/src/session/session-manager.ts +326 -19
  386. package/src/session/startup-auth-config.ts +116 -8
  387. package/src/session/streaming-output.ts +262 -4
  388. package/src/session/terminal-abort.ts +14 -2
  389. package/src/session-import/redact.ts +53 -2
  390. package/src/session-import/service.ts +1 -0
  391. package/src/skill-state/workflow-mutation-guard.ts +2145 -206
  392. package/src/slash-commands/builtin-registry.ts +21 -6
  393. package/src/slash-commands/helpers/credential-switch.ts +10 -5
  394. package/src/slash-commands/helpers/mcp.ts +11 -3
  395. package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
  396. package/src/ssh/ssh-executor.ts +9 -2
  397. package/src/stt/recorder.ts +26 -9
  398. package/src/system-prompt.ts +61 -16
  399. package/src/task/executor.ts +115 -20
  400. package/src/task/index.ts +389 -175
  401. package/src/task/role-body.ts +84 -0
  402. package/src/task/token-log-mode.test.ts +162 -0
  403. package/src/task/token-log.ts +91 -2
  404. package/src/tools/archive-reader.ts +650 -37
  405. package/src/tools/ask.ts +1 -0
  406. package/src/tools/ast-edit-write-path.ts +64 -0
  407. package/src/tools/ast-edit.ts +18 -1
  408. package/src/tools/ast-grep.ts +7 -2
  409. package/src/tools/atomic-file-write.ts +46 -15
  410. package/src/tools/auto-generated-guard.ts +15 -3
  411. package/src/tools/awaiting-input.ts +114 -0
  412. package/src/tools/bash-allowed-prefixes.ts +214 -6
  413. package/src/tools/bash-interactive.ts +14 -2
  414. package/src/tools/bash-skill-urls.ts +58 -5
  415. package/src/tools/bash.ts +113 -26
  416. package/src/tools/browser/tab-worker.ts +39 -13
  417. package/src/tools/browser.ts +17 -7
  418. package/src/tools/cron.ts +10 -1
  419. package/src/tools/debug.ts +16 -8
  420. package/src/tools/descriptors.test.ts +44 -0
  421. package/src/tools/descriptors.ts +50 -6
  422. package/src/tools/eval.ts +15 -0
  423. package/src/tools/fetch.ts +93 -4
  424. package/src/tools/gh.ts +27 -12
  425. package/src/tools/image-gen.ts +20 -6
  426. package/src/tools/index.ts +2 -0
  427. package/src/tools/irc.ts +5 -3
  428. package/src/tools/monitor.ts +9 -1
  429. package/src/tools/output-meta.ts +74 -5
  430. package/src/tools/python.ts +1 -1
  431. package/src/tools/read.ts +26 -37
  432. package/src/tools/recipe/runner.ts +23 -12
  433. package/src/tools/render-utils.ts +2 -2
  434. package/src/tools/report-issue.ts +184 -0
  435. package/src/tools/search.ts +3 -2
  436. package/src/tools/ssh.ts +274 -8
  437. package/src/tools/subagent-render.ts +114 -12
  438. package/src/tools/subagent.ts +118 -5
  439. package/src/tools/tmux-self-injection-guard.ts +3301 -122
  440. package/src/tools/todo-write.ts +41 -3
  441. package/src/tools/tool-catalog.generated.ts +32 -4
  442. package/src/tools/ultragoal-ask-guard.ts +13 -1
  443. package/src/tools/write.ts +42 -3
  444. package/src/tui/tree-list.ts +15 -1
  445. package/src/utils/commit-message-generator.ts +12 -4
  446. package/src/utils/external-editor.ts +21 -7
  447. package/src/utils/file-mentions.ts +75 -7
  448. package/src/utils/git.ts +38 -7
  449. package/src/utils/image-limits.ts +8 -0
  450. package/src/utils/image-loading.ts +1 -1
  451. package/src/utils/open.ts +73 -4
  452. package/src/utils/pasted-image-loading.ts +9 -8
  453. package/src/utils/prompt-suggestion.ts +5 -4
  454. package/src/utils/shell-snapshot.ts +9 -1
  455. package/src/utils/title-generator.ts +72 -22
  456. package/src/web/scrapers/index.ts +3 -1
  457. package/src/web/scrapers/types.ts +8 -0
  458. package/src/web/scrapers/youtube.ts +3 -2
  459. package/src/web/search/index.ts +2 -1
  460. package/src/web/search/providers/codex.ts +29 -32
  461. package/src/web/search/providers/insane.ts +91 -28
  462. package/src/web/search/providers/searxng.ts +62 -10
@@ -49,6 +49,7 @@ import {
49
49
  } from "../append-only-mode";
50
50
  import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled, jobElapsedMs } from "../async";
51
51
  import { asyncJobEndpointId as deriveAsyncJobEndpointId } from "../async/endpoint-id";
52
+ import { formatAsyncResultForFollowUp } from "../async/result-formatting";
52
53
  import { resolveBrowserBackend } from "../browser-backend";
53
54
  import { loadCapability, reset as resetCapabilities } from "../capability";
54
55
  import { type Rule, ruleCapability, setActiveRules } from "../capability/rule";
@@ -85,6 +86,7 @@ import { disposeKernelSessionsByOwner } from "../eval/py/executor";
85
86
  import type { MasterModeContext } from "../master-mode/context";
86
87
  import { describeFoldReceipt } from "../session/fold-coordinator";
87
88
  import type { BashRestrictionProfile } from "../tools/bash-allowed-prefixes";
89
+ import { wrapUntrustedContent } from "../tools/fetch";
88
90
  import { SearchTool } from "../tools/search";
89
91
  import "../discovery";
90
92
  import { resolveConfigValue } from "../config/resolve-config-value";
@@ -161,7 +163,8 @@ import {
161
163
  resolveMCPToolCache,
162
164
  } from "../runtime-mcp";
163
165
  import { createMCPFormInputHandler } from "../runtime-mcp/elicitation";
164
- import type { MCPLoadResult } from "../runtime-mcp/manager";
166
+ import { type MCPLoadResult, omitUnapprovedProjectStdio } from "../runtime-mcp/manager";
167
+ import { omitPluginMcpNameShadows, retainPluginMcpMandatoryNames } from "../runtime-mcp/plugin-mcp-name-filter";
165
168
  import { MCP_STARTUP_WAIT_GRACE_MS } from "../runtime-mcp/startup-policy";
166
169
  import type { MCPServerConfig } from "../runtime-mcp/types";
167
170
  import {
@@ -187,6 +190,7 @@ import {
187
190
  parsePersistedCredentialSelector,
188
191
  resolveStartupAuthConfig,
189
192
  type StartupAuthConfigSnapshot,
193
+ startupAuthConfigError,
190
194
  } from "../session/startup-auth-config";
191
195
  import {
192
196
  isOwnedCompletionEnvelopeAllowed,
@@ -206,7 +210,11 @@ import {
206
210
  } from "../system-prompt";
207
211
  import { AgentOutputManager } from "../task/output-manager";
208
212
  import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } from "../thinking";
209
- import { isMCPBridgeTool, selectRestorableDiscoveredBuiltinToolNames } from "../tool-discovery/tool-index";
213
+ import {
214
+ isMCPBridgeTool,
215
+ isMCPToolName,
216
+ selectRestorableDiscoveredBuiltinToolNames,
217
+ } from "../tool-discovery/tool-index";
210
218
  import {
211
219
  type AutomationToolName,
212
220
  type AutomationTools,
@@ -215,6 +223,7 @@ import {
215
223
  computeEssentialBuiltinNames,
216
224
  createTools,
217
225
  HIDDEN_TOOLS,
226
+ type LazyAgentTool,
218
227
  resolveEffectiveDiscoveryMode,
219
228
  type Tool,
220
229
  type ToolSession,
@@ -778,6 +787,7 @@ export async function discoverAuthStorage(
778
787
  const resolvedStartupAuth = startupAuth ?? (await resolveStartupAuthConfig(agentDir));
779
788
  const brokerConfig = resolvedStartupAuth.broker;
780
789
  const credentialRankingMode = resolvedStartupAuth.credentialRankingMode;
790
+ const credentialPreferences = resolvedStartupAuth.credentialPreferences;
781
791
  if (brokerConfig) {
782
792
  const client = new AuthBrokerClient({ url: brokerConfig.url, token: brokerConfig.token });
783
793
  const initialResult = await client.fetchSnapshot();
@@ -789,16 +799,18 @@ export async function discoverAuthStorage(
789
799
  configValueResolver: resolveConfigValue,
790
800
  sourceLabel: `broker ${brokerConfig.url}`,
791
801
  credentialRankingMode,
802
+ credentialPreferences,
792
803
  });
793
- return await reloadDiscoveredAuthStorage(storage);
804
+ return rejectDuplicateCredentialPreferences(await reloadDiscoveredAuthStorage(storage), agentDir);
794
805
  }
795
806
  const dbPath = getAgentDbPath(agentDir);
796
807
  const storage = await AuthStorage.create(dbPath, {
797
808
  configValueResolver: resolveConfigValue,
798
809
  sourceLabel: `local ${dbPath}`,
799
810
  credentialRankingMode,
811
+ credentialPreferences,
800
812
  });
801
- return await reloadDiscoveredAuthStorage(storage);
813
+ return rejectDuplicateCredentialPreferences(await reloadDiscoveredAuthStorage(storage), agentDir);
802
814
  }
803
815
 
804
816
  async function reloadDiscoveredAuthStorage(storage: AuthStorage): Promise<AuthStorage> {
@@ -815,6 +827,26 @@ async function reloadDiscoveredAuthStorage(storage: AuthStorage): Promise<AuthSt
815
827
  return storage;
816
828
  }
817
829
 
830
+ /**
831
+ * Two preference entries can name one stored account through different selectors (`email:` and `account:` for the
832
+ * same login). Only the loaded rows reveal that, so the startup-config check finishes here and fails closed like any
833
+ * other invalid preference list.
834
+ */
835
+ function rejectDuplicateCredentialPreferences(storage: AuthStorage, agentDir: string): AuthStorage {
836
+ const duplicates = storage.findDuplicateCredentialPreferences();
837
+ if (duplicates.length === 0) return storage;
838
+ logger.warn("Configured credential preferences name one account twice", {
839
+ providers: duplicates.map(({ provider }) => sanitizeProviderForLog(provider)),
840
+ });
841
+ const error = startupAuthConfigError(agentDir, "invalid-credential-preferences");
842
+ try {
843
+ storage.close();
844
+ } catch (cleanupError) {
845
+ throw attachStartupCleanupDiagnostic(error, cleanupError);
846
+ }
847
+ throw error;
848
+ }
849
+
818
850
  /** Ranking is resolved as part of the typed startup-auth snapshot. */
819
851
 
820
852
  /**
@@ -1209,7 +1241,10 @@ function buildMCPPromptCommands(manager: MCPManager): LoadedCustomCommand[] {
1209
1241
  }
1210
1242
  }
1211
1243
  }
1212
- return parts.join("\n\n");
1244
+ const body = parts.join("\n\n");
1245
+ // A blank body must stay blank so the prompt entry still rejects it.
1246
+ if (body.trim().length === 0) return body;
1247
+ return wrapUntrustedContent(body);
1213
1248
  },
1214
1249
  },
1215
1250
  });
@@ -1309,8 +1344,11 @@ function classifyInheritedMcpToolNames(
1309
1344
  for (const tool of tools) {
1310
1345
  const serverName = tool.mcpServerName;
1311
1346
  if (serverName === undefined) continue;
1312
- if (pluginServers?.has(serverName)) pluginMcpToolNames.push(tool.name);
1313
- else if (conventionalServers?.has(serverName)) conventionalMcpToolNames.push(tool.name);
1347
+ // Caller-supplied source metadata is descriptive; only a manager's
1348
+ // validated plugin-server set can grant mandatory-tool authority.
1349
+ if (pluginServers?.has(serverName)) {
1350
+ pluginMcpToolNames.push(tool.name);
1351
+ } else if (conventionalServers?.has(serverName)) conventionalMcpToolNames.push(tool.name);
1314
1352
  }
1315
1353
  return { pluginMcpToolNames, conventionalMcpToolNames };
1316
1354
  }
@@ -1549,6 +1587,19 @@ function validateAutomationTools(options: CreateAgentSessionOptions): Automation
1549
1587
  return automationTools;
1550
1588
  }
1551
1589
 
1590
+ /** User/global `mcp.enableProjectConfig` only. A project file cannot set it.
1591
+ * Unset keeps non-stdio project MCP and does not approve a project stdio spawn.
1592
+ */
1593
+ function nativeProjectMcpAutoload(settings: Settings): {
1594
+ enableProjectConfig: boolean;
1595
+ allowProjectStdio: boolean;
1596
+ } {
1597
+ const configured = settings.getGlobal("mcp.enableProjectConfig");
1598
+ if (configured === true) return { enableProjectConfig: true, allowProjectStdio: true };
1599
+ if (configured === false) return { enableProjectConfig: false, allowProjectStdio: false };
1600
+ return { enableProjectConfig: true, allowProjectStdio: false };
1601
+ }
1602
+
1552
1603
  export async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {
1553
1604
  const automationTools = validateAutomationTools(options);
1554
1605
  const primaryControlSurface = primaryControlSurfaceFor(options);
@@ -2215,7 +2266,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2215
2266
  ? { aliasIntent: "preset-equivalent" }
2216
2267
  : undefined;
2217
2268
  const allowedModels = await logger.time("resolveAllowedModels", () =>
2218
- resolveAllowedModels(modelRegistry, settings, modelMatchPreferences),
2269
+ resolveAllowedModels(modelRegistry, settings, modelMatchPreferences, credentialSessionId),
2219
2270
  );
2220
2271
  const defaultRoleSpec = logger.time("resolveDefaultModelRole", () =>
2221
2272
  resolveModelRoleValue(settings.getModelRole("default"), allowedModels, {
@@ -2243,6 +2294,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2243
2294
  : existingSession.models.default
2244
2295
  ? [existingSession.models.default]
2245
2296
  : [];
2297
+ if (
2298
+ startupRegistryMutationAuthorized &&
2299
+ !hasExplicitModel &&
2300
+ hasExistingSession &&
2301
+ defaultModelEntries.length > 0
2302
+ ) {
2303
+ // Resume skips startup discovery, so refresh a missing saved provider
2304
+ // before resolution when this session owns authority to mutate the registry.
2305
+ await refreshMissingQualifiedModelProviders(defaultModelEntries, modelRegistry, credentialSessionId);
2306
+ }
2246
2307
  const persistedProfileName =
2247
2308
  persistedDefaultChain?.origin === "profile-activation" ? persistedDefaultChain.identity : undefined;
2248
2309
  const resolvedPersistedProfileName = persistedProfileName
@@ -2455,7 +2516,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2455
2516
  const rulebookRules: Rule[] = [];
2456
2517
  const alwaysApplyRules: Rule[] = [];
2457
2518
  for (const rule of rulesResult.items) {
2458
- const isTtsrRule = rule.condition && rule.condition.length > 0 ? ttsrManager.addRule(rule) : false;
2519
+ const hasTtsrCondition = (rule.condition?.length ?? 0) > 0 || (rule.astCondition?.length ?? 0) > 0;
2520
+ const isTtsrRule = hasTtsrCondition ? ttsrManager.addRule(rule) : false;
2459
2521
  if (isTtsrRule) {
2460
2522
  continue;
2461
2523
  }
@@ -2515,33 +2577,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2515
2577
 
2516
2578
  const backgroundJobsEnabled = isBackgroundJobSupportEnabled(settings);
2517
2579
  const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ?? 100));
2518
- const ASYNC_INLINE_RESULT_MAX_CHARS = 12_000;
2519
- const ASYNC_PREVIEW_MAX_CHARS = 4_000;
2520
- const formatAsyncResultForFollowUp = async (result: string, allowArtifact = true): Promise<string> => {
2521
- if (result.length <= ASYNC_INLINE_RESULT_MAX_CHARS) {
2522
- return result;
2523
- }
2524
-
2525
- const preview = `${result.slice(0, ASYNC_PREVIEW_MAX_CHARS)}\n\n[Output truncated. Showing first ${ASYNC_PREVIEW_MAX_CHARS.toLocaleString()} characters.]`;
2526
- // A delivery already denied by a scope:"owned" gate never reaches the
2527
- // model: allocating an artifact for it would leave the stopped job's
2528
- // output in an unreferenced artifact after the flush drops it (review
2529
- // thread P2). Only the inline preview is produced.
2530
- if (!allowArtifact) return preview;
2531
- try {
2532
- const { path: artifactPath, id: artifactId } = await sessionManager.allocateArtifactPath("async");
2533
- if (artifactPath && artifactId) {
2534
- await Bun.write(artifactPath, result);
2535
- return `${preview}\nFull output: artifact://${artifactId}`;
2536
- }
2537
- } catch (error) {
2538
- logger.warn("Failed to persist async follow-up artifact", {
2539
- error: error instanceof Error ? error.message : String(error),
2540
- });
2541
- }
2542
-
2543
- return preview;
2544
- };
2545
2580
  // Only top-level sessions own an AsyncJobManager. Subagents reach the
2546
2581
  // parent's manager via `AsyncJobManager.instance()` (set below), so creating
2547
2582
  // a second instance here just to leave it orphaned wastes a constructor and
@@ -2599,7 +2634,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2599
2634
  if (job) asyncJobManager?.retainParkedDelivery(job, result);
2600
2635
  return;
2601
2636
  }
2602
- const formattedResult = await formatAsyncResultForFollowUp(result, !deniedOwnedDelivery);
2637
+ const formattedResult = await formatAsyncResultForFollowUp(
2638
+ sessionManager,
2639
+ result,
2640
+ !deniedOwnedDelivery,
2641
+ );
2603
2642
  if (
2604
2643
  foldDisposition.kind === "receipt" &&
2605
2644
  job &&
@@ -2742,16 +2781,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2742
2781
  ownedMcpManagerTools = [];
2743
2782
  publishOwnedMcpTools = false;
2744
2783
  let nextManager: MCPManager | undefined;
2784
+ const projectMcp = nativeProjectMcpAutoload(settings);
2745
2785
  try {
2746
2786
  const loaded = await loadAllMCPConfigs(to, {
2747
2787
  agentDir,
2748
- enableProjectConfig: settings.has("mcp.enableProjectConfig")
2749
- ? settings.get("mcp.enableProjectConfig")
2750
- : true,
2788
+ enableProjectConfig: projectMcp.enableProjectConfig,
2751
2789
  autoloadOnly: true,
2752
2790
  nativeOnly: true,
2753
2791
  settings,
2754
2792
  });
2793
+ omitUnapprovedProjectStdio(loaded.configs, loaded.sources, projectMcp.allowProjectStdio);
2755
2794
  const { configs: pluginConfigs } = await buildPluginMcpConfigs({ cwd: to });
2756
2795
  const pluginNames = new Set(Object.keys(pluginConfigs));
2757
2796
  const mergedConfigs = { ...loaded.configs, ...pluginConfigs };
@@ -2776,6 +2815,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2776
2815
  {
2777
2816
  sharedPoolIdleMs: settings.get("mcp.sharedPoolIdleMs"),
2778
2817
  toolCacheServerNames: conventionalCacheServerNames,
2818
+ allowUntrustedProjectStdio: projectMcp.allowProjectStdio,
2779
2819
  },
2780
2820
  );
2781
2821
  nextManager.setAuthStorage(authStorage);
@@ -2814,9 +2854,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2814
2854
  for (const tool of result.tools) {
2815
2855
  const serverName = tool.mcpServerName;
2816
2856
  if (serverName === undefined) continue;
2817
- if (pluginNames.has(serverName)) pluginMcpToolNames.push(tool.name);
2818
- else conventionalMcpToolNames.push(tool.name);
2857
+ if (!pluginNames.has(serverName)) conventionalMcpToolNames.push(tool.name);
2819
2858
  }
2859
+ pluginMcpToolNames.push(
2860
+ ...retainPluginMcpMandatoryNames(
2861
+ result.tools,
2862
+ result.tools
2863
+ .filter(tool => tool.mcpServerName && pluginNames.has(tool.mcpServerName))
2864
+ .map(tool => tool.name),
2865
+ ),
2866
+ );
2820
2867
  }
2821
2868
  } catch (error) {
2822
2869
  logger.warn("Failed to recreate MCP authority after session rescope", {
@@ -2835,7 +2882,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2835
2882
  await session.replaceNamedCustomTools(
2836
2883
  previousCwdCapturing.filter(name => !nextCustomTools.some(tool => tool.name === name)),
2837
2884
  nextCustomTools,
2838
- { mandatoryMCPToolNames: pluginMcpToolNames },
2885
+ {
2886
+ mandatoryMCPToolNames: pluginMcpToolNames,
2887
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload ? [] : conventionalMcpToolNames,
2888
+ inactiveNewToolNames: deferConventionalMcpAutoload ? conventionalMcpToolNames : undefined,
2889
+ },
2839
2890
  );
2840
2891
  wireOwnedMcpToolSync();
2841
2892
  };
@@ -2945,11 +2996,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2945
2996
  "This session has already been rescoped; only one agent-invoked move is allowed per session.",
2946
2997
  );
2947
2998
  }
2948
- if (session?.getEffectiveActiveWorkflowSkillState()) {
2949
- throw new Error(
2950
- "A workflow skill is active in this session; finish or exit it before rescoping.",
2951
- );
2952
- }
2953
2999
  if (options.mcpManager && !ownsMcpManager) {
2954
3000
  throw new Error(
2955
3001
  "Cannot rescope a session with caller-owned MCP authority; recreate the session at the target cwd.",
@@ -2961,9 +3007,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2961
3007
  "This session has already been rescoped; only one agent-invoked move is allowed per session.",
2962
3008
  );
2963
3009
  }
2964
- if (session?.getEffectiveActiveWorkflowSkillState()) {
3010
+ if (await session?.refreshEffectiveActiveWorkflowSkillState()) {
2965
3011
  throw new Error(
2966
- "A workflow skill became active while waiting for the cwd transition; finish or exit it before rescoping.",
3012
+ "A workflow skill is active in this session; finish or exit it before rescoping.",
2967
3013
  );
2968
3014
  }
2969
3015
  const from = sessionManager.getCwd();
@@ -3281,6 +3327,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3281
3327
  getWorkflowGateEmitter: () => session?.getWorkflowGateEmitter(),
3282
3328
  getAskAnswerSource: () => session?.getAskAnswerSource(),
3283
3329
  getGoalRuntime: () => session?.goalRuntime,
3330
+ getSdkPermissionMode: () => session?.sdkPermissionMode ?? "allow",
3284
3331
  getClientBridge: () => session?.clientBridge,
3285
3332
  getCompactContext: () => session.formatCompactContext(),
3286
3333
  getTodoPhases: () => session.getTodoPhases(),
@@ -3400,6 +3447,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3400
3447
  options.toolNames,
3401
3448
  automationTools,
3402
3449
  );
3450
+ const taskFacade = builtinTools.find(tool => tool.name === "task") as LazyAgentTool | undefined;
3403
3451
 
3404
3452
  // A top-level session loads MCP tools from three bounded surfaces: a
3405
3453
  // caller-supplied exact config (`--mcp-config`), conventional native
@@ -3754,6 +3802,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3754
3802
  // `--mcp-config` exact-file sessions never reach here. The owned manager's
3755
3803
  // tools are surfaced as always-on custom tools (like plugin MCPs), so an
3756
3804
  // ordinary session exposes them without needing MCP discovery mode.
3805
+ const projectMcp = nativeProjectMcpAutoload(settings);
3757
3806
  let conventionalConfigs: Record<string, MCPServerConfig> = {};
3758
3807
  let conventionalSources: Record<string, SourceMeta> = {};
3759
3808
  if (options.enableMcpAutoload !== false) {
@@ -3763,13 +3812,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3763
3812
  // `gjc mcp add` (user scope) writes; an SDK embedder that runs on
3764
3813
  // its own agent directory autoloads its own registrations.
3765
3814
  agentDir,
3766
- // Project-scope native config loads by default; only an
3767
- // explicitly configured `mcp.enableProjectConfig: false`
3768
- // disables it (the legacy schema default stays false for
3769
- // foreign-format discovery consumers of the capability system).
3770
- enableProjectConfig: settings.has("mcp.enableProjectConfig")
3771
- ? settings.get("mcp.enableProjectConfig")
3772
- : true,
3815
+ // Non-stdio project MCP stays on unless the user/global layer
3816
+ // sets `mcp.enableProjectConfig` to false. Project files cannot
3817
+ // set that flag. Project stdio also needs it explicitly true.
3818
+ enableProjectConfig: projectMcp.enableProjectConfig,
3773
3819
  autoloadOnly: true,
3774
3820
  // Runtime authority is GJC's native `.gjc` config in both scopes;
3775
3821
  // Claude Code/Codex MCP files are explicit import sources into
@@ -3777,6 +3823,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3777
3823
  nativeOnly: true,
3778
3824
  settings,
3779
3825
  });
3826
+ omitUnapprovedProjectStdio(loaded.configs, loaded.sources, projectMcp.allowProjectStdio);
3780
3827
  conventionalConfigs = loaded.configs;
3781
3828
  conventionalSources = loaded.sources;
3782
3829
  for (const warning of loaded.warnings) {
@@ -3841,6 +3888,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3841
3888
  {
3842
3889
  sharedPoolIdleMs: settings.get("mcp.sharedPoolIdleMs"),
3843
3890
  toolCacheServerNames: conventionalCacheServerNames,
3891
+ allowUntrustedProjectStdio: projectMcp.allowProjectStdio,
3844
3892
  ...(maxPluginMcpStartupWaitMs === undefined
3845
3893
  ? {}
3846
3894
  : { maxStartupTimeoutMs: maxPluginMcpStartupWaitMs }),
@@ -3940,7 +3988,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
3940
3988
  const inlineExtensions: ExtensionFactory[] = [...(options.extensions ?? [])];
3941
3989
  const discoveredHookExtensions: Array<{ factory: ExtensionFactory; name: string }> = [];
3942
3990
  if (customTools.length > 0) {
3943
- inlineExtensions.push(createCustomToolsExtension(customTools));
3991
+ inlineExtensions.push(createCustomToolsExtension(omitPluginMcpNameShadows(customTools)));
3944
3992
  }
3945
3993
  if (!options.disableExtensionDiscovery) {
3946
3994
  try {
@@ -4092,6 +4140,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4092
4140
  if (!session) throw new Error("Terminal abort session is not initialized.");
4093
4141
  return session.pendingToolExecutions(handle);
4094
4142
  },
4143
+ waitForRunSettlement: handle => {
4144
+ if (!session) throw new Error("Image owner session is not initialized.");
4145
+ return session.agent.resourceLedger.waitForSettlement(handle, { graceMs: null });
4146
+ },
4095
4147
  },
4096
4148
  ensureProviderDaemon: options.ensureNotificationProviderDaemon,
4097
4149
  runBtwTurn: async (question, signal) => {
@@ -4186,6 +4238,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4186
4238
  if (!session) throw new Error("Terminal abort session is not initialized.");
4187
4239
  return session.pendingToolExecutions(handle);
4188
4240
  },
4241
+ waitForRunSettlement: handle => {
4242
+ if (!session) throw new Error("Image owner session is not initialized.");
4243
+ return session.agent.resourceLedger.waitForSettlement(handle, { graceMs: null });
4244
+ },
4189
4245
  },
4190
4246
  });
4191
4247
  }
@@ -4198,18 +4254,19 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4198
4254
  });
4199
4255
  }
4200
4256
 
4201
- // Extension modules are discovered at session startup from the canonical
4202
- // native locations (`<agentDir>/extensions`, `<cwd>/.gjc/extensions`),
4203
- // installed plugin bundles, the `extensions` setting, and explicitly
4204
- // supplied `additionalExtensionPaths`. `disableExtensionDiscovery` keeps its
4205
- // documented opt-out semantics: explicit paths still load, matching
4257
+ // Extension modules are discovered at session startup from the user agent
4258
+ // directory, installed plugin bundles, the user/global `extensions` setting,
4259
+ // and explicitly supplied `additionalExtensionPaths`. A repository
4260
+ // `.gjc/extensions` tree is not imported. `disableExtensionDiscovery` keeps
4261
+ // its documented opt-out semantics: explicit paths still load, matching
4206
4262
  // `cli/list-models.ts`. A caller-supplied `preloadedExtensions` result
4207
4263
  // suppresses discovery entirely.
4208
4264
  const explicitExtensionPaths = options.additionalExtensionPaths ?? [];
4209
- // The `extensions` setting is schema-typed as an array of paths, but a
4210
- // hand-edited config can hold an invalid shape; discovery must degrade to
4211
- // no extra paths instead of aborting startup for every session.
4212
- const extensionsSettingPaths = Array.isArray(settings.get("extensions")) ? settings.get("extensions") : [];
4265
+ // The merged `extensions` value includes the project layer, which can name
4266
+ // any module. Only the user/global list is imported. A hand-edited value
4267
+ // with an invalid shape contributes no extra paths.
4268
+ const globalExtensionPaths = settings.getGlobal("extensions");
4269
+ const extensionsSettingPaths = Array.isArray(globalExtensionPaths) ? globalExtensionPaths : [];
4213
4270
  // Discovery must never block session creation: a filesystem or plugin-registry
4214
4271
  // failure degrades to the explicit paths and then to no extensions at all, and
4215
4272
  // the failure stays observable in `extensionsResult.errors`.
@@ -4412,7 +4469,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4412
4469
  startupModelReference.id,
4413
4470
  startupCredentialSelector,
4414
4471
  );
4415
- const currentStartupModel = modelRegistry.find(startupModelReference.provider, startupModelReference.id);
4472
+ const currentStartupModel = modelRegistry.find(
4473
+ startupModelReference.provider,
4474
+ startupModelReference.id,
4475
+ credentialSessionId,
4476
+ );
4416
4477
  const providerMismatchRejectsTarget =
4417
4478
  startupCredentialProviderMismatch &&
4418
4479
  modelRegistry.requiresStoredLiteralCredentialCacheAdmission(
@@ -4437,7 +4498,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4437
4498
 
4438
4499
  // Resolve deferred --model pattern now that extension models are registered.
4439
4500
  if (!model && options.modelPattern && !startupCredentialModelRejected) {
4440
- const availableModels = modelRegistry.getAll();
4501
+ const availableModels = modelRegistry.getAll(credentialSessionId);
4441
4502
  const matchPreferences = {
4442
4503
  usageOrder: settings.getStorage()?.getModelUsageOrder(),
4443
4504
  };
@@ -4479,7 +4540,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4479
4540
  ) {
4480
4541
  // Re-resolve the allowed set: extension factories above may have
4481
4542
  // registered providers/models that weren't visible at startup.
4482
- const allowedFallbackCandidates = await resolveAllowedModels(modelRegistry, settings, modelMatchPreferences);
4543
+ const allowedFallbackCandidates = await resolveAllowedModels(
4544
+ modelRegistry,
4545
+ settings,
4546
+ modelMatchPreferences,
4547
+ credentialSessionId,
4548
+ );
4483
4549
  // Candidate order is not a quality signal: catalogs sort retired models
4484
4550
  // ahead of current ones whenever their IDs carry older date suffixes, so
4485
4551
  // an unconfigured install would otherwise start on a model its provider
@@ -4768,7 +4834,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4768
4834
  // epoch additionally fences overlapping rebuilds, so a slower earlier
4769
4835
  // pass cannot publish over a newer one.
4770
4836
  const gjcPassEpoch = gjcRuntimeStore.beginPass();
4771
- toolContextStore.setToolNames(toolNames);
4772
4837
  const promptTools = (() => {
4773
4838
  const previousPromptMetadataModel = promptMetadataModel;
4774
4839
  promptMetadataModel = candidateModel;
@@ -4888,6 +4953,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4888
4953
  const requestedToolNameSet = new Set(normalizedRequested);
4889
4954
  const effectiveDiscoveryMode = resolveEffectiveDiscoveryMode(settings, explicitMcpConfigPath);
4890
4955
  const mcpDiscoveryEnabled = effectiveDiscoveryMode !== "off";
4956
+ const discoveryDefaultServerNames = new Set(settings.get("mcp.discoveryDefaultServers") ?? []);
4957
+ const deferConventionalMcpAutoload = mcpDiscoveryEnabled && settings.get("mcp.discoveryDeferAutoload");
4891
4958
  const defaultInactiveToolNames = new Set(
4892
4959
  registeredTools.filter(tool => tool.definition.defaultInactive).map(tool => tool.definition.name),
4893
4960
  );
@@ -4906,7 +4973,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4906
4973
  let hasExplicitDiscoveredBuiltinToolSelection = false;
4907
4974
  let explicitlyRequestedDiscoveredBuiltinToolNames: string[] = [];
4908
4975
  if (mcpDiscoveryEnabled) {
4909
- const defaultServerNames = new Set(settings.get("mcp.discoveryDefaultServers") ?? []);
4910
4976
  for (const tool of toolRegistry.values()) {
4911
4977
  if (!isMCPBridgeTool(tool)) continue;
4912
4978
  discoverableMCPToolNames.add(tool.name);
@@ -4914,22 +4980,37 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4914
4980
  explicitlyRequestedMCPToolNames.push(tool.name);
4915
4981
  }
4916
4982
  const serverName = (tool as AgentTool & { mcpServerName?: string }).mcpServerName;
4917
- if (serverName && defaultServerNames.has(serverName)) {
4983
+ if (serverName && discoveryDefaultServerNames.has(serverName)) {
4918
4984
  discoveryDefaultServerToolNames.push(tool.name);
4919
4985
  }
4920
4986
  }
4921
4987
  }
4922
- const mandatoryMCPToolNameSet = new Set(pluginMcpToolNames);
4923
- const selectableExplicitMCPToolNames = explicitlyRequestedMCPToolNames.filter(
4924
- name => !mandatoryMCPToolNameSet.has(name),
4988
+ // Mandatory names follow the plugin tools that survived registration.
4989
+ // A colliding user tool keeps the normalized name and must stay selectable.
4990
+ pluginMcpToolNames.splice(
4991
+ 0,
4992
+ pluginMcpToolNames.length,
4993
+ ...retainPluginMcpMandatoryNames(customTools, pluginMcpToolNames),
4925
4994
  );
4995
+ const mandatoryMCPToolNameSet = new Set(pluginMcpToolNames);
4996
+ const deferredMcpConnectPending = deferredExactMcpConfig !== undefined || deferredConventionalMcp !== undefined;
4997
+ const requestedDeferredMCPToolNames =
4998
+ deferredMcpConnectPending && hasExplicitToolNames
4999
+ ? options
5000
+ .toolNames!.map(name => name.toLowerCase())
5001
+ .filter(name => isMCPToolName(name) && !toolRegistry.has(name))
5002
+ : [];
5003
+ const selectableExplicitMCPToolNames = [
5004
+ ...new Set([
5005
+ ...explicitlyRequestedMCPToolNames.filter(name => !mandatoryMCPToolNameSet.has(name)),
5006
+ ...requestedDeferredMCPToolNames.filter(name => !mandatoryMCPToolNameSet.has(name)),
5007
+ ]),
5008
+ ];
4926
5009
  let initialToolNames = [...initialRequestedActiveToolNames];
4927
5010
  if (mcpDiscoveryEnabled) {
4928
5011
  // A pending deferred MCP connect (exact or conventional) registers its
4929
5012
  // tools after construction, so persisted selections must be preserved
4930
5013
  // verbatim instead of being trimmed to names the registry currently has.
4931
- const deferredMcpConnectPending =
4932
- deferredExactMcpConfig !== undefined || deferredConventionalMcp !== undefined;
4933
5014
  const restoredSelectedMCPToolNames = deferredMcpConnectPending
4934
5015
  ? existingSession.selectedMCPToolNames.filter(name => !mandatoryMCPToolNameSet.has(name))
4935
5016
  : existingSession.selectedMCPToolNames.filter(
@@ -4947,8 +5028,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4947
5028
  ...discoveryDefaultServerToolNames,
4948
5029
  ...(explicitMcpConfigPath !== undefined ? exactMcpToolNames : []),
4949
5030
  // Conventional autoload servers are selected by default so their
4950
- // tools are exposed in sessions that enable MCP discovery mode.
4951
- ...conventionalMcpToolNames,
5031
+ // tools are exposed in sessions that enable MCP discovery mode,
5032
+ // unless `mcp.discoveryDeferAutoload` keeps them behind tool search.
5033
+ ...(deferConventionalMcpAutoload ? [] : conventionalMcpToolNames),
4952
5034
  ]),
4953
5035
  ];
4954
5036
  hasExplicitMCPToolSelection =
@@ -5428,6 +5510,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5428
5510
  taskDepth,
5429
5511
  workflowGatePublication: isCanonicalSubSession ? "local" : "endpoint",
5430
5512
  toolRegistry,
5513
+ onToolNamesChanged: toolNames => toolContextStore.setToolNames(toolNames),
5431
5514
  builtinToolIdentities,
5432
5515
  workflowGateToolSession: toolSession,
5433
5516
  transformContext,
@@ -5461,6 +5544,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5461
5544
  initialSelectedDiscoveredBuiltinToolNames,
5462
5545
  initialBaselineDiscoveredBuiltinToolNames,
5463
5546
  defaultSelectedMCPToolNames,
5547
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload ? [] : conventionalMcpToolNames,
5464
5548
  mandatoryMCPToolNames: pluginMcpToolNames,
5465
5549
  persistInitialMCPToolSelection: !hasExistingSession && hasExplicitMCPToolSelection,
5466
5550
  persistInitialDiscoveredBuiltinToolSelection: !hasExistingSession && hasExplicitDiscoveredBuiltinToolSelection,
@@ -5497,6 +5581,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5497
5581
  // carried by the host replay ring through the internal runtime seam above.
5498
5582
  if (autoroutingInactive) session.configWarnings.push(AUTOROUTING_INACTIVE_WARNING);
5499
5583
  hasSession = true;
5584
+ if (taskFacade) {
5585
+ const unregisterTaskMoveListener = sessionManager.registerAfterMoveListener(move =>
5586
+ taskFacade.invalidateForSessionMove(move.newCwd),
5587
+ );
5588
+ session.registerToolSessionCleanup(unregisterTaskMoveListener);
5589
+ }
5500
5590
  const cleanupOwnedManager = cleanupOwnedMcpManager;
5501
5591
  const sessionOwnedMcpManager = ownsMcpManager ? mcpManager : undefined;
5502
5592
  if (cleanupOwnedManager && cleanupOwnedMcpManagerOwner !== sessionOwnedMcpManager) {
@@ -5745,14 +5835,19 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5745
5835
  const previousNames = ownedMcpManagerToolNames;
5746
5836
  const nextToolNames = nextTools.map(tool => tool.name);
5747
5837
  const previousSet = new Set(previousNames);
5748
- const nextPluginToolNames = nextTools
5749
- .filter(tool => tool.mcpServerName && pluginServerNames.has(tool.mcpServerName))
5750
- .map(tool => tool.name);
5838
+ const nextPluginToolNames = retainPluginMcpMandatoryNames(
5839
+ nextTools,
5840
+ nextTools
5841
+ .filter(tool => tool.mcpServerName && pluginServerNames.has(tool.mcpServerName))
5842
+ .map(tool => tool.name),
5843
+ );
5751
5844
  const nextConventionalToolNames = nextTools
5752
5845
  .filter(tool => tool.mcpServerName && conventionalServerNames.has(tool.mcpServerName))
5753
5846
  .map(tool => tool.name);
5754
5847
  const nextMandatoryMcpToolNames = [
5755
- ...pluginMcpToolNames.filter(name => !previousSet.has(name)),
5848
+ ...retainPluginMcpMandatoryNames(nextTools, pluginMcpToolNames).filter(
5849
+ name => !previousSet.has(name),
5850
+ ),
5756
5851
  ...nextPluginToolNames,
5757
5852
  ];
5758
5853
  const nextConventionalMcpToolNames = [
@@ -5775,8 +5870,27 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5775
5870
  try {
5776
5871
  await session.replaceNamedCustomTools(previousNames, nextTools, {
5777
5872
  mandatoryMCPToolNames: nextMandatoryMcpToolNames,
5873
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload
5874
+ ? []
5875
+ : nextConventionalToolNames,
5778
5876
  activateNewTools: false,
5877
+ persistMCPSelection: false,
5779
5878
  });
5879
+ const defaultMcpToolNamesToActivate =
5880
+ deferConventionalMcpAutoload && !session.hasCommittedMCPToolSelectionAuthority()
5881
+ ? nextTools
5882
+ .filter(
5883
+ tool =>
5884
+ tool.mcpServerName !== undefined &&
5885
+ discoveryDefaultServerNames.has(tool.mcpServerName),
5886
+ )
5887
+ .map(tool => tool.name)
5888
+ : [];
5889
+ if (defaultMcpToolNamesToActivate.length > 0 && !session.hasCommittedMCPToolSelectionAuthority()) {
5890
+ await session.activateDiscoveredTools(defaultMcpToolNamesToActivate, {
5891
+ persistMCPSelection: false,
5892
+ });
5893
+ }
5780
5894
  } catch (error) {
5781
5895
  ownedMcpManagerToolNames = [...new Set([...previousNames, ...nextToolNames])];
5782
5896
  throw error;
@@ -5865,17 +5979,37 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5865
5979
  const previousNames = inheritedMcpManagerToolNames;
5866
5980
  const nextNames = snapshot.map(tool => tool.name);
5867
5981
  const classifiedTools = classifyInheritedMcpToolNames(manager, snapshot);
5982
+ const mandatoryPluginToolNames = retainPluginMcpMandatoryNames(
5983
+ snapshot,
5984
+ classifiedTools.pluginMcpToolNames,
5985
+ );
5868
5986
  try {
5869
5987
  await session.replaceNamedCustomTools(previousNames, snapshot, {
5870
- mandatoryMCPToolNames: classifiedTools.pluginMcpToolNames,
5988
+ mandatoryMCPToolNames: mandatoryPluginToolNames,
5871
5989
  activateNewTools: false,
5990
+ persistMCPSelection: false,
5872
5991
  });
5992
+ const defaultMcpToolNamesToActivate =
5993
+ deferConventionalMcpAutoload && !session.hasCommittedMCPToolSelectionAuthority()
5994
+ ? snapshot
5995
+ .filter(
5996
+ tool =>
5997
+ tool.mcpServerName !== undefined &&
5998
+ discoveryDefaultServerNames.has(tool.mcpServerName),
5999
+ )
6000
+ .map(tool => tool.name)
6001
+ : [];
6002
+ if (defaultMcpToolNamesToActivate.length > 0 && !session.hasCommittedMCPToolSelectionAuthority()) {
6003
+ await session.activateDiscoveredTools(defaultMcpToolNamesToActivate, {
6004
+ persistMCPSelection: false,
6005
+ });
6006
+ }
5873
6007
  } catch (error) {
5874
6008
  inheritedMcpManagerToolNames = [...new Set([...previousNames, ...nextNames])];
5875
6009
  throw error;
5876
6010
  }
5877
6011
  inheritedMcpManagerToolNames = nextNames;
5878
- pluginMcpToolNames.splice(0, pluginMcpToolNames.length, ...classifiedTools.pluginMcpToolNames);
6012
+ pluginMcpToolNames.splice(0, pluginMcpToolNames.length, ...mandatoryPluginToolNames);
5879
6013
  conventionalMcpToolNames.splice(
5880
6014
  0,
5881
6015
  conventionalMcpToolNames.length,
@@ -5964,11 +6098,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5964
6098
  throw new ExactMcpToolNameCollisionError(collidingToolNames);
5965
6099
  }
5966
6100
  if (!cancelled && !session.isDisposed) {
5967
- await session.refreshMCPTools(resultTools);
5968
- if (
5969
- !session.isDisposed &&
5970
- (!mcpDiscoveryEnabled || !existingSession.hasPersistedMCPToolSelection)
5971
- ) {
6101
+ await session.refreshMCPTools(resultTools, { persistMCPSelection: false });
6102
+ if (!session.isDisposed && (!mcpDiscoveryEnabled || !session.hasMCPToolSelectionAuthority())) {
5972
6103
  await session.activateDiscoveredTools(toolNames);
5973
6104
  }
5974
6105
  }
@@ -5994,14 +6125,23 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5994
6125
  // only re-activates a swapped tool that was already active; running it
5995
6126
  // before this registration would therefore drop a persisted conventional
5996
6127
  // MCP selection and persist the empty set.
5997
- await session.refreshMCPTools(resultTools);
6128
+ await session.refreshMCPTools(resultTools, { persistMCPSelection: false });
5998
6129
  wireOwnedMcpToolSync(resultTools);
5999
6130
  wireOwnedMcpManagerLifecycle();
6000
- if (
6001
- !session.isDisposed &&
6002
- (!mcpDiscoveryEnabled || !existingSession.hasPersistedMCPToolSelection)
6003
- ) {
6004
- await session.activateDiscoveredTools(resultTools.map(tool => tool.name));
6131
+ const shouldActivateStartupMcpTools =
6132
+ !mcpDiscoveryEnabled || !session.hasMCPToolSelectionAuthority();
6133
+ if (!session.isDisposed && shouldActivateStartupMcpTools) {
6134
+ await session.activateDiscoveredTools(
6135
+ resultTools
6136
+ .filter(
6137
+ tool =>
6138
+ !deferConventionalMcpAutoload ||
6139
+ (tool.mcpServerName !== undefined &&
6140
+ discoveryDefaultServerNames.has(tool.mcpServerName)),
6141
+ )
6142
+ .map(tool => tool.name),
6143
+ deferConventionalMcpAutoload ? { persistMCPSelection: false } : undefined,
6144
+ );
6005
6145
  }
6006
6146
  }
6007
6147
  loadedToolCount = resultTools.length;