mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Disallow and suppress misused spread operator. (#23294)
This commit is contained in:
committed by
GitHub
parent
e7b6326cfa
commit
8f391585ab
@@ -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',
|
||||
{
|
||||
|
||||
@@ -54,6 +54,7 @@ export async function getMcpServersFromConfig(
|
||||
return;
|
||||
}
|
||||
mcpServers[key] = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
||||
...server,
|
||||
extension,
|
||||
};
|
||||
|
||||
@@ -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<string, MCPServerConfig> = {
|
||||
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<string, MCPServerConfig> = {
|
||||
serverA: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
||||
...localMcpServers['serverA'],
|
||||
includeTools: ['local_tool'],
|
||||
},
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
},
|
||||
|
||||
@@ -163,6 +163,7 @@ describe('ToolConfirmationQueue', () => {
|
||||
</Box>,
|
||||
{
|
||||
config: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
||||
...mockConfig,
|
||||
getUseAlternateBuffer: () => true,
|
||||
} as unknown as Config,
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -291,6 +291,7 @@ function createMockConfig(overrides: Partial<Config> = {}): 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;
|
||||
|
||||
@@ -74,6 +74,7 @@ function createMockConfig(overrides: Partial<Config> = {}): Config {
|
||||
}) as unknown as PolicyEngine,
|
||||
} as unknown as Config;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
||||
return { ...baseConfig, ...overrides } as Config;
|
||||
}
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -196,6 +196,7 @@ async function truncateHistoryToBudget(
|
||||
|
||||
newParts.unshift({
|
||||
functionResponse: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-spread
|
||||
...part.functionResponse,
|
||||
response: { output: truncatedMessage },
|
||||
},
|
||||
|
||||
@@ -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 },
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user