@gajae-code/coding-agent 0.18.12 → 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 (305) hide show
  1. package/CHANGELOG.md +467 -0
  2. package/dist/types/capability/rule.d.ts +7 -2
  3. package/dist/types/cli/append-system-prompt.d.ts +6 -0
  4. package/dist/types/cli/args.d.ts +7 -2
  5. package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
  6. package/dist/types/cli/customize-doctor.d.ts +4 -3
  7. package/dist/types/cli/public-command-errors.d.ts +1 -0
  8. package/dist/types/cli/root-flags.d.ts +0 -12
  9. package/dist/types/cli/update-cli.d.ts +7 -2
  10. package/dist/types/cli-main.d.ts +0 -6
  11. package/dist/types/commands/launch.d.ts +0 -6
  12. package/dist/types/commands/migrate.d.ts +1 -1
  13. package/dist/types/commands/sdk.d.ts +8 -0
  14. package/dist/types/commit/map-reduce/index.d.ts +4 -4
  15. package/dist/types/config/autorouting-tier-map.d.ts +23 -1
  16. package/dist/types/config/config-hot-reload.d.ts +5 -0
  17. package/dist/types/config/file-lock.d.ts +44 -2
  18. package/dist/types/config/model-profile-activation.d.ts +19 -5
  19. package/dist/types/config/model-registry.d.ts +16 -3
  20. package/dist/types/config/model-resolver.d.ts +5 -4
  21. package/dist/types/config/settings-schema.d.ts +11 -1
  22. package/dist/types/coordinator-mcp/server.d.ts +4 -0
  23. package/dist/types/customization/import.d.ts +2 -0
  24. package/dist/types/customization/types.d.ts +1 -1
  25. package/dist/types/dap/session.d.ts +11 -2
  26. package/dist/types/discovery/helpers.d.ts +7 -2
  27. package/dist/types/edit/index.d.ts +5 -0
  28. package/dist/types/edit/modes/patch.d.ts +9 -0
  29. package/dist/types/eval/py/runtime.d.ts +9 -0
  30. package/dist/types/export/ttsr.d.ts +19 -0
  31. package/dist/types/extensibility/extensions/types.d.ts +5 -1
  32. package/dist/types/extensibility/slash-commands.d.ts +1 -0
  33. package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
  34. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
  35. package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
  36. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
  37. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
  38. package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
  39. package/dist/types/hindsight/content.d.ts +5 -6
  40. package/dist/types/internal-urls/types.d.ts +2 -0
  41. package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
  42. package/dist/types/main.d.ts +23 -18
  43. package/dist/types/migrate/action-planner.d.ts +10 -1
  44. package/dist/types/migrate/adapters/codex.d.ts +1 -1
  45. package/dist/types/migrate/adapters/index.d.ts +35 -3
  46. package/dist/types/migrate/hook-module.d.ts +23 -0
  47. package/dist/types/migrate/report.d.ts +2 -1
  48. package/dist/types/migrate/types.d.ts +69 -2
  49. package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
  50. package/dist/types/modes/components/model-selector.d.ts +43 -0
  51. package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
  52. package/dist/types/modes/utils/host-status.d.ts +15 -11
  53. package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
  54. package/dist/types/sdk/broker/broker-exit.d.ts +1 -1
  55. package/dist/types/sdk/broker/broker.d.ts +22 -1
  56. package/dist/types/sdk/broker/ensure.d.ts +5 -2
  57. package/dist/types/sdk/broker/hop.d.ts +9 -0
  58. package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
  59. package/dist/types/sdk/broker/session-index.d.ts +2 -0
  60. package/dist/types/sdk/broker/transport.d.ts +2 -0
  61. package/dist/types/sdk/bus/index.d.ts +21 -0
  62. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
  63. package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
  64. package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
  65. package/dist/types/sdk/host/control/operations.d.ts +5 -1
  66. package/dist/types/sdk/host/events.d.ts +4 -0
  67. package/dist/types/sdk/host/host.d.ts +2 -1
  68. package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
  69. package/dist/types/sdk/host/session-runtime.d.ts +8 -8
  70. package/dist/types/sdk/host/surface-policy.d.ts +2 -1
  71. package/dist/types/sdk/lifecycle/service.d.ts +12 -0
  72. package/dist/types/sdk/prompt-status.d.ts +11 -4
  73. package/dist/types/session/agent-session.d.ts +50 -8
  74. package/dist/types/session/session-manager.d.ts +16 -0
  75. package/dist/types/skill-state/workflow-mutation-guard.d.ts +13 -1
  76. package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
  77. package/dist/types/ssh/ssh-executor.d.ts +8 -1
  78. package/dist/types/system-prompt.d.ts +3 -2
  79. package/dist/types/task/role-body.d.ts +11 -0
  80. package/dist/types/tools/awaiting-input.d.ts +28 -0
  81. package/dist/types/tools/bash-allowed-prefixes.d.ts +6 -0
  82. package/dist/types/tools/bash-skill-urls.d.ts +4 -0
  83. package/dist/types/tools/bash.d.ts +7 -0
  84. package/dist/types/tools/descriptors.d.ts +13 -2
  85. package/dist/types/tools/fetch.d.ts +6 -0
  86. package/dist/types/tools/irc.d.ts +5 -3
  87. package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
  88. package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
  89. package/dist/types/tools/write.d.ts +2 -0
  90. package/dist/types/utils/file-mentions.d.ts +5 -0
  91. package/dist/types/utils/image-limits.d.ts +7 -0
  92. package/dist/types/utils/image-loading.d.ts +0 -1
  93. package/dist/types/utils/open.d.ts +0 -1
  94. package/dist/types/utils/pasted-image-loading.d.ts +1 -5
  95. package/dist/types/utils/prompt-suggestion.d.ts +2 -2
  96. package/dist/types/utils/shell-snapshot.d.ts +2 -0
  97. package/dist/types/utils/title-generator.d.ts +13 -3
  98. package/dist/types/web/search/providers/codex.d.ts +6 -7
  99. package/package.json +9 -8
  100. package/scripts/acp-conformance-agent.ts +12 -2
  101. package/scripts/generate-sdk-operation-inventory.ts +16 -0
  102. package/src/capability/fs.ts +31 -3
  103. package/src/capability/rule.ts +11 -2
  104. package/src/cli/append-system-prompt.ts +12 -0
  105. package/src/cli/args.ts +11 -7
  106. package/src/cli/customize-doctor-precedence.ts +31 -0
  107. package/src/cli/customize-doctor.ts +49 -39
  108. package/src/cli/fast-help.ts +0 -2
  109. package/src/cli/migrate-cli.ts +14 -3
  110. package/src/cli/public-command-errors.ts +2 -0
  111. package/src/cli/root-flags.ts +0 -2
  112. package/src/cli/update-cli.ts +247 -6
  113. package/src/commands/harness.ts +25 -15
  114. package/src/commands/migrate.ts +3 -3
  115. package/src/commands/sdk.ts +81 -11
  116. package/src/commit/agentic/agent.ts +6 -6
  117. package/src/commit/analysis/conventional.ts +14 -5
  118. package/src/commit/map-reduce/index.ts +7 -7
  119. package/src/commit/pipeline.ts +12 -12
  120. package/src/config/autorouting-tier-map.ts +20 -1
  121. package/src/config/config-file.ts +106 -3
  122. package/src/config/config-hot-reload.ts +8 -0
  123. package/src/config/file-lock.ts +1431 -304
  124. package/src/config/keybindings.ts +154 -7
  125. package/src/config/model-profile-activation.ts +177 -39
  126. package/src/config/model-registry.ts +380 -55
  127. package/src/config/model-resolver.ts +49 -21
  128. package/src/config/settings-schema.ts +13 -1
  129. package/src/config/settings.ts +2 -0
  130. package/src/coordinator-mcp/server.ts +37 -2
  131. package/src/crash/sanitize.ts +3 -1
  132. package/src/customization/import.ts +276 -7
  133. package/src/customization/inventory.ts +24 -8
  134. package/src/customization/types.ts +1 -0
  135. package/src/dap/client.ts +3 -2
  136. package/src/dap/session.ts +161 -36
  137. package/src/debug/crash-diagnostics.ts +87 -5
  138. package/src/debug/report-bundle.ts +71 -2
  139. package/src/discovery/builtin.ts +4 -3
  140. package/src/discovery/helpers.ts +24 -14
  141. package/src/edit/index.ts +191 -5
  142. package/src/edit/modes/patch.ts +27 -0
  143. package/src/eval/py/runtime.ts +44 -4
  144. package/src/exec/non-interactive-env.ts +0 -1
  145. package/src/export/html/index.ts +60 -20
  146. package/src/export/ttsr.ts +176 -1
  147. package/src/extensibility/extensions/loader.ts +2 -0
  148. package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
  149. package/src/extensibility/extensions/types.ts +5 -1
  150. package/src/extensibility/hooks/loader.ts +10 -2
  151. package/src/extensibility/plugins/marketplace/manager.ts +36 -10
  152. package/src/extensibility/slash-commands.ts +5 -0
  153. package/src/gjc-runtime/gc-runtime.ts +4 -1
  154. package/src/gjc-runtime/launch-tmux.ts +23 -13
  155. package/src/gjc-runtime/ralplan-current-final.ts +294 -0
  156. package/src/gjc-runtime/ralplan-runtime.ts +95 -1
  157. package/src/gjc-runtime/state-writer.ts +109 -5
  158. package/src/gjc-runtime/tmux-sessions.ts +93 -13
  159. package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
  160. package/src/gjc-runtime/ultragoal-guard.ts +9 -1
  161. package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
  162. package/src/harness-control-plane/finalize.ts +11 -0
  163. package/src/harness-control-plane/receipt-spool.ts +105 -28
  164. package/src/harness-control-plane/storage.ts +124 -6
  165. package/src/hindsight/content.ts +116 -16
  166. package/src/hindsight/mental-models.ts +22 -10
  167. package/src/hindsight/state.ts +7 -4
  168. package/src/hooks/native-skill-hook.ts +3 -1
  169. package/src/internal-urls/artifact-protocol.ts +3 -1
  170. package/src/internal-urls/docs-index.generated.ts +14 -14
  171. package/src/internal-urls/local-protocol.ts +28 -3
  172. package/src/internal-urls/types.ts +2 -0
  173. package/src/lsp/client.ts +2 -1
  174. package/src/lsp/clients/biome-client.ts +2 -0
  175. package/src/lsp/clients/swiftlint-client.ts +2 -0
  176. package/src/main.ts +330 -92
  177. package/src/memories/index.ts +25 -2
  178. package/src/migrate/action-planner.ts +517 -2
  179. package/src/migrate/adapters/claude-code.ts +141 -3
  180. package/src/migrate/adapters/codex.ts +57 -5
  181. package/src/migrate/adapters/index.ts +240 -5
  182. package/src/migrate/adapters/opencode.ts +4 -0
  183. package/src/migrate/executor.ts +141 -3
  184. package/src/migrate/hook-module.ts +193 -0
  185. package/src/migrate/report.ts +45 -1
  186. package/src/migrate/types.ts +73 -3
  187. package/src/modes/acp/acp-agent.ts +10 -1
  188. package/src/modes/components/agent-dashboard.ts +20 -4
  189. package/src/modes/components/customization/customization-dashboard.ts +7 -0
  190. package/src/modes/components/customization/import-wizard.ts +29 -3
  191. package/src/modes/components/model-selector.ts +157 -103
  192. package/src/modes/components/welcome.ts +3 -1
  193. package/src/modes/controllers/command-controller.ts +271 -16
  194. package/src/modes/controllers/event-controller.ts +1 -1
  195. package/src/modes/controllers/extension-ui-controller.ts +31 -1
  196. package/src/modes/controllers/goal-mode-controller.ts +79 -10
  197. package/src/modes/controllers/input-controller.ts +2 -0
  198. package/src/modes/controllers/plan-mode-controller.ts +49 -4
  199. package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
  200. package/src/modes/controllers/selector-controller.ts +14 -1
  201. package/src/modes/interactive-mode.ts +55 -4
  202. package/src/modes/prompt-suggestion-controller.ts +1 -1
  203. package/src/modes/runtime-init.ts +5 -1
  204. package/src/modes/utils/host-status.ts +21 -10
  205. package/src/prompts/agent-fragments/browser-aside.md +2 -2
  206. package/src/prompts/system/irc-incoming.md +3 -1
  207. package/src/prompts/tools/irc.md +1 -1
  208. package/src/runtime-mcp/manager.ts +8 -3
  209. package/src/runtime-mcp/project-host-values.ts +12 -8
  210. package/src/runtime-mcp/tool-bridge.ts +68 -4
  211. package/src/runtime-mcp/transports/stdio.ts +2 -1
  212. package/src/sdk/broker/broker-exit.ts +2 -0
  213. package/src/sdk/broker/broker.ts +143 -4
  214. package/src/sdk/broker/ensure.ts +74 -6
  215. package/src/sdk/broker/hop.ts +13 -1
  216. package/src/sdk/broker/lifecycle-ledger.ts +3 -0
  217. package/src/sdk/broker/lifecycle.ts +102 -6
  218. package/src/sdk/broker/session-index.ts +29 -4
  219. package/src/sdk/broker/transport.ts +17 -1
  220. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  221. package/src/sdk/bus/index.ts +408 -14
  222. package/src/sdk/bus/session-control.ts +2 -0
  223. package/src/sdk/bus/slack-daemon.ts +105 -9
  224. package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
  225. package/src/sdk/bus/telegram-daemon.ts +10 -2
  226. package/src/sdk/bus/threaded-render.ts +20 -1
  227. package/src/sdk/cli/session-cli.ts +2 -0
  228. package/src/sdk/host/control/dispatch.ts +13 -1
  229. package/src/sdk/host/control/operations.ts +10 -1
  230. package/src/sdk/host/events.ts +67 -4
  231. package/src/sdk/host/host.ts +8 -2
  232. package/src/sdk/host/prompt-image-upload.ts +438 -0
  233. package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
  234. package/src/sdk/host/session-runtime.test.ts +1537 -24
  235. package/src/sdk/host/session-runtime.ts +332 -36
  236. package/src/sdk/host/surface-policy.ts +4 -0
  237. package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
  238. package/src/sdk/host/websocket-transport.ts +19 -7
  239. package/src/sdk/lifecycle/service.ts +14 -1
  240. package/src/sdk/prompt-status.ts +6 -4
  241. package/src/sdk/protocol/adapter-validation.ts +28 -1
  242. package/src/sdk/protocol/operation-inventory.generated.json +160 -0
  243. package/src/sdk/protocol/operation-registry.ts +33 -3
  244. package/src/sdk/session.ts +123 -36
  245. package/src/session/agent-session.ts +1614 -329
  246. package/src/session/history-storage.ts +182 -12
  247. package/src/session/internal/managed-session-scope.ts +47 -18
  248. package/src/session/internal/managed-session-storage.ts +71 -1
  249. package/src/session/session-manager.ts +90 -5
  250. package/src/session-import/redact.ts +53 -2
  251. package/src/skill-state/workflow-mutation-guard.ts +1498 -18
  252. package/src/slash-commands/builtin-registry.ts +6 -3
  253. package/src/slash-commands/helpers/mcp.ts +11 -3
  254. package/src/ssh/ssh-executor.ts +9 -2
  255. package/src/stt/recorder.ts +26 -9
  256. package/src/system-prompt.ts +61 -16
  257. package/src/task/executor.ts +12 -8
  258. package/src/task/role-body.ts +84 -0
  259. package/src/task/token-log-mode.test.ts +162 -0
  260. package/src/task/token-log.ts +91 -2
  261. package/src/tools/archive-reader.ts +650 -37
  262. package/src/tools/ask.ts +1 -0
  263. package/src/tools/ast-grep.ts +7 -2
  264. package/src/tools/auto-generated-guard.ts +12 -3
  265. package/src/tools/awaiting-input.ts +114 -0
  266. package/src/tools/bash-allowed-prefixes.ts +61 -1
  267. package/src/tools/bash-skill-urls.ts +58 -5
  268. package/src/tools/bash.ts +99 -26
  269. package/src/tools/browser/tab-worker.ts +39 -13
  270. package/src/tools/browser.ts +17 -7
  271. package/src/tools/cron.ts +10 -1
  272. package/src/tools/debug.ts +9 -2
  273. package/src/tools/descriptors.test.ts +4 -4
  274. package/src/tools/descriptors.ts +16 -4
  275. package/src/tools/eval.ts +15 -0
  276. package/src/tools/fetch.ts +90 -2
  277. package/src/tools/gh.ts +27 -12
  278. package/src/tools/image-gen.ts +20 -6
  279. package/src/tools/irc.ts +5 -3
  280. package/src/tools/monitor.ts +9 -1
  281. package/src/tools/output-meta.ts +51 -3
  282. package/src/tools/read.ts +9 -2
  283. package/src/tools/recipe/runner.ts +23 -12
  284. package/src/tools/render-utils.ts +2 -2
  285. package/src/tools/search.ts +3 -2
  286. package/src/tools/ssh.ts +274 -8
  287. package/src/tools/subagent.ts +10 -4
  288. package/src/tools/tmux-self-injection-guard.ts +3301 -122
  289. package/src/tools/tool-catalog.generated.ts +1 -1
  290. package/src/tools/ultragoal-ask-guard.ts +13 -1
  291. package/src/tools/write.ts +7 -0
  292. package/src/tui/tree-list.ts +15 -1
  293. package/src/utils/commit-message-generator.ts +3 -2
  294. package/src/utils/external-editor.ts +21 -7
  295. package/src/utils/file-mentions.ts +46 -6
  296. package/src/utils/git.ts +38 -7
  297. package/src/utils/image-limits.ts +8 -0
  298. package/src/utils/image-loading.ts +1 -1
  299. package/src/utils/open.ts +73 -4
  300. package/src/utils/pasted-image-loading.ts +9 -8
  301. package/src/utils/prompt-suggestion.ts +5 -4
  302. package/src/utils/shell-snapshot.ts +9 -1
  303. package/src/utils/title-generator.ts +65 -20
  304. package/src/web/search/index.ts +2 -1
  305. package/src/web/search/providers/codex.ts +29 -32
@@ -86,6 +86,7 @@ import { disposeKernelSessionsByOwner } from "../eval/py/executor";
86
86
  import type { MasterModeContext } from "../master-mode/context";
87
87
  import { describeFoldReceipt } from "../session/fold-coordinator";
88
88
  import type { BashRestrictionProfile } from "../tools/bash-allowed-prefixes";
89
+ import { wrapUntrustedContent } from "../tools/fetch";
89
90
  import { SearchTool } from "../tools/search";
90
91
  import "../discovery";
91
92
  import { resolveConfigValue } from "../config/resolve-config-value";
@@ -209,7 +210,11 @@ import {
209
210
  } from "../system-prompt";
210
211
  import { AgentOutputManager } from "../task/output-manager";
211
212
  import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } from "../thinking";
212
- import { isMCPBridgeTool, selectRestorableDiscoveredBuiltinToolNames } from "../tool-discovery/tool-index";
213
+ import {
214
+ isMCPBridgeTool,
215
+ isMCPToolName,
216
+ selectRestorableDiscoveredBuiltinToolNames,
217
+ } from "../tool-discovery/tool-index";
213
218
  import {
214
219
  type AutomationToolName,
215
220
  type AutomationTools,
@@ -1236,7 +1241,10 @@ function buildMCPPromptCommands(manager: MCPManager): LoadedCustomCommand[] {
1236
1241
  }
1237
1242
  }
1238
1243
  }
1239
- 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);
1240
1248
  },
1241
1249
  },
1242
1250
  });
@@ -2258,7 +2266,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2258
2266
  ? { aliasIntent: "preset-equivalent" }
2259
2267
  : undefined;
2260
2268
  const allowedModels = await logger.time("resolveAllowedModels", () =>
2261
- resolveAllowedModels(modelRegistry, settings, modelMatchPreferences),
2269
+ resolveAllowedModels(modelRegistry, settings, modelMatchPreferences, credentialSessionId),
2262
2270
  );
2263
2271
  const defaultRoleSpec = logger.time("resolveDefaultModelRole", () =>
2264
2272
  resolveModelRoleValue(settings.getModelRole("default"), allowedModels, {
@@ -2286,6 +2294,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2286
2294
  : existingSession.models.default
2287
2295
  ? [existingSession.models.default]
2288
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
+ }
2289
2307
  const persistedProfileName =
2290
2308
  persistedDefaultChain?.origin === "profile-activation" ? persistedDefaultChain.identity : undefined;
2291
2309
  const resolvedPersistedProfileName = persistedProfileName
@@ -2498,7 +2516,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2498
2516
  const rulebookRules: Rule[] = [];
2499
2517
  const alwaysApplyRules: Rule[] = [];
2500
2518
  for (const rule of rulesResult.items) {
2501
- 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;
2502
2521
  if (isTtsrRule) {
2503
2522
  continue;
2504
2523
  }
@@ -2863,7 +2882,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2863
2882
  await session.replaceNamedCustomTools(
2864
2883
  previousCwdCapturing.filter(name => !nextCustomTools.some(tool => tool.name === name)),
2865
2884
  nextCustomTools,
2866
- { mandatoryMCPToolNames: pluginMcpToolNames },
2885
+ {
2886
+ mandatoryMCPToolNames: pluginMcpToolNames,
2887
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload ? [] : conventionalMcpToolNames,
2888
+ inactiveNewToolNames: deferConventionalMcpAutoload ? conventionalMcpToolNames : undefined,
2889
+ },
2867
2890
  );
2868
2891
  wireOwnedMcpToolSync();
2869
2892
  };
@@ -2973,11 +2996,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2973
2996
  "This session has already been rescoped; only one agent-invoked move is allowed per session.",
2974
2997
  );
2975
2998
  }
2976
- if (session?.getEffectiveActiveWorkflowSkillState()) {
2977
- throw new Error(
2978
- "A workflow skill is active in this session; finish or exit it before rescoping.",
2979
- );
2980
- }
2981
2999
  if (options.mcpManager && !ownsMcpManager) {
2982
3000
  throw new Error(
2983
3001
  "Cannot rescope a session with caller-owned MCP authority; recreate the session at the target cwd.",
@@ -2989,9 +3007,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2989
3007
  "This session has already been rescoped; only one agent-invoked move is allowed per session.",
2990
3008
  );
2991
3009
  }
2992
- if (session?.getEffectiveActiveWorkflowSkillState()) {
3010
+ if (await session?.refreshEffectiveActiveWorkflowSkillState()) {
2993
3011
  throw new Error(
2994
- "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.",
2995
3013
  );
2996
3014
  }
2997
3015
  const from = sessionManager.getCwd();
@@ -4122,6 +4140,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4122
4140
  if (!session) throw new Error("Terminal abort session is not initialized.");
4123
4141
  return session.pendingToolExecutions(handle);
4124
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
+ },
4125
4147
  },
4126
4148
  ensureProviderDaemon: options.ensureNotificationProviderDaemon,
4127
4149
  runBtwTurn: async (question, signal) => {
@@ -4216,6 +4238,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4216
4238
  if (!session) throw new Error("Terminal abort session is not initialized.");
4217
4239
  return session.pendingToolExecutions(handle);
4218
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
+ },
4219
4245
  },
4220
4246
  });
4221
4247
  }
@@ -4443,7 +4469,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4443
4469
  startupModelReference.id,
4444
4470
  startupCredentialSelector,
4445
4471
  );
4446
- const currentStartupModel = modelRegistry.find(startupModelReference.provider, startupModelReference.id);
4472
+ const currentStartupModel = modelRegistry.find(
4473
+ startupModelReference.provider,
4474
+ startupModelReference.id,
4475
+ credentialSessionId,
4476
+ );
4447
4477
  const providerMismatchRejectsTarget =
4448
4478
  startupCredentialProviderMismatch &&
4449
4479
  modelRegistry.requiresStoredLiteralCredentialCacheAdmission(
@@ -4468,7 +4498,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4468
4498
 
4469
4499
  // Resolve deferred --model pattern now that extension models are registered.
4470
4500
  if (!model && options.modelPattern && !startupCredentialModelRejected) {
4471
- const availableModels = modelRegistry.getAll();
4501
+ const availableModels = modelRegistry.getAll(credentialSessionId);
4472
4502
  const matchPreferences = {
4473
4503
  usageOrder: settings.getStorage()?.getModelUsageOrder(),
4474
4504
  };
@@ -4510,7 +4540,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4510
4540
  ) {
4511
4541
  // Re-resolve the allowed set: extension factories above may have
4512
4542
  // registered providers/models that weren't visible at startup.
4513
- const allowedFallbackCandidates = await resolveAllowedModels(modelRegistry, settings, modelMatchPreferences);
4543
+ const allowedFallbackCandidates = await resolveAllowedModels(
4544
+ modelRegistry,
4545
+ settings,
4546
+ modelMatchPreferences,
4547
+ credentialSessionId,
4548
+ );
4514
4549
  // Candidate order is not a quality signal: catalogs sort retired models
4515
4550
  // ahead of current ones whenever their IDs carry older date suffixes, so
4516
4551
  // an unconfigured install would otherwise start on a model its provider
@@ -4799,7 +4834,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4799
4834
  // epoch additionally fences overlapping rebuilds, so a slower earlier
4800
4835
  // pass cannot publish over a newer one.
4801
4836
  const gjcPassEpoch = gjcRuntimeStore.beginPass();
4802
- toolContextStore.setToolNames(toolNames);
4803
4837
  const promptTools = (() => {
4804
4838
  const previousPromptMetadataModel = promptMetadataModel;
4805
4839
  promptMetadataModel = candidateModel;
@@ -4919,6 +4953,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4919
4953
  const requestedToolNameSet = new Set(normalizedRequested);
4920
4954
  const effectiveDiscoveryMode = resolveEffectiveDiscoveryMode(settings, explicitMcpConfigPath);
4921
4955
  const mcpDiscoveryEnabled = effectiveDiscoveryMode !== "off";
4956
+ const discoveryDefaultServerNames = new Set(settings.get("mcp.discoveryDefaultServers") ?? []);
4957
+ const deferConventionalMcpAutoload = mcpDiscoveryEnabled && settings.get("mcp.discoveryDeferAutoload");
4922
4958
  const defaultInactiveToolNames = new Set(
4923
4959
  registeredTools.filter(tool => tool.definition.defaultInactive).map(tool => tool.definition.name),
4924
4960
  );
@@ -4937,7 +4973,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4937
4973
  let hasExplicitDiscoveredBuiltinToolSelection = false;
4938
4974
  let explicitlyRequestedDiscoveredBuiltinToolNames: string[] = [];
4939
4975
  if (mcpDiscoveryEnabled) {
4940
- const defaultServerNames = new Set(settings.get("mcp.discoveryDefaultServers") ?? []);
4941
4976
  for (const tool of toolRegistry.values()) {
4942
4977
  if (!isMCPBridgeTool(tool)) continue;
4943
4978
  discoverableMCPToolNames.add(tool.name);
@@ -4945,7 +4980,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4945
4980
  explicitlyRequestedMCPToolNames.push(tool.name);
4946
4981
  }
4947
4982
  const serverName = (tool as AgentTool & { mcpServerName?: string }).mcpServerName;
4948
- if (serverName && defaultServerNames.has(serverName)) {
4983
+ if (serverName && discoveryDefaultServerNames.has(serverName)) {
4949
4984
  discoveryDefaultServerToolNames.push(tool.name);
4950
4985
  }
4951
4986
  }
@@ -4958,16 +4993,24 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4958
4993
  ...retainPluginMcpMandatoryNames(customTools, pluginMcpToolNames),
4959
4994
  );
4960
4995
  const mandatoryMCPToolNameSet = new Set(pluginMcpToolNames);
4961
- const selectableExplicitMCPToolNames = explicitlyRequestedMCPToolNames.filter(
4962
- name => !mandatoryMCPToolNameSet.has(name),
4963
- );
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
+ ];
4964
5009
  let initialToolNames = [...initialRequestedActiveToolNames];
4965
5010
  if (mcpDiscoveryEnabled) {
4966
5011
  // A pending deferred MCP connect (exact or conventional) registers its
4967
5012
  // tools after construction, so persisted selections must be preserved
4968
5013
  // verbatim instead of being trimmed to names the registry currently has.
4969
- const deferredMcpConnectPending =
4970
- deferredExactMcpConfig !== undefined || deferredConventionalMcp !== undefined;
4971
5014
  const restoredSelectedMCPToolNames = deferredMcpConnectPending
4972
5015
  ? existingSession.selectedMCPToolNames.filter(name => !mandatoryMCPToolNameSet.has(name))
4973
5016
  : existingSession.selectedMCPToolNames.filter(
@@ -4985,8 +5028,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
4985
5028
  ...discoveryDefaultServerToolNames,
4986
5029
  ...(explicitMcpConfigPath !== undefined ? exactMcpToolNames : []),
4987
5030
  // Conventional autoload servers are selected by default so their
4988
- // tools are exposed in sessions that enable MCP discovery mode.
4989
- ...conventionalMcpToolNames,
5031
+ // tools are exposed in sessions that enable MCP discovery mode,
5032
+ // unless `mcp.discoveryDeferAutoload` keeps them behind tool search.
5033
+ ...(deferConventionalMcpAutoload ? [] : conventionalMcpToolNames),
4990
5034
  ]),
4991
5035
  ];
4992
5036
  hasExplicitMCPToolSelection =
@@ -5466,6 +5510,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5466
5510
  taskDepth,
5467
5511
  workflowGatePublication: isCanonicalSubSession ? "local" : "endpoint",
5468
5512
  toolRegistry,
5513
+ onToolNamesChanged: toolNames => toolContextStore.setToolNames(toolNames),
5469
5514
  builtinToolIdentities,
5470
5515
  workflowGateToolSession: toolSession,
5471
5516
  transformContext,
@@ -5499,6 +5544,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5499
5544
  initialSelectedDiscoveredBuiltinToolNames,
5500
5545
  initialBaselineDiscoveredBuiltinToolNames,
5501
5546
  defaultSelectedMCPToolNames,
5547
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload ? [] : conventionalMcpToolNames,
5502
5548
  mandatoryMCPToolNames: pluginMcpToolNames,
5503
5549
  persistInitialMCPToolSelection: !hasExistingSession && hasExplicitMCPToolSelection,
5504
5550
  persistInitialDiscoveredBuiltinToolSelection: !hasExistingSession && hasExplicitDiscoveredBuiltinToolSelection,
@@ -5824,8 +5870,27 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5824
5870
  try {
5825
5871
  await session.replaceNamedCustomTools(previousNames, nextTools, {
5826
5872
  mandatoryMCPToolNames: nextMandatoryMcpToolNames,
5873
+ defaultSelectedConventionalMCPToolNames: deferConventionalMcpAutoload
5874
+ ? []
5875
+ : nextConventionalToolNames,
5827
5876
  activateNewTools: false,
5877
+ persistMCPSelection: false,
5828
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
+ }
5829
5894
  } catch (error) {
5830
5895
  ownedMcpManagerToolNames = [...new Set([...previousNames, ...nextToolNames])];
5831
5896
  throw error;
@@ -5922,7 +5987,23 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
5922
5987
  await session.replaceNamedCustomTools(previousNames, snapshot, {
5923
5988
  mandatoryMCPToolNames: mandatoryPluginToolNames,
5924
5989
  activateNewTools: false,
5990
+ persistMCPSelection: false,
5925
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
+ }
5926
6007
  } catch (error) {
5927
6008
  inheritedMcpManagerToolNames = [...new Set([...previousNames, ...nextNames])];
5928
6009
  throw error;
@@ -6017,11 +6098,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
6017
6098
  throw new ExactMcpToolNameCollisionError(collidingToolNames);
6018
6099
  }
6019
6100
  if (!cancelled && !session.isDisposed) {
6020
- await session.refreshMCPTools(resultTools);
6021
- if (
6022
- !session.isDisposed &&
6023
- (!mcpDiscoveryEnabled || !existingSession.hasPersistedMCPToolSelection)
6024
- ) {
6101
+ await session.refreshMCPTools(resultTools, { persistMCPSelection: false });
6102
+ if (!session.isDisposed && (!mcpDiscoveryEnabled || !session.hasMCPToolSelectionAuthority())) {
6025
6103
  await session.activateDiscoveredTools(toolNames);
6026
6104
  }
6027
6105
  }
@@ -6047,14 +6125,23 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
6047
6125
  // only re-activates a swapped tool that was already active; running it
6048
6126
  // before this registration would therefore drop a persisted conventional
6049
6127
  // MCP selection and persist the empty set.
6050
- await session.refreshMCPTools(resultTools);
6128
+ await session.refreshMCPTools(resultTools, { persistMCPSelection: false });
6051
6129
  wireOwnedMcpToolSync(resultTools);
6052
6130
  wireOwnedMcpManagerLifecycle();
6053
- if (
6054
- !session.isDisposed &&
6055
- (!mcpDiscoveryEnabled || !existingSession.hasPersistedMCPToolSelection)
6056
- ) {
6057
- 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
+ );
6058
6145
  }
6059
6146
  }
6060
6147
  loadedToolCount = resultTools.length;