diff --git a/eslint.config.js b/eslint.config.js index e48cc3b678..5b39a21098 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -166,6 +166,7 @@ export default tseslint.config( radix: 'error', 'default-case': 'error', '@typescript-eslint/no-floating-promises': ['error'], + '@typescript-eslint/no-unnecessary-type-assertion': ['error'], }, }, { diff --git a/packages/a2a-server/src/agent/executor.ts b/packages/a2a-server/src/agent/executor.ts index 3f87c600fe..8464f27b43 100644 --- a/packages/a2a-server/src/agent/executor.ts +++ b/packages/a2a-server/src/agent/executor.ts @@ -12,11 +12,7 @@ import type { RequestContext, ExecutionEventBus, } from '@a2a-js/sdk/server'; -import type { - ToolCallRequestInfo, - ServerGeminiToolCallRequestEvent, - Config, -} from '@google/gemini-cli-core'; +import type { ToolCallRequestInfo, Config } from '@google/gemini-cli-core'; import { GeminiEventType, SimpleExtensionLoader, @@ -287,8 +283,8 @@ export class CoderAgentExecutor implements AgentExecutor { requestContext: RequestContext, eventBus: ExecutionEventBus, ): Promise { - const userMessage = requestContext.userMessage as Message; - const sdkTask = requestContext.task as SDKTask | undefined; + const userMessage = requestContext.userMessage; + const sdkTask = requestContext.task; const taskId = sdkTask?.id || userMessage.taskId || uuidv4(); const contextId: string = @@ -485,9 +481,7 @@ export class CoderAgentExecutor implements AgentExecutor { throw new Error('Execution aborted'); } if (event.type === GeminiEventType.ToolCallRequest) { - toolCallRequests.push( - (event as ServerGeminiToolCallRequestEvent).value, - ); + toolCallRequests.push(event.value); continue; } await currentTask.acceptAgentMessage(event); diff --git a/packages/a2a-server/src/agent/task.test.ts b/packages/a2a-server/src/agent/task.test.ts index 862e8abcff..148ce21531 100644 --- a/packages/a2a-server/src/agent/task.test.ts +++ b/packages/a2a-server/src/agent/task.test.ts @@ -370,12 +370,7 @@ describe('Task', () => { }; // @ts-expect-error - Calling private constructor - task = new Task( - 'task-id', - 'context-id', - mockConfig as Config, - mockEventBus, - ); + task = new Task('task-id', 'context-id', mockConfig, mockEventBus); // Spy on the method we want to check calls for setTaskStateAndPublishUpdateSpy = vi.spyOn( diff --git a/packages/a2a-server/src/agent/task.ts b/packages/a2a-server/src/agent/task.ts index e9a9fb3668..a44892241c 100644 --- a/packages/a2a-server/src/agent/task.ts +++ b/packages/a2a-server/src/agent/task.ts @@ -747,8 +747,8 @@ export class Task { return false; } - const callId = part.data['callId'] as string; - const outcomeString = part.data['outcome'] as string; + const callId = part.data['callId']; + const outcomeString = part.data['outcome']; let confirmationOutcome: ToolConfirmationOutcome | undefined; if (outcomeString === 'proceed_once') { diff --git a/packages/a2a-server/src/config/settings.ts b/packages/a2a-server/src/config/settings.ts index 3fc9c8ee35..f46db47b6f 100644 --- a/packages/a2a-server/src/config/settings.ts +++ b/packages/a2a-server/src/config/settings.ts @@ -123,7 +123,7 @@ function resolveEnvVarsInString(value: string): string { return value.replace(envVarRegex, (match, varName1, varName2) => { const varName = varName1 || varName2; if (process && process.env && typeof process.env[varName] === 'string') { - return process.env[varName]!; + return process.env[varName]; } return match; }); diff --git a/packages/cli/src/commands/extensions/disable.test.ts b/packages/cli/src/commands/extensions/disable.test.ts index 128a313452..a8a853af28 100644 --- a/packages/cli/src/commands/extensions/disable.test.ts +++ b/packages/cli/src/commands/extensions/disable.test.ts @@ -14,7 +14,7 @@ import { type Mock, } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule, type Argv } from 'yargs'; +import { type Argv } from 'yargs'; import { handleDisable, disableCommand } from './disable.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { @@ -148,7 +148,7 @@ describe('extensions disable command', () => { }); describe('disableCommand', () => { - const command = disableCommand as CommandModule; + const command = disableCommand; it('should have correct command and describe', () => { expect(command.command).toBe('disable [--scope] '); diff --git a/packages/cli/src/commands/extensions/disable.ts b/packages/cli/src/commands/extensions/disable.ts index c36d32856c..2b6a3bdc9a 100644 --- a/packages/cli/src/commands/extensions/disable.ts +++ b/packages/cli/src/commands/extensions/disable.ts @@ -65,7 +65,7 @@ export const disableCommand: CommandModule = { argv.scope && !Object.values(SettingScope) .map((s) => s.toLowerCase()) - .includes((argv.scope as string).toLowerCase()) + .includes(argv.scope.toLowerCase()) ) { throw new Error( `Invalid scope: ${argv.scope}. Please use one of ${Object.values( diff --git a/packages/cli/src/commands/extensions/enable.test.ts b/packages/cli/src/commands/extensions/enable.test.ts index 45fc38b5fe..926dbd6325 100644 --- a/packages/cli/src/commands/extensions/enable.test.ts +++ b/packages/cli/src/commands/extensions/enable.test.ts @@ -14,7 +14,7 @@ import { type Mock, } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule, type Argv } from 'yargs'; +import { type Argv } from 'yargs'; import { handleEnable, enableCommand } from './enable.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { @@ -137,7 +137,7 @@ describe('extensions enable command', () => { }); describe('enableCommand', () => { - const command = enableCommand as CommandModule; + const command = enableCommand; it('should have correct command and describe', () => { expect(command.command).toBe('enable [--scope] '); diff --git a/packages/cli/src/commands/extensions/enable.ts b/packages/cli/src/commands/extensions/enable.ts index 8e29389f89..67d7087d2d 100644 --- a/packages/cli/src/commands/extensions/enable.ts +++ b/packages/cli/src/commands/extensions/enable.ts @@ -70,7 +70,7 @@ export const enableCommand: CommandModule = { argv.scope && !Object.values(SettingScope) .map((s) => s.toLowerCase()) - .includes((argv.scope as string).toLowerCase()) + .includes(argv.scope.toLowerCase()) ) { throw new Error( `Invalid scope: ${argv.scope}. Please use one of ${Object.values( diff --git a/packages/cli/src/commands/extensions/examples/mcp-server/example.test.ts b/packages/cli/src/commands/extensions/examples/mcp-server/example.test.ts index 6b732ae981..5f5660df76 100644 --- a/packages/cli/src/commands/extensions/examples/mcp-server/example.test.ts +++ b/packages/cli/src/commands/extensions/examples/mcp-server/example.test.ts @@ -4,15 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { - describe, - it, - expect, - vi, - beforeEach, - afterEach, - type Mock, -} from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { z } from 'zod'; @@ -90,7 +82,7 @@ describe('MCP Server Example', () => { json: vi.fn().mockResolvedValue(mockPosts), }); - const toolFn = (mockRegisterTool as Mock).mock.calls[0][2]; + const toolFn = mockRegisterTool.mock.calls[0][2]; const result = await toolFn(); expect(global.fetch).toHaveBeenCalledWith( @@ -109,7 +101,7 @@ describe('MCP Server Example', () => { describe('poem-writer prompt implementation', () => { it('should generate a prompt with a title', () => { - const promptFn = (mockRegisterPrompt as Mock).mock.calls[0][2]; + const promptFn = mockRegisterPrompt.mock.calls[0][2]; const result = promptFn({ title: 'My Poem' }); expect(result).toEqual({ messages: [ @@ -125,7 +117,7 @@ describe('MCP Server Example', () => { }); it('should generate a prompt with a title and mood', () => { - const promptFn = (mockRegisterPrompt as Mock).mock.calls[0][2]; + const promptFn = mockRegisterPrompt.mock.calls[0][2]; const result = promptFn({ title: 'My Poem', mood: 'sad' }); expect(result).toEqual({ messages: [ diff --git a/packages/cli/src/commands/extensions/link.test.ts b/packages/cli/src/commands/extensions/link.test.ts index 631aee629b..e6de832221 100644 --- a/packages/cli/src/commands/extensions/link.test.ts +++ b/packages/cli/src/commands/extensions/link.test.ts @@ -14,7 +14,7 @@ import { type Mock, } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule, type Argv } from 'yargs'; +import { type Argv } from 'yargs'; import { handleLink, linkCommand } from './link.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { loadSettings, type LoadedSettings } from '../../config/settings.js'; @@ -126,7 +126,7 @@ describe('extensions link command', () => { }); describe('linkCommand', () => { - const command = linkCommand as CommandModule; + const command = linkCommand; it('should have correct command and describe', () => { expect(command.command).toBe('link '); diff --git a/packages/cli/src/commands/extensions/list.test.ts b/packages/cli/src/commands/extensions/list.test.ts index 5ef259277c..cc17e6410b 100644 --- a/packages/cli/src/commands/extensions/list.test.ts +++ b/packages/cli/src/commands/extensions/list.test.ts @@ -6,7 +6,6 @@ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule } from 'yargs'; import { handleList, listCommand } from './list.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { loadSettings, type LoadedSettings } from '../../config/settings.js'; @@ -124,7 +123,7 @@ describe('extensions list command', () => { }); describe('listCommand', () => { - const command = listCommand as CommandModule; + const command = listCommand; it('should have correct command and describe', () => { expect(command.command).toBe('list'); diff --git a/packages/cli/src/commands/extensions/uninstall.test.ts b/packages/cli/src/commands/extensions/uninstall.test.ts index 8842da960b..e191131e73 100644 --- a/packages/cli/src/commands/extensions/uninstall.test.ts +++ b/packages/cli/src/commands/extensions/uninstall.test.ts @@ -14,7 +14,7 @@ import { type Mock, } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule, type Argv } from 'yargs'; +import { type Argv } from 'yargs'; import { handleUninstall, uninstallCommand } from './uninstall.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { loadSettings, type LoadedSettings } from '../../config/settings.js'; @@ -233,7 +233,7 @@ describe('extensions uninstall command', () => { }); describe('uninstallCommand', () => { - const command = uninstallCommand as CommandModule; + const command = uninstallCommand; it('should have correct command and describe', () => { expect(command.command).toBe('uninstall '); diff --git a/packages/cli/src/commands/extensions/uninstall.ts b/packages/cli/src/commands/extensions/uninstall.ts index 5e94cd598b..3a3a26aa1e 100644 --- a/packages/cli/src/commands/extensions/uninstall.ts +++ b/packages/cli/src/commands/extensions/uninstall.ts @@ -62,7 +62,7 @@ export const uninstallCommand: CommandModule = { array: true, }) .check((argv) => { - if (!argv.names || (argv.names as string[]).length === 0) { + if (!argv.names || argv.names.length === 0) { throw new Error( 'Please include at least one extension name to uninstall as a positional argument.', ); diff --git a/packages/cli/src/commands/extensions/update.test.ts b/packages/cli/src/commands/extensions/update.test.ts index a88b06b429..50847ca9bb 100644 --- a/packages/cli/src/commands/extensions/update.test.ts +++ b/packages/cli/src/commands/extensions/update.test.ts @@ -14,7 +14,7 @@ import { type Mock, } from 'vitest'; import { format } from 'node:util'; -import { type CommandModule, type Argv } from 'yargs'; +import { type Argv } from 'yargs'; import { handleUpdate, updateCommand } from './update.js'; import { ExtensionManager } from '../../config/extension-manager.js'; import { loadSettings, type LoadedSettings } from '../../config/settings.js'; @@ -155,7 +155,7 @@ describe('extensions update command', () => { }); describe('updateCommand', () => { - const command = updateCommand as CommandModule; + const command = updateCommand; it('should have correct command and describe', () => { expect(command.command).toBe('update [] [--all]'); diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 5a605ea4a0..0bf30ebf91 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -60,7 +60,7 @@ vi.mock('fs', async (importOriginal) => { if (mockPaths.has(p.toString())) { return { isDirectory: () => true } as unknown as import('fs').Stats; } - return (actualFs as typeof import('fs')).statSync(p as unknown as string); + return actualFs.statSync(p as unknown as string); }), realpathSync: vi.fn((p) => p), }; diff --git a/packages/cli/src/config/extension-manager.ts b/packages/cli/src/config/extension-manager.ts index 8671c976ac..796867c614 100644 --- a/packages/cli/src/config/extension-manager.ts +++ b/packages/cli/src/config/extension-manager.ts @@ -123,7 +123,7 @@ export class ExtensionManager extends ExtensionLoader { 'Extensions not yet loaded, must call `loadExtensions` first', ); } - return this.loadedExtensions!; + return this.loadedExtensions; } async installOrUpdateExtension( @@ -319,7 +319,7 @@ export class ExtensionManager extends ExtensionLoader { // TODO: Gracefully handle this call failing, we should back up the old // extension prior to overwriting it and then restore and restart it. - extension = await this.loadExtension(destinationPath)!; + extension = await this.loadExtension(destinationPath); if (!extension) { throw new Error(`Extension not found`); } diff --git a/packages/cli/src/config/extensions/github_fetch.ts b/packages/cli/src/config/extensions/github_fetch.ts index a4f9d29b70..720db7a93f 100644 --- a/packages/cli/src/config/extensions/github_fetch.ts +++ b/packages/cli/src/config/extensions/github_fetch.ts @@ -31,7 +31,7 @@ export async function fetchJson( if (!res.headers.location) { return reject(new Error('No location header in redirect response')); } - fetchJson(res.headers.location!, redirectCount++) + fetchJson(res.headers.location, redirectCount++) .then(resolve) .catch(reject); return; diff --git a/packages/cli/src/config/settings-validation.ts b/packages/cli/src/config/settings-validation.ts index 17b3351565..f7f267a410 100644 --- a/packages/cli/src/config/settings-validation.ts +++ b/packages/cli/src/config/settings-validation.ts @@ -18,7 +18,7 @@ function buildZodSchemaFromJsonSchema(def: any): z.ZodTypeAny { if (def.anyOf) { return z.union( // eslint-disable-next-line @typescript-eslint/no-explicit-any - def.anyOf.map((d: any) => buildZodSchemaFromJsonSchema(d)) as any, + def.anyOf.map((d: any) => buildZodSchemaFromJsonSchema(d)), ); } diff --git a/packages/cli/src/config/settings.test.ts b/packages/cli/src/config/settings.test.ts index f370a8dd1c..a1ca034316 100644 --- a/packages/cli/src/config/settings.test.ts +++ b/packages/cli/src/config/settings.test.ts @@ -2231,7 +2231,7 @@ describe('Settings Loading and Merging', () => { beforeEach(() => { vi.resetAllMocks(); mockFsExistsSync = vi.mocked(fs.existsSync); - (mockFsExistsSync as Mock).mockReturnValue(true); + mockFsExistsSync.mockReturnValue(true); mockFsReadFileSync = vi.mocked(fs.readFileSync); mockFsReadFileSync.mockReturnValue('{}'); vi.mocked(isWorkspaceTrusted).mockReturnValue({ @@ -2256,15 +2256,13 @@ describe('Settings Loading and Merging', () => { }, }; - (mockFsReadFileSync as Mock).mockImplementation( - (p: fs.PathOrFileDescriptor) => { - if (p === USER_SETTINGS_PATH) - return JSON.stringify(userSettingsContent); - if (p === MOCK_WORKSPACE_SETTINGS_PATH) - return JSON.stringify(workspaceSettingsContent); - return '{}'; - }, - ); + mockFsReadFileSync.mockImplementation((p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + if (p === MOCK_WORKSPACE_SETTINGS_PATH) + return JSON.stringify(workspaceSettingsContent); + return '{}'; + }); const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); const setValueSpy = vi.spyOn(loadedSettings, 'setValue'); @@ -2329,15 +2327,13 @@ describe('Settings Loading and Merging', () => { someOtherSetting: 'value', }; - (mockFsReadFileSync as Mock).mockImplementation( - (p: fs.PathOrFileDescriptor) => { - if (p === USER_SETTINGS_PATH) - return JSON.stringify(userSettingsContent); - if (p === MOCK_WORKSPACE_SETTINGS_PATH) - return JSON.stringify(workspaceSettingsContent); - return '{}'; - }, - ); + mockFsReadFileSync.mockImplementation((p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + if (p === MOCK_WORKSPACE_SETTINGS_PATH) + return JSON.stringify(workspaceSettingsContent); + return '{}'; + }); const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); const setValueSpy = vi.spyOn(loadedSettings, 'setValue'); diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts index 95e15ca297..343b3526e7 100644 --- a/packages/cli/src/config/settingsSchema.test.ts +++ b/packages/cli/src/config/settingsSchema.test.ts @@ -33,7 +33,7 @@ describe('SettingsSchema', () => { ]; expectedSettings.forEach((setting) => { - expect(getSettingsSchema()[setting as keyof Settings]).toBeDefined(); + expect(getSettingsSchema()[setting]).toBeDefined(); }); }); @@ -66,9 +66,7 @@ describe('SettingsSchema', () => { ]; nestedSettings.forEach((setting) => { - const definition = getSettingsSchema()[ - setting as keyof Settings - ] as SettingDefinition; + const definition = getSettingsSchema()[setting] as SettingDefinition; expect(definition.type).toBe('object'); expect(definition.properties).toBeDefined(); expect(typeof definition.properties).toBe('object'); @@ -142,7 +140,7 @@ describe('SettingsSchema', () => { it('should have consistent default values for boolean settings', () => { const checkBooleanDefaults = (schema: SettingsSchema) => { Object.entries(schema).forEach(([, definition]) => { - const def = definition as SettingDefinition; + const def = definition; if (def.type === 'boolean') { // Boolean settings can have boolean or undefined defaults (for optional settings) expect(['boolean', 'undefined']).toContain(typeof def.default); diff --git a/packages/cli/src/services/FileCommandLoader.test.ts b/packages/cli/src/services/FileCommandLoader.test.ts index 562562c9e4..cdfef1532e 100644 --- a/packages/cli/src/services/FileCommandLoader.test.ts +++ b/packages/cli/src/services/FileCommandLoader.test.ts @@ -238,7 +238,7 @@ describe('FileCommandLoader', () => { const loader = new FileCommandLoader(mockConfig); const commands = await loader.loadCommands(signal); expect(commands).toHaveLength(1); - expect(commands[0]!.name).toBe('gcp:pipelines:run'); + expect(commands[0].name).toBe('gcp:pipelines:run'); }); it('creates namespaces from nested directories', async () => { diff --git a/packages/cli/src/ui/commands/chatCommand.test.ts b/packages/cli/src/ui/commands/chatCommand.test.ts index d1ca6e874f..05a5391902 100644 --- a/packages/cli/src/ui/commands/chatCommand.test.ts +++ b/packages/cli/src/ui/commands/chatCommand.test.ts @@ -326,7 +326,7 @@ describe('chatCommand', () => { const fakeFiles = ['checkpoint-alpha.json', 'checkpoint-beta.json']; mockFs.readdir.mockImplementation( (async (_: string): Promise => - fakeFiles as string[]) as unknown as typeof fsPromises.readdir, + fakeFiles) as unknown as typeof fsPromises.readdir, ); mockFs.stat.mockImplementation( @@ -346,7 +346,7 @@ describe('chatCommand', () => { const date = new Date(); mockFs.readdir.mockImplementation( (async (_: string): Promise => - fakeFiles as string[]) as unknown as typeof fsPromises.readdir, + fakeFiles) as unknown as typeof fsPromises.readdir, ); mockFs.stat.mockImplementation((async ( path: string, @@ -406,7 +406,7 @@ describe('chatCommand', () => { const fakeFiles = ['checkpoint-alpha.json', 'checkpoint-beta.json']; mockFs.readdir.mockImplementation( (async (_: string): Promise => - fakeFiles as string[]) as unknown as typeof fsPromises.readdir, + fakeFiles) as unknown as typeof fsPromises.readdir, ); mockFs.stat.mockImplementation( diff --git a/packages/cli/src/ui/commands/ideCommand.test.ts b/packages/cli/src/ui/commands/ideCommand.test.ts index d63d81851c..73486e2bf1 100644 --- a/packages/cli/src/ui/commands/ideCommand.test.ts +++ b/packages/cli/src/ui/commands/ideCommand.test.ts @@ -110,7 +110,7 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Connected, }); const command = await ideCommand(); - const result = await command!.subCommands!.find( + const result = await command.subCommands!.find( (c) => c.name === 'status', )!.action!(mockContext, ''); expect(vi.mocked(mockIdeClient.getConnectionStatus)).toHaveBeenCalled(); @@ -126,7 +126,7 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Connecting, }); const command = await ideCommand(); - const result = await command!.subCommands!.find( + const result = await command.subCommands!.find( (c) => c.name === 'status', )!.action!(mockContext, ''); expect(vi.mocked(mockIdeClient.getConnectionStatus)).toHaveBeenCalled(); @@ -141,7 +141,7 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Disconnected, }); const command = await ideCommand(); - const result = await command!.subCommands!.find( + const result = await command.subCommands!.find( (c) => c.name === 'status', )!.action!(mockContext, ''); expect(vi.mocked(mockIdeClient.getConnectionStatus)).toHaveBeenCalled(); @@ -159,7 +159,7 @@ describe('ideCommand', () => { details, }); const command = await ideCommand(); - const result = await command!.subCommands!.find( + const result = await command.subCommands!.find( (c) => c.name === 'status', )!.action!(mockContext, ''); expect(vi.mocked(mockIdeClient.getConnectionStatus)).toHaveBeenCalled(); @@ -200,7 +200,7 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Connected, }); - const actionPromise = command!.subCommands!.find( + const actionPromise = command.subCommands!.find( (c) => c.name === 'install', )!.action!(mockContext, ''); await vi.runAllTimersAsync(); @@ -239,7 +239,7 @@ describe('ideCommand', () => { }); const command = await ideCommand(); - await command!.subCommands!.find((c) => c.name === 'install')!.action!( + await command.subCommands!.find((c) => c.name === 'install')!.action!( mockContext, '', ); diff --git a/packages/cli/src/ui/commands/mcpCommand.ts b/packages/cli/src/ui/commands/mcpCommand.ts index 45c4cb2577..34b88e72f1 100644 --- a/packages/cli/src/ui/commands/mcpCommand.ts +++ b/packages/cli/src/ui/commands/mcpCommand.ts @@ -10,11 +10,7 @@ import type { CommandContext, } from './types.js'; import { CommandKind } from './types.js'; -import type { - DiscoveredMCPPrompt, - DiscoveredMCPResource, - MessageActionReturn, -} from '@google/gemini-cli-core'; +import type { MessageActionReturn } from '@google/gemini-cli-core'; import { DiscoveredMCPTool, getMCPDiscoveryState, @@ -218,25 +214,20 @@ const listAction = async ( connectingServers.length > 0; const allTools = toolRegistry.getAllTools(); - const mcpTools = allTools.filter( - (tool) => tool instanceof DiscoveredMCPTool, - ) as DiscoveredMCPTool[]; + const mcpTools = allTools.filter((tool) => tool instanceof DiscoveredMCPTool); const promptRegistry = await config.getPromptRegistry(); const mcpPrompts = promptRegistry .getAllPrompts() .filter( (prompt) => - 'serverName' in prompt && - serverNames.includes(prompt.serverName as string), - ) as DiscoveredMCPPrompt[]; + 'serverName' in prompt && serverNames.includes(prompt.serverName), + ); const resourceRegistry = config.getResourceRegistry(); const mcpResources = resourceRegistry .getAllResources() - .filter((entry) => - serverNames.includes(entry.serverName), - ) as DiscoveredMCPResource[]; + .filter((entry) => serverNames.includes(entry.serverName)); const authStatus: HistoryItemMcpStatus['authStatus'] = {}; const tokenStorage = new MCPOAuthTokenStorage(); @@ -269,7 +260,7 @@ const listAction = async ( schema: tool.schema, })), prompts: mcpPrompts.map((prompt) => ({ - serverName: prompt.serverName as string, + serverName: prompt.serverName, name: prompt.name, description: prompt.description, })), diff --git a/packages/cli/src/ui/commands/restoreCommand.ts b/packages/cli/src/ui/commands/restoreCommand.ts index 5825572642..f95bd05d99 100644 --- a/packages/cli/src/ui/commands/restoreCommand.ts +++ b/packages/cli/src/ui/commands/restoreCommand.ts @@ -22,7 +22,6 @@ import { CommandKind, } from './types.js'; import type { HistoryItem } from '../types.js'; -import type { Content } from '@google/genai'; const HistoryItemSchema = z .object({ @@ -117,9 +116,7 @@ async function restoreAction( } else if (action.type === 'load_history' && loadHistory) { loadHistory(action.history); if (action.clientHistory) { - await config - ?.getGeminiClient() - ?.setHistory(action.clientHistory as Content[]); + await config?.getGeminiClient()?.setHistory(action.clientHistory); } } } diff --git a/packages/cli/src/ui/components/QuittingDisplay.test.tsx b/packages/cli/src/ui/components/QuittingDisplay.test.tsx index 177d469d8e..79cc7e5d7b 100644 --- a/packages/cli/src/ui/components/QuittingDisplay.test.tsx +++ b/packages/cli/src/ui/components/QuittingDisplay.test.tsx @@ -17,7 +17,7 @@ vi.mock('./HistoryItemDisplay.js', async () => { const { Text } = await vi.importActual('ink'); return { HistoryItemDisplay: ({ item }: { item: { content: string } }) => - React.createElement(Text as unknown as React.FC, null, item.content), + React.createElement(Text as React.FC, null, item.content), }; }); diff --git a/packages/cli/src/ui/components/SettingsDialog.test.tsx b/packages/cli/src/ui/components/SettingsDialog.test.tsx index 8d4a255eb2..66ad349a9a 100644 --- a/packages/cli/src/ui/components/SettingsDialog.test.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.test.tsx @@ -326,7 +326,7 @@ describe('SettingsDialog', () => { // Navigate down act(() => { - stdin.write(down as string); + stdin.write(down); }); await waitFor(() => { @@ -335,7 +335,7 @@ describe('SettingsDialog', () => { // Navigate up act(() => { - stdin.write(up as string); + stdin.write(up); }); await waitFor(() => { diff --git a/packages/cli/src/ui/components/ToolStatsDisplay.tsx b/packages/cli/src/ui/components/ToolStatsDisplay.tsx index 64c0d146ce..02a8cf4852 100644 --- a/packages/cli/src/ui/components/ToolStatsDisplay.tsx +++ b/packages/cli/src/ui/components/ToolStatsDisplay.tsx @@ -144,7 +144,7 @@ export const ToolStatsDisplay: React.FC = () => { {/* Tool Rows */} {activeTools.map(([name, stats]) => ( - + ))} diff --git a/packages/cli/src/ui/components/messages/Todo.tsx b/packages/cli/src/ui/components/messages/Todo.tsx index 8780887e85..fcbc92aafd 100644 --- a/packages/cli/src/ui/components/messages/Todo.tsx +++ b/packages/cli/src/ui/components/messages/Todo.tsx @@ -119,7 +119,7 @@ export const TodoTray: React.FC = () => { ) { continue; } - return tool.resultDisplay as TodoList; + return tool.resultDisplay; } } return null; diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx index 78ec581e72..3939a5d211 100644 --- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx @@ -11,8 +11,6 @@ import { DiffRenderer } from './DiffRenderer.js'; import { RenderInline } from '../../utils/InlineMarkdownRenderer.js'; import type { ToolCallConfirmationDetails, - ToolExecuteConfirmationDetails, - ToolMcpConfirmationDetails, Config, } from '@google/gemini-cli-core'; import { IdeClient, ToolConfirmationOutcome } from '@google/gemini-cli-core'; @@ -135,8 +133,7 @@ export const ToolConfirmationMessage: React.FC< }); } } else if (confirmationDetails.type === 'exec') { - const executionProps = - confirmationDetails as ToolExecuteConfirmationDetails; + const executionProps = confirmationDetails; question = `Allow execution of: '${executionProps.rootCommand}'?`; options.push({ @@ -187,7 +184,7 @@ export const ToolConfirmationMessage: React.FC< }); } else { // mcp tool confirmation - const mcpProps = confirmationDetails as ToolMcpConfirmationDetails; + const mcpProps = confirmationDetails; question = `Allow execution of MCP tool "${mcpProps.toolName}" from server "${mcpProps.serverName}"?`; options.push({ label: 'Yes, allow once', @@ -258,8 +255,7 @@ export const ToolConfirmationMessage: React.FC< ); } } else if (confirmationDetails.type === 'exec') { - const executionProps = - confirmationDetails as ToolExecuteConfirmationDetails; + const executionProps = confirmationDetails; let bodyContentHeight = availableBodyContentHeight(); if (bodyContentHeight !== undefined) { bodyContentHeight -= 2; // Account for padding; @@ -312,7 +308,7 @@ export const ToolConfirmationMessage: React.FC< ); } else { // mcp tool confirmation - const mcpProps = confirmationDetails as ToolMcpConfirmationDetails; + const mcpProps = confirmationDetails; bodyContent = ( diff --git a/packages/cli/src/ui/components/shared/VirtualizedList.tsx b/packages/cli/src/ui/components/shared/VirtualizedList.tsx index fd7902d33d..7f027c8127 100644 --- a/packages/cli/src/ui/components/shared/VirtualizedList.tsx +++ b/packages/cli/src/ui/components/shared/VirtualizedList.tsx @@ -59,7 +59,7 @@ function findLastIndex( predicate: (value: T, index: number, obj: T[]) => unknown, ): number { for (let i = array.length - 1; i >= 0; i--) { - if (predicate(array[i]!, i, array)) { + if (predicate(array[i], i, array)) { return i; } } @@ -192,7 +192,7 @@ function VirtualizedList( return { index: 0, offset: 0 }; } - return { index, offset: scrollTop - offsets[index]! }; + return { index, offset: scrollTop - offsets[index] }; }, [], ); diff --git a/packages/cli/src/ui/hooks/atCommandProcessor.ts b/packages/cli/src/ui/hooks/atCommandProcessor.ts index 05b2f1542e..99a9cfa95d 100644 --- a/packages/cli/src/ui/hooks/atCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/atCommandProcessor.ts @@ -433,7 +433,7 @@ export async function handleAtCommand({ const processedQueryParts: PartListUnion = [{ text: initialQueryText }]; const resourcePromises = resourceAttachments.map(async (resource) => { - const uri = resource.uri!; + const uri = resource.uri; const client = mcpClientManager?.getClient(resource.serverName); try { if (!client) { diff --git a/packages/cli/src/ui/hooks/useAutoAcceptIndicator.test.ts b/packages/cli/src/ui/hooks/useAutoAcceptIndicator.test.ts index 910c0960c0..b61491b11e 100644 --- a/packages/cli/src/ui/hooks/useAutoAcceptIndicator.test.ts +++ b/packages/cli/src/ui/hooks/useAutoAcceptIndicator.test.ts @@ -26,9 +26,7 @@ import { MessageType } from '../types.js'; vi.mock('./useKeypress.js'); vi.mock('@google/gemini-cli-core', async () => { - const actualServerModule = (await vi.importActual( - '@google/gemini-cli-core', - )) as Record; + const actualServerModule = await vi.importActual('@google/gemini-cli-core'); return { ...actualServerModule, Config: vi.fn(), diff --git a/packages/cli/src/ui/hooks/useGeminiStream.test.tsx b/packages/cli/src/ui/hooks/useGeminiStream.test.tsx index 679822ffd1..a813adc722 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.test.tsx +++ b/packages/cli/src/ui/hooks/useGeminiStream.test.tsx @@ -24,7 +24,6 @@ import { useReactToolScheduler } from './useReactToolScheduler.js'; import type { Config, EditorType, - GeminiClient, AnyToolInvocation, } from '@google/gemini-cli-core'; import { @@ -809,8 +808,8 @@ describe('useGeminiStream', () => { expect(client.addHistory).toHaveBeenCalledWith({ role: 'user', parts: [ - ...(cancelledToolCall1.response.responseParts as Part[]), - ...(cancelledToolCall2.response.responseParts as Part[]), + ...cancelledToolCall1.response.responseParts, + ...cancelledToolCall2.response.responseParts, ], }); @@ -2074,7 +2073,7 @@ describe('useGeminiStream', () => { const { result } = renderHook(() => useGeminiStream( - mockConfig.getGeminiClient() as GeminiClient, + mockConfig.getGeminiClient(), [], mockAddItem, mockConfig, diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts index 86c4b6c114..306653bd2d 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.ts +++ b/packages/cli/src/ui/hooks/useGeminiStream.ts @@ -833,10 +833,7 @@ export const useGeminiStream = ( ); break; case ServerGeminiEventType.Finished: - handleFinishedEvent( - event as ServerGeminiFinishedEvent, - userMessageTimestamp, - ); + handleFinishedEvent(event, userMessageTimestamp); break; case ServerGeminiEventType.Citation: handleCitationEvent(event.value, userMessageTimestamp); diff --git a/packages/cli/src/ui/hooks/useIncludeDirsTrust.test.tsx b/packages/cli/src/ui/hooks/useIncludeDirsTrust.test.tsx index 6fd3e5185d..1954301c2a 100644 --- a/packages/cli/src/ui/hooks/useIncludeDirsTrust.test.tsx +++ b/packages/cli/src/ui/hooks/useIncludeDirsTrust.test.tsx @@ -183,7 +183,7 @@ describe('useIncludeDirsTrust', () => { ).props; expect(dialogProps.folders).toEqual(['/undefined']); expect(dialogProps.trustedDirs).toEqual(['/trusted']); - expect(dialogProps.errors as string[]).toEqual([ + expect(dialogProps.errors).toEqual([ `The following directories are explicitly untrusted and cannot be added to a trusted workspace:\n- /untrusted\nPlease use the permissions command to modify their trust level.`, ]); }); diff --git a/packages/cli/src/ui/hooks/useReactToolScheduler.ts b/packages/cli/src/ui/hooks/useReactToolScheduler.ts index 9c21fe2bcc..af32b18288 100644 --- a/packages/cli/src/ui/hooks/useReactToolScheduler.ts +++ b/packages/cli/src/ui/hooks/useReactToolScheduler.ts @@ -99,7 +99,7 @@ export function useReactToolScheduler( setToolCallsForDisplay((prevCalls) => prevCalls.map((tc) => { if (tc.request.callId === toolCallId && tc.status === 'executing') { - const executingTc = tc as TrackedExecutingToolCall; + const executingTc = tc; return { ...executingTc, liveOutput: outputChunk }; } return tc; @@ -137,7 +137,7 @@ export function useReactToolScheduler( ...coreTc, responseSubmittedToGemini, liveOutput, - pid: (coreTc as ExecutingToolCall).pid, + pid: coreTc.pid, }; } else { return { @@ -312,10 +312,9 @@ export function mapToDisplay( return { ...baseDisplayProperties, status: mapCoreStatusToDisplayStatus(trackedCall.status), - resultDisplay: - (trackedCall as TrackedExecutingToolCall).liveOutput ?? undefined, + resultDisplay: trackedCall.liveOutput ?? undefined, confirmationDetails: undefined, - ptyId: (trackedCall as TrackedExecutingToolCall).pid, + ptyId: trackedCall.pid, }; case 'validating': // Fallthrough case 'scheduled': diff --git a/packages/cli/src/ui/hooks/useSelectionList.ts b/packages/cli/src/ui/hooks/useSelectionList.ts index eca760760d..85fe5d6f88 100644 --- a/packages/cli/src/ui/hooks/useSelectionList.ts +++ b/packages/cli/src/ui/hooks/useSelectionList.ts @@ -106,7 +106,7 @@ const computeInitialIndex = ( if (initialKey !== undefined) { for (let i = 0; i < items.length; i++) { - if (items[i]!.key === initialKey && !items[i]!.disabled) { + if (items[i].key === initialKey && !items[i].disabled) { return i; } } @@ -212,7 +212,7 @@ function areBaseItemsEqual( if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { - if (a[i]!.key !== b[i]!.key || a[i]!.disabled !== b[i]!.disabled) { + if (a[i].key !== b[i].key || a[i].disabled !== b[i].disabled) { return false; } } @@ -283,7 +283,7 @@ export function useSelectionList({ let needsClear = false; if (state.pendingHighlight && items[state.activeIndex]) { - onHighlight?.(items[state.activeIndex]!.value); + onHighlight?.(items[state.activeIndex].value); needsClear = true; } diff --git a/packages/cli/src/ui/utils/commandUtils.test.ts b/packages/cli/src/ui/utils/commandUtils.test.ts index 6133b33a38..0694a7715d 100644 --- a/packages/cli/src/ui/utils/commandUtils.test.ts +++ b/packages/cli/src/ui/utils/commandUtils.test.ts @@ -231,7 +231,7 @@ describe('commandUtils', () => { const expected = `${ESC}]52;c;${b64}${BEL}`; expect(tty.write).toHaveBeenCalledTimes(1); - expect((tty.write as Mock).mock.calls[0][0]).toBe(expected); + expect(tty.write.mock.calls[0][0]).toBe(expected); expect(tty.end).toHaveBeenCalledTimes(1); // /dev/tty closed after write expect(mockClipboardyWrite).not.toHaveBeenCalled(); }); @@ -245,7 +245,7 @@ describe('commandUtils', () => { await copyToClipboard(testText); - const written = (tty.write as Mock).mock.calls[0][0] as string; + const written = tty.write.mock.calls[0][0] as string; // Starts with tmux DCS wrapper and ends with ST expect(written.startsWith(`${ESC}Ptmux;`)).toBe(true); expect(written.endsWith(ST)).toBe(true); @@ -264,7 +264,7 @@ describe('commandUtils', () => { await copyToClipboard(testText); - const written = (tty.write as Mock).mock.calls[0][0] as string; + const written = tty.write.mock.calls[0][0] as string; const chunkStarts = (written.match(new RegExp(`${ESC}P`, 'g')) || []) .length; const chunkEnds = written.split(ST).length - 1; diff --git a/packages/cli/src/utils/envVarResolver.test.ts b/packages/cli/src/utils/envVarResolver.test.ts index a45b65b1b9..2d06432538 100644 --- a/packages/cli/src/utils/envVarResolver.test.ts +++ b/packages/cli/src/utils/envVarResolver.test.ts @@ -240,7 +240,7 @@ describe('resolveEnvVarsInObject', () => { // Create circular reference arr.push(arr); - const result = resolveEnvVarsInObject(arr) as ArrayWithCircularRef; + const result = resolveEnvVarsInObject(arr); expect(result[0]).toBe('array-value'); expect(result[1]).toBe(123); diff --git a/packages/cli/src/utils/envVarResolver.ts b/packages/cli/src/utils/envVarResolver.ts index 7374024e95..1343a6d92b 100644 --- a/packages/cli/src/utils/envVarResolver.ts +++ b/packages/cli/src/utils/envVarResolver.ts @@ -25,10 +25,10 @@ export function resolveEnvVarsInString( return value.replace(envVarRegex, (match, varName1, varName2) => { const varName = varName1 || varName2; if (customEnv && typeof customEnv[varName] === 'string') { - return customEnv[varName]!; + return customEnv[varName]; } if (process && process.env && typeof process.env[varName] === 'string') { - return process.env[varName]!; + return process.env[varName]; } return match; }); diff --git a/packages/cli/src/validateNonInterActiveAuth.ts b/packages/cli/src/validateNonInterActiveAuth.ts index bd452310d7..e3a63acbfe 100644 --- a/packages/cli/src/validateNonInterActiveAuth.ts +++ b/packages/cli/src/validateNonInterActiveAuth.ts @@ -52,7 +52,7 @@ export async function validateNonInteractiveAuth( throw new Error(message); } - const authType: AuthType = effectiveAuthType as AuthType; + const authType: AuthType = effectiveAuthType; if (!useExternalAuth) { const err = validateAuthMethod(String(authType)); diff --git a/packages/cli/src/zed-integration/acp.test.ts b/packages/cli/src/zed-integration/acp.test.ts index 5554e2a653..95e22a538b 100644 --- a/packages/cli/src/zed-integration/acp.test.ts +++ b/packages/cli/src/zed-integration/acp.test.ts @@ -121,8 +121,7 @@ describe('acp', () => { authMethods: [], protocolVersion: 1, }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('initialize', initializeParams); expect(mockAgent.initialize).toHaveBeenCalledWith(initializeParams); @@ -132,8 +131,7 @@ describe('acp', () => { it('should call agent.newSession when Connection handler receives session_new method', async () => { const newSessionParams = { cwd: '/tmp', mcpServers: [] }; const newSessionResponse = { sessionId: 'session-1' }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('session/new', newSessionParams); expect(mockAgent.newSession).toHaveBeenCalledWith(newSessionParams); @@ -147,8 +145,7 @@ describe('acp', () => { sessionId: 'session-1', }; const loadSessionResponse = { sessionId: 'session-1' }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('session/load', loadSessionParams); expect(mockAgent.loadSession).toHaveBeenCalledWith(loadSessionParams); @@ -162,8 +159,7 @@ describe('acp', () => { mcpServers: [], sessionId: 'session-1', }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; await expect(handler('session/load', loadSessionParams)).rejects.toThrow( RequestError.methodNotFound().message, ); @@ -173,8 +169,7 @@ describe('acp', () => { const authenticateParams = { methodId: 'test-auth-method', }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('authenticate', authenticateParams); expect(mockAgent.authenticate).toHaveBeenCalledWith(authenticateParams); @@ -191,8 +186,7 @@ describe('acp', () => { traceId: 'trace-1', }; (mockAgent.prompt as Mock).mockResolvedValue(promptResponse); - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('session/prompt', promptParams); expect(mockAgent.prompt).toHaveBeenCalledWith(promptParams); @@ -201,8 +195,7 @@ describe('acp', () => { it('should call agent.cancel when Connection handler receives session_cancel method', async () => { const cancelParams = { sessionId: 'session-1' }; - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; const result = await handler('session/cancel', cancelParams); expect(mockAgent.cancel).toHaveBeenCalledWith(cancelParams); @@ -210,8 +203,7 @@ describe('acp', () => { }); it('should throw methodNotFound for unknown methods', async () => { - const handler = mockConnectionConstructor.mock - .calls[0][0]! as MethodHandler; + const handler = mockConnectionConstructor.mock.calls[0][0]; await expect(handler('unknown_method', {})).rejects.toThrow( RequestError.methodNotFound().message, ); @@ -248,7 +240,7 @@ describe('acp', () => { const response = { outcome: { outcome: 'selected', optionId: 'option-1' }, }; - (connectionInstance.sendRequest as Mock).mockResolvedValue(response); + connectionInstance.sendRequest.mockResolvedValue(response); const result = await agentSideConnection.requestPermission(params); expect(connectionInstance.sendRequest).toHaveBeenCalledWith( @@ -261,7 +253,7 @@ describe('acp', () => { it('should send readTextFile request via connection', async () => { const params = { path: '/a/b.txt', sessionId: 'session-1' }; const response = { content: 'file content' }; - (connectionInstance.sendRequest as Mock).mockResolvedValue(response); + connectionInstance.sendRequest.mockResolvedValue(response); const result = await agentSideConnection.readTextFile(params); expect(connectionInstance.sendRequest).toHaveBeenCalledWith( @@ -278,7 +270,7 @@ describe('acp', () => { sessionId: 'session-1', }; const response = { success: true }; - (connectionInstance.sendRequest as Mock).mockResolvedValue(response); + connectionInstance.sendRequest.mockResolvedValue(response); const result = await agentSideConnection.writeTextFile(params); expect(connectionInstance.sendRequest).toHaveBeenCalledWith( diff --git a/packages/cli/src/zed-integration/connection.ts b/packages/cli/src/zed-integration/connection.ts index 17fd83999f..84d0acf82f 100644 --- a/packages/cli/src/zed-integration/connection.ts +++ b/packages/cli/src/zed-integration/connection.ts @@ -147,7 +147,7 @@ export class Connection { await this.#tryCallHandler(message.method, message.params); } else if ('id' in message) { // It's a response - this.#handleResponse(message as AnyResponse); + this.#handleResponse(message); } } diff --git a/packages/cli/src/zed-integration/zedIntegration.ts b/packages/cli/src/zed-integration/zedIntegration.ts index fce417f095..0694a79f80 100644 --- a/packages/cli/src/zed-integration/zedIntegration.ts +++ b/packages/cli/src/zed-integration/zedIntegration.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { WritableStream, ReadableStream } from 'node:stream/web'; +import type { ReadableStream } from 'node:stream/web'; import type { Config, @@ -53,7 +53,7 @@ export async function runZedIntegration( argv: CliArgs, ) { const { stdout: workingStdout } = createWorkingStdio(); - const stdout = Writable.toWeb(workingStdout) as WritableStream; + const stdout = Writable.toWeb(workingStdout); const stdin = Readable.toWeb(process.stdin) as ReadableStream; new acp.AgentSideConnection( @@ -355,7 +355,7 @@ export class Session { fc: FunctionCall, ): Promise { const callId = fc.id ?? `${fc.name}-${Date.now()}`; - const args = (fc.args ?? {}) as Record; + const args = fc.args ?? {}; const startTime = Date.now(); @@ -393,7 +393,7 @@ export class Session { } const toolRegistry = this.config.getToolRegistry(); - const tool = toolRegistry.getTool(fc.name as string); + const tool = toolRegistry.getTool(fc.name); if (!tool) { return errorResponse( diff --git a/packages/core/src/agents/executor.test.ts b/packages/core/src/agents/executor.test.ts index 254435feaa..5a161cd4b9 100644 --- a/packages/core/src/agents/executor.test.ts +++ b/packages/core/src/agents/executor.test.ts @@ -317,7 +317,7 @@ describe('AgentExecutor', () => { onActivity, ); - const agentRegistry = executor['toolRegistry'] as ToolRegistry; + const agentRegistry = executor['toolRegistry']; expect(agentRegistry).not.toBe(parentToolRegistry); expect(agentRegistry.getAllToolNames()).toEqual( @@ -754,7 +754,7 @@ describe('AgentExecutor', () => { expect(turn2Parts).toBeDefined(); expect(turn2Parts).toHaveLength(1); - expect((turn2Parts as Part[])![0]).toEqual( + expect((turn2Parts as Part[])[0]).toEqual( expect.objectContaining({ functionResponse: expect.objectContaining({ name: TASK_COMPLETE_TOOL_NAME, @@ -944,7 +944,7 @@ describe('AgentExecutor', () => { const turn2Params = getMockMessageParams(1); const parts = turn2Params.message; expect(parts).toBeDefined(); - expect((parts as Part[])![0]).toEqual( + expect((parts as Part[])[0]).toEqual( expect.objectContaining({ functionResponse: expect.objectContaining({ id: badCallId, diff --git a/packages/core/src/agents/executor.ts b/packages/core/src/agents/executor.ts index 2a3b812a6f..c7bee33705 100644 --- a/packages/core/src/agents/executor.ts +++ b/packages/core/src/agents/executor.ts @@ -707,7 +707,7 @@ export class AgentExecutor { for (const [index, functionCall] of functionCalls.entries()) { const callId = functionCall.id ?? `${promptId}-${index}`; - const args = (functionCall.args ?? {}) as Record; + const args = functionCall.args ?? {}; this.emitActivity('TOOL_CALL_START', { name: functionCall.name, @@ -918,10 +918,10 @@ export class AgentExecutor { toolNamesToLoad.push(toolRef); } else if (typeof toolRef === 'object' && 'schema' in toolRef) { // Tool instance with an explicit schema property. - toolsList.push(toolRef.schema as FunctionDeclaration); + toolsList.push(toolRef.schema); } else { // Raw `FunctionDeclaration` object. - toolsList.push(toolRef as FunctionDeclaration); + toolsList.push(toolRef); } } // Add schemas from tools that were registered by name. diff --git a/packages/core/src/availability/policyCatalog.test.ts b/packages/core/src/availability/policyCatalog.test.ts index 092123ff65..3f5172a2de 100644 --- a/packages/core/src/availability/policyCatalog.test.ts +++ b/packages/core/src/availability/policyCatalog.test.ts @@ -43,9 +43,9 @@ describe('policyCatalog', () => { it('clones policy maps so edits do not leak between calls', () => { const firstCall = getModelPolicyChain({ previewEnabled: false }); - firstCall[0]!.actions.terminal = 'silent'; + firstCall[0].actions.terminal = 'silent'; const secondCall = getModelPolicyChain({ previewEnabled: false }); - expect(secondCall[0]!.actions.terminal).toBe('prompt'); + expect(secondCall[0].actions.terminal).toBe('prompt'); }); it('passes when there is exactly one last-resort policy', () => { diff --git a/packages/core/src/config/config.test.ts b/packages/core/src/config/config.test.ts index 2c51151967..bec1920dd7 100644 --- a/packages/core/src/config/config.test.ts +++ b/packages/core/src/config/config.test.ts @@ -827,15 +827,15 @@ describe('Server Config (config.ts)', () => { ).ToolRegistry.prototype.registerTool; // Check that registerTool was called for ShellTool - const wasShellToolRegistered = (registerToolMock as Mock).mock.calls.some( + const wasShellToolRegistered = registerToolMock.mock.calls.some( (call) => call[0] instanceof vi.mocked(ShellTool), ); expect(wasShellToolRegistered).toBe(true); // Check that registerTool was NOT called for ReadFileTool - const wasReadFileToolRegistered = ( - registerToolMock as Mock - ).mock.calls.some((call) => call[0] instanceof vi.mocked(ReadFileTool)); + const wasReadFileToolRegistered = registerToolMock.mock.calls.some( + (call) => call[0] instanceof vi.mocked(ReadFileTool), + ); expect(wasReadFileToolRegistered).toBe(false); }); @@ -948,9 +948,9 @@ describe('Server Config (config.ts)', () => { } ).ToolRegistry.prototype.registerTool; - const wasShellToolRegistered = ( - registerToolMock as Mock - ).mock.calls.some((call) => call[0] instanceof vi.mocked(ShellTool)); + const wasShellToolRegistered = registerToolMock.mock.calls.some( + (call) => call[0] instanceof vi.mocked(ShellTool), + ); expect(wasShellToolRegistered).toBe(true); }); @@ -968,9 +968,9 @@ describe('Server Config (config.ts)', () => { } ).ToolRegistry.prototype.registerTool; - const wasShellToolRegistered = ( - registerToolMock as Mock - ).mock.calls.some((call) => call[0] instanceof vi.mocked(ShellTool)); + const wasShellToolRegistered = registerToolMock.mock.calls.some( + (call) => call[0] instanceof vi.mocked(ShellTool), + ); expect(wasShellToolRegistered).toBe(true); }); }); diff --git a/packages/core/src/confirmation-bus/message-bus.ts b/packages/core/src/confirmation-bus/message-bus.ts index c4d3911ecc..8a6eae6025 100644 --- a/packages/core/src/confirmation-bus/message-bus.ts +++ b/packages/core/src/confirmation-bus/message-bus.ts @@ -11,7 +11,6 @@ import { PolicyDecision, getHookSource } from '../policy/types.js'; import { MessageBusType, type Message, - type HookExecutionRequest, type HookPolicyDecision, } from './types.js'; import { safeJsonStringify } from '../utils/safeJsonStringify.js'; @@ -91,7 +90,7 @@ export class MessageBus extends EventEmitter { } } else if (message.type === MessageBusType.HOOK_EXECUTION_REQUEST) { // Handle hook execution requests through policy evaluation - const hookRequest = message as HookExecutionRequest; + const hookRequest = message; const decision = await this.policyEngine.checkHook(hookRequest); // Map decision to allow/deny for observability (ASK_USER treated as deny for hooks) diff --git a/packages/core/src/core/baseLlmClient.test.ts b/packages/core/src/core/baseLlmClient.test.ts index 4027b070e8..4d768923d1 100644 --- a/packages/core/src/core/baseLlmClient.test.ts +++ b/packages/core/src/core/baseLlmClient.test.ts @@ -299,7 +299,7 @@ describe('BaseLlmClient', () => { // Validate the telemetry event content - find the most recent call const calls = vi.mocked(logMalformedJsonResponse).mock.calls; const lastCall = calls[calls.length - 1]; - const event = lastCall[1] as MalformedJsonResponseEvent; + const event = lastCall[1]; expect(event.model).toBe(defaultOptions.modelConfigKey.model); }); @@ -347,7 +347,7 @@ describe('BaseLlmClient', () => { expect(logMalformedJsonResponse).toHaveBeenCalled(); const calls = vi.mocked(logMalformedJsonResponse).mock.calls; const lastCall = calls[calls.length - 1]; - const event = lastCall[1] as MalformedJsonResponseEvent; + const event = lastCall[1]; // This is the key assertion: it should be the resolved model, not the alias expect(event.model).toBe(resolvedModel); diff --git a/packages/core/src/core/contentGenerator.test.ts b/packages/core/src/core/contentGenerator.test.ts index f5f46d7d68..9910ff98a8 100644 --- a/packages/core/src/core/contentGenerator.test.ts +++ b/packages/core/src/core/contentGenerator.test.ts @@ -149,10 +149,7 @@ describe('createContentGenerator', () => { }, }); expect(generator).toEqual( - new LoggingContentGenerator( - (mockGenerator as GoogleGenAI).models, - mockConfig, - ), + new LoggingContentGenerator(mockGenerator.models, mockConfig), ); }); @@ -342,10 +339,7 @@ describe('createContentGenerator', () => { }, }); expect(generator).toEqual( - new LoggingContentGenerator( - (mockGenerator as GoogleGenAI).models, - mockConfig, - ), + new LoggingContentGenerator(mockGenerator.models, mockConfig), ); }); }); diff --git a/packages/core/src/core/coreToolScheduler.test.ts b/packages/core/src/core/coreToolScheduler.test.ts index ed4a91442f..9743b4bf86 100644 --- a/packages/core/src/core/coreToolScheduler.test.ts +++ b/packages/core/src/core/coreToolScheduler.test.ts @@ -1531,7 +1531,7 @@ describe('CoreToolScheduler request queueing', () => { // Capture confirmation handlers for awaiting_approval tools toolCalls.forEach((call) => { if (call.status === 'awaiting_approval') { - const waitingCall = call as WaitingToolCall; + const waitingCall = call; if (waitingCall.confirmationDetails?.onConfirm) { const originalHandler = pendingConfirmations.find( (h) => h === waitingCall.confirmationDetails.onConfirm, diff --git a/packages/core/src/core/coreToolScheduler.ts b/packages/core/src/core/coreToolScheduler.ts index 20936675f9..7ea9e28397 100644 --- a/packages/core/src/core/coreToolScheduler.ts +++ b/packages/core/src/core/coreToolScheduler.ts @@ -506,7 +506,7 @@ export class CoreToolScheduler { // Preserve diff for cancelled edit operations let resultDisplay: ToolResultDisplay | undefined = undefined; if (currentCall.status === 'awaiting_approval') { - const waitingCall = currentCall as WaitingToolCall; + const waitingCall = currentCall; if (waitingCall.confirmationDetails.type === 'edit') { resultDisplay = { fileDiff: waitingCall.confirmationDetails.fileDiff, diff --git a/packages/core/src/core/geminiChat.test.ts b/packages/core/src/core/geminiChat.test.ts index 7afdd00ec7..b61e47aa61 100644 --- a/packages/core/src/core/geminiChat.test.ts +++ b/packages/core/src/core/geminiChat.test.ts @@ -270,9 +270,9 @@ describe('GeminiChat', () => { // 3. Verify history was recorded correctly const history = chat.getHistory(); expect(history.length).toBe(2); // user turn + model turn - const modelTurn = history[1]!; + const modelTurn = history[1]; expect(modelTurn?.parts?.length).toBe(1); // The empty part is discarded - expect(modelTurn?.parts![0]!.functionCall).toBeDefined(); + expect(modelTurn?.parts![0].functionCall).toBeDefined(); }); it('should fail if the stream ends with an empty part and has no finishReason', async () => { @@ -370,9 +370,9 @@ describe('GeminiChat', () => { // 3. Verify history was recorded correctly with only the valid part. const history = chat.getHistory(); expect(history.length).toBe(2); // user turn + model turn - const modelTurn = history[1]!; + const modelTurn = history[1]; expect(modelTurn?.parts?.length).toBe(1); - expect(modelTurn?.parts![0]!.text).toBe('Initial valid content...'); + expect(modelTurn?.parts![0].text).toBe('Initial valid content...'); }); it('should consolidate subsequent text chunks after receiving an empty text chunk', async () => { @@ -414,9 +414,9 @@ describe('GeminiChat', () => { // 3. Assert: Check that the final history was correctly consolidated. const history = chat.getHistory(); expect(history.length).toBe(2); - const modelTurn = history[1]!; + const modelTurn = history[1]; expect(modelTurn?.parts?.length).toBe(1); - expect(modelTurn?.parts![0]!.text).toBe('Hello World!'); + expect(modelTurn?.parts![0].text).toBe('Hello World!'); }); it('should consolidate adjacent text parts that arrive in separate stream chunks', async () => { @@ -476,14 +476,14 @@ describe('GeminiChat', () => { // The history should contain the user's turn and ONE consolidated model turn. expect(history.length).toBe(2); - const modelTurn = history[1]!; + const modelTurn = history[1]; expect(modelTurn.role).toBe('model'); // The model turn should have 3 distinct parts: the merged text, the function call, and the final text. expect(modelTurn?.parts?.length).toBe(3); - expect(modelTurn?.parts![0]!.text).toBe('This is the first part.'); - expect(modelTurn.parts![1]!.functionCall).toBeDefined(); - expect(modelTurn.parts![2]!.text).toBe('This is the second part.'); + expect(modelTurn?.parts![0].text).toBe('This is the first part.'); + expect(modelTurn.parts![1].functionCall).toBeDefined(); + expect(modelTurn.parts![2].text).toBe('This is the second part.'); }); it('should preserve text parts that stream in the same chunk as a thought', async () => { // 1. Mock the API to return a single chunk containing both a thought and visible text. @@ -525,14 +525,14 @@ describe('GeminiChat', () => { // The history should contain two turns: the user's message and the model's response. expect(history.length).toBe(2); - const modelTurn = history[1]!; + const modelTurn = history[1]; expect(modelTurn.role).toBe('model'); // CRUCIAL ASSERTION: // The buggy code would fail here, resulting in parts.length being 0. // The corrected code will pass, preserving the single visible text part. expect(modelTurn?.parts?.length).toBe(1); - expect(modelTurn?.parts![0]!.text).toBe( + expect(modelTurn?.parts![0].text).toBe( 'This is the visible text that should not be lost.', ); }); @@ -1979,8 +1979,8 @@ describe('GeminiChat', () => { ); const history = chat.getHistory(); - const modelTurn = history[1]!; - expect(modelTurn.parts![0]!.text).toBe('Success on retry'); + const modelTurn = history[1]; + expect(modelTurn.parts![0].text).toBe('Success on retry'); }); it('should switch to DEFAULT_GEMINI_FLASH_MODEL and use thinkingBudget when falling back from a gemini-3 model', async () => { @@ -2154,11 +2154,11 @@ describe('GeminiChat', () => { const history = chat.getHistory(); expect(history.length).toBe(2); // user turn + final model turn - const modelTurn = history[1]!; + const modelTurn = history[1]; // The model turn should only contain the text from the successful attempt - expect(modelTurn!.parts![0]!.text).toBe('Successful final response'); + expect(modelTurn.parts![0].text).toBe('Successful final response'); // It should NOT contain any text from the failed attempt - expect(modelTurn!.parts![0]!.text).not.toContain( + expect(modelTurn.parts![0].text).not.toContain( 'This valid part should be discarded', ); }); diff --git a/packages/core/src/core/geminiChat.ts b/packages/core/src/core/geminiChat.ts index bec85a5152..0af1b44536 100644 --- a/packages/core/src/core/geminiChat.ts +++ b/packages/core/src/core/geminiChat.ts @@ -357,9 +357,7 @@ export class GeminiChat { // Check if we have more attempts left. if (attempt < maxAttempts - 1) { const delayMs = INVALID_CONTENT_RETRY_OPTIONS.initialDelayMs; - const retryType = isContentError - ? (error as InvalidStreamError).type - : 'NETWORK_ERROR'; + const retryType = isContentError ? error.type : 'NETWORK_ERROR'; logContentRetry( this.config, @@ -382,11 +380,7 @@ export class GeminiChat { ) { logContentRetryFailure( this.config, - new ContentRetryFailureEvent( - maxAttempts, - (lastError as InvalidStreamError).type, - model, - ), + new ContentRetryFailureEvent(maxAttempts, lastError.type, model), ); } throw lastError; @@ -712,7 +706,7 @@ export class GeminiChat { if (content.role === 'model' && content.parts) { const newParts = content.parts.slice(); for (let j = 0; j < newParts.length; j++) { - const part = newParts[j]!; + const part = newParts[j]; if (part.functionCall) { if (!part.thoughtSignature) { newParts[j] = { @@ -913,7 +907,7 @@ export class GeminiChat { name: call.request.name, args: call.request.args, result: call.response?.responseParts || null, - status: call.status as 'error' | 'success' | 'cancelled', + status: call.status, timestamp: new Date().toISOString(), resultDisplay, }; diff --git a/packages/core/src/core/logger.ts b/packages/core/src/core/logger.ts index 003891010c..9959ba136a 100644 --- a/packages/core/src/core/logger.ts +++ b/packages/core/src/core/logger.ts @@ -408,7 +408,7 @@ export class Logger { } // 2. Attempt to delete the old raw path for backward compatibility. - const oldPath = path.join(this.geminiDir!, `checkpoint-${tag}.json`); + const oldPath = path.join(this.geminiDir, `checkpoint-${tag}.json`); if (newPath !== oldPath) { try { await fs.unlink(oldPath); diff --git a/packages/core/src/core/turn.ts b/packages/core/src/core/turn.ts index e29eeef893..4c802d8362 100644 --- a/packages/core/src/core/turn.ts +++ b/packages/core/src/core/turn.ts @@ -264,7 +264,7 @@ export class Turn { } // Assuming other events are chunks with a `value` property - const resp = streamEvent.value as GenerateContentResponse; + const resp = streamEvent.value; if (!resp) continue; // Skip if there's no response body this.debugResponses.push(resp); @@ -374,7 +374,7 @@ export class Turn { fnCall.id ?? `${fnCall.name}-${Date.now()}-${Math.random().toString(16).slice(2)}`; const name = fnCall.name || 'undefined_tool_name'; - const args = (fnCall.args || {}) as Record; + const args = fnCall.args || {}; const toolCallRequest: ToolCallRequestInfo = { callId, diff --git a/packages/core/src/hooks/hookRegistry.ts b/packages/core/src/hooks/hookRegistry.ts index d170349ade..a074160808 100644 --- a/packages/core/src/hooks/hookRegistry.ts +++ b/packages/core/src/hooks/hookRegistry.ts @@ -137,7 +137,7 @@ export class HookRegistry { continue; } - const typedEventName = eventName as HookEventName; + const typedEventName = eventName; if (!Array.isArray(definitions)) { debugLogger.warn( diff --git a/packages/core/src/hooks/hookRunner.test.ts b/packages/core/src/hooks/hookRunner.test.ts index 8bb0c68598..8892c42218 100644 --- a/packages/core/src/hooks/hookRunner.test.ts +++ b/packages/core/src/hooks/hookRunner.test.ts @@ -21,9 +21,9 @@ type MockChildProcessWithoutNullStreams = ChildProcessWithoutNullStreams & { // Mock child_process with importOriginal for partial mocking vi.mock('node:child_process', async (importOriginal) => { - const actual = (await importOriginal()) as object; + const actual = await importOriginal(); return { - ...actual, + ...(actual as object), spawn: vi.fn(), }; }); diff --git a/packages/core/src/hooks/hookSystem.test.ts b/packages/core/src/hooks/hookSystem.test.ts index 0969a204f0..d4e1edd998 100644 --- a/packages/core/src/hooks/hookSystem.test.ts +++ b/packages/core/src/hooks/hookSystem.test.ts @@ -21,9 +21,9 @@ type MockChildProcessWithoutNullStreams = ChildProcessWithoutNullStreams & { // Mock child_process with importOriginal for partial mocking vi.mock('node:child_process', async (importOriginal) => { - const actual = (await importOriginal()) as object; + const actual = await importOriginal(); return { - ...actual, + ...(actual as object), spawn: vi.fn(), }; }); diff --git a/packages/core/src/ide/ide-installer.test.ts b/packages/core/src/ide/ide-installer.test.ts index ff19e6be2b..4ca07dd419 100644 --- a/packages/core/src/ide/ide-installer.test.ts +++ b/packages/core/src/ide/ide-installer.test.ts @@ -7,10 +7,9 @@ import { vi } from 'vitest'; vi.mock('node:child_process', async (importOriginal) => { - const actual = - (await importOriginal()) as typeof import('node:child_process'); + const actual = await importOriginal(); return { - ...actual, + ...(actual as object), execSync: vi.fn(), spawnSync: vi.fn(() => ({ status: 0 })), }; diff --git a/packages/core/src/mcp/oauth-provider.ts b/packages/core/src/mcp/oauth-provider.ts index 06f5a95cf8..6c20745843 100644 --- a/packages/core/src/mcp/oauth-provider.ts +++ b/packages/core/src/mcp/oauth-provider.ts @@ -302,8 +302,8 @@ export class MCPOAuthProvider {

Authentication Failed

-

Error: ${(error as string).replace(//g, '>')}

-

${((url.searchParams.get('error_description') || '') as string).replace(//g, '>')}

+

Error: ${error.replace(//g, '>')}

+

${(url.searchParams.get('error_description') || '').replace(//g, '>')}

You can close this window.

diff --git a/packages/core/src/services/loopDetectionService.ts b/packages/core/src/services/loopDetectionService.ts index da4974f64d..8381165c58 100644 --- a/packages/core/src/services/loopDetectionService.ts +++ b/packages/core/src/services/loopDetectionService.ts @@ -519,7 +519,7 @@ export class LoopDetectionService { signal: AbortSignal, ): Promise | null> { try { - const result = (await this.config.getBaseLlmClient().generateJson({ + const result = await this.config.getBaseLlmClient().generateJson({ modelConfigKey: { model }, contents, schema: LOOP_DETECTION_SCHEMA, @@ -527,7 +527,7 @@ export class LoopDetectionService { abortSignal: signal, promptId: this.promptId, maxAttempts: 2, - })) as Record; + }); if ( result && diff --git a/packages/core/src/services/modelConfigService.ts b/packages/core/src/services/modelConfigService.ts index 0a642b7e61..0b86baa4ad 100644 --- a/packages/core/src/services/modelConfigService.ts +++ b/packages/core/src/services/modelConfigService.ts @@ -258,10 +258,7 @@ export class ModelConfigService { // TODO(joshualitt): Consider knobs here, i.e. opt-in to deep merging // arrays on a case-by-case basis. if (this.isObject(accValue) && this.isObject(objValue)) { - acc[key] = this.deepMerge( - accValue as Record, - objValue as Record, - ); + acc[key] = this.deepMerge(accValue, objValue); } else { acc[key] = objValue; } diff --git a/packages/core/src/services/shellExecutionService.test.ts b/packages/core/src/services/shellExecutionService.test.ts index 09a2ce0750..39a708a1b0 100644 --- a/packages/core/src/services/shellExecutionService.test.ts +++ b/packages/core/src/services/shellExecutionService.test.ts @@ -36,10 +36,9 @@ vi.mock('@lydell/node-pty', () => ({ spawn: mockPtySpawn, })); vi.mock('node:child_process', async (importOriginal) => { - const actual = - (await importOriginal()) as typeof import('node:child_process'); + const actual = await importOriginal(); return { - ...actual, + ...(actual as object), spawn: mockCpSpawn, }; }); @@ -90,7 +89,7 @@ const createMockSerializeTerminalToObjectReturnValue = ( text: string | string[], ): AnsiOutput => { const lines = Array.isArray(text) ? text : text.split('\n'); - const len = (shellExecutionConfig.terminalHeight ?? 24) as number; + const len = shellExecutionConfig.terminalHeight ?? 24; const expected: AnsiOutput = Array.from({ length: len }, (_, i) => [ { text: (lines[i] || '').trim(), @@ -108,7 +107,7 @@ const createMockSerializeTerminalToObjectReturnValue = ( const createExpectedAnsiOutput = (text: string | string[]): AnsiOutput => { const lines = Array.isArray(text) ? text : text.split('\n'); - const len = (shellExecutionConfig.terminalHeight ?? 24) as number; + const len = shellExecutionConfig.terminalHeight ?? 24; const expected: AnsiOutput = Array.from({ length: len }, (_, i) => [ { text: expect.stringMatching((lines[i] || '').trim()), @@ -419,7 +418,7 @@ describe('ShellExecutionService', () => { it('should write to the pty and trigger a render', async () => { vi.useFakeTimers(); await simulateExecution('interactive-app', (pty) => { - ShellExecutionService.writeToPty(pty.pid!, 'input'); + ShellExecutionService.writeToPty(pty.pid, 'input'); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }); @@ -434,7 +433,7 @@ describe('ShellExecutionService', () => { it('should resize the pty and the headless terminal', async () => { await simulateExecution('ls -l', (pty) => { pty.onData.mock.calls[0][0]('file1.txt\n'); - ShellExecutionService.resizePty(pty.pid!, 100, 40); + ShellExecutionService.resizePty(pty.pid, 100, 40); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }); @@ -448,7 +447,7 @@ describe('ShellExecutionService', () => { .mockReturnValue(false); await simulateExecution('ls -l', (pty) => { - ShellExecutionService.resizePty(pty.pid!, 100, 40); + ShellExecutionService.resizePty(pty.pid, 100, 40); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }); @@ -468,7 +467,7 @@ describe('ShellExecutionService', () => { // We don't expect this test to throw an error await expect( simulateExecution('ls -l', (pty) => { - ShellExecutionService.resizePty(pty.pid!, 100, 40); + ShellExecutionService.resizePty(pty.pid, 100, 40); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }), ).resolves.not.toThrow(); @@ -484,7 +483,7 @@ describe('ShellExecutionService', () => { await expect( simulateExecution('ls -l', (pty) => { - ShellExecutionService.resizePty(pty.pid!, 100, 40); + ShellExecutionService.resizePty(pty.pid, 100, 40); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }), ).rejects.toThrow('Some other error'); @@ -493,7 +492,7 @@ describe('ShellExecutionService', () => { it('should scroll the headless terminal', async () => { await simulateExecution('ls -l', (pty) => { pty.onData.mock.calls[0][0]('file1.txt\n'); - ShellExecutionService.scrollPty(pty.pid!, 10); + ShellExecutionService.scrollPty(pty.pid, 10); pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null }); }); diff --git a/packages/core/src/services/shellExecutionService.ts b/packages/core/src/services/shellExecutionService.ts index f917a2999b..a1ffc5c7f7 100644 --- a/packages/core/src/services/shellExecutionService.ts +++ b/packages/core/src/services/shellExecutionService.ts @@ -715,9 +715,7 @@ export class ShellExecutionService { error, aborted: abortSignal.aborted, pid: ptyProcess.pid, - executionMethod: - (ptyInfo?.name as 'node-pty' | 'lydell-node-pty') ?? - 'node-pty', + executionMethod: ptyInfo?.name ?? 'node-pty', }); }; diff --git a/packages/core/src/telemetry/activity-detector.test.ts b/packages/core/src/telemetry/activity-detector.test.ts index dd5d56e5a9..6d3948daf6 100644 --- a/packages/core/src/telemetry/activity-detector.test.ts +++ b/packages/core/src/telemetry/activity-detector.test.ts @@ -136,7 +136,7 @@ describe('Global Activity Detector Functions', () => { vi.useRealTimers(); }); it('should record activity on existing detector', () => { - const detector = getActivityDetector()!; + const detector = getActivityDetector(); const beforeTime = detector.getLastActivityTime(); vi.advanceTimersByTime(100); diff --git a/packages/core/src/telemetry/config.ts b/packages/core/src/telemetry/config.ts index 5569d4137a..bd7cbdf09c 100644 --- a/packages/core/src/telemetry/config.ts +++ b/packages/core/src/telemetry/config.ts @@ -61,7 +61,7 @@ export async function resolveTelemetrySettings(options: { settings.enabled; const rawTarget = - (argv.telemetryTarget as string | TelemetryTarget | undefined) ?? + argv.telemetryTarget ?? env['GEMINI_TELEMETRY_TARGET'] ?? (settings.target as string | TelemetryTarget | undefined); const target = parseTelemetryTargetValue(rawTarget); @@ -80,7 +80,7 @@ export async function resolveTelemetrySettings(options: { settings.otlpEndpoint; const rawProtocol = - (argv.telemetryOtlpProtocol as string | undefined) ?? + argv.telemetryOtlpProtocol ?? env['GEMINI_TELEMETRY_OTLP_PROTOCOL'] ?? settings.otlpProtocol; const otlpProtocol = (['grpc', 'http'] as const).find( diff --git a/packages/core/src/telemetry/metrics.test.ts b/packages/core/src/telemetry/metrics.test.ts index e86f814240..9ec20e4100 100644 --- a/packages/core/src/telemetry/metrics.test.ts +++ b/packages/core/src/telemetry/metrics.test.ts @@ -101,7 +101,7 @@ describe('Telemetry Metrics', () => { vi.resetModules(); vi.doMock('@opentelemetry/api', () => { const actualApi = originalOtelMockFactory(); - (actualApi.metrics.getMeter as Mock).mockReturnValue(mockMeterInstance); + actualApi.metrics.getMeter.mockReturnValue(mockMeterInstance); return actualApi; }); diff --git a/packages/core/src/telemetry/startupProfiler.test.ts b/packages/core/src/telemetry/startupProfiler.test.ts index 5a45974862..ff22abda62 100644 --- a/packages/core/src/telemetry/startupProfiler.test.ts +++ b/packages/core/src/telemetry/startupProfiler.test.ts @@ -291,8 +291,7 @@ describe('StartupProfiler', () => { profiler.flush(mockConfig); - const calls = (recordStartupPerformance as ReturnType).mock - .calls; + const calls = recordStartupPerformance.mock.calls; const outerCall = calls.find((call) => call[2].phase === 'outer'); const innerCall = calls.find((call) => call[2].phase === 'inner'); diff --git a/packages/core/src/telemetry/trace.ts b/packages/core/src/telemetry/trace.ts index 3c84a3b675..d44625bf92 100644 --- a/packages/core/src/telemetry/trace.ts +++ b/packages/core/src/telemetry/trace.ts @@ -88,7 +88,7 @@ export async function runInDevTraceSpan( span.setAttribute('output-json', safeJsonStringify(meta.output)); } for (const [key, value] of Object.entries(meta.attributes)) { - span.setAttribute(key, value as AttributeValue); + span.setAttribute(key, value); } if (meta.error) { span.setStatus({ diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index 1368967719..701bd09fcb 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -15,7 +15,6 @@ import type { ApprovalMode } from '../policy/types.js'; import type { CompletedToolCall } from '../core/coreToolScheduler.js'; import { DiscoveredMCPTool } from '../tools/mcp-tool.js'; -import type { FileDiff } from '../tools/tools.js'; import { AuthType } from '../core/contentGenerator.js'; import type { LogAttributes, LogRecord } from '@opentelemetry/api-logs'; import { @@ -115,9 +114,7 @@ export class StartSessionEvent implements BaseTelemetryEvent { .getAllTools() .filter((tool) => tool instanceof DiscoveredMCPTool); this.mcp_tools_count = mcpTools.length; - this.mcp_tools = mcpTools - .map((tool) => (tool as DiscoveredMCPTool).name) - .join(','); + this.mcp_tools = mcpTools.map((tool) => tool.name).join(','); } } @@ -299,7 +296,7 @@ export class ToolCallEvent implements BaseTelemetryEvent { call.response.resultDisplay !== null && 'diffStat' in call.response.resultDisplay ) { - const diffStat = (call.response.resultDisplay as FileDiff).diffStat; + const diffStat = call.response.resultDisplay.diffStat; if (diffStat) { this.metadata = { model_added_lines: diffStat.model_added_lines, diff --git a/packages/core/src/test-utils/mock-message-bus.ts b/packages/core/src/test-utils/mock-message-bus.ts index 3423cc3dcf..7c494c343b 100644 --- a/packages/core/src/test-utils/mock-message-bus.ts +++ b/packages/core/src/test-utils/mock-message-bus.ts @@ -33,12 +33,12 @@ export class MockMessageBus { // Capture hook-specific messages if (message.type === MessageBusType.HOOK_EXECUTION_REQUEST) { - this.hookRequests.push(message as HookExecutionRequest); + this.hookRequests.push(message); // Auto-respond with success for testing const response: HookExecutionResponse = { type: MessageBusType.HOOK_EXECUTION_RESPONSE, - correlationId: (message as HookExecutionRequest).correlationId, + correlationId: message.correlationId, success: true, output: { decision: 'allow', diff --git a/packages/core/src/tools/edit.test.ts b/packages/core/src/tools/edit.test.ts index 1f301c2129..e02abecaaf 100644 --- a/packages/core/src/tools/edit.test.ts +++ b/packages/core/src/tools/edit.test.ts @@ -156,12 +156,12 @@ describe('EditTool', () => { const problematicSnippet = snippetMatch && snippetMatch[1] ? snippetMatch[1] : ''; - if (((schema as any).properties as any)?.corrected_target_snippet) { + if ((schema as any).properties?.corrected_target_snippet) { return Promise.resolve({ corrected_target_snippet: problematicSnippet, }); } - if (((schema as any).properties as any)?.corrected_new_string) { + if ((schema as any).properties?.corrected_new_string) { // For new_string correction, we might need more sophisticated logic, // but for now, returning original is a safe default if not specified by a test. const originalNewStringMatch = promptText.match( diff --git a/packages/core/src/tools/grep.ts b/packages/core/src/tools/grep.ts index 3d492bec41..0df4dc5ec4 100644 --- a/packages/core/src/tools/grep.ts +++ b/packages/core/src/tools/grep.ts @@ -523,7 +523,7 @@ class GrepToolInvocation extends BaseToolInvocation< const allMatches: GrepMatch[] = []; for await (const filePath of filesStream) { - const fileAbsolutePath = filePath as string; + const fileAbsolutePath = filePath; try { const content = await fsPromises.readFile(fileAbsolutePath, 'utf8'); const lines = content.split(/\r?\n/); diff --git a/packages/core/src/tools/modifiable-tool.ts b/packages/core/src/tools/modifiable-tool.ts index 47463235a1..328158bb78 100644 --- a/packages/core/src/tools/modifiable-tool.ts +++ b/packages/core/src/tools/modifiable-tool.ts @@ -184,11 +184,11 @@ export async function modifyWithEditor( overrides !== undefined && 'proposedContent' in overrides; const currentContent = hasCurrentOverride - ? (overrides!.currentContent ?? '') + ? (overrides.currentContent ?? '') : await modifyContext.getCurrentContent(originalParams); const proposedContent = hasProposedOverride - ? (overrides!.proposedContent ?? '') + ? (overrides.proposedContent ?? '') : await modifyContext.getProposedContent(originalParams); const { oldPath, newPath, dirPath } = createTempFilesForModify( diff --git a/packages/core/src/tools/read-file.test.ts b/packages/core/src/tools/read-file.test.ts index ccc07fd283..a01c4a5261 100644 --- a/packages/core/src/tools/read-file.test.ts +++ b/packages/core/src/tools/read-file.test.ts @@ -16,7 +16,6 @@ import type { Config } from '../config/config.js'; import { FileDiscoveryService } from '../services/fileDiscoveryService.js'; import { StandardFileSystemService } from '../services/fileSystemService.js'; import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js'; -import type { ToolInvocation, ToolResult } from './tools.js'; import { WorkspaceContext } from '../utils/workspaceContext.js'; vi.mock('../telemetry/loggers.js', () => ({ @@ -72,10 +71,7 @@ describe('ReadFileTool', () => { }; const result = tool.build(params); expect(typeof result).not.toBe('string'); - const invocation = result as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = result; expect(invocation.toolLocations()[0].path).toBe( path.join(tempRootDir, 'test.txt'), ); @@ -146,11 +142,9 @@ describe('ReadFileTool', () => { }; const invocation = tool.build(params); expect(typeof invocation).not.toBe('string'); - expect( - ( - invocation as ToolInvocation - ).getDescription(), - ).toBe(path.join('sub', 'dir', 'file.txt')); + expect(invocation.getDescription()).toBe( + path.join('sub', 'dir', 'file.txt'), + ); }); it('should return shortened path when file path is deep', () => { @@ -170,9 +164,7 @@ describe('ReadFileTool', () => { const params: ReadFileToolParams = { file_path: deepPath }; const invocation = tool.build(params); expect(typeof invocation).not.toBe('string'); - const desc = ( - invocation as ToolInvocation - ).getDescription(); + const desc = invocation.getDescription(); expect(desc).toContain('...'); expect(desc).toContain('file.txt'); }); @@ -184,22 +176,16 @@ describe('ReadFileTool', () => { }; const invocation = tool.build(params); expect(typeof invocation).not.toBe('string'); - expect( - ( - invocation as ToolInvocation - ).getDescription(), - ).toBe(path.join('sub', 'dir', 'file.txt')); + expect(invocation.getDescription()).toBe( + path.join('sub', 'dir', 'file.txt'), + ); }); it('should return . if path is the root directory', () => { const params: ReadFileToolParams = { file_path: tempRootDir }; const invocation = tool.build(params); expect(typeof invocation).not.toBe('string'); - expect( - ( - invocation as ToolInvocation - ).getDescription(), - ).toBe('.'); + expect(invocation.getDescription()).toBe('.'); }); }); @@ -209,10 +195,7 @@ describe('ReadFileTool', () => { const fileContent = 'This is a test file.'; await fsp.writeFile(filePath, fileContent, 'utf-8'); const params: ReadFileToolParams = { file_path: 'textfile.txt' }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); expect(await invocation.execute(abortSignal)).toEqual({ llmContent: fileContent, @@ -223,10 +206,7 @@ describe('ReadFileTool', () => { it('should return error if file does not exist', async () => { const filePath = path.join(tempRootDir, 'nonexistent.txt'); const params: ReadFileToolParams = { file_path: filePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result).toEqual({ @@ -245,10 +225,7 @@ describe('ReadFileTool', () => { const fileContent = 'This is a test file.'; await fsp.writeFile(filePath, fileContent, 'utf-8'); const params: ReadFileToolParams = { file_path: filePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); expect(await invocation.execute(abortSignal)).toEqual({ llmContent: fileContent, @@ -260,10 +237,7 @@ describe('ReadFileTool', () => { const dirPath = path.join(tempRootDir, 'directory'); await fsp.mkdir(dirPath); const params: ReadFileToolParams = { file_path: dirPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result).toEqual({ @@ -283,10 +257,7 @@ describe('ReadFileTool', () => { const largeContent = 'x'.repeat(21 * 1024 * 1024); await fsp.writeFile(filePath, largeContent, 'utf-8'); const params: ReadFileToolParams = { file_path: filePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result).toHaveProperty('error'); @@ -302,10 +273,7 @@ describe('ReadFileTool', () => { const fileContent = `Short line\n${longLine}\nAnother short line`; await fsp.writeFile(filePath, fileContent, 'utf-8'); const params: ReadFileToolParams = { file_path: filePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toContain( @@ -323,10 +291,7 @@ describe('ReadFileTool', () => { ]); await fsp.writeFile(imagePath, pngHeader); const params: ReadFileToolParams = { file_path: imagePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toEqual({ @@ -344,10 +309,7 @@ describe('ReadFileTool', () => { const pdfHeader = Buffer.from('%PDF-1.4'); await fsp.writeFile(pdfPath, pdfHeader); const params: ReadFileToolParams = { file_path: pdfPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toEqual({ @@ -365,10 +327,7 @@ describe('ReadFileTool', () => { const binaryData = Buffer.from([0x00, 0xff, 0x00, 0xff]); await fsp.writeFile(binPath, binaryData); const params: ReadFileToolParams = { file_path: binPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toBe( @@ -382,10 +341,7 @@ describe('ReadFileTool', () => { const svgContent = ''; await fsp.writeFile(svgPath, svgContent, 'utf-8'); const params: ReadFileToolParams = { file_path: svgPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toBe(svgContent); @@ -398,10 +354,7 @@ describe('ReadFileTool', () => { const largeContent = '' + 'x'.repeat(1024 * 1024 + 1) + ''; await fsp.writeFile(svgPath, largeContent, 'utf-8'); const params: ReadFileToolParams = { file_path: svgPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toBe( @@ -416,10 +369,7 @@ describe('ReadFileTool', () => { const emptyPath = path.join(tempRootDir, 'empty.txt'); await fsp.writeFile(emptyPath, '', 'utf-8'); const params: ReadFileToolParams = { file_path: emptyPath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toBe(''); @@ -437,10 +387,7 @@ describe('ReadFileTool', () => { offset: 5, // Start from line 6 limit: 3, }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toContain( @@ -465,10 +412,7 @@ describe('ReadFileTool', () => { await fsp.writeFile(tempFilePath, tempFileContent, 'utf-8'); const params: ReadFileToolParams = { file_path: tempFilePath }; - const invocation = tool.build(params) as ToolInvocation< - ReadFileToolParams, - ToolResult - >; + const invocation = tool.build(params); const result = await invocation.execute(abortSignal); expect(result.llmContent).toBe(tempFileContent); diff --git a/packages/core/src/tools/smart-edit.test.ts b/packages/core/src/tools/smart-edit.test.ts index 2a003f0b8a..01232d7db5 100644 --- a/packages/core/src/tools/smart-edit.test.ts +++ b/packages/core/src/tools/smart-edit.test.ts @@ -147,12 +147,12 @@ describe('SmartEditTool', () => { const problematicSnippet = snippetMatch && snippetMatch[1] ? snippetMatch[1] : ''; - if (((schema as any).properties as any)?.corrected_target_snippet) { + if ((schema as any).properties?.corrected_target_snippet) { return Promise.resolve({ corrected_target_snippet: problematicSnippet, }); } - if (((schema as any).properties as any)?.corrected_new_string) { + if ((schema as any).properties?.corrected_new_string) { const originalNewStringMatch = promptText.match( /original_new_string \(what was intended to replace original_old_string\):\n```\n([\s\S]*?)\n```/, ); diff --git a/packages/core/src/tools/write-file.test.ts b/packages/core/src/tools/write-file.test.ts index 3cb0f7e741..9d7e32a0ac 100644 --- a/packages/core/src/tools/write-file.test.ts +++ b/packages/core/src/tools/write-file.test.ts @@ -536,7 +536,7 @@ describe('WriteFileTool', () => { expect(confirmation.onConfirm).toBeDefined(); // Call `onConfirm` to trigger the logic that updates the content - await confirmation.onConfirm!(ToolConfirmationOutcome.ProceedOnce); + await confirmation.onConfirm(ToolConfirmationOutcome.ProceedOnce); // Now, check if the original `params` object (captured by the invocation) was modified expect(invocation.params.content).toBe('ide-modified-content'); diff --git a/packages/core/src/utils/checkpointUtils.ts b/packages/core/src/utils/checkpointUtils.ts index 5508531185..96e1185c37 100644 --- a/packages/core/src/utils/checkpointUtils.ts +++ b/packages/core/src/utils/checkpointUtils.ts @@ -48,7 +48,7 @@ export function getToolCallDataSchema(historyItemSchema?: z.ZodTypeAny) { export function generateCheckpointFileName( toolCall: ToolCallRequestInfo, ): string | null { - const toolArgs = toolCall.args as Record; + const toolArgs = toolCall.args; const toolFilePath = toolArgs['file_path'] as string; if (!toolFilePath) { diff --git a/packages/core/src/utils/filesearch/crawlCache.ts b/packages/core/src/utils/filesearch/crawlCache.ts index b905c9dfc3..f9c2df3c88 100644 --- a/packages/core/src/utils/filesearch/crawlCache.ts +++ b/packages/core/src/utils/filesearch/crawlCache.ts @@ -40,7 +40,7 @@ export const read = (key: string): string[] | undefined => crawlCache.get(key); export const write = (key: string, results: string[], ttlMs: number): void => { // Clear any existing timer for this key to prevent premature deletion if (cacheTimers.has(key)) { - clearTimeout(cacheTimers.get(key)!); + clearTimeout(cacheTimers.get(key)); } // Store the new data diff --git a/packages/core/src/utils/filesearch/fileSearch.ts b/packages/core/src/utils/filesearch/fileSearch.ts index d81e023824..6cd82b75a3 100644 --- a/packages/core/src/utils/filesearch/fileSearch.ts +++ b/packages/core/src/utils/filesearch/fileSearch.ts @@ -129,7 +129,7 @@ class RecursiveFileSearch implements FileSearch { let filteredCandidates; const { files: candidates, isExactMatch } = - await this.resultCache!.get(pattern); + await this.resultCache.get(pattern); if (isExactMatch) { // Use the cached result. @@ -151,7 +151,7 @@ class RecursiveFileSearch implements FileSearch { } if (shouldCache) { - this.resultCache!.set(pattern, filteredCandidates); + this.resultCache.set(pattern, filteredCandidates); } } diff --git a/packages/core/src/utils/tool-utils.ts b/packages/core/src/utils/tool-utils.ts index ebf73f90bd..45c6cbe665 100644 --- a/packages/core/src/utils/tool-utils.ts +++ b/packages/core/src/utils/tool-utils.ts @@ -29,7 +29,7 @@ export function doesToolInvocationMatch( if (isTool(toolOrToolName)) { toolNames = [toolOrToolName.name, toolOrToolName.constructor.name]; } else { - toolNames = [toolOrToolName as string]; + toolNames = [toolOrToolName]; } if (toolNames.some((name) => SHELL_TOOL_NAMES.includes(name))) { diff --git a/packages/test-utils/src/file-system-test-helpers.ts b/packages/test-utils/src/file-system-test-helpers.ts index 0824211b20..43ce6a5d1b 100644 --- a/packages/test-utils/src/file-system-test-helpers.ts +++ b/packages/test-utils/src/file-system-test-helpers.ts @@ -66,12 +66,12 @@ async function create(dir: string, structure: FileSystemStructure) { if (typeof item === 'string') { await fs.writeFile(path.join(newPath, item), ''); } else { - await create(newPath, item as FileSystemStructure); + await create(newPath, item); } } } else if (typeof content === 'object' && content !== null) { await fs.mkdir(newPath, { recursive: true }); - await create(newPath, content as FileSystemStructure); + await create(newPath, content); } } }