diff --git a/eslint.config.js b/eslint.config.js index 26e15aa9b8..e827f9b236 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -158,6 +158,7 @@ export default tseslint.config( '@typescript-eslint/await-thenable': ['error'], '@typescript-eslint/no-floating-promises': ['error'], '@typescript-eslint/no-unnecessary-type-assertion': ['error'], + '@typescript-eslint/no-misused-spread': ['error'], 'no-restricted-imports': [ 'error', { diff --git a/packages/cli/src/commands/mcp/list.ts b/packages/cli/src/commands/mcp/list.ts index a1df1a8027..8154e3b7bf 100644 --- a/packages/cli/src/commands/mcp/list.ts +++ b/packages/cli/src/commands/mcp/list.ts @@ -54,6 +54,7 @@ export async function getMcpServersFromConfig( return; } mcpServers[key] = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...server, extension, }; diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 746fc14475..2325711ad0 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -1716,6 +1716,7 @@ describe('loadCliConfig with admin.mcp.config', () => { const serverA = config.getMcpServers()?.['serverA']; expect(serverA).toEqual({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...localMcpServers['serverA'], type: 'sse', url: 'https://admin-server-a.com/sse', @@ -1766,6 +1767,7 @@ describe('loadCliConfig with admin.mcp.config', () => { }; const localMcpServersWithTools: Record = { serverA: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...localMcpServers['serverA'], includeTools: ['local_tool'], timeout: 1234, @@ -1808,6 +1810,7 @@ describe('loadCliConfig with admin.mcp.config', () => { }; const localMcpServersWithTools: Record = { serverA: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...localMcpServers['serverA'], includeTools: ['local_tool'], }, diff --git a/packages/cli/src/config/mcp/mcpServerEnablement.test.ts b/packages/cli/src/config/mcp/mcpServerEnablement.test.ts index 8b41324790..12b483d59d 100644 --- a/packages/cli/src/config/mcp/mcpServerEnablement.test.ts +++ b/packages/cli/src/config/mcp/mcpServerEnablement.test.ts @@ -13,6 +13,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => { return { ...actual, Storage: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...actual.Storage, getGlobalGeminiDir: () => '/virtual-home/.gemini', }, diff --git a/packages/cli/src/gemini.test.tsx b/packages/cli/src/gemini.test.tsx index 08c2cbabe8..69ea6db56e 100644 --- a/packages/cli/src/gemini.test.tsx +++ b/packages/cli/src/gemini.test.tsx @@ -126,6 +126,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => { clearInstance: vi.fn(), }, coreEvents: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...actual.coreEvents, emitFeedback: vi.fn(), emitConsoleLog: vi.fn(), @@ -1508,6 +1509,7 @@ describe('startInteractiveUI', () => { .spyOn(process.stdout, 'write') .mockImplementation(() => true); const mockConfigWithScreenReader = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getScreenReader: () => screenReader, } as Config; diff --git a/packages/cli/src/services/BuiltinCommandLoader.test.ts b/packages/cli/src/services/BuiltinCommandLoader.test.ts index b5e7856711..f166c161cd 100644 --- a/packages/cli/src/services/BuiltinCommandLoader.test.ts +++ b/packages/cli/src/services/BuiltinCommandLoader.test.ts @@ -266,6 +266,7 @@ describe('BuiltinCommandLoader', () => { it('should include policies command when message bus integration is enabled', async () => { const mockConfigWithMessageBus = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getEnableHooks: () => false, getMcpEnabled: () => true, diff --git a/packages/cli/src/ui/commands/rewindCommand.test.tsx b/packages/cli/src/ui/commands/rewindCommand.test.tsx index d93d365a3e..f878091a45 100644 --- a/packages/cli/src/ui/commands/rewindCommand.test.tsx +++ b/packages/cli/src/ui/commands/rewindCommand.test.tsx @@ -38,6 +38,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => { return { ...actual, coreEvents: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...actual.coreEvents, emitFeedback: vi.fn(), }, diff --git a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx index 90d762581d..ec13eda2e6 100644 --- a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx +++ b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx @@ -163,6 +163,7 @@ describe('ToolConfirmationQueue', () => { , { config: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getUseAlternateBuffer: () => true, } as unknown as Config, diff --git a/packages/cli/src/ui/hooks/useAtCompletion.test.ts b/packages/cli/src/ui/hooks/useAtCompletion.test.ts index 381849a1d2..27e779acef 100644 --- a/packages/cli/src/ui/hooks/useAtCompletion.test.ts +++ b/packages/cli/src/ui/hooks/useAtCompletion.test.ts @@ -674,6 +674,7 @@ describe('useAtCompletion', () => { multiDirTmpDirs.push(addedDir); const multiDirConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getWorkspaceContext: vi.fn().mockReturnValue({ getDirectories: () => [cwdDir, addedDir], @@ -706,6 +707,7 @@ describe('useAtCompletion', () => { const directories = [cwdDir]; const dynamicConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getWorkspaceContext: vi.fn().mockReturnValue({ getDirectories: () => [...directories], @@ -750,6 +752,7 @@ describe('useAtCompletion', () => { multiDirTmpDirs.push(dir2); const multiDirConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getWorkspaceContext: vi.fn().mockReturnValue({ getDirectories: () => [dir1, dir2], diff --git a/packages/cli/src/ui/hooks/useGeminiStream.test.tsx b/packages/cli/src/ui/hooks/useGeminiStream.test.tsx index b912dbe4f8..e62956d6bb 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.test.tsx +++ b/packages/cli/src/ui/hooks/useGeminiStream.test.tsx @@ -1069,6 +1069,7 @@ describe('useGeminiStream', () => { } as unknown as TrackedCompletedToolCall, ]; const lowVerbositySettings = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockLoadedSettings, merged: { ...mockLoadedSettings.merged, @@ -2023,6 +2024,7 @@ describe('useGeminiStream', () => { ); const testConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getContentGenerator: vi.fn(), getContentGeneratorConfig: vi.fn(() => ({ @@ -2826,6 +2828,7 @@ describe('useGeminiStream', () => { describe('Thought Reset', () => { it('should keep full thinking entries in history when mode is full', async () => { const fullThinkingSettings: LoadedSettings = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockLoadedSettings, merged: { ...mockLoadedSettings.merged, diff --git a/packages/cli/src/ui/key/keyBindings.ts b/packages/cli/src/ui/key/keyBindings.ts index 5b1afc0735..c84f189664 100644 --- a/packages/cli/src/ui/key/keyBindings.ts +++ b/packages/cli/src/ui/key/keyBindings.ts @@ -194,6 +194,7 @@ export class KeyBinding { const key = remains; + // eslint-disable-next-line @typescript-eslint/no-misused-spread const isSingleChar = [...key].length === 1; if (!isSingleChar && !KeyBinding.VALID_LONG_KEYS.has(key.toLowerCase())) { diff --git a/packages/core/src/agents/local-executor.test.ts b/packages/core/src/agents/local-executor.test.ts index 65f3b76877..fb21e1093d 100644 --- a/packages/core/src/agents/local-executor.test.ts +++ b/packages/core/src/agents/local-executor.test.ts @@ -175,6 +175,7 @@ vi.mock('../utils/promptIdContext.js', async (importOriginal) => { return { ...actual, promptIdContext: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...actual.promptIdContext, getStore: vi.fn(), run: vi.fn((_id, fn) => fn()), diff --git a/packages/core/src/code_assist/admin/mcpUtils.ts b/packages/core/src/code_assist/admin/mcpUtils.ts index 768a40847e..99fde70ae9 100644 --- a/packages/core/src/code_assist/admin/mcpUtils.ts +++ b/packages/core/src/code_assist/admin/mcpUtils.ts @@ -37,6 +37,7 @@ export function applyAdminAllowlist( const adminConfig = adminAllowlist[serverId]; if (adminConfig) { const mergedConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...localConfig, url: adminConfig.url, type: adminConfig.type, diff --git a/packages/core/src/config/models.test.ts b/packages/core/src/config/models.test.ts index dbe558fc85..19b6d81b29 100644 --- a/packages/core/src/config/models.test.ts +++ b/packages/core/src/config/models.test.ts @@ -71,10 +71,12 @@ describe('Dynamic Configuration Parity', () => { for (const flags of flagCombos) { for (const hasAccess of [true, false]) { const mockLegacyConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...legacyConfig, getHasAccessToPreviewModel: () => hasAccess, } as unknown as Config; const mockDynamicConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...dynamicConfig, getHasAccessToPreviewModel: () => hasAccess, } as unknown as Config; @@ -110,10 +112,12 @@ describe('Dynamic Configuration Parity', () => { for (const hasAccess of [true, false]) { const mockLegacyConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...legacyConfig, getHasAccessToPreviewModel: () => hasAccess, } as unknown as Config; const mockDynamicConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...dynamicConfig, getHasAccessToPreviewModel: () => hasAccess, } as unknown as Config; diff --git a/packages/core/src/core/coreToolScheduler.test.ts b/packages/core/src/core/coreToolScheduler.test.ts index c897e4ed30..28350fef10 100644 --- a/packages/core/src/core/coreToolScheduler.test.ts +++ b/packages/core/src/core/coreToolScheduler.test.ts @@ -291,6 +291,7 @@ function createMockConfig(overrides: Partial = {}): Config { getExperiments: () => {}, } as unknown as Config; + // eslint-disable-next-line @typescript-eslint/no-misused-spread const finalConfig = { ...baseConfig, ...overrides } as Config; (finalConfig as unknown as { config: Config }).config = finalConfig; diff --git a/packages/core/src/core/coreToolSchedulerHooks.test.ts b/packages/core/src/core/coreToolSchedulerHooks.test.ts index 63c22e0b11..a6c2e470d0 100644 --- a/packages/core/src/core/coreToolSchedulerHooks.test.ts +++ b/packages/core/src/core/coreToolSchedulerHooks.test.ts @@ -74,6 +74,7 @@ function createMockConfig(overrides: Partial = {}): Config { }) as unknown as PolicyEngine, } as unknown as Config; + // eslint-disable-next-line @typescript-eslint/no-misused-spread return { ...baseConfig, ...overrides } as Config; } diff --git a/packages/core/src/mcp/google-auth-provider.test.ts b/packages/core/src/mcp/google-auth-provider.test.ts index f535f17d83..cd15263984 100644 --- a/packages/core/src/mcp/google-auth-provider.test.ts +++ b/packages/core/src/mcp/google-auth-provider.test.ts @@ -177,6 +177,7 @@ describe('GoogleCredentialProvider', () => { it('should prioritize config headers over quota project ID', async () => { mockClient['quotaProjectId'] = 'quota-project-id'; const configWithHeaders = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...validConfig, headers: { 'X-Goog-User-Project': 'config-project-id', @@ -193,6 +194,7 @@ describe('GoogleCredentialProvider', () => { it('should prioritize config headers over quota project ID (case-insensitive)', async () => { mockClient['quotaProjectId'] = 'quota-project-id'; const configWithHeaders = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...validConfig, headers: { 'x-goog-user-project': 'config-project-id', diff --git a/packages/core/src/services/chatCompressionService.ts b/packages/core/src/services/chatCompressionService.ts index a1f9c12f2c..4640860e48 100644 --- a/packages/core/src/services/chatCompressionService.ts +++ b/packages/core/src/services/chatCompressionService.ts @@ -196,6 +196,7 @@ async function truncateHistoryToBudget( newParts.unshift({ functionResponse: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...part.functionResponse, response: { output: truncatedMessage }, }, diff --git a/packages/core/src/services/toolOutputMaskingService.ts b/packages/core/src/services/toolOutputMaskingService.ts index 9d5a3fb2c2..4151ec46d5 100644 --- a/packages/core/src/services/toolOutputMaskingService.ts +++ b/packages/core/src/services/toolOutputMaskingService.ts @@ -226,6 +226,7 @@ export class ToolOutputMaskingService { const maskedPart = { ...part, functionResponse: { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...part.functionResponse, response: { output: maskedSnippet }, }, diff --git a/packages/core/src/telemetry/loggers.test.ts b/packages/core/src/telemetry/loggers.test.ts index ba33c0d2e7..71e2e8ea7b 100644 --- a/packages/core/src/telemetry/loggers.test.ts +++ b/packages/core/src/telemetry/loggers.test.ts @@ -286,6 +286,7 @@ describe('loggers', () => { it('should set worktree_active to true when worktree settings are present', async () => { const mockConfig = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...baseMockConfig, getWorktreeSettings: () => ({ name: 'test-worktree', @@ -556,6 +557,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_API_RESPONSE, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -715,6 +717,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_API_ERROR, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1285,6 +1288,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1422,6 +1426,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1502,6 +1507,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1581,6 +1587,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1661,6 +1668,7 @@ describe('loggers', () => { ); expect(mockUiEvent.addEvent).toHaveBeenCalledWith({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': '2025-01-01T00:00:00.000Z', @@ -1955,6 +1963,7 @@ describe('loggers', () => { 'session.id': 'test-session-id', 'user.email': 'test-user@example.com', 'installation.id': 'test-installation-id', + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_MODEL_ROUTING, interactive: false, @@ -1992,6 +2001,7 @@ describe('loggers', () => { 'session.id': 'test-session-id', 'user.email': 'test-user@example.com', 'installation.id': 'test-installation-id', + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_MODEL_ROUTING, interactive: false, diff --git a/packages/core/src/telemetry/loggers.ts b/packages/core/src/telemetry/loggers.ts index f3208f91f3..53c7dcb894 100644 --- a/packages/core/src/telemetry/loggers.ts +++ b/packages/core/src/telemetry/loggers.ts @@ -135,6 +135,7 @@ export function logUserPrompt(config: Config, event: UserPromptEvent): void { export function logToolCall(config: Config, event: ToolCallEvent): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_TOOL_CALL, 'event.timestamp': new Date().toISOString(), @@ -269,6 +270,7 @@ export function logRipgrepFallback( export function logApiError(config: Config, event: ApiErrorEvent): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_API_ERROR, 'event.timestamp': new Date().toISOString(), @@ -301,6 +303,7 @@ export function logApiError(config: Config, event: ApiErrorEvent): void { export function logApiResponse(config: Config, event: ApiResponseEvent): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_API_RESPONSE, 'event.timestamp': new Date().toISOString(), @@ -401,6 +404,7 @@ export function logSlashCommand( export function logRewind(config: Config, event: RewindEvent): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...event, 'event.name': EVENT_REWIND, 'event.timestamp': new Date().toISOString(), diff --git a/packages/core/src/telemetry/uiTelemetry.test.ts b/packages/core/src/telemetry/uiTelemetry.test.ts index abbfecf313..9669a5ae59 100644 --- a/packages/core/src/telemetry/uiTelemetry.test.ts +++ b/packages/core/src/telemetry/uiTelemetry.test.ts @@ -403,6 +403,7 @@ describe('UiTelemetryService', () => { ToolConfirmationOutcome.ProceedOnce, ); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -437,6 +438,7 @@ describe('UiTelemetryService', () => { ToolConfirmationOutcome.Cancel, ); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -471,6 +473,7 @@ describe('UiTelemetryService', () => { ToolConfirmationOutcome.ModifyWithEditor, ); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -487,6 +490,7 @@ describe('UiTelemetryService', () => { it('should process a ToolCallEvent without a decision', () => { const toolCall = createFakeCompletedToolCall('test_tool', true, 100); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -523,10 +527,12 @@ describe('UiTelemetryService', () => { ); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall1)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall2)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -558,10 +564,12 @@ describe('UiTelemetryService', () => { const toolCall1 = createFakeCompletedToolCall('tool_A', true, 100); const toolCall2 = createFakeCompletedToolCall('tool_B', false, 200); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall1)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); service.addEvent({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall2)), 'event.name': EVENT_TOOL_CALL, } as ToolCallEvent & { 'event.name': typeof EVENT_TOOL_CALL }); @@ -818,6 +826,7 @@ describe('UiTelemetryService', () => { it('should aggregate valid line count metadata', () => { const toolCall = createFakeCompletedToolCall('test_tool', true, 100); const event = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, metadata: { @@ -836,6 +845,7 @@ describe('UiTelemetryService', () => { it('should ignore null/undefined values in line count metadata', () => { const toolCall = createFakeCompletedToolCall('test_tool', true, 100); const event = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...structuredClone(new ToolCallEvent(toolCall)), 'event.name': EVENT_TOOL_CALL, metadata: { diff --git a/packages/core/src/tools/mcp-client-manager.test.ts b/packages/core/src/tools/mcp-client-manager.test.ts index dce8708628..84d3e138ce 100644 --- a/packages/core/src/tools/mcp-client-manager.test.ts +++ b/packages/core/src/tools/mcp-client-manager.test.ts @@ -511,6 +511,7 @@ describe('McpClientManager', () => { await manager.startExtension(extension); mockedMcpClient.getServerConfig.mockReturnValue({ + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...extension.mcpServers!['test-server'], extension, }); diff --git a/packages/core/src/tools/mcp-client-manager.ts b/packages/core/src/tools/mcp-client-manager.ts index a607b19508..666b6d5321 100644 --- a/packages/core/src/tools/mcp-client-manager.ts +++ b/packages/core/src/tools/mcp-client-manager.ts @@ -215,6 +215,7 @@ export class McpClientManager { await Promise.all( Object.entries(extension.mcpServers ?? {}).map(([name, config]) => this.maybeDiscoverMcpServer(name, { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...config, extension, }), @@ -331,7 +332,9 @@ export class McpClientManager { const env = { ...(base.env ?? {}), ...(override.env ?? {}) }; return { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...base, + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...override, includeTools, excludeTools: excludeTools.length > 0 ? excludeTools : undefined, diff --git a/packages/core/src/tools/write-file.test.ts b/packages/core/src/tools/write-file.test.ts index a014ec354c..b3d762554a 100644 --- a/packages/core/src/tools/write-file.test.ts +++ b/packages/core/src/tools/write-file.test.ts @@ -367,6 +367,7 @@ describe('WriteFileTool', () => { const abortSignal = new AbortController().signal; const mockGemini3Config = { + // eslint-disable-next-line @typescript-eslint/no-misused-spread ...mockConfig, getActiveModel: () => 'gemini-3.0-pro', } as unknown as Config;