@google/gemini-cli-core 0.31.0-preview.2 → 0.32.0-preview.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 (312) hide show
  1. package/dist/docs/changelogs/index.md +22 -0
  2. package/dist/docs/changelogs/latest.md +307 -352
  3. package/dist/docs/changelogs/preview.md +391 -293
  4. package/dist/docs/cli/plan-mode.md +29 -7
  5. package/dist/docs/cli/settings.md +15 -6
  6. package/dist/docs/cli/telemetry.md +39 -11
  7. package/dist/docs/extensions/reference.md +36 -0
  8. package/dist/docs/get-started/installation.md +1 -1
  9. package/dist/docs/local-development.md +49 -43
  10. package/dist/docs/reference/configuration.md +32 -0
  11. package/dist/docs/reference/keyboard-shortcuts.md +6 -6
  12. package/dist/docs/reference/policy-engine.md +4 -3
  13. package/dist/docs/resources/faq.md +13 -0
  14. package/dist/docs/resources/tos-privacy.md +6 -0
  15. package/dist/docs/resources/uninstall.md +1 -10
  16. package/dist/docs/tools/mcp-server.md +22 -0
  17. package/dist/src/agents/a2a-client-manager.d.ts +7 -6
  18. package/dist/src/agents/a2a-client-manager.js +8 -9
  19. package/dist/src/agents/a2a-client-manager.js.map +1 -1
  20. package/dist/src/agents/a2a-client-manager.test.js +45 -31
  21. package/dist/src/agents/a2a-client-manager.test.js.map +1 -1
  22. package/dist/src/agents/a2aUtils.d.ts +25 -7
  23. package/dist/src/agents/a2aUtils.js +165 -58
  24. package/dist/src/agents/a2aUtils.js.map +1 -1
  25. package/dist/src/agents/a2aUtils.test.js +170 -27
  26. package/dist/src/agents/a2aUtils.test.js.map +1 -1
  27. package/dist/src/agents/generalist-agent.js +1 -2
  28. package/dist/src/agents/generalist-agent.js.map +1 -1
  29. package/dist/src/agents/registry.test.js +4 -2
  30. package/dist/src/agents/registry.test.js.map +1 -1
  31. package/dist/src/agents/remote-invocation.d.ts +2 -1
  32. package/dist/src/agents/remote-invocation.js +41 -22
  33. package/dist/src/agents/remote-invocation.js.map +1 -1
  34. package/dist/src/agents/remote-invocation.test.js +196 -56
  35. package/dist/src/agents/remote-invocation.test.js.map +1 -1
  36. package/dist/src/agents/subagent-tool-wrapper.js +1 -1
  37. package/dist/src/agents/subagent-tool-wrapper.test.js +1 -1
  38. package/dist/src/agents/subagent-tool.js +15 -2
  39. package/dist/src/agents/subagent-tool.js.map +1 -1
  40. package/dist/src/agents/subagent-tool.test.js +31 -0
  41. package/dist/src/agents/subagent-tool.test.js.map +1 -1
  42. package/dist/src/billing/billing.d.ts +80 -0
  43. package/dist/src/billing/billing.js +127 -0
  44. package/dist/src/billing/billing.js.map +1 -0
  45. package/dist/src/billing/billing.test.d.ts +6 -0
  46. package/dist/src/billing/billing.test.js +182 -0
  47. package/dist/src/billing/billing.test.js.map +1 -0
  48. package/dist/src/billing/index.d.ts +6 -0
  49. package/dist/src/billing/index.js +7 -0
  50. package/dist/src/billing/index.js.map +1 -0
  51. package/dist/src/code_assist/codeAssist.js +1 -1
  52. package/dist/src/code_assist/codeAssist.js.map +1 -1
  53. package/dist/src/code_assist/codeAssist.test.js +2 -2
  54. package/dist/src/code_assist/codeAssist.test.js.map +1 -1
  55. package/dist/src/code_assist/converter.d.ts +9 -4
  56. package/dist/src/code_assist/converter.js +17 -2
  57. package/dist/src/code_assist/converter.js.map +1 -1
  58. package/dist/src/code_assist/converter.test.js.map +1 -1
  59. package/dist/src/code_assist/oauth2.js +6 -3
  60. package/dist/src/code_assist/oauth2.js.map +1 -1
  61. package/dist/src/code_assist/oauth2.test.js +1 -0
  62. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  63. package/dist/src/code_assist/server.d.ts +9 -4
  64. package/dist/src/code_assist/server.js +86 -5
  65. package/dist/src/code_assist/server.js.map +1 -1
  66. package/dist/src/code_assist/server.test.js +11 -0
  67. package/dist/src/code_assist/server.test.js.map +1 -1
  68. package/dist/src/code_assist/setup.d.ts +2 -1
  69. package/dist/src/code_assist/setup.js +15 -4
  70. package/dist/src/code_assist/setup.js.map +1 -1
  71. package/dist/src/code_assist/types.d.ts +33 -10
  72. package/dist/src/code_assist/types.js.map +1 -1
  73. package/dist/src/config/config.d.ts +50 -4
  74. package/dist/src/config/config.js +77 -3
  75. package/dist/src/config/config.js.map +1 -1
  76. package/dist/src/config/config.test.js +151 -1
  77. package/dist/src/config/config.test.js.map +1 -1
  78. package/dist/src/config/storage.d.ts +1 -0
  79. package/dist/src/config/storage.js +4 -1
  80. package/dist/src/config/storage.js.map +1 -1
  81. package/dist/src/core/contentGenerator.d.ts +3 -2
  82. package/dist/src/core/contentGenerator.js +9 -2
  83. package/dist/src/core/contentGenerator.js.map +1 -1
  84. package/dist/src/core/coreToolScheduler.js +2 -1
  85. package/dist/src/core/coreToolScheduler.js.map +1 -1
  86. package/dist/src/core/coreToolScheduler.test.js +21 -2
  87. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  88. package/dist/src/core/fakeContentGenerator.d.ts +2 -1
  89. package/dist/src/core/fakeContentGenerator.js +1 -0
  90. package/dist/src/core/fakeContentGenerator.js.map +1 -1
  91. package/dist/src/core/geminiChat.js +6 -2
  92. package/dist/src/core/geminiChat.js.map +1 -1
  93. package/dist/src/core/geminiChat.test.js +34 -0
  94. package/dist/src/core/geminiChat.test.js.map +1 -1
  95. package/dist/src/core/localLiteRtLmClient.d.ts +24 -0
  96. package/dist/src/core/localLiteRtLmClient.js +77 -0
  97. package/dist/src/core/localLiteRtLmClient.js.map +1 -0
  98. package/dist/src/core/localLiteRtLmClient.test.d.ts +6 -0
  99. package/dist/src/core/localLiteRtLmClient.test.js +87 -0
  100. package/dist/src/core/localLiteRtLmClient.test.js.map +1 -0
  101. package/dist/src/core/loggingContentGenerator.d.ts +2 -1
  102. package/dist/src/core/loggingContentGenerator.js +39 -17
  103. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  104. package/dist/src/core/loggingContentGenerator.test.js +122 -5
  105. package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
  106. package/dist/src/core/prompts.test.js +1 -1
  107. package/dist/src/core/prompts.test.js.map +1 -1
  108. package/dist/src/fallback/handler.js +2 -0
  109. package/dist/src/fallback/handler.js.map +1 -1
  110. package/dist/src/fallback/types.d.ts +1 -1
  111. package/dist/src/generated/git-commit.d.ts +2 -2
  112. package/dist/src/generated/git-commit.js +2 -2
  113. package/dist/src/index.d.ts +5 -0
  114. package/dist/src/index.js +5 -0
  115. package/dist/src/index.js.map +1 -1
  116. package/dist/src/policy/config.d.ts +18 -6
  117. package/dist/src/policy/config.js +51 -14
  118. package/dist/src/policy/config.js.map +1 -1
  119. package/dist/src/policy/config.test.js +26 -26
  120. package/dist/src/policy/config.test.js.map +1 -1
  121. package/dist/src/policy/persistence.test.js +9 -14
  122. package/dist/src/policy/persistence.test.js.map +1 -1
  123. package/dist/src/policy/policies/plan.toml +1 -1
  124. package/dist/src/policy/policy-engine.d.ts +8 -0
  125. package/dist/src/policy/policy-engine.js +12 -0
  126. package/dist/src/policy/policy-engine.js.map +1 -1
  127. package/dist/src/policy/policy-engine.test.js +93 -0
  128. package/dist/src/policy/policy-engine.test.js.map +1 -1
  129. package/dist/src/policy/policy-updater.test.js +1 -1
  130. package/dist/src/policy/policy-updater.test.js.map +1 -1
  131. package/dist/src/policy/toml-loader.d.ts +1 -1
  132. package/dist/src/policy/toml-loader.js +4 -2
  133. package/dist/src/policy/toml-loader.js.map +1 -1
  134. package/dist/src/policy/toml-loader.test.js +15 -12
  135. package/dist/src/policy/toml-loader.test.js.map +1 -1
  136. package/dist/src/policy/workspace-policy.test.js +10 -10
  137. package/dist/src/prompts/snippets.js +43 -27
  138. package/dist/src/prompts/snippets.js.map +1 -1
  139. package/dist/src/routing/modelRouterService.js +19 -11
  140. package/dist/src/routing/modelRouterService.js.map +1 -1
  141. package/dist/src/routing/modelRouterService.test.js +38 -1
  142. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  143. package/dist/src/routing/routingStrategy.d.ts +3 -2
  144. package/dist/src/routing/strategies/classifierStrategy.d.ts +2 -1
  145. package/dist/src/routing/strategies/classifierStrategy.js +1 -1
  146. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  147. package/dist/src/routing/strategies/classifierStrategy.test.js +15 -13
  148. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  149. package/dist/src/routing/strategies/compositeStrategy.d.ts +2 -1
  150. package/dist/src/routing/strategies/compositeStrategy.js +3 -3
  151. package/dist/src/routing/strategies/compositeStrategy.js.map +1 -1
  152. package/dist/src/routing/strategies/compositeStrategy.test.js +10 -8
  153. package/dist/src/routing/strategies/compositeStrategy.test.js.map +1 -1
  154. package/dist/src/routing/strategies/defaultStrategy.d.ts +2 -1
  155. package/dist/src/routing/strategies/defaultStrategy.js +1 -1
  156. package/dist/src/routing/strategies/defaultStrategy.js.map +1 -1
  157. package/dist/src/routing/strategies/defaultStrategy.test.js +8 -4
  158. package/dist/src/routing/strategies/defaultStrategy.test.js.map +1 -1
  159. package/dist/src/routing/strategies/fallbackStrategy.d.ts +2 -1
  160. package/dist/src/routing/strategies/fallbackStrategy.js +1 -1
  161. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
  162. package/dist/src/routing/strategies/fallbackStrategy.test.js +6 -5
  163. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
  164. package/dist/src/routing/strategies/gemmaClassifierStrategy.d.ts +14 -0
  165. package/dist/src/routing/strategies/gemmaClassifierStrategy.js +182 -0
  166. package/dist/src/routing/strategies/gemmaClassifierStrategy.js.map +1 -0
  167. package/dist/src/routing/strategies/gemmaClassifierStrategy.test.d.ts +6 -0
  168. package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js +218 -0
  169. package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js.map +1 -0
  170. package/dist/src/routing/strategies/numericalClassifierStrategy.d.ts +2 -1
  171. package/dist/src/routing/strategies/numericalClassifierStrategy.js +1 -1
  172. package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -1
  173. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +24 -22
  174. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -1
  175. package/dist/src/routing/strategies/overrideStrategy.d.ts +2 -1
  176. package/dist/src/routing/strategies/overrideStrategy.js +1 -1
  177. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
  178. package/dist/src/routing/strategies/overrideStrategy.test.js +5 -4
  179. package/dist/src/routing/strategies/overrideStrategy.test.js.map +1 -1
  180. package/dist/src/scheduler/scheduler.d.ts +1 -0
  181. package/dist/src/scheduler/scheduler.js +18 -7
  182. package/dist/src/scheduler/scheduler.js.map +1 -1
  183. package/dist/src/scheduler/scheduler.test.js +19 -1
  184. package/dist/src/scheduler/scheduler.test.js.map +1 -1
  185. package/dist/src/scheduler/scheduler_parallel.test.js +94 -3
  186. package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -1
  187. package/dist/src/scheduler/tool-executor.js +21 -12
  188. package/dist/src/scheduler/tool-executor.js.map +1 -1
  189. package/dist/src/scheduler/tool-executor.test.js +54 -0
  190. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  191. package/dist/src/services/trackerService.d.ts +49 -0
  192. package/dist/src/services/trackerService.js +172 -0
  193. package/dist/src/services/trackerService.js.map +1 -0
  194. package/dist/src/services/trackerService.test.d.ts +6 -0
  195. package/dist/src/services/trackerService.test.js +117 -0
  196. package/dist/src/services/trackerService.test.js.map +1 -0
  197. package/dist/src/services/trackerTypes.d.ts +51 -0
  198. package/dist/src/services/trackerTypes.js +33 -0
  199. package/dist/src/services/trackerTypes.js.map +1 -0
  200. package/dist/src/telemetry/billingEvents.d.ts +75 -0
  201. package/dist/src/telemetry/billingEvents.js +181 -0
  202. package/dist/src/telemetry/billingEvents.js.map +1 -0
  203. package/dist/src/telemetry/billingEvents.test.d.ts +6 -0
  204. package/dist/src/telemetry/billingEvents.test.js +139 -0
  205. package/dist/src/telemetry/billingEvents.test.js.map +1 -0
  206. package/dist/src/telemetry/conseca-logger.test.js +1 -0
  207. package/dist/src/telemetry/conseca-logger.test.js.map +1 -1
  208. package/dist/src/telemetry/constants.d.ts +25 -0
  209. package/dist/src/telemetry/constants.js +29 -0
  210. package/dist/src/telemetry/constants.js.map +1 -1
  211. package/dist/src/telemetry/index.d.ts +3 -1
  212. package/dist/src/telemetry/index.js +5 -1
  213. package/dist/src/telemetry/index.js.map +1 -1
  214. package/dist/src/telemetry/loggers.d.ts +2 -0
  215. package/dist/src/telemetry/loggers.js +10 -0
  216. package/dist/src/telemetry/loggers.js.map +1 -1
  217. package/dist/src/telemetry/loggers.test.js +16 -0
  218. package/dist/src/telemetry/loggers.test.js.map +1 -1
  219. package/dist/src/telemetry/metrics.d.ts +28 -0
  220. package/dist/src/telemetry/metrics.js +40 -0
  221. package/dist/src/telemetry/metrics.js.map +1 -1
  222. package/dist/src/telemetry/sanitize.test.js +1 -0
  223. package/dist/src/telemetry/sanitize.test.js.map +1 -1
  224. package/dist/src/telemetry/sdk.test.js +1 -0
  225. package/dist/src/telemetry/sdk.test.js.map +1 -1
  226. package/dist/src/telemetry/telemetryAttributes.js +2 -0
  227. package/dist/src/telemetry/telemetryAttributes.js.map +1 -1
  228. package/dist/src/telemetry/trace.d.ts +2 -1
  229. package/dist/src/telemetry/trace.js +13 -18
  230. package/dist/src/telemetry/trace.js.map +1 -1
  231. package/dist/src/telemetry/trace.test.d.ts +6 -0
  232. package/dist/src/telemetry/trace.test.js +116 -0
  233. package/dist/src/telemetry/trace.test.js.map +1 -0
  234. package/dist/src/tools/confirmation-policy.test.js +1 -0
  235. package/dist/src/tools/confirmation-policy.test.js.map +1 -1
  236. package/dist/src/tools/definitions/model-family-sets/default-legacy.js +2 -2
  237. package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
  238. package/dist/src/tools/definitions/model-family-sets/gemini-3.js +3 -3
  239. package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
  240. package/dist/src/tools/grep-utils.d.ts +1 -1
  241. package/dist/src/tools/grep-utils.js +4 -4
  242. package/dist/src/tools/grep-utils.js.map +1 -1
  243. package/dist/src/tools/grep.d.ts +1 -1
  244. package/dist/src/tools/grep.js +9 -9
  245. package/dist/src/tools/grep.js.map +1 -1
  246. package/dist/src/tools/grep.test.js +8 -5
  247. package/dist/src/tools/grep.test.js.map +1 -1
  248. package/dist/src/tools/line-endings.test.js +3 -11
  249. package/dist/src/tools/line-endings.test.js.map +1 -1
  250. package/dist/src/tools/mcp-client-manager.d.ts +25 -0
  251. package/dist/src/tools/mcp-client-manager.js +66 -3
  252. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  253. package/dist/src/tools/mcp-client-manager.test.js +47 -0
  254. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  255. package/dist/src/tools/mcp-client.d.ts +20 -9
  256. package/dist/src/tools/mcp-client.js +50 -46
  257. package/dist/src/tools/mcp-client.js.map +1 -1
  258. package/dist/src/tools/mcp-client.test.js +96 -84
  259. package/dist/src/tools/mcp-client.test.js.map +1 -1
  260. package/dist/src/tools/mcp-tool.d.ts +3 -3
  261. package/dist/src/tools/mcp-tool.js +1 -0
  262. package/dist/src/tools/mcp-tool.js.map +1 -1
  263. package/dist/src/tools/ripGrep.d.ts +1 -1
  264. package/dist/src/tools/ripGrep.js +7 -7
  265. package/dist/src/tools/ripGrep.js.map +1 -1
  266. package/dist/src/tools/ripGrep.test.js +10 -7
  267. package/dist/src/tools/ripGrep.test.js.map +1 -1
  268. package/dist/src/tools/tools.d.ts +1 -0
  269. package/dist/src/tools/tools.js +1 -0
  270. package/dist/src/tools/tools.js.map +1 -1
  271. package/dist/src/tools/write-file.js +4 -17
  272. package/dist/src/tools/write-file.js.map +1 -1
  273. package/dist/src/tools/write-file.test.js +29 -83
  274. package/dist/src/tools/write-file.test.js.map +1 -1
  275. package/dist/src/utils/editCorrector.d.ts +1 -42
  276. package/dist/src/utils/editCorrector.js +9 -461
  277. package/dist/src/utils/editCorrector.js.map +1 -1
  278. package/dist/src/utils/editCorrector.test.js +17 -421
  279. package/dist/src/utils/editCorrector.test.js.map +1 -1
  280. package/dist/src/utils/envExpansion.js.map +1 -1
  281. package/dist/src/utils/errors.js +7 -0
  282. package/dist/src/utils/errors.js.map +1 -1
  283. package/dist/src/utils/errors_timeout.test.d.ts +6 -0
  284. package/dist/src/utils/errors_timeout.test.js +40 -0
  285. package/dist/src/utils/errors_timeout.test.js.map +1 -0
  286. package/dist/src/utils/extensionLoader.js +35 -0
  287. package/dist/src/utils/extensionLoader.js.map +1 -1
  288. package/dist/src/utils/extensionLoader.test.js +36 -0
  289. package/dist/src/utils/extensionLoader.test.js.map +1 -1
  290. package/dist/src/utils/fetch.js +13 -2
  291. package/dist/src/utils/fetch.js.map +1 -1
  292. package/dist/src/utils/fileUtils.js +0 -1
  293. package/dist/src/utils/fileUtils.js.map +1 -1
  294. package/dist/src/utils/fileUtils.test.js +0 -1
  295. package/dist/src/utils/fileUtils.test.js.map +1 -1
  296. package/dist/src/utils/flashFallback.test.js +24 -0
  297. package/dist/src/utils/flashFallback.test.js.map +1 -1
  298. package/dist/src/utils/googleErrors.d.ts +2 -2
  299. package/dist/src/utils/googleQuotaErrors.d.ts +3 -1
  300. package/dist/src/utils/googleQuotaErrors.js +22 -12
  301. package/dist/src/utils/googleQuotaErrors.js.map +1 -1
  302. package/dist/src/utils/googleQuotaErrors.test.js +33 -1
  303. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
  304. package/dist/src/utils/retry.js +4 -2
  305. package/dist/src/utils/retry.js.map +1 -1
  306. package/dist/src/utils/retry.test.js +20 -0
  307. package/dist/src/utils/retry.test.js.map +1 -1
  308. package/dist/src/utils/schemaValidator.js +0 -1
  309. package/dist/src/utils/schemaValidator.js.map +1 -1
  310. package/dist/tsconfig.tsbuildinfo +1 -1
  311. package/package.json +1 -1
  312. package/dist/google-gemini-cli-core-0.31.0-preview.1.tgz +0 -0
@@ -25,6 +25,13 @@ const EMPTY_CONFIG = {
25
25
  allowedEnvironmentVariables: [],
26
26
  blockedEnvironmentVariables: [],
27
27
  };
28
+ const MOCK_CONTEXT_DEFAULT = {
29
+ sanitizationConfig: EMPTY_CONFIG,
30
+ emitMcpDiagnostic: vi.fn(),
31
+ setUserInteractedWithMcp: vi.fn(),
32
+ isTrustedFolder: vi.fn().mockReturnValue(true),
33
+ };
34
+ let MOCK_CONTEXT = MOCK_CONTEXT_DEFAULT;
28
35
  vi.mock('@modelcontextprotocol/sdk/client/stdio.js');
29
36
  vi.mock('@modelcontextprotocol/sdk/client/index.js');
30
37
  vi.mock('@google/genai');
@@ -43,6 +50,12 @@ describe('mcp-client', () => {
43
50
  let workspaceContext;
44
51
  let testWorkspace;
45
52
  beforeEach(() => {
53
+ MOCK_CONTEXT = {
54
+ sanitizationConfig: EMPTY_CONFIG,
55
+ emitMcpDiagnostic: vi.fn(),
56
+ setUserInteractedWithMcp: vi.fn(),
57
+ isTrustedFolder: vi.fn().mockReturnValue(true),
58
+ };
46
59
  // create a tmp dir for this test
47
60
  // Create a unique temporary directory for the workspace to avoid conflicts
48
61
  testWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-agent-test-'));
@@ -95,9 +108,9 @@ describe('mcp-client', () => {
95
108
  };
96
109
  const client = new McpClient('test-server', {
97
110
  command: 'test-command',
98
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
111
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
99
112
  await client.connect();
100
- await client.discover({});
113
+ await client.discover(MOCK_CONTEXT);
101
114
  expect(mockedClient.listTools).toHaveBeenCalledWith({}, expect.objectContaining({ timeout: 600000, progressReporter: client }));
102
115
  });
103
116
  it('should not skip tools even if a parameter is missing a type', async () => {
@@ -157,9 +170,9 @@ describe('mcp-client', () => {
157
170
  };
158
171
  const client = new McpClient('test-server', {
159
172
  command: 'test-command',
160
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
173
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
161
174
  await client.connect();
162
- await client.discover({});
175
+ await client.discover(MOCK_CONTEXT);
163
176
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledTimes(2);
164
177
  expect(consoleWarnSpy).not.toHaveBeenCalled();
165
178
  consoleWarnSpy.mockRestore();
@@ -194,10 +207,10 @@ describe('mcp-client', () => {
194
207
  };
195
208
  const client = new McpClient('test-server', {
196
209
  command: 'test-command',
197
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
210
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
198
211
  await client.connect();
199
- await expect(client.discover({})).rejects.toThrow('Test error');
200
- expect(coreEvents.emitFeedback).toHaveBeenCalledWith('error', `Error discovering prompts from test-server: Test error`, expect.any(Error));
212
+ await expect(client.discover(MOCK_CONTEXT)).rejects.toThrow('Test error');
213
+ expect(MOCK_CONTEXT.emitMcpDiagnostic).toHaveBeenCalledWith('error', `Error discovering prompts from test-server: Test error`, expect.any(Error), 'test-server');
201
214
  });
202
215
  it('should not discover tools if server does not support them', async () => {
203
216
  const mockedClient = {
@@ -229,9 +242,9 @@ describe('mcp-client', () => {
229
242
  };
230
243
  const client = new McpClient('test-server', {
231
244
  command: 'test-command',
232
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
245
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
233
246
  await client.connect();
234
- await expect(client.discover({})).rejects.toThrow('No prompts, tools, or resources found on the server.');
247
+ await expect(client.discover(MOCK_CONTEXT)).rejects.toThrow('No prompts, tools, or resources found on the server.');
235
248
  });
236
249
  it('should discover tools if server supports them', async () => {
237
250
  const mockedClient = {
@@ -272,9 +285,9 @@ describe('mcp-client', () => {
272
285
  };
273
286
  const client = new McpClient('test-server', {
274
287
  command: 'test-command',
275
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
288
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
276
289
  await client.connect();
277
- await client.discover({});
290
+ await client.discover(MOCK_CONTEXT);
278
291
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledOnce();
279
292
  });
280
293
  it('should register tool with readOnlyHint and preserve annotations', async () => {
@@ -322,7 +335,7 @@ describe('mcp-client', () => {
322
335
  setResourcesForServer: vi.fn(),
323
336
  removeResourcesByServer: vi.fn(),
324
337
  };
325
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
338
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
326
339
  await client.connect();
327
340
  await client.discover(mockConfig);
328
341
  // Verify tool registration
@@ -379,7 +392,7 @@ describe('mcp-client', () => {
379
392
  setResourcesForServer: vi.fn(),
380
393
  removeResourcesByServer: vi.fn(),
381
394
  };
382
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
395
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
383
396
  await client.connect();
384
397
  await client.discover(mockConfig);
385
398
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledOnce();
@@ -434,7 +447,7 @@ describe('mcp-client', () => {
434
447
  setResourcesForServer: vi.fn(),
435
448
  removeResourcesByServer: vi.fn(),
436
449
  };
437
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
450
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
438
451
  await client.connect();
439
452
  await client.discover(mockConfig);
440
453
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledOnce();
@@ -500,9 +513,9 @@ describe('mcp-client', () => {
500
513
  };
501
514
  const client = new McpClient('test-server', {
502
515
  command: 'test-command',
503
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
516
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
504
517
  await client.connect();
505
- await client.discover({});
518
+ await client.discover(MOCK_CONTEXT);
506
519
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledOnce();
507
520
  const registeredTool = vi.mocked(mockedToolRegistry.registerTool).mock
508
521
  .calls[0][0];
@@ -564,9 +577,9 @@ describe('mcp-client', () => {
564
577
  };
565
578
  const client = new McpClient('test-server', {
566
579
  command: 'test-command',
567
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
580
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
568
581
  await client.connect();
569
- await client.discover({});
582
+ await client.discover(MOCK_CONTEXT);
570
583
  expect(resourceRegistry.setResourcesForServer).toHaveBeenCalledWith('test-server', [
571
584
  expect.objectContaining({
572
585
  uri: 'file:///tmp/resource.txt',
@@ -632,16 +645,16 @@ describe('mcp-client', () => {
632
645
  };
633
646
  const client = new McpClient('test-server', {
634
647
  command: 'test-command',
635
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
648
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
636
649
  await client.connect();
637
- await client.discover({});
650
+ await client.discover(MOCK_CONTEXT);
638
651
  expect(mockedClient.setNotificationHandler).toHaveBeenCalledTimes(2);
639
652
  expect(resourceListHandler).toBeDefined();
640
653
  await resourceListHandler?.({
641
654
  method: 'notifications/resources/list_changed',
642
655
  });
643
656
  expect(resourceRegistry.setResourcesForServer).toHaveBeenLastCalledWith('test-server', [expect.objectContaining({ uri: 'file:///tmp/two.txt' })]);
644
- expect(coreEvents.emitFeedback).toHaveBeenCalledWith('info', 'Resources updated for server: test-server');
657
+ expect(MOCK_CONTEXT.emitMcpDiagnostic).toHaveBeenCalledWith('info', 'Resources updated for server: test-server', undefined, 'test-server');
645
658
  });
646
659
  it('refreshes prompts when prompt list change notification is received', async () => {
647
660
  let listCallCount = 0;
@@ -691,9 +704,9 @@ describe('mcp-client', () => {
691
704
  };
692
705
  const client = new McpClient('test-server', {
693
706
  command: 'test-command',
694
- }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
707
+ }, mockedToolRegistry, promptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
695
708
  await client.connect();
696
- await client.discover({ sanitizationConfig: EMPTY_CONFIG });
709
+ await client.discover(MOCK_CONTEXT);
697
710
  expect(mockedClient.setNotificationHandler).toHaveBeenCalledTimes(2);
698
711
  expect(promptListHandler).toBeDefined();
699
712
  await promptListHandler?.({
@@ -701,7 +714,7 @@ describe('mcp-client', () => {
701
714
  });
702
715
  expect(promptRegistry.removePromptsByServer).toHaveBeenCalledWith('test-server');
703
716
  expect(promptRegistry.registerPrompt).toHaveBeenLastCalledWith(expect.objectContaining({ name: 'two' }));
704
- expect(coreEvents.emitFeedback).toHaveBeenCalledWith('info', 'Prompts updated for server: test-server');
717
+ expect(MOCK_CONTEXT.emitMcpDiagnostic).toHaveBeenCalledWith('info', 'Prompts updated for server: test-server', undefined, 'test-server');
705
718
  });
706
719
  it('should remove tools and prompts on disconnect', async () => {
707
720
  const mockedClient = {
@@ -748,9 +761,9 @@ describe('mcp-client', () => {
748
761
  };
749
762
  const client = new McpClient('test-server', {
750
763
  command: 'test-command',
751
- }, mockedToolRegistry, mockedPromptRegistry, resourceRegistry, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
764
+ }, mockedToolRegistry, mockedPromptRegistry, resourceRegistry, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
752
765
  await client.connect();
753
- await client.discover({});
766
+ await client.discover(MOCK_CONTEXT);
754
767
  expect(mockedToolRegistry.registerTool).toHaveBeenCalledOnce();
755
768
  expect(mockedPromptRegistry.registerPrompt).toHaveBeenCalledOnce();
756
769
  await client.disconnect();
@@ -778,7 +791,7 @@ describe('mcp-client', () => {
778
791
  };
779
792
  vi.mocked(ClientLib.Client).mockReturnValue(mockedClient);
780
793
  vi.spyOn(SdkClientStdioLib, 'StdioClientTransport').mockReturnValue({});
781
- const client = new McpClient('test-server', { command: 'test-command' }, {}, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
794
+ const client = new McpClient('test-server', { command: 'test-command' }, {}, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
782
795
  await client.connect();
783
796
  expect(mockedClient.setNotificationHandler).toHaveBeenCalledWith(ToolListChangedNotificationSchema, expect.any(Function));
784
797
  });
@@ -793,7 +806,7 @@ describe('mcp-client', () => {
793
806
  };
794
807
  vi.mocked(ClientLib.Client).mockReturnValue(mockedClient);
795
808
  vi.spyOn(SdkClientStdioLib, 'StdioClientTransport').mockReturnValue({});
796
- const client = new McpClient('test-server', { command: 'test-command' }, {}, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
809
+ const client = new McpClient('test-server', { command: 'test-command' }, {}, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
797
810
  await client.connect();
798
811
  expect(mockedClient.setNotificationHandler).toHaveBeenCalledOnce();
799
812
  });
@@ -828,7 +841,7 @@ describe('mcp-client', () => {
828
841
  };
829
842
  const onToolsUpdatedSpy = vi.fn().mockResolvedValue(undefined);
830
843
  // Initialize client with onToolsUpdated callback
831
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1', onToolsUpdatedSpy);
844
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1', onToolsUpdatedSpy);
832
845
  // 1. Connect (sets up listener)
833
846
  await client.connect();
834
847
  // 2. Extract the callback passed to setNotificationHandler
@@ -845,7 +858,7 @@ describe('mcp-client', () => {
845
858
  // It should notify the manager
846
859
  expect(onToolsUpdatedSpy).toHaveBeenCalled();
847
860
  // It should emit feedback event
848
- expect(coreEvents.emitFeedback).toHaveBeenCalledWith('info', 'Tools updated for server: test-server');
861
+ expect(MOCK_CONTEXT.emitMcpDiagnostic).toHaveBeenCalledWith('info', 'Tools updated for server: test-server', undefined, 'test-server');
849
862
  });
850
863
  it('should handle errors during tool refresh gracefully', async () => {
851
864
  const mockedClient = {
@@ -866,7 +879,7 @@ describe('mcp-client', () => {
866
879
  removeMcpToolsByServer: vi.fn(),
867
880
  getMessageBus: vi.fn().mockReturnValue(undefined),
868
881
  };
869
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
882
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
870
883
  await client.connect();
871
884
  const notificationCallback = mockedClient.setNotificationHandler.mock.calls[0][1];
872
885
  // Trigger notification - should fail internally but catch the error
@@ -909,8 +922,8 @@ describe('mcp-client', () => {
909
922
  getMessageBus: vi.fn().mockReturnValue(undefined),
910
923
  };
911
924
  const onToolsUpdatedSpy = vi.fn().mockResolvedValue(undefined);
912
- const clientA = new McpClient('server-A', { command: 'cmd-a' }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1', onToolsUpdatedSpy);
913
- const clientB = new McpClient('server-B', { command: 'cmd-b' }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1', onToolsUpdatedSpy);
925
+ const clientA = new McpClient('server-A', { command: 'cmd-a' }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1', onToolsUpdatedSpy);
926
+ const clientB = new McpClient('server-B', { command: 'cmd-b' }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1', onToolsUpdatedSpy);
914
927
  await clientA.connect();
915
928
  await clientB.connect();
916
929
  const handlerA = mockClientA.setNotificationHandler.mock.calls[0][1];
@@ -959,7 +972,7 @@ describe('mcp-client', () => {
959
972
  };
960
973
  const client = new McpClient('test-server',
961
974
  // Set a short timeout
962
- { command: 'test-command', timeout: 100 }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1');
975
+ { command: 'test-command', timeout: 100 }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1');
963
976
  await client.connect();
964
977
  const notificationCallback = mockedClient.setNotificationHandler.mock.calls[0][1];
965
978
  const refreshPromise = notificationCallback();
@@ -993,7 +1006,7 @@ describe('mcp-client', () => {
993
1006
  getMessageBus: vi.fn().mockReturnValue(undefined),
994
1007
  };
995
1008
  const onToolsUpdatedSpy = vi.fn().mockResolvedValue(undefined);
996
- const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, { sanitizationConfig: EMPTY_CONFIG }, false, '0.0.1', onToolsUpdatedSpy);
1009
+ const client = new McpClient('test-server', { command: 'test-command' }, mockedToolRegistry, {}, {}, workspaceContext, MOCK_CONTEXT, false, '0.0.1', onToolsUpdatedSpy);
997
1010
  await client.connect();
998
1011
  const notificationCallback = mockedClient.setNotificationHandler.mock.calls[0][1];
999
1012
  await notificationCallback();
@@ -1027,7 +1040,7 @@ describe('mcp-client', () => {
1027
1040
  it('without headers', async () => {
1028
1041
  const transport = await createTransport('test-server', {
1029
1042
  httpUrl: 'http://test-server',
1030
- }, false, EMPTY_CONFIG);
1043
+ }, false, MOCK_CONTEXT);
1031
1044
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1032
1045
  expect(transport).toMatchObject({
1033
1046
  _url: new URL('http://test-server'),
@@ -1038,7 +1051,7 @@ describe('mcp-client', () => {
1038
1051
  const transport = await createTransport('test-server', {
1039
1052
  httpUrl: 'http://test-server',
1040
1053
  headers: { Authorization: 'derp' },
1041
- }, false, EMPTY_CONFIG);
1054
+ }, false, MOCK_CONTEXT);
1042
1055
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1043
1056
  expect(transport).toMatchObject({
1044
1057
  _url: new URL('http://test-server'),
@@ -1052,7 +1065,7 @@ describe('mcp-client', () => {
1052
1065
  it('without headers', async () => {
1053
1066
  const transport = await createTransport('test-server', {
1054
1067
  url: 'http://test-server',
1055
- }, false, EMPTY_CONFIG);
1068
+ }, false, MOCK_CONTEXT);
1056
1069
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1057
1070
  expect(transport).toMatchObject({
1058
1071
  _url: new URL('http://test-server'),
@@ -1063,7 +1076,7 @@ describe('mcp-client', () => {
1063
1076
  const transport = await createTransport('test-server', {
1064
1077
  url: 'http://test-server',
1065
1078
  headers: { Authorization: 'derp' },
1066
- }, false, EMPTY_CONFIG);
1079
+ }, false, MOCK_CONTEXT);
1067
1080
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1068
1081
  expect(transport).toMatchObject({
1069
1082
  _url: new URL('http://test-server'),
@@ -1076,7 +1089,7 @@ describe('mcp-client', () => {
1076
1089
  const transport = await createTransport('test-server', {
1077
1090
  url: 'http://test-server',
1078
1091
  type: 'http',
1079
- }, false, EMPTY_CONFIG);
1092
+ }, false, MOCK_CONTEXT);
1080
1093
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1081
1094
  expect(transport).toMatchObject({
1082
1095
  _url: new URL('http://test-server'),
@@ -1087,7 +1100,7 @@ describe('mcp-client', () => {
1087
1100
  const transport = await createTransport('test-server', {
1088
1101
  url: 'http://test-server',
1089
1102
  type: 'sse',
1090
- }, false, EMPTY_CONFIG);
1103
+ }, false, MOCK_CONTEXT);
1091
1104
  expect(transport).toBeInstanceOf(SSEClientTransport);
1092
1105
  expect(transport).toMatchObject({
1093
1106
  _url: new URL('http://test-server'),
@@ -1097,7 +1110,7 @@ describe('mcp-client', () => {
1097
1110
  it('without type defaults to StreamableHTTPClientTransport', async () => {
1098
1111
  const transport = await createTransport('test-server', {
1099
1112
  url: 'http://test-server',
1100
- }, false, EMPTY_CONFIG);
1113
+ }, false, MOCK_CONTEXT);
1101
1114
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1102
1115
  expect(transport).toMatchObject({
1103
1116
  _url: new URL('http://test-server'),
@@ -1109,7 +1122,7 @@ describe('mcp-client', () => {
1109
1122
  url: 'http://test-server',
1110
1123
  type: 'http',
1111
1124
  headers: { Authorization: 'Bearer token' },
1112
- }, false, EMPTY_CONFIG);
1125
+ }, false, MOCK_CONTEXT);
1113
1126
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1114
1127
  expect(transport).toMatchObject({
1115
1128
  _url: new URL('http://test-server'),
@@ -1123,7 +1136,7 @@ describe('mcp-client', () => {
1123
1136
  url: 'http://test-server',
1124
1137
  type: 'sse',
1125
1138
  headers: { 'X-API-Key': 'key123' },
1126
- }, false, EMPTY_CONFIG);
1139
+ }, false, MOCK_CONTEXT);
1127
1140
  expect(transport).toBeInstanceOf(SSEClientTransport);
1128
1141
  expect(transport).toMatchObject({
1129
1142
  _url: new URL('http://test-server'),
@@ -1136,7 +1149,7 @@ describe('mcp-client', () => {
1136
1149
  const transport = await createTransport('test-server', {
1137
1150
  httpUrl: 'http://test-server-http',
1138
1151
  url: 'http://test-server-url',
1139
- }, false, EMPTY_CONFIG);
1152
+ }, false, MOCK_CONTEXT);
1140
1153
  // httpUrl should take priority and create HTTP transport
1141
1154
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1142
1155
  expect(transport).toMatchObject({
@@ -1154,7 +1167,7 @@ describe('mcp-client', () => {
1154
1167
  args: ['--foo', 'bar'],
1155
1168
  env: { FOO: 'bar' },
1156
1169
  cwd: 'test/cwd',
1157
- }, false, EMPTY_CONFIG);
1170
+ }, false, MOCK_CONTEXT);
1158
1171
  expect(mockedTransport).toHaveBeenCalledWith({
1159
1172
  command: 'test-command',
1160
1173
  args: ['--foo', 'bar'],
@@ -1172,7 +1185,7 @@ describe('mcp-client', () => {
1172
1185
  args: ['--foo', 'bar'],
1173
1186
  env: {},
1174
1187
  cwd: 'test/cwd',
1175
- }, false, EMPTY_CONFIG);
1188
+ }, false, MOCK_CONTEXT);
1176
1189
  const callArgs = mockedTransport.mock.calls[0][0];
1177
1190
  expect(callArgs.env).toBeDefined();
1178
1191
  expect(callArgs.env['GEMINI_CLI']).toBe('1');
@@ -1199,7 +1212,7 @@ describe('mcp-client', () => {
1199
1212
  contextFiles: [],
1200
1213
  id: '',
1201
1214
  },
1202
- }, false, EMPTY_CONFIG);
1215
+ }, false, MOCK_CONTEXT);
1203
1216
  const callArgs = mockedTransport.mock.calls[0][0];
1204
1217
  expect(callArgs.env).toBeDefined();
1205
1218
  expect(callArgs.env['GEMINI_CLI_EXT_VAR']).toBeUndefined();
@@ -1226,7 +1239,7 @@ describe('mcp-client', () => {
1226
1239
  contextFiles: [],
1227
1240
  id: '',
1228
1241
  },
1229
- }, false, EMPTY_CONFIG);
1242
+ }, false, MOCK_CONTEXT);
1230
1243
  const callArgs = mockedTransport.mock.calls[0][0];
1231
1244
  expect(callArgs.env).toBeDefined();
1232
1245
  expect(callArgs.env['GEMINI_CLI_EXT_VAR']).toBe('defined-value');
@@ -1256,7 +1269,7 @@ describe('mcp-client', () => {
1256
1269
  contextFiles: [],
1257
1270
  id: '',
1258
1271
  },
1259
- }, false, EMPTY_CONFIG);
1272
+ }, false, MOCK_CONTEXT);
1260
1273
  const callArgs = mockedTransport.mock.calls[0][0];
1261
1274
  expect(callArgs.env).toBeDefined();
1262
1275
  expect(callArgs.env['GEMINI_CLI_EXT_VAR']).toBe('ext-value');
@@ -1278,7 +1291,7 @@ describe('mcp-client', () => {
1278
1291
  TEST_EXPANDED: 'Value is $GEMINI_TEST_VAR',
1279
1292
  SECRET_KEY: 'intentional-secret-123',
1280
1293
  },
1281
- }, false, EMPTY_CONFIG);
1294
+ }, false, MOCK_CONTEXT);
1282
1295
  const callArgs = mockedTransport.mock.calls[0][0];
1283
1296
  expect(callArgs.env).toBeDefined();
1284
1297
  expect(callArgs.env['TEST_EXPANDED']).toBe('Value is expanded-value');
@@ -1307,13 +1320,12 @@ describe('mcp-client', () => {
1307
1320
  headers: {
1308
1321
  'X-Goog-User-Project': 'myproject',
1309
1322
  },
1310
- }, false, EMPTY_CONFIG);
1323
+ }, false, MOCK_CONTEXT);
1311
1324
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1312
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1313
- const authProvider = transport._authProvider;
1325
+ const testableTransport = transport;
1326
+ const authProvider = testableTransport._authProvider;
1314
1327
  expect(authProvider).toBeInstanceOf(GoogleCredentialProvider);
1315
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1316
- const googUserProject = transport._requestInit?.headers?.['X-Goog-User-Project'];
1328
+ const googUserProject = testableTransport._requestInit?.headers?.['X-Goog-User-Project'];
1317
1329
  expect(googUserProject).toBe('myproject');
1318
1330
  });
1319
1331
  it('should use headers from GoogleCredentialProvider', async () => {
@@ -1327,12 +1339,12 @@ describe('mcp-client', () => {
1327
1339
  oauth: {
1328
1340
  scopes: ['scope1'],
1329
1341
  },
1330
- }, false, EMPTY_CONFIG);
1342
+ }, false, MOCK_CONTEXT);
1331
1343
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1332
1344
  expect(mockGetRequestHeaders).toHaveBeenCalled();
1333
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1334
- const headers = transport._requestInit?.headers;
1335
- expect(headers['X-Goog-User-Project']).toBe('provider-project');
1345
+ const testableTransport = transport;
1346
+ const headers = testableTransport._requestInit?.headers;
1347
+ expect(headers?.['X-Goog-User-Project']).toBe('provider-project');
1336
1348
  });
1337
1349
  it('should prioritize provider headers over config headers', async () => {
1338
1350
  const mockGetRequestHeaders = vi.fn().mockResolvedValue({
@@ -1348,11 +1360,11 @@ describe('mcp-client', () => {
1348
1360
  headers: {
1349
1361
  'X-Goog-User-Project': 'config-project',
1350
1362
  },
1351
- }, false, EMPTY_CONFIG);
1363
+ }, false, MOCK_CONTEXT);
1352
1364
  expect(transport).toBeInstanceOf(StreamableHTTPClientTransport);
1353
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1354
- const headers = transport._requestInit?.headers;
1355
- expect(headers['X-Goog-User-Project']).toBe('provider-project');
1365
+ const testableTransport = transport;
1366
+ const headers = testableTransport._requestInit?.headers;
1367
+ expect(headers?.['X-Goog-User-Project']).toBe('provider-project');
1356
1368
  });
1357
1369
  it('should use GoogleCredentialProvider with SSE transport', async () => {
1358
1370
  const transport = await createTransport('test-server', {
@@ -1362,10 +1374,10 @@ describe('mcp-client', () => {
1362
1374
  oauth: {
1363
1375
  scopes: ['scope1'],
1364
1376
  },
1365
- }, false, EMPTY_CONFIG);
1377
+ }, false, MOCK_CONTEXT);
1366
1378
  expect(transport).toBeInstanceOf(SSEClientTransport);
1367
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1368
- const authProvider = transport._authProvider;
1379
+ const testableTransport = transport;
1380
+ const authProvider = testableTransport._authProvider;
1369
1381
  expect(authProvider).toBeInstanceOf(GoogleCredentialProvider);
1370
1382
  });
1371
1383
  it('should throw an error if no URL is provided with GoogleCredentialProvider', async () => {
@@ -1374,7 +1386,7 @@ describe('mcp-client', () => {
1374
1386
  oauth: {
1375
1387
  scopes: ['scope1'],
1376
1388
  },
1377
- }, false, EMPTY_CONFIG)).rejects.toThrow('URL must be provided in the config for Google Credentials provider');
1389
+ }, false, MOCK_CONTEXT)).rejects.toThrow('URL must be provided in the config for Google Credentials provider');
1378
1390
  });
1379
1391
  });
1380
1392
  });
@@ -1486,18 +1498,18 @@ describe('connectToMcpServer with OAuth', () => {
1486
1498
  tokenUrl,
1487
1499
  scopes: ['test-scope'],
1488
1500
  });
1489
- // We need this to be an any type because we dig into its private state.
1490
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1501
+ // We need this to be typed to dig into its private state.
1491
1502
  let capturedTransport;
1492
1503
  vi.mocked(mockedClient.connect).mockImplementationOnce(async (transport) => {
1493
1504
  capturedTransport = transport;
1494
1505
  return Promise.resolve();
1495
1506
  });
1496
- const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, EMPTY_CONFIG);
1507
+ const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, MOCK_CONTEXT);
1497
1508
  expect(client).toBe(mockedClient);
1498
1509
  expect(mockedClient.connect).toHaveBeenCalledTimes(2);
1499
1510
  expect(mockAuthProvider.authenticate).toHaveBeenCalledOnce();
1500
- const authHeader = capturedTransport._requestInit?.headers?.['Authorization'];
1511
+ const authHeader = capturedTransport._requestInit
1512
+ ?.headers?.['Authorization'];
1501
1513
  expect(authHeader).toBe('Bearer test-access-token');
1502
1514
  });
1503
1515
  it('should discover oauth config if not in www-authenticate header', async () => {
@@ -1511,19 +1523,19 @@ describe('connectToMcpServer with OAuth', () => {
1511
1523
  scopes: ['test-scope'],
1512
1524
  });
1513
1525
  vi.mocked(mockAuthProvider.getValidToken).mockResolvedValue('test-access-token-from-discovery');
1514
- // We need this to be an any type because we dig into its private state.
1515
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1526
+ // We need this to be typed to dig into its private state.
1516
1527
  let capturedTransport;
1517
1528
  vi.mocked(mockedClient.connect).mockImplementationOnce(async (transport) => {
1518
1529
  capturedTransport = transport;
1519
1530
  return Promise.resolve();
1520
1531
  });
1521
- const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, EMPTY_CONFIG);
1532
+ const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, MOCK_CONTEXT);
1522
1533
  expect(client).toBe(mockedClient);
1523
1534
  expect(mockedClient.connect).toHaveBeenCalledTimes(2);
1524
1535
  expect(mockAuthProvider.authenticate).toHaveBeenCalledOnce();
1525
1536
  expect(OAuthUtils.discoverOAuthConfig).toHaveBeenCalledWith(serverUrl);
1526
- const authHeader = capturedTransport._requestInit?.headers?.['Authorization'];
1537
+ const authHeader = capturedTransport._requestInit
1538
+ ?.headers?.['Authorization'];
1527
1539
  expect(authHeader).toBe('Bearer test-access-token-from-discovery');
1528
1540
  });
1529
1541
  it('should use discoverOAuthFromWWWAuthenticate when it succeeds and skip discoverOAuthConfig', async () => {
@@ -1538,7 +1550,7 @@ describe('connectToMcpServer with OAuth', () => {
1538
1550
  scopes: ['read'],
1539
1551
  });
1540
1552
  vi.mocked(mockedClient.connect).mockResolvedValueOnce(undefined);
1541
- const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, EMPTY_CONFIG);
1553
+ const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, MOCK_CONTEXT);
1542
1554
  expect(client).toBe(mockedClient);
1543
1555
  expect(OAuthUtils.discoverOAuthFromWWWAuthenticate).toHaveBeenCalledWith(wwwAuthHeader, serverUrl);
1544
1556
  expect(OAuthUtils.discoverOAuthConfig).not.toHaveBeenCalled();
@@ -1559,7 +1571,7 @@ describe('connectToMcpServer with OAuth', () => {
1559
1571
  scopes: ['read'],
1560
1572
  });
1561
1573
  vi.mocked(mockedClient.connect).mockResolvedValueOnce(undefined);
1562
- const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, EMPTY_CONFIG);
1574
+ const client = await connectToMcpServer('0.0.1', 'test-server', { httpUrl: serverUrl, oauth: { enabled: true } }, false, workspaceContext, MOCK_CONTEXT);
1563
1575
  expect(client).toBe(mockedClient);
1564
1576
  expect(OAuthUtils.discoverOAuthFromWWWAuthenticate).toHaveBeenCalledWith(wwwAuthHeader, serverUrl);
1565
1577
  expect(OAuthUtils.extractBaseUrl).toHaveBeenCalledWith(serverUrl);
@@ -1592,13 +1604,13 @@ describe('connectToMcpServer - HTTP→SSE fallback', () => {
1592
1604
  });
1593
1605
  it('should NOT trigger fallback when type="http" is explicit', async () => {
1594
1606
  vi.mocked(mockedClient.connect).mockRejectedValueOnce(new Error('Connection failed'));
1595
- await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', type: 'http' }, false, workspaceContext, EMPTY_CONFIG)).rejects.toThrow('Connection failed');
1607
+ await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', type: 'http' }, false, workspaceContext, MOCK_CONTEXT)).rejects.toThrow('Connection failed');
1596
1608
  // Should only try once (no fallback)
1597
1609
  expect(mockedClient.connect).toHaveBeenCalledTimes(1);
1598
1610
  });
1599
1611
  it('should NOT trigger fallback when type="sse" is explicit', async () => {
1600
1612
  vi.mocked(mockedClient.connect).mockRejectedValueOnce(new Error('Connection failed'));
1601
- await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', type: 'sse' }, false, workspaceContext, EMPTY_CONFIG)).rejects.toThrow('Connection failed');
1613
+ await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', type: 'sse' }, false, workspaceContext, MOCK_CONTEXT)).rejects.toThrow('Connection failed');
1602
1614
  // Should only try once (no fallback)
1603
1615
  expect(mockedClient.connect).toHaveBeenCalledTimes(1);
1604
1616
  });
@@ -1606,7 +1618,7 @@ describe('connectToMcpServer - HTTP→SSE fallback', () => {
1606
1618
  vi.mocked(mockedClient.connect)
1607
1619
  .mockRejectedValueOnce(new StreamableHTTPError(500, 'Server error'))
1608
1620
  .mockResolvedValueOnce(undefined);
1609
- const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, EMPTY_CONFIG);
1621
+ const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, MOCK_CONTEXT);
1610
1622
  expect(client).toBe(mockedClient);
1611
1623
  // First HTTP attempt fails, second SSE attempt succeeds
1612
1624
  expect(mockedClient.connect).toHaveBeenCalledTimes(2);
@@ -1617,14 +1629,14 @@ describe('connectToMcpServer - HTTP→SSE fallback', () => {
1617
1629
  vi.mocked(mockedClient.connect)
1618
1630
  .mockRejectedValueOnce(httpError)
1619
1631
  .mockRejectedValueOnce(sseError);
1620
- await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, EMPTY_CONFIG)).rejects.toThrow('Server error');
1632
+ await expect(connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, MOCK_CONTEXT)).rejects.toThrow('Server error');
1621
1633
  expect(mockedClient.connect).toHaveBeenCalledTimes(2);
1622
1634
  });
1623
1635
  it('should handle HTTP 404 followed by SSE success', async () => {
1624
1636
  vi.mocked(mockedClient.connect)
1625
1637
  .mockRejectedValueOnce(new StreamableHTTPError(404, 'Not Found'))
1626
1638
  .mockResolvedValueOnce(undefined);
1627
- const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, EMPTY_CONFIG);
1639
+ const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server' }, false, workspaceContext, MOCK_CONTEXT);
1628
1640
  expect(client).toBe(mockedClient);
1629
1641
  expect(mockedClient.connect).toHaveBeenCalledTimes(2);
1630
1642
  });
@@ -1685,7 +1697,7 @@ describe('connectToMcpServer - OAuth with transport fallback', () => {
1685
1697
  .mockRejectedValueOnce(new StreamableHTTPError(404, 'Not Found'))
1686
1698
  .mockRejectedValueOnce(new StreamableHTTPError(401, 'Unauthorized'))
1687
1699
  .mockResolvedValueOnce(undefined);
1688
- const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', oauth: { enabled: true } }, false, workspaceContext, EMPTY_CONFIG);
1700
+ const client = await connectToMcpServer('0.0.1', 'test-server', { url: 'http://test-server', oauth: { enabled: true } }, false, workspaceContext, MOCK_CONTEXT);
1689
1701
  expect(client).toBe(mockedClient);
1690
1702
  expect(mockedClient.connect).toHaveBeenCalledTimes(3);
1691
1703
  expect(mockAuthProvider.authenticate).toHaveBeenCalledOnce();