From fd65416a2ffa3ade06bc793a7e0aa04fd5af0555 Mon Sep 17 00:00:00 2001 From: Christian Gunderman Date: Tue, 10 Feb 2026 00:10:15 +0000 Subject: [PATCH] Disallow unsafe type assertions (#18688) --- eslint.config.js | 8 +++++ packages/a2a-server/src/agent/executor.ts | 4 +++ packages/a2a-server/src/agent/task.ts | 11 ++++++- packages/a2a-server/src/commands/init.ts | 1 + packages/a2a-server/src/config/config.ts | 1 + packages/a2a-server/src/config/extension.ts | 3 ++ packages/a2a-server/src/config/settings.ts | 4 +++ packages/a2a-server/src/http/app.ts | 2 ++ packages/a2a-server/src/persistence/gcs.ts | 1 + packages/a2a-server/src/types.ts | 1 + .../a2a-server/src/utils/testing_utils.ts | 7 +++++ .../cli/src/commands/extensions/configure.ts | 3 ++ .../cli/src/commands/extensions/disable.ts | 2 ++ .../cli/src/commands/extensions/enable.ts | 2 ++ .../cli/src/commands/extensions/install.ts | 5 ++++ packages/cli/src/commands/extensions/link.ts | 2 ++ packages/cli/src/commands/extensions/list.ts | 1 + packages/cli/src/commands/extensions/new.ts | 2 ++ .../cli/src/commands/extensions/uninstall.ts | 1 + .../cli/src/commands/extensions/update.ts | 2 ++ .../cli/src/commands/extensions/validate.ts | 1 + packages/cli/src/commands/hooks/migrate.ts | 7 +++++ packages/cli/src/commands/mcp/add.ts | 14 +++++++++ packages/cli/src/commands/mcp/remove.ts | 2 ++ packages/cli/src/commands/skills/disable.ts | 1 + packages/cli/src/commands/skills/enable.ts | 1 + packages/cli/src/commands/skills/install.ts | 4 +++ packages/cli/src/commands/skills/link.ts | 3 ++ packages/cli/src/commands/skills/list.ts | 2 ++ packages/cli/src/commands/skills/uninstall.ts | 2 ++ packages/cli/src/config/config.ts | 7 +++++ .../config/extension-manager-themes.spec.ts | 2 ++ packages/cli/src/config/extension-manager.ts | 6 ++++ packages/cli/src/config/extension.ts | 1 + .../cli/src/config/extensionRegistryClient.ts | 1 + .../cli/src/config/extensions/github_fetch.ts | 1 + .../cli/src/config/extensions/variables.ts | 4 +++ .../cli/src/config/mcp/mcpServerEnablement.ts | 1 + .../cli/src/config/settings-validation.ts | 6 +++- packages/cli/src/config/settings.ts | 15 ++++++++++ packages/cli/src/config/trustedFolders.ts | 3 ++ packages/cli/src/deferred.ts | 2 ++ packages/cli/src/gemini.tsx | 1 + packages/cli/src/nonInteractiveCli.ts | 2 ++ .../cli/src/services/FileCommandLoader.ts | 1 + packages/cli/src/test-utils/customMatchers.ts | 3 +- .../cli/src/test-utils/mockCommandContext.ts | 4 +++ packages/cli/src/test-utils/mockConfig.ts | 3 ++ packages/cli/src/test-utils/render.tsx | 13 ++++++++ packages/cli/src/test-utils/settings.ts | 5 ++++ packages/cli/src/ui/AppContainer.tsx | 2 ++ packages/cli/src/ui/auth/AuthDialog.tsx | 2 ++ packages/cli/src/ui/auth/useAuth.ts | 1 + packages/cli/src/ui/commands/chatCommand.ts | 1 + .../cli/src/ui/commands/directoryCommand.tsx | 1 + packages/cli/src/ui/commands/initCommand.ts | 1 + packages/cli/src/ui/commands/memoryCommand.ts | 1 + .../src/ui/components/AgentConfigDialog.tsx | 9 ++++++ .../ui/components/EditorSettingsDialog.tsx | 1 + .../ui/components/MultiFolderTrustDialog.tsx | 1 + .../cli/src/ui/components/SettingsDialog.tsx | 5 ++++ packages/cli/src/ui/components/Table.tsx | 1 + .../components/messages/ToolResultDisplay.tsx | 5 ++++ .../src/ui/components/shared/Scrollable.tsx | 1 + .../ui/components/shared/ScrollableList.tsx | 2 ++ .../ui/components/shared/VirtualizedList.tsx | 1 + .../ui/components/triage/TriageDuplicates.tsx | 2 ++ .../src/ui/components/triage/TriageIssues.tsx | 1 + .../src/ui/editors/editorSettingsManager.ts | 1 + .../cli/src/ui/hooks/slashCommandProcessor.ts | 3 ++ .../src/ui/hooks/useApprovalModeIndicator.ts | 1 + packages/cli/src/ui/hooks/useGeminiStream.ts | 16 +++++----- .../cli/src/ui/hooks/useHistoryManager.ts | 2 ++ .../cli/src/ui/hooks/useIncludeDirsTrust.tsx | 1 + .../cli/src/ui/hooks/usePrivacySettings.ts | 1 + .../cli/src/ui/hooks/useReactToolScheduler.ts | 1 + packages/cli/src/ui/keyMatchers.ts | 1 + packages/cli/src/ui/themes/theme-manager.ts | 1 + packages/cli/src/ui/utils/CodeColorizer.tsx | 1 + packages/cli/src/ui/utils/commandUtils.ts | 3 ++ packages/cli/src/ui/utils/rewindFileOps.ts | 1 + packages/cli/src/ui/utils/terminalSetup.ts | 2 ++ packages/cli/src/ui/utils/textUtils.ts | 4 +++ packages/cli/src/utils/activityLogger.ts | 5 +++- packages/cli/src/utils/commentJson.ts | 5 ++++ packages/cli/src/utils/deepMerge.ts | 1 + packages/cli/src/utils/envVarResolver.ts | 3 ++ packages/cli/src/utils/errors.ts | 1 + packages/cli/src/utils/sessionCleanup.ts | 2 ++ packages/cli/src/utils/sessionUtils.ts | 4 ++- packages/cli/src/utils/settingsUtils.ts | 4 +++ .../cli/src/zed-integration/zedIntegration.ts | 1 + packages/core/src/agents/agentLoader.ts | 4 +++ packages/core/src/agents/local-executor.ts | 2 ++ packages/core/src/availability/testUtils.ts | 1 + packages/core/src/code_assist/converter.ts | 1 + .../code_assist/experiments/experiments.ts | 1 + .../code_assist/oauth-credential-storage.ts | 1 + packages/core/src/code_assist/oauth2.ts | 2 ++ packages/core/src/code_assist/server.ts | 6 ++++ packages/core/src/commands/restore.ts | 1 + .../core/src/confirmation-bus/message-bus.ts | 2 +- .../core/src/core/coreToolHookTriggers.ts | 1 + packages/core/src/core/coreToolScheduler.ts | 13 ++++++++ .../core/src/core/fakeContentGenerator.ts | 2 ++ packages/core/src/core/geminiChat.ts | 3 ++ packages/core/src/core/logger.ts | 10 +++++++ .../core/src/core/loggingContentGenerator.ts | 3 +- .../src/core/recordingContentGenerator.ts | 2 ++ packages/core/src/core/turn.ts | 3 +- packages/core/src/hooks/hookAggregator.ts | 1 + packages/core/src/hooks/hookRegistry.ts | 2 ++ packages/core/src/hooks/hookRunner.ts | 8 +++++ packages/core/src/hooks/hookSystem.ts | 3 ++ packages/core/src/hooks/hookTranslator.ts | 7 ++++- packages/core/src/hooks/trustedHooks.ts | 2 ++ packages/core/src/hooks/types.ts | 7 +++++ packages/core/src/ide/ide-connection-utils.ts | 2 ++ packages/core/src/mcp/oauth-provider.ts | 4 +++ packages/core/src/mcp/oauth-token-storage.ts | 3 ++ packages/core/src/mcp/oauth-utils.ts | 2 ++ .../core/src/mcp/sa-impersonation-provider.ts | 1 + .../mcp/token-storage/file-token-storage.ts | 4 +++ .../token-storage/keychain-token-storage.ts | 3 ++ packages/core/src/policy/config.ts | 2 ++ packages/core/src/policy/policy-engine.ts | 1 + packages/core/src/policy/stable-stringify.ts | 1 + packages/core/src/policy/toml-loader.ts | 6 ++++ packages/core/src/policy/types.ts | 2 ++ packages/core/src/prompts/promptProvider.ts | 10 +++---- .../routing/strategies/compositeStrategy.ts | 1 + packages/core/src/safety/built-in.ts | 1 + packages/core/src/safety/context-builder.ts | 4 ++- packages/core/src/scheduler/confirmation.ts | 4 +++ packages/core/src/scheduler/scheduler.ts | 1 + packages/core/src/scheduler/state-manager.ts | 2 ++ packages/core/src/scheduler/tool-modifier.ts | 2 ++ .../core/src/services/chatRecordingService.ts | 3 ++ .../core/src/services/loopDetectionService.ts | 4 ++- .../core/src/services/modelConfigService.ts | 5 ++++ .../services/modelConfigServiceTestUtils.ts | 1 + .../src/services/shellExecutionService.ts | 4 +++ .../src/services/toolOutputMaskingService.ts | 3 ++ packages/core/src/skills/skillLoader.ts | 1 + .../core/src/telemetry/activity-monitor.ts | 1 + .../clearcut-logger/clearcut-logger.ts | 2 ++ packages/core/src/telemetry/gcp-exporters.ts | 1 + .../telemetry/integration.test.circular.ts | 3 +- .../src/telemetry/loggers.test.circular.ts | 2 ++ packages/core/src/telemetry/loggers.ts | 4 +++ packages/core/src/telemetry/metrics.ts | 30 +++++++++++++++++++ packages/core/src/telemetry/semantic.ts | 4 +++ packages/core/src/telemetry/types.ts | 1 + .../core/src/test-utils/mock-message-bus.ts | 4 +++ .../src/test-utils/mockWorkspaceContext.ts | 1 + packages/core/src/tools/activate-skill.ts | 1 + packages/core/src/tools/mcp-client.ts | 9 +++++- packages/core/src/tools/mcp-tool.ts | 2 ++ packages/core/src/tools/memoryTool.ts | 1 + packages/core/src/tools/tool-registry.ts | 6 ++++ packages/core/src/tools/tools.ts | 5 ++++ packages/core/src/tools/web-fetch.ts | 2 ++ packages/core/src/tools/web-search.ts | 1 + .../core/src/tools/xcode-mcp-fix-transport.ts | 2 +- packages/core/src/utils/bfsFileSearch.ts | 2 ++ packages/core/src/utils/checkpointUtils.ts | 2 ++ packages/core/src/utils/editor.ts | 9 ++++-- packages/core/src/utils/errors.ts | 3 ++ packages/core/src/utils/events.ts | 23 +++++++------- .../utils/generateContentResponseUtilities.ts | 3 ++ packages/core/src/utils/googleErrors.ts | 4 +++ packages/core/src/utils/httpErrors.ts | 7 +++-- packages/core/src/utils/llm-edit-fixer.ts | 1 + packages/core/src/utils/memoryDiscovery.ts | 6 ++++ packages/core/src/utils/nextSpeakerChecker.ts | 1 + packages/core/src/utils/partUtils.ts | 1 + .../core/src/utils/quotaErrorDetection.ts | 3 ++ packages/core/src/utils/retry.ts | 3 ++ packages/core/src/utils/safeJsonStringify.ts | 1 + packages/core/src/utils/schemaValidator.ts | 8 +++-- packages/core/src/utils/security.ts | 3 ++ packages/core/src/utils/shell-utils.ts | 1 + packages/core/src/utils/testUtils.ts | 20 +++++++++++++ packages/core/src/utils/tokenCalculation.ts | 1 + packages/core/src/utils/tool-utils.ts | 1 + packages/core/src/utils/userAccountManager.ts | 1 + .../vscode-ide-companion/src/diff-manager.ts | 1 + .../vscode-ide-companion/src/ide-server.ts | 3 ++ 188 files changed, 592 insertions(+), 47 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index f13773d11d..52620efe49 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -192,6 +192,14 @@ export default tseslint.config( ], }, }, + { + // Rules that only apply to product code + files: ['packages/*/src/**/*.{ts,tsx}'], + ignores: ['**/*.test.ts', '**/*.test.tsx'], + rules: { + '@typescript-eslint/no-unsafe-type-assertion': 'error', + }, + }, { // Allow os.homedir() in tests and paths.ts where it is used to implement the helper files: [ diff --git a/packages/a2a-server/src/agent/executor.ts b/packages/a2a-server/src/agent/executor.ts index 8464f27b43..b0522a945f 100644 --- a/packages/a2a-server/src/agent/executor.ts +++ b/packages/a2a-server/src/agent/executor.ts @@ -117,6 +117,7 @@ export class CoderAgentExecutor implements AgentExecutor { const agentSettings = persistedState._agentSettings; const config = await this.getConfig(agentSettings, sdkTask.id); const contextId: string = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (metadata['_contextId'] as string) || sdkTask.contextId; const runtimeTask = await Task.create( sdkTask.id, @@ -140,6 +141,7 @@ export class CoderAgentExecutor implements AgentExecutor { agentSettingsInput?: AgentSettings, eventBus?: ExecutionEventBus, ): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const agentSettings = agentSettingsInput || ({} as AgentSettings); const config = await this.getConfig(agentSettings, taskId); const runtimeTask = await Task.create( @@ -290,6 +292,7 @@ export class CoderAgentExecutor implements AgentExecutor { const contextId: string = userMessage.contextId || sdkTask?.contextId || + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (sdkTask?.metadata?.['_contextId'] as string) || uuidv4(); @@ -385,6 +388,7 @@ export class CoderAgentExecutor implements AgentExecutor { } } else { logger.info(`[CoderAgentExecutor] Creating new task ${taskId}.`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const agentSettings = userMessage.metadata?.[ 'coderAgent' ] as AgentSettings; diff --git a/packages/a2a-server/src/agent/task.ts b/packages/a2a-server/src/agent/task.ts index 6fefd84919..890bc85b11 100644 --- a/packages/a2a-server/src/agent/task.ts +++ b/packages/a2a-server/src/agent/task.ts @@ -378,6 +378,7 @@ export class Task { if (tc.status === 'awaiting_approval' && tc.confirmationDetails) { this.pendingToolConfirmationDetails.set( tc.request.callId, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion tc.confirmationDetails as ToolCallConfirmationDetails, ); } @@ -411,7 +412,7 @@ export class Task { ); toolCalls.forEach((tc: ToolCall) => { if (tc.status === 'awaiting_approval' && tc.confirmationDetails) { - // eslint-disable-next-line @typescript-eslint/no-floating-promises + // eslint-disable-next-line @typescript-eslint/no-floating-promises, @typescript-eslint/no-unsafe-type-assertion (tc.confirmationDetails as ToolCallConfirmationDetails).onConfirm( ToolConfirmationOutcome.ProceedOnce, ); @@ -465,12 +466,14 @@ export class Task { T extends ToolCall | AnyDeclarativeTool, K extends UnionKeys, >(from: T, ...fields: K[]): Partial { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const ret = {} as Pick; for (const field of fields) { if (field in from) { ret[field] = from[field]; } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return ret as Partial; } @@ -493,6 +496,7 @@ export class Task { ); if (tc.tool) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion serializableToolCall.tool = this._pickFields( tc.tool, 'name', @@ -622,8 +626,11 @@ export class Task { request.args['new_string'] ) { const newContent = await this.getProposedContent( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion request.args['file_path'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion request.args['old_string'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion request.args['new_string'] as string, ); return { ...request, args: { ...request.args, newContent } }; @@ -719,6 +726,7 @@ export class Task { case GeminiEventType.Error: default: { // Block scope for lexical declaration + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const errorEvent = event as ServerGeminiErrorEvent; // Type assertion const errorMessage = errorEvent.value?.error.message ?? 'Unknown error from LLM stream'; @@ -807,6 +815,7 @@ export class Task { if (confirmationDetails.type === 'edit') { const payload = part.data['newContent'] ? ({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion newContent: part.data['newContent'] as string, } as ToolConfirmationPayload) : undefined; diff --git a/packages/a2a-server/src/commands/init.ts b/packages/a2a-server/src/commands/init.ts index 2a78ae5f95..57697e1a24 100644 --- a/packages/a2a-server/src/commands/init.ts +++ b/packages/a2a-server/src/commands/init.ts @@ -85,6 +85,7 @@ export class InitCommand implements Command { if (!context.agentExecutor) { throw new Error('Agent executor not found in context.'); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const agentExecutor = context.agentExecutor as CoderAgentExecutor; const agentSettings: AgentSettings = { diff --git a/packages/a2a-server/src/config/config.ts b/packages/a2a-server/src/config/config.ts index 91c23d7910..48daffbe42 100644 --- a/packages/a2a-server/src/config/config.ts +++ b/packages/a2a-server/src/config/config.ts @@ -77,6 +77,7 @@ export async function loadConfig( cwd: workspaceDir, telemetry: { enabled: settings.telemetry?.enabled, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion target: settings.telemetry?.target as TelemetryTarget, otlpEndpoint: process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? diff --git a/packages/a2a-server/src/config/extension.ts b/packages/a2a-server/src/config/extension.ts index 7da0f0572e..634cb04dc3 100644 --- a/packages/a2a-server/src/config/extension.ts +++ b/packages/a2a-server/src/config/extension.ts @@ -93,6 +93,7 @@ function loadExtension(extensionDir: string): GeminiCLIExtension | null { try { const configContent = fs.readFileSync(configFilePath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const config = JSON.parse(configContent) as ExtensionConfig; if (!config.name || !config.version) { logger.error( @@ -107,6 +108,7 @@ function loadExtension(extensionDir: string): GeminiCLIExtension | null { .map((contextFileName) => path.join(extensionDir, contextFileName)) .filter((contextFilePath) => fs.existsSync(contextFilePath)); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return { name: config.name, version: config.version, @@ -140,6 +142,7 @@ export function loadInstallMetadata( const metadataFilePath = path.join(extensionDir, INSTALL_METADATA_FILENAME); try { const configContent = fs.readFileSync(metadataFilePath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const metadata = JSON.parse(configContent) as ExtensionInstallMetadata; return metadata; } catch (e) { diff --git a/packages/a2a-server/src/config/settings.ts b/packages/a2a-server/src/config/settings.ts index 5538576dc7..8d15247128 100644 --- a/packages/a2a-server/src/config/settings.ts +++ b/packages/a2a-server/src/config/settings.ts @@ -67,6 +67,7 @@ export function loadSettings(workspaceDir: string): Settings { try { if (fs.existsSync(USER_SETTINGS_PATH)) { const userContent = fs.readFileSync(USER_SETTINGS_PATH, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const parsedUserSettings = JSON.parse( stripJsonComments(userContent), ) as Settings; @@ -89,6 +90,7 @@ export function loadSettings(workspaceDir: string): Settings { try { if (fs.existsSync(workspaceSettingsPath)) { const projectContent = fs.readFileSync(workspaceSettingsPath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const parsedWorkspaceSettings = JSON.parse( stripJsonComments(projectContent), ) as Settings; @@ -139,10 +141,12 @@ function resolveEnvVarsInObject(obj: T): T { } if (typeof obj === 'string') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return resolveEnvVarsInString(obj) as unknown as T; } if (Array.isArray(obj)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return obj.map((item) => resolveEnvVarsInObject(item)) as unknown as T; } diff --git a/packages/a2a-server/src/http/app.ts b/packages/a2a-server/src/http/app.ts index 4b5763f00b..c061d4e3b3 100644 --- a/packages/a2a-server/src/http/app.ts +++ b/packages/a2a-server/src/http/app.ts @@ -118,6 +118,7 @@ async function handleExecuteCommand( const eventHandler = (event: AgentExecutionEvent) => { const jsonRpcResponse = { jsonrpc: '2.0', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion id: 'taskId' in event ? event.taskId : (event as Message).messageId, result: event, }; @@ -206,6 +207,7 @@ export async function createApp() { expressApp.post('/tasks', async (req, res) => { try { const taskId = uuidv4(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const agentSettings = req.body.agentSettings as | AgentSettings | undefined; diff --git a/packages/a2a-server/src/persistence/gcs.ts b/packages/a2a-server/src/persistence/gcs.ts index 6ee9ddee23..ec6b86e56a 100644 --- a/packages/a2a-server/src/persistence/gcs.ts +++ b/packages/a2a-server/src/persistence/gcs.ts @@ -95,6 +95,7 @@ export class GCSTaskStore implements TaskStore { await this.ensureBucketInitialized(); const taskId = task.id; const persistedState = getPersistedState( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion task.metadata as PersistedTaskMetadata, ); diff --git a/packages/a2a-server/src/types.ts b/packages/a2a-server/src/types.ts index c3cfc3d85f..0ed6a67994 100644 --- a/packages/a2a-server/src/types.ts +++ b/packages/a2a-server/src/types.ts @@ -125,6 +125,7 @@ export const METADATA_KEY = '__persistedState'; export function getPersistedState( metadata: PersistedTaskMetadata, ): PersistedStateMetadata | undefined { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return metadata?.[METADATA_KEY] as PersistedStateMetadata | undefined; } diff --git a/packages/a2a-server/src/utils/testing_utils.ts b/packages/a2a-server/src/utils/testing_utils.ts index 36880fda79..74e93f8f7b 100644 --- a/packages/a2a-server/src/utils/testing_utils.ts +++ b/packages/a2a-server/src/utils/testing_utils.ts @@ -24,6 +24,7 @@ import { expect, vi } from 'vitest'; export function createMockConfig( overrides: Partial = {}, ): Partial { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getToolRegistry: vi.fn().mockReturnValue({ getTool: vi.fn(), @@ -40,6 +41,7 @@ export function createMockConfig( }), getTargetDir: () => '/test', getCheckpointingEnabled: vi.fn().mockReturnValue(false), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion storage: { getProjectTempDir: () => '/tmp', getProjectTempCheckpointsDir: () => '/tmp/checkpoints', @@ -145,6 +147,7 @@ export function assertUniqueFinalEventIsLast( events: SendStreamingMessageSuccessResponse[], ) { // Final event is input-required & final + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const finalEvent = events[events.length - 1].result as TaskStatusUpdateEvent; expect(finalEvent.metadata?.['coderAgent']).toMatchObject({ kind: 'state-change', @@ -154,9 +157,11 @@ export function assertUniqueFinalEventIsLast( // There is only one event with final and its the last expect( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion events.filter((e) => (e.result as TaskStatusUpdateEvent).final).length, ).toBe(1); expect( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion events.findIndex((e) => (e.result as TaskStatusUpdateEvent).final), ).toBe(events.length - 1); } @@ -165,11 +170,13 @@ export function assertTaskCreationAndWorkingStatus( events: SendStreamingMessageSuccessResponse[], ) { // Initial task creation event + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const taskEvent = events[0].result as SDKTask; expect(taskEvent.kind).toBe('task'); expect(taskEvent.status.state).toBe('submitted'); // Status update: working + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const workingEvent = events[1].result as TaskStatusUpdateEvent; expect(workingEvent.kind).toBe('status-update'); expect(workingEvent.status.state).toBe('working'); diff --git a/packages/cli/src/commands/extensions/configure.ts b/packages/cli/src/commands/extensions/configure.ts index ef1222c97d..a2136968b3 100644 --- a/packages/cli/src/commands/extensions/configure.ts +++ b/packages/cli/src/commands/extensions/configure.ts @@ -71,6 +71,7 @@ export const configureCommand: CommandModule = { extensionManager, name, setting, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope as ExtensionSettingScope, ); } @@ -79,6 +80,7 @@ export const configureCommand: CommandModule = { await configureExtension( extensionManager, name, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope as ExtensionSettingScope, ); } @@ -86,6 +88,7 @@ export const configureCommand: CommandModule = { else { await configureAllExtensions( extensionManager, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope as ExtensionSettingScope, ); } diff --git a/packages/cli/src/commands/extensions/disable.ts b/packages/cli/src/commands/extensions/disable.ts index 2b6a3bdc9a..cdbc6a0ed4 100644 --- a/packages/cli/src/commands/extensions/disable.ts +++ b/packages/cli/src/commands/extensions/disable.ts @@ -79,7 +79,9 @@ export const disableCommand: CommandModule = { }), handler: async (argv) => { await handleDisable({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as string, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/enable.ts b/packages/cli/src/commands/extensions/enable.ts index 55f3e596c4..e0976aa10a 100644 --- a/packages/cli/src/commands/extensions/enable.ts +++ b/packages/cli/src/commands/extensions/enable.ts @@ -105,7 +105,9 @@ export const enableCommand: CommandModule = { }), handler: async (argv) => { await handleEnable({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as string, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/install.ts b/packages/cli/src/commands/extensions/install.ts index 5830055024..b094dc63f4 100644 --- a/packages/cli/src/commands/extensions/install.ts +++ b/packages/cli/src/commands/extensions/install.ts @@ -99,10 +99,15 @@ export const installCommand: CommandModule = { }), handler: async (argv) => { await handleInstall({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion source: argv['source'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ref: argv['ref'] as string | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion autoUpdate: argv['auto-update'] as boolean | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion allowPreRelease: argv['pre-release'] as boolean | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion consent: argv['consent'] as boolean | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/link.ts b/packages/cli/src/commands/extensions/link.ts index b12b7267ce..d7c5f2fd5c 100644 --- a/packages/cli/src/commands/extensions/link.ts +++ b/packages/cli/src/commands/extensions/link.ts @@ -79,7 +79,9 @@ export const linkCommand: CommandModule = { .check((_) => true), handler: async (argv) => { await handleLink({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion path: argv['path'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion consent: argv['consent'] as boolean | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/list.ts b/packages/cli/src/commands/extensions/list.ts index 39a8a3f108..9b4789ca55 100644 --- a/packages/cli/src/commands/extensions/list.ts +++ b/packages/cli/src/commands/extensions/list.ts @@ -62,6 +62,7 @@ export const listCommand: CommandModule = { }), handler: async (argv) => { await handleList({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion outputFormat: argv['output-format'] as 'text' | 'json', }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/new.ts b/packages/cli/src/commands/extensions/new.ts index 75cfff7370..e5507194d0 100644 --- a/packages/cli/src/commands/extensions/new.ts +++ b/packages/cli/src/commands/extensions/new.ts @@ -98,7 +98,9 @@ export const newCommand: CommandModule = { }, handler: async (args) => { await handleNew({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion path: args['path'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion template: args['template'] as string | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/uninstall.ts b/packages/cli/src/commands/extensions/uninstall.ts index 3a3a26aa1e..a67a4d3abe 100644 --- a/packages/cli/src/commands/extensions/uninstall.ts +++ b/packages/cli/src/commands/extensions/uninstall.ts @@ -71,6 +71,7 @@ export const uninstallCommand: CommandModule = { }), handler: async (argv) => { await handleUninstall({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion names: argv['names'] as string[], }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/update.ts b/packages/cli/src/commands/extensions/update.ts index 4798892551..4e5f593518 100644 --- a/packages/cli/src/commands/extensions/update.ts +++ b/packages/cli/src/commands/extensions/update.ts @@ -155,7 +155,9 @@ export const updateCommand: CommandModule = { }), handler: async (argv) => { await handleUpdate({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion all: argv['all'] as boolean | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/extensions/validate.ts b/packages/cli/src/commands/extensions/validate.ts index 7c0bbf3a63..1385871219 100644 --- a/packages/cli/src/commands/extensions/validate.ts +++ b/packages/cli/src/commands/extensions/validate.ts @@ -100,6 +100,7 @@ export const validateCommand: CommandModule = { }), handler: async (args) => { await handleValidate({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion path: args['path'] as string, }); await exitCli(); diff --git a/packages/cli/src/commands/hooks/migrate.ts b/packages/cli/src/commands/hooks/migrate.ts index 1ced601052..47cc8660d7 100644 --- a/packages/cli/src/commands/hooks/migrate.ts +++ b/packages/cli/src/commands/hooks/migrate.ts @@ -70,6 +70,7 @@ function migrateClaudeHook(claudeHook: unknown): unknown { return claudeHook; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hook = claudeHook as Record; const migrated: Record = {}; @@ -107,10 +108,12 @@ function migrateClaudeHooks(claudeConfig: unknown): Record { return {}; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const config = claudeConfig as Record; const geminiHooks: Record = {}; // Check if there's a hooks section + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hooksSection = config['hooks'] as Record | undefined; if (!hooksSection || typeof hooksSection !== 'object') { return {}; @@ -130,6 +133,7 @@ function migrateClaudeHooks(claudeConfig: unknown): Record { return def; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const definition = def as Record; const migratedDef: Record = {}; @@ -179,6 +183,7 @@ export async function handleMigrateFromClaude() { sourceFile = claudeLocalSettingsPath; try { const content = fs.readFileSync(claudeLocalSettingsPath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion claudeSettings = JSON.parse(stripJsonComments(content)) as Record< string, unknown @@ -192,6 +197,7 @@ export async function handleMigrateFromClaude() { sourceFile = claudeSettingsPath; try { const content = fs.readFileSync(claudeSettingsPath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion claudeSettings = JSON.parse(stripJsonComments(content)) as Record< string, unknown @@ -259,6 +265,7 @@ export const migrateCommand: CommandModule = { default: false, }), handler: async (argv) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const args = argv as unknown as MigrateArgs; if (args.fromClaude) { await handleMigrateFromClaude(); diff --git a/packages/cli/src/commands/mcp/add.ts b/packages/cli/src/commands/mcp/add.ts index be3eb30716..7d744a1daa 100644 --- a/packages/cli/src/commands/mcp/add.ts +++ b/packages/cli/src/commands/mcp/add.ts @@ -219,24 +219,38 @@ export const addCommand: CommandModule = { .middleware((argv) => { // Handle -- separator args as server args if present if (argv['--']) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const existingArgs = (argv['args'] as Array) || []; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv['args'] = [...existingArgs, ...(argv['--'] as string[])]; } }), handler: async (argv) => { await addMcpServer( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv['name'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv['commandOrUrl'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv['args'] as Array, { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion transport: argv['transport'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion env: argv['env'] as string[], + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion header: argv['header'] as string[], + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion timeout: argv['timeout'] as number | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion trust: argv['trust'] as boolean | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion description: argv['description'] as string | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion includeTools: argv['includeTools'] as string[] | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion excludeTools: argv['excludeTools'] as string[] | undefined, }, ); diff --git a/packages/cli/src/commands/mcp/remove.ts b/packages/cli/src/commands/mcp/remove.ts index f0f6b1fba6..8c5bd1efab 100644 --- a/packages/cli/src/commands/mcp/remove.ts +++ b/packages/cli/src/commands/mcp/remove.ts @@ -55,7 +55,9 @@ export const removeCommand: CommandModule = { choices: ['user', 'project'], }), handler: async (argv) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion await removeMcpServer(argv['name'] as string, { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as string, }); await exitCli(); diff --git a/packages/cli/src/commands/skills/disable.ts b/packages/cli/src/commands/skills/disable.ts index 95fd607924..59a74fd3c5 100644 --- a/packages/cli/src/commands/skills/disable.ts +++ b/packages/cli/src/commands/skills/disable.ts @@ -53,6 +53,7 @@ export const disableCommand: CommandModule = { ? SettingScope.Workspace : SettingScope.User; await handleDisable({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string, scope, }); diff --git a/packages/cli/src/commands/skills/enable.ts b/packages/cli/src/commands/skills/enable.ts index bc9d0066b1..6f58cf471e 100644 --- a/packages/cli/src/commands/skills/enable.ts +++ b/packages/cli/src/commands/skills/enable.ts @@ -40,6 +40,7 @@ export const enableCommand: CommandModule = { }), handler: async (argv) => { await handleEnable({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string, }); await exitCli(); diff --git a/packages/cli/src/commands/skills/install.ts b/packages/cli/src/commands/skills/install.ts index f0701d39b6..70ee094ae5 100644 --- a/packages/cli/src/commands/skills/install.ts +++ b/packages/cli/src/commands/skills/install.ts @@ -102,9 +102,13 @@ export const installCommand: CommandModule = { }), handler: async (argv) => { await handleInstall({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion source: argv['source'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as 'user' | 'workspace', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion path: argv['path'] as string | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion consent: argv['consent'] as boolean | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/skills/link.ts b/packages/cli/src/commands/skills/link.ts index 354b86133c..60bf364bf4 100644 --- a/packages/cli/src/commands/skills/link.ts +++ b/packages/cli/src/commands/skills/link.ts @@ -84,8 +84,11 @@ export const linkCommand: CommandModule = { }), handler: async (argv) => { await handleLink({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion path: argv['path'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as 'user' | 'workspace', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion consent: argv['consent'] as boolean | undefined, }); await exitCli(); diff --git a/packages/cli/src/commands/skills/list.ts b/packages/cli/src/commands/skills/list.ts index c262f39b9b..49fc3a54f1 100644 --- a/packages/cli/src/commands/skills/list.ts +++ b/packages/cli/src/commands/skills/list.ts @@ -18,6 +18,7 @@ export async function handleList(args: { all?: boolean }) { const config = await loadCliConfig( settings.merged, 'skills-list-session', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion { debug: false, } as Partial as CliArgs, @@ -72,6 +73,7 @@ export const listCommand: CommandModule = { default: false, }), handler: async (argv) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion await handleList({ all: argv['all'] as boolean }); await exitCli(); }, diff --git a/packages/cli/src/commands/skills/uninstall.ts b/packages/cli/src/commands/skills/uninstall.ts index 1ab0c130b9..d5f030e1d2 100644 --- a/packages/cli/src/commands/skills/uninstall.ts +++ b/packages/cli/src/commands/skills/uninstall.ts @@ -64,7 +64,9 @@ export const uninstallCommand: CommandModule = { }), handler: async (argv) => { await handleUninstall({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion name: argv['name'] as string, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion scope: argv['scope'] as 'user' | 'workspace', }); await exitCli(); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index fcc62721af..b30a0dc704 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -281,6 +281,7 @@ export async function parseArguments( .check((argv) => { // The 'query' positional can be a string (for one arg) or string[] (for multiple). // This guard safely checks if any positional argument was provided. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const query = argv['query'] as string | string[] | undefined; const hasPositionalQuery = Array.isArray(query) ? query.length > 0 @@ -298,6 +299,7 @@ export async function parseArguments( if ( argv['outputFormat'] && !['text', 'json', 'stream-json'].includes( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv['outputFormat'] as string, ) ) { @@ -346,6 +348,7 @@ export async function parseArguments( } // Normalize query args: handle both quoted "@path file" and unquoted @path file + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const queryArg = (result as { query?: string | string[] | undefined }).query; const q: string | undefined = Array.isArray(queryArg) ? queryArg.join(' ') @@ -369,6 +372,7 @@ export async function parseArguments( // The import format is now only controlled by settings.memoryImportFormat // We no longer accept it as a CLI argument + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return result as unknown as CliArgs; } @@ -477,6 +481,7 @@ export async function loadCliConfig( requestSetting: promptForSetting, workspaceDir: cwd, enabledExtensionOverrides: argv.extensions, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion eventEmitter: coreEvents as EventEmitter, clientVersion: await getVersion(), }); @@ -580,6 +585,7 @@ export async function loadCliConfig( let telemetrySettings; try { telemetrySettings = await resolveTelemetrySettings({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion env: process.env as unknown as Record, settings: settings.telemetry, }); @@ -809,6 +815,7 @@ export async function loadCliConfig( eventEmitter: coreEvents, useWriteTodos: argv.useWriteTodos ?? settings.useWriteTodos, output: { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion format: (argv.outputFormat ?? settings.output?.format) as OutputFormat, }, fakeResponses: argv.fakeResponses, diff --git a/packages/cli/src/config/extension-manager-themes.spec.ts b/packages/cli/src/config/extension-manager-themes.spec.ts index 29588c8749..7db2899929 100644 --- a/packages/cli/src/config/extension-manager-themes.spec.ts +++ b/packages/cli/src/config/extension-manager-themes.spec.ts @@ -85,6 +85,7 @@ describe('ExtensionManager theme loading', () => { await extensionManager.loadExtensions(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getEnableExtensionReloading: () => false, getMcpClientManager: () => ({ @@ -170,6 +171,7 @@ describe('ExtensionManager theme loading', () => { await extensionManager.loadExtensions(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getWorkingDir: () => tempHomeDir, shouldLoadMemoryFromIncludeDirectories: () => false, diff --git a/packages/cli/src/config/extension-manager.ts b/packages/cli/src/config/extension-manager.ts index d94c686e50..7544231c98 100644 --- a/packages/cli/src/config/extension-manager.ts +++ b/packages/cli/src/config/extension-manager.ts @@ -730,6 +730,7 @@ Would you like to attempt to install via "git clone" instead?`, if (Object.keys(hookEnv).length > 0) { for (const eventName of Object.keys(hooks)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const eventHooks = hooks[eventName as HookEventName]; if (eventHooks) { for (const definition of eventHooks) { @@ -826,13 +827,16 @@ Would you like to attempt to install via "git clone" instead?`, } try { const configContent = await fs.promises.readFile(configFilePath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const rawConfig = JSON.parse(configContent) as ExtensionConfig; if (!rawConfig.name || !rawConfig.version) { throw new Error( `Invalid configuration in ${configFilePath}: missing ${!rawConfig.name ? '"name"' : '"version"'}`, ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const config = recursivelyHydrateStrings( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion rawConfig as unknown as JsonObject, { extensionPath: extensionDir, @@ -878,6 +882,7 @@ Would you like to attempt to install via "git clone" instead?`, // Hydrate variables in the hooks configuration const hydratedHooks = recursivelyHydrateStrings( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion rawHooks.hooks as unknown as JsonObject, { ...context, @@ -888,6 +893,7 @@ Would you like to attempt to install via "git clone" instead?`, return hydratedHooks; } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((e as NodeJS.ErrnoException).code === 'ENOENT') { return undefined; // File not found is not an error here. } diff --git a/packages/cli/src/config/extension.ts b/packages/cli/src/config/extension.ts index b6256fc83b..815cf23ece 100644 --- a/packages/cli/src/config/extension.ts +++ b/packages/cli/src/config/extension.ts @@ -47,6 +47,7 @@ export function loadInstallMetadata( const metadataFilePath = path.join(extensionDir, INSTALL_METADATA_FILENAME); try { const configContent = fs.readFileSync(metadataFilePath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const metadata = JSON.parse(configContent) as ExtensionInstallMetadata; return metadata; } catch (_e) { diff --git a/packages/cli/src/config/extensionRegistryClient.ts b/packages/cli/src/config/extensionRegistryClient.ts index 8104b8aeac..aeda50dc48 100644 --- a/packages/cli/src/config/extensionRegistryClient.ts +++ b/packages/cli/src/config/extensionRegistryClient.ts @@ -105,6 +105,7 @@ export class ExtensionRegistryClient { throw new Error(`Failed to fetch extensions: ${response.statusText}`); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (await response.json()) as RegistryExtension[]; } catch (error) { // Clear the promise on failure so that subsequent calls can try again diff --git a/packages/cli/src/config/extensions/github_fetch.ts b/packages/cli/src/config/extensions/github_fetch.ts index 720db7a93f..33a9cb674f 100644 --- a/packages/cli/src/config/extensions/github_fetch.ts +++ b/packages/cli/src/config/extensions/github_fetch.ts @@ -45,6 +45,7 @@ export async function fetchJson( res.on('data', (chunk) => chunks.push(chunk)); res.on('end', () => { const data = Buffer.concat(chunks).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion resolve(JSON.parse(data) as T); }); }) diff --git a/packages/cli/src/config/extensions/variables.ts b/packages/cli/src/config/extensions/variables.ts index 2ac28b2021..5a2e0ca457 100644 --- a/packages/cli/src/config/extensions/variables.ts +++ b/packages/cli/src/config/extensions/variables.ts @@ -52,9 +52,11 @@ export function recursivelyHydrateStrings( values: VariableContext, ): T { if (typeof obj === 'string') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return hydrateString(obj, values) as unknown as T; } if (Array.isArray(obj)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return obj.map((item) => recursivelyHydrateStrings(item, values), ) as unknown as T; @@ -64,11 +66,13 @@ export function recursivelyHydrateStrings( for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = recursivelyHydrateStrings( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (obj as Record)[key], values, ); } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return newObj as T; } return obj; diff --git a/packages/cli/src/config/mcp/mcpServerEnablement.ts b/packages/cli/src/config/mcp/mcpServerEnablement.ts index a510dd6697..1a6c445604 100644 --- a/packages/cli/src/config/mcp/mcpServerEnablement.ts +++ b/packages/cli/src/config/mcp/mcpServerEnablement.ts @@ -358,6 +358,7 @@ export class McpServerEnablementManager { private async readConfig(): Promise { try { const content = await fs.readFile(this.configFilePath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return JSON.parse(content) as McpServerEnablementConfig; } catch (error) { if ( diff --git a/packages/cli/src/config/settings-validation.ts b/packages/cli/src/config/settings-validation.ts index da06cf082e..3207c2da2a 100644 --- a/packages/cli/src/config/settings-validation.ts +++ b/packages/cli/src/config/settings-validation.ts @@ -23,6 +23,7 @@ function buildZodSchemaFromJsonSchema(def: any): z.ZodTypeAny { } if (def.type === 'string') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if (def.enum) return z.enum(def.enum as [string, ...string[]]); return z.string(); } @@ -40,7 +41,7 @@ function buildZodSchemaFromJsonSchema(def: any): z.ZodTypeAny { let schema; if (def.properties) { const shape: Record = {}; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion for (const [key, propDef] of Object.entries(def.properties) as any) { let propSchema = buildZodSchemaFromJsonSchema(propDef); if ( @@ -86,9 +87,11 @@ function buildEnumSchema( } const values = options.map((opt) => opt.value); if (values.every((v) => typeof v === 'string')) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return z.enum(values as [string, ...string[]]); } else if (values.every((v) => typeof v === 'number')) { return z.union( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion values.map((v) => z.literal(v)) as [ z.ZodLiteral, z.ZodLiteral, @@ -97,6 +100,7 @@ function buildEnumSchema( ); } else { return z.union( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion values.map((v) => z.literal(v)) as [ z.ZodLiteral, z.ZodLiteral, diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index 9842716886..a267cfe185 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -213,6 +213,7 @@ function setNestedProperty( } const next = current[key]; if (typeof next === 'object' && next !== null) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion current = next as Record; } else { // This path is invalid, so we stop. @@ -254,6 +255,7 @@ export function mergeSettings( // 3. User Settings // 4. Workspace Settings // 5. System Settings (as overrides) + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return customDeepMerge( getMergeStrategyForPath, schemaDefaults, @@ -274,6 +276,7 @@ export function mergeSettings( export function createTestMergedSettings( overrides: Partial = {}, ): MergedSettings { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return customDeepMerge( getMergeStrategyForPath, getDefaultsFromSchema(), @@ -355,6 +358,7 @@ export class LoadedSettings { // The final admin settings are the defaults overridden by remote settings. // Any admin settings from files are ignored. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion merged.admin = customDeepMerge( (path: string[]) => getMergeStrategyForPath(['admin', ...path]), adminDefaults, @@ -617,6 +621,7 @@ export function loadSettings( return { settings: {} }; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const settingsObject = rawSettings as Record; // Validate settings structure with Zod @@ -850,6 +855,7 @@ export function migrateDeprecatedSettings( const uiSettings = settings.ui as Record | undefined; if (uiSettings) { const newUi = { ...uiSettings }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const accessibilitySettings = newUi['accessibility'] as | Record | undefined; @@ -880,6 +886,7 @@ export function migrateDeprecatedSettings( | undefined; if (contextSettings) { const newContext = { ...contextSettings }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const fileFilteringSettings = newContext['fileFiltering'] as | Record | undefined; @@ -1000,6 +1007,7 @@ function migrateExperimentalSettings( ...(settings.agents as Record | undefined), }; const agentsOverrides = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...((agentsSettings['overrides'] as Record) || {}), }; let modified = false; @@ -1011,6 +1019,7 @@ function migrateExperimentalSettings( const old = experimentalSettings[oldKey]; if (old) { foundDeprecated?.push(`experimental.${oldKey}`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion migrateFn(old as Record); modified = true; } @@ -1019,6 +1028,7 @@ function migrateExperimentalSettings( // Migrate codebaseInvestigatorSettings -> agents.overrides.codebase_investigator migrateExperimental('codebaseInvestigatorSettings', (old) => { const override = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(agentsOverrides['codebase_investigator'] as | Record | undefined), @@ -1027,6 +1037,7 @@ function migrateExperimentalSettings( if (old['enabled'] !== undefined) override['enabled'] = old['enabled']; const runConfig = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(override['runConfig'] as Record | undefined), }; if (old['maxNumTurns'] !== undefined) @@ -1037,16 +1048,19 @@ function migrateExperimentalSettings( if (old['model'] !== undefined || old['thinkingBudget'] !== undefined) { const modelConfig = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(override['modelConfig'] as Record | undefined), }; if (old['model'] !== undefined) modelConfig['model'] = old['model']; if (old['thinkingBudget'] !== undefined) { const generateContentConfig = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(modelConfig['generateContentConfig'] as | Record | undefined), }; const thinkingConfig = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(generateContentConfig['thinkingConfig'] as | Record | undefined), @@ -1064,6 +1078,7 @@ function migrateExperimentalSettings( // Migrate cliHelpAgentSettings -> agents.overrides.cli_help migrateExperimental('cliHelpAgentSettings', (old) => { const override = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(agentsOverrides['cli_help'] as Record | undefined), }; if (old['enabled'] !== undefined) override['enabled'] = old['enabled']; diff --git a/packages/cli/src/config/trustedFolders.ts b/packages/cli/src/config/trustedFolders.ts index 0b00449700..1f85684900 100644 --- a/packages/cli/src/config/trustedFolders.ts +++ b/packages/cli/src/config/trustedFolders.ts @@ -47,6 +47,7 @@ export function isTrustLevel( ): value is TrustLevel { return ( typeof value === 'string' && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion Object.values(TrustLevel).includes(value as TrustLevel) ); } @@ -197,6 +198,7 @@ export class LoadedTrustedFolders { const content = await fsPromises.readFile(this.user.path, 'utf-8'); let config: Record; try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion config = parseTrustedFoldersJson(content) as Record; } catch (error) { coreEvents.emitFeedback( @@ -251,6 +253,7 @@ export function loadTrustedFolders(): LoadedTrustedFolders { try { if (fs.existsSync(userPath)) { const content = fs.readFileSync(userPath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const parsed = parseTrustedFoldersJson(content) as Record; if ( diff --git a/packages/cli/src/deferred.ts b/packages/cli/src/deferred.ts index dec6d9d114..1864ec2cb5 100644 --- a/packages/cli/src/deferred.ts +++ b/packages/cli/src/deferred.ts @@ -86,9 +86,11 @@ export function defer( ...commandModule, handler: (argv: ArgumentsCamelCase) => { setDeferredCommand({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion handler: commandModule.handler as ( argv: ArgumentsCamelCase, ) => void | Promise, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion argv: argv as unknown as ArgumentsCamelCase, commandName: parentCommandName || 'unknown', }); diff --git a/packages/cli/src/gemini.tsx b/packages/cli/src/gemini.tsx index fcbe183032..65b42088a2 100644 --- a/packages/cli/src/gemini.tsx +++ b/packages/cli/src/gemini.tsx @@ -819,6 +819,7 @@ function setupAdminControlsListener() { let config: Config | undefined; const messageHandler = (msg: unknown) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const message = msg as { type?: string; settings?: AdminControlsSettings; diff --git a/packages/cli/src/nonInteractiveCli.ts b/packages/cli/src/nonInteractiveCli.ts index dfe3e0274f..f8ed72169b 100644 --- a/packages/cli/src/nonInteractiveCli.ts +++ b/packages/cli/src/nonInteractiveCli.ts @@ -250,6 +250,7 @@ export async function runNonInteractive({ // Otherwise, slashCommandResult falls through to the default prompt // handling. if (slashCommandResult) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion query = slashCommandResult as Part[]; } } @@ -271,6 +272,7 @@ export async function runNonInteractive({ error || 'Exiting due to an error processing the @ command.', ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion query = processedQuery as Part[]; } diff --git a/packages/cli/src/services/FileCommandLoader.ts b/packages/cli/src/services/FileCommandLoader.ts index 5bfbcd8996..fb27327ead 100644 --- a/packages/cli/src/services/FileCommandLoader.ts +++ b/packages/cli/src/services/FileCommandLoader.ts @@ -125,6 +125,7 @@ export class FileCommandLoader implements ICommandLoader { } catch (error) { if ( !signal.aborted && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (error as { code?: string })?.code !== 'ENOENT' ) { coreEvents.emitFeedback( diff --git a/packages/cli/src/test-utils/customMatchers.ts b/packages/cli/src/test-utils/customMatchers.ts index 2a1b275ad2..0351c7011c 100644 --- a/packages/cli/src/test-utils/customMatchers.ts +++ b/packages/cli/src/test-utils/customMatchers.ts @@ -21,7 +21,7 @@ import type { TextBuffer } from '../ui/components/shared/text-buffer.js'; const invalidCharsRegex = /[\b\x1b]/; function toHaveOnlyValidCharacters(this: Assertion, buffer: TextBuffer) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion const { isNot } = this as any; let pass = true; const invalidLines: Array<{ line: number; content: string }> = []; @@ -50,6 +50,7 @@ function toHaveOnlyValidCharacters(this: Assertion, buffer: TextBuffer) { }; } +// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion expect.extend({ toHaveOnlyValidCharacters, // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/cli/src/test-utils/mockCommandContext.ts b/packages/cli/src/test-utils/mockCommandContext.ts index b3dc0b9f7f..c2f1bbcfd3 100644 --- a/packages/cli/src/test-utils/mockCommandContext.ts +++ b/packages/cli/src/test-utils/mockCommandContext.ts @@ -38,12 +38,14 @@ export const createMockCommandContext = ( }, services: { config: null, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion settings: { merged: defaultMergedSettings, setValue: vi.fn(), forScope: vi.fn().mockReturnValue({ settings: {} }), } as unknown as LoadedSettings, git: undefined as GitService | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion logger: { log: vi.fn(), logMessage: vi.fn(), @@ -52,6 +54,7 @@ export const createMockCommandContext = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any, // Cast because Logger is a class. }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ui: { addItem: vi.fn(), clear: vi.fn(), @@ -70,6 +73,7 @@ export const createMockCommandContext = ( } as any, session: { sessionShellAllowlist: new Set(), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion stats: { sessionStartTime: new Date(), lastPromptTokenCount: 0, diff --git a/packages/cli/src/test-utils/mockConfig.ts b/packages/cli/src/test-utils/mockConfig.ts index 30031a0599..ac2176c0e3 100644 --- a/packages/cli/src/test-utils/mockConfig.ts +++ b/packages/cli/src/test-utils/mockConfig.ts @@ -13,6 +13,7 @@ import { createTestMergedSettings } from '../config/settings.js'; * Creates a mocked Config object with default values and allows overrides. */ export const createMockConfig = (overrides: Partial = {}): Config => + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ({ getSandbox: vi.fn(() => undefined), getQuestion: vi.fn(() => ''), @@ -163,9 +164,11 @@ export function createMockSettings( overrides: Record = {}, ): LoadedSettings { const merged = createTestMergedSettings( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (overrides['merged'] as Partial) || {}, ); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return { system: { settings: {} }, systemDefaults: { settings: {} }, diff --git a/packages/cli/src/test-utils/render.tsx b/packages/cli/src/test-utils/render.tsx index c0bcfd6b95..64fccf1b3e 100644 --- a/packages/cli/src/test-utils/render.tsx +++ b/packages/cli/src/test-utils/render.tsx @@ -52,6 +52,7 @@ export const render = ( terminalWidth?: number, ): ReturnType => { let renderResult: ReturnType = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion undefined as unknown as ReturnType; act(() => { renderResult = inkRender(tree); @@ -113,6 +114,7 @@ const getMockConfigInternal = (): Config => { return mockConfigInternal; }; +// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const configProxy = new Proxy({} as Config, { get(_target, prop) { if (prop === 'getTargetDir') { @@ -121,6 +123,7 @@ const configProxy = new Proxy({} as Config, { } const internal = getMockConfigInternal(); if (prop in internal) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return internal[prop as keyof typeof internal]; } throw new Error(`mockConfig does not have property ${String(prop)}`); @@ -210,6 +213,7 @@ export const renderWithProviders = ( uiState: providedUiState, width, mouseEventsEnabled = false, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion config = configProxy as unknown as Config, useAlternateBuffer = true, uiActions, @@ -231,17 +235,20 @@ export const renderWithProviders = ( appState?: AppState; } = {}, ): ReturnType & { simulateClick: typeof simulateClick } => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const baseState: UIState = new Proxy( { ...baseMockUiState, ...providedUiState }, { get(target, prop) { if (prop in target) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return target[prop as keyof typeof target]; } // For properties not in the base mock or provided state, // we'll check the original proxy to see if it's a defined but // unprovided property, and if not, throw. if (prop in baseMockUiState) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return baseMockUiState[prop as keyof typeof baseMockUiState]; } throw new Error(`mockUiState does not have property ${String(prop)}`); @@ -347,7 +354,9 @@ export function renderHook( rerender: (props?: Props) => void; unmount: () => void; } { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const result = { current: undefined as unknown as Result }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion let currentProps = options?.initialProps as Props; function TestComponent({ @@ -378,6 +387,7 @@ export function renderHook( function rerender(props?: Props) { if (arguments.length > 0) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion currentProps = props as Props; } act(() => { @@ -411,6 +421,7 @@ export function renderHookWithProviders( rerender: (props?: Props) => void; unmount: () => void; } { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const result = { current: undefined as unknown as Result }; let setPropsFn: ((props: Props) => void) | undefined; @@ -432,6 +443,7 @@ export function renderHookWithProviders( act(() => { renderResult = renderWithProviders( + {/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion */} , options, @@ -441,6 +453,7 @@ export function renderHookWithProviders( function rerender(newProps?: Props) { act(() => { if (arguments.length > 0 && setPropsFn) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion setPropsFn(newProps as Props); } else if (forceUpdateFn) { forceUpdateFn(); diff --git a/packages/cli/src/test-utils/settings.ts b/packages/cli/src/test-utils/settings.ts index 14b93f3578..77e8450a9c 100644 --- a/packages/cli/src/test-utils/settings.ts +++ b/packages/cli/src/test-utils/settings.ts @@ -51,13 +51,17 @@ export const createMockSettings = ( } = overrides; const loaded = new LoadedSettings( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (system as any) || { path: '', settings: {}, originalSettings: {} }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (systemDefaults as any) || { path: '', settings: {}, originalSettings: {} }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (user as any) || { path: '', settings: settingsOverrides, originalSettings: settingsOverrides, }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (workspace as any) || { path: '', settings: {}, originalSettings: {} }, isTrusted ?? true, errors || [], @@ -71,6 +75,7 @@ export const createMockSettings = ( // Assign any function overrides (e.g., vi.fn() for methods) for (const key in overrides) { if (typeof overrides[key] === 'function') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (loaded as any)[key] = overrides[key]; } } diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx index 12ec88a8ac..fbfa93ac3a 100644 --- a/packages/cli/src/ui/AppContainer.tsx +++ b/packages/cli/src/ui/AppContainer.tsx @@ -249,6 +249,7 @@ export const AppContainer = (props: AppContainerProps) => { const { bannerText } = useBanner(bannerData); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const extensionManager = config.getExtensionLoader() as ExtensionManager; // We are in the interactive CLI, update how we request consent and settings. extensionManager.setRequestConsent((description) => @@ -468,6 +469,7 @@ export const AppContainer = (props: AppContainerProps) => { const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100); const getPreferredEditor = useCallback( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion () => settings.merged.general.preferredEditor as EditorType, [settings.merged.general.preferredEditor], ); diff --git a/packages/cli/src/ui/auth/AuthDialog.tsx b/packages/cli/src/ui/auth/AuthDialog.tsx index 0acb27e2af..ec107d1689 100644 --- a/packages/cli/src/ui/auth/AuthDialog.tsx +++ b/packages/cli/src/ui/auth/AuthDialog.tsx @@ -88,8 +88,10 @@ export function AuthDialog({ const defaultAuthTypeEnv = process.env['GEMINI_DEFAULT_AUTH_TYPE']; if ( defaultAuthTypeEnv && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion Object.values(AuthType).includes(defaultAuthTypeEnv as AuthType) ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion defaultAuthType = defaultAuthTypeEnv as AuthType; } diff --git a/packages/cli/src/ui/auth/useAuth.ts b/packages/cli/src/ui/auth/useAuth.ts index 2b61265890..effb17cdff 100644 --- a/packages/cli/src/ui/auth/useAuth.ts +++ b/packages/cli/src/ui/auth/useAuth.ts @@ -113,6 +113,7 @@ export const useAuthCommand = ( const defaultAuthType = process.env['GEMINI_DEFAULT_AUTH_TYPE']; if ( defaultAuthType && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion !Object.values(AuthType).includes(defaultAuthType as AuthType) ) { onAuthError( diff --git a/packages/cli/src/ui/commands/chatCommand.ts b/packages/cli/src/ui/commands/chatCommand.ts index 3dafe59554..e1969fff67 100644 --- a/packages/cli/src/ui/commands/chatCommand.ts +++ b/packages/cli/src/ui/commands/chatCommand.ts @@ -213,6 +213,7 @@ const resumeCommand: SlashCommand = { continue; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion uiHistory.push({ type: (item.role && rolemap[item.role]) || MessageType.GEMINI, text, diff --git a/packages/cli/src/ui/commands/directoryCommand.tsx b/packages/cli/src/ui/commands/directoryCommand.tsx index 2da2f107df..08a65ca78a 100644 --- a/packages/cli/src/ui/commands/directoryCommand.tsx +++ b/packages/cli/src/ui/commands/directoryCommand.tsx @@ -49,6 +49,7 @@ async function finishAddingDirectories( text: `Successfully added GEMINI.md files from the following directories if there are:\n- ${added.join('\n- ')}`, }); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion errors.push(`Error refreshing memory: ${(error as Error).message}`); } } diff --git a/packages/cli/src/ui/commands/initCommand.ts b/packages/cli/src/ui/commands/initCommand.ts index 6c2209921f..ea0d1ea0c6 100644 --- a/packages/cli/src/ui/commands/initCommand.ts +++ b/packages/cli/src/ui/commands/initCommand.ts @@ -48,6 +48,7 @@ export const initCommand: SlashCommand = { ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return result as SlashCommandActionReturn; }, }; diff --git a/packages/cli/src/ui/commands/memoryCommand.ts b/packages/cli/src/ui/commands/memoryCommand.ts index 8f4bdaffbe..fc5d37fb9b 100644 --- a/packages/cli/src/ui/commands/memoryCommand.ts +++ b/packages/cli/src/ui/commands/memoryCommand.ts @@ -93,6 +93,7 @@ export const memoryCommand: SlashCommand = { context.ui.addItem( { type: MessageType.ERROR, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion text: `Error refreshing memory: ${(error as Error).message}`, }, Date.now(), diff --git a/packages/cli/src/ui/components/AgentConfigDialog.tsx b/packages/cli/src/ui/components/AgentConfigDialog.tsx index 9226098bc7..5b4eb1e912 100644 --- a/packages/cli/src/ui/components/AgentConfigDialog.tsx +++ b/packages/cli/src/ui/components/AgentConfigDialog.tsx @@ -123,6 +123,7 @@ function getNestedValue( for (const key of path) { if (current === null || current === undefined) return undefined; if (typeof current !== 'object') return undefined; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion current = (current as Record)[key]; } return current; @@ -144,8 +145,10 @@ function setNestedValue( if (current[key] === undefined || current[key] === null) { current[key] = {}; } else { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion current[key] = { ...(current[key] as Record) }; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion current = current[key] as Record; } @@ -265,6 +268,7 @@ export function AgentConfigDialog({ () => AGENT_CONFIG_FIELDS.map((field) => { const currentValue = getNestedValue( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion pendingOverride as Record, field.path, ); @@ -300,6 +304,7 @@ export function AgentConfigDialog({ displayValue, isGreyedOut: currentValue === undefined, scopeMessage: undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion rawValue: rawValue as string | number | boolean | undefined, }; }), @@ -320,6 +325,7 @@ export function AgentConfigDialog({ if (!field || field.type !== 'boolean') return; const currentValue = getNestedValue( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion pendingOverride as Record, field.path, ); @@ -329,6 +335,7 @@ export function AgentConfigDialog({ const newValue = !effectiveValue; const newOverride = setNestedValue( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion pendingOverride as Record, field.path, newValue, @@ -369,6 +376,7 @@ export function AgentConfigDialog({ // Update pending override locally const newOverride = setNestedValue( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion pendingOverride as Record, field.path, parsed, @@ -391,6 +399,7 @@ export function AgentConfigDialog({ // Remove the override (set to undefined) const newOverride = setNestedValue( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion pendingOverride as Record, field.path, undefined, diff --git a/packages/cli/src/ui/components/EditorSettingsDialog.tsx b/packages/cli/src/ui/components/EditorSettingsDialog.tsx index ade91da3ec..f75b1c27b8 100644 --- a/packages/cli/src/ui/components/EditorSettingsDialog.tsx +++ b/packages/cli/src/ui/components/EditorSettingsDialog.tsx @@ -132,6 +132,7 @@ export function EditorSettingsDialog({ ) { mergedEditorName = EDITOR_DISPLAY_NAMES[ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion settings.merged.general.preferredEditor as EditorType ]; } diff --git a/packages/cli/src/ui/components/MultiFolderTrustDialog.tsx b/packages/cli/src/ui/components/MultiFolderTrustDialog.tsx index f9ea8d5145..0c2c4e362d 100644 --- a/packages/cli/src/ui/components/MultiFolderTrustDialog.tsx +++ b/packages/cli/src/ui/components/MultiFolderTrustDialog.tsx @@ -133,6 +133,7 @@ export const MultiFolderTrustDialog: React.FC = ({ workspaceContext.addDirectory(expandedPath); added.push(dir); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; errors.push(`Error adding '${dir}': ${error.message}`); } diff --git a/packages/cli/src/ui/components/SettingsDialog.tsx b/packages/cli/src/ui/components/SettingsDialog.tsx index a9e2d54aac..fe3acbd1f1 100644 --- a/packages/cli/src/ui/components/SettingsDialog.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.tsx @@ -259,10 +259,12 @@ export function SettingsDialog({ key, label: definition?.label || key, description: definition?.description, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion type: type as 'boolean' | 'number' | 'string' | 'enum', displayValue, isGreyedOut, scopeMessage, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion rawValue: rawValue as string | number | boolean | undefined, }; }); @@ -283,8 +285,10 @@ export function SettingsDialog({ const currentValue = getEffectiveValue(key, pendingSettings, {}); let newValue: SettingsValue; if (definition?.type === 'boolean') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion newValue = !(currentValue as boolean); setPendingSettings((prev) => + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion setPendingSettingValue(key, newValue as boolean, prev), ); } else if (definition?.type === 'enum' && definition.options) { @@ -377,6 +381,7 @@ export function SettingsDialog({ // Record pending change globally setGlobalPendingChanges((prev) => { const next = new Map(prev); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion next.set(key, newValue as PendingValue); return next; }); diff --git a/packages/cli/src/ui/components/Table.tsx b/packages/cli/src/ui/components/Table.tsx index e06e5d38f2..c5d64139b9 100644 --- a/packages/cli/src/ui/components/Table.tsx +++ b/packages/cli/src/ui/components/Table.tsx @@ -75,6 +75,7 @@ export function Table({ data, columns }: TableProps) { col.renderCell(item) ) : ( + {/* eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion */} {String((item as Record)[col.key])} )} diff --git a/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx b/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx index 2bdc74bec3..61f1540017 100644 --- a/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx +++ b/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx @@ -121,6 +121,7 @@ export const ToolResultDisplay: React.FC = ({ // where Container grows -> List renders more -> Container grows. const limit = maxLines ?? availableHeight ?? ACTIVE_SHELL_MAX_LINES; const listHeight = Math.min( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (truncatedResultDisplay as AnsiOutput).length, limit, ); @@ -129,6 +130,7 @@ export const ToolResultDisplay: React.FC = ({ 1} @@ -184,7 +186,9 @@ export const ToolResultDisplay: React.FC = ({ ) { content = ( = ({ content = ( = ({ const scrollableEntry = useMemo( () => ({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ref: ref as React.RefObject, getScrollState, scrollBy: scrollByWithAnimation, diff --git a/packages/cli/src/ui/components/shared/ScrollableList.tsx b/packages/cli/src/ui/components/shared/ScrollableList.tsx index 41a235fc73..3ee7bdbb2b 100644 --- a/packages/cli/src/ui/components/shared/ScrollableList.tsx +++ b/packages/cli/src/ui/components/shared/ScrollableList.tsx @@ -219,6 +219,7 @@ function ScrollableList( const scrollableEntry = useMemo( () => ({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ref: containerRef as React.RefObject, getScrollState, scrollBy: scrollByWithAnimation, @@ -254,6 +255,7 @@ function ScrollableList( ); } +// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const ScrollableListWithForwardRef = forwardRef(ScrollableList) as ( props: ScrollableListProps & { ref?: React.Ref> }, ) => React.ReactElement; diff --git a/packages/cli/src/ui/components/shared/VirtualizedList.tsx b/packages/cli/src/ui/components/shared/VirtualizedList.tsx index 7f027c8127..66b1244754 100644 --- a/packages/cli/src/ui/components/shared/VirtualizedList.tsx +++ b/packages/cli/src/ui/components/shared/VirtualizedList.tsx @@ -492,6 +492,7 @@ function VirtualizedList( ); } +// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const VirtualizedListWithForwardRef = forwardRef(VirtualizedList) as ( props: VirtualizedListProps & { ref?: React.Ref> }, ) => React.ReactElement; diff --git a/packages/cli/src/ui/components/triage/TriageDuplicates.tsx b/packages/cli/src/ui/components/triage/TriageDuplicates.tsx index dce4fd1925..a79fbb2eb1 100644 --- a/packages/cli/src/ui/components/triage/TriageDuplicates.tsx +++ b/packages/cli/src/ui/components/triage/TriageDuplicates.tsx @@ -157,6 +157,7 @@ export const TriageDuplicates = ({ '--json', 'number,title,body,state,stateReason,labels,url,comments,author,reactionGroups', ]); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return JSON.parse(stdout) as Candidate; } catch (err) { debugLogger.error( @@ -280,6 +281,7 @@ Return a JSON object with: promptId: 'triage-duplicates', }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const rec = response as unknown as GeminiRecommendation; let canonical: Candidate | undefined; diff --git a/packages/cli/src/ui/components/triage/TriageIssues.tsx b/packages/cli/src/ui/components/triage/TriageIssues.tsx index c1e21e274a..01322440ae 100644 --- a/packages/cli/src/ui/components/triage/TriageIssues.tsx +++ b/packages/cli/src/ui/components/triage/TriageIssues.tsx @@ -225,6 +225,7 @@ Return a JSON object with: promptId: 'triage-issues', }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return response as unknown as AnalysisResult; }, [config], diff --git a/packages/cli/src/ui/editors/editorSettingsManager.ts b/packages/cli/src/ui/editors/editorSettingsManager.ts index 6869cd7f8e..d8aab97a6e 100644 --- a/packages/cli/src/ui/editors/editorSettingsManager.ts +++ b/packages/cli/src/ui/editors/editorSettingsManager.ts @@ -21,6 +21,7 @@ class EditorSettingsManager { private readonly availableEditors: EditorDisplay[]; constructor() { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const editorTypes = Object.keys( EDITOR_DISPLAY_NAMES, ).sort() as EditorType[]; diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index c6d5f1decc..7289906a36 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -467,6 +467,7 @@ export const useSlashCommandProcessor = ( actions.openModelDialog(); return { type: 'handled' }; case 'agentConfig': { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const props = result.props as Record; if ( !props || @@ -482,12 +483,14 @@ export const useSlashCommandProcessor = ( actions.openAgentConfigDialog( props['name'], props['displayName'], + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion props['definition'] as AgentDefinition, ); return { type: 'handled' }; } case 'permissions': actions.openPermissionsDialog( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion result.props as { targetDirectory?: string }, ); return { type: 'handled' }; diff --git a/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts b/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts index c9c1d768c8..b48ce92338 100644 --- a/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts +++ b/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts @@ -102,6 +102,7 @@ export function useApprovalModeIndicator({ addItem( { type: MessageType.INFO, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion text: (e as Error).message, }, Date.now(), diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts index 17dcbdb136..dc78c76a50 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.ts +++ b/packages/cli/src/ui/hooks/useGeminiStream.ts @@ -46,7 +46,6 @@ import type { ToolCallResponseInfo, GeminiErrorEventValue, RetryAttemptPayload, - ToolCallConfirmationDetails, } from '@google/gemini-cli-core'; import { type Part, type PartListUnion, FinishReason } from '@google/genai'; import type { @@ -427,6 +426,7 @@ export const useGeminiStream = ( (tc) => tc.status === 'executing' && tc.request.name === 'run_shell_command', ); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (executingShellTool as TrackedExecutingToolCall | undefined)?.pid; }, [toolCalls]); @@ -551,6 +551,7 @@ export const useGeminiStream = ( // If it is a shell command, we update the status to Canceled and clear the output // to avoid artifacts, then add it to history immediately. if (isShellCommand) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const toolGroup = pendingHistoryItemRef.current as HistoryItemToolGroup; const updatedTools = toolGroup.tools.map((tool) => { if (tool.name === SHELL_COMMAND_NAME) { @@ -764,6 +765,7 @@ export const useGeminiStream = ( if (splitPoint === newGeminiMessageBuffer.length) { // Update the existing message with accumulated content setPendingHistoryItem((item) => ({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion type: item?.type as 'gemini' | 'gemini_content', text: newGeminiMessageBuffer, })); @@ -780,6 +782,7 @@ export const useGeminiStream = ( const afterText = newGeminiMessageBuffer.substring(splitPoint); addItem( { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion type: pendingHistoryItemRef.current?.type as | 'gemini' | 'gemini_content', @@ -1372,13 +1375,10 @@ export const useGeminiStream = ( // Process pending tool calls sequentially to reduce UI chaos for (const call of awaitingApprovalCalls) { - if ( - (call.confirmationDetails as ToolCallConfirmationDetails)?.onConfirm - ) { + const details = call.confirmationDetails; + if (details && 'onConfirm' in details) { try { - await ( - call.confirmationDetails as ToolCallConfirmationDetails - ).onConfirm(ToolConfirmationOutcome.ProceedOnce); + await details.onConfirm(ToolConfirmationOutcome.ProceedOnce); } catch (error) { debugLogger.warn( `Failed to auto-approve tool call ${call.request.callId}:`, @@ -1444,7 +1444,9 @@ export const useGeminiStream = ( const pid = data?.pid; if (isShell && pid) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const command = (data?.['command'] as string) ?? 'shell'; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const initialOutput = (data?.['initialOutput'] as string) ?? ''; registerBackgroundShell(pid, command, initialOutput); diff --git a/packages/cli/src/ui/hooks/useHistoryManager.ts b/packages/cli/src/ui/hooks/useHistoryManager.ts index bbcf5c3794..93f7f01f28 100644 --- a/packages/cli/src/ui/hooks/useHistoryManager.ts +++ b/packages/cli/src/ui/hooks/useHistoryManager.ts @@ -62,6 +62,7 @@ export function useHistory({ isResuming: boolean = false, ): number => { const id = getNextMessageId(baseTimestamp); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const newItem: HistoryItem = { ...itemData, id } as HistoryItem; setHistory((prevHistory) => { @@ -139,6 +140,7 @@ export function useHistory({ // Apply updates based on whether it's an object or a function const newUpdates = typeof updates === 'function' ? updates(item) : updates; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return { ...item, ...newUpdates } as HistoryItem; } return item; diff --git a/packages/cli/src/ui/hooks/useIncludeDirsTrust.tsx b/packages/cli/src/ui/hooks/useIncludeDirsTrust.tsx index fa27d3e0ec..ec29a8180c 100644 --- a/packages/cli/src/ui/hooks/useIncludeDirsTrust.tsx +++ b/packages/cli/src/ui/hooks/useIncludeDirsTrust.tsx @@ -38,6 +38,7 @@ async function finishAddingDirectories( await refreshServerHierarchicalMemory(config); } } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion errors.push(`Error refreshing memory: ${(error as Error).message}`); } diff --git a/packages/cli/src/ui/hooks/usePrivacySettings.ts b/packages/cli/src/ui/hooks/usePrivacySettings.ts index 7404f8778d..64a9673812 100644 --- a/packages/cli/src/ui/hooks/usePrivacySettings.ts +++ b/packages/cli/src/ui/hooks/usePrivacySettings.ts @@ -106,6 +106,7 @@ async function getRemoteDataCollectionOptIn( return resp.freeTierDataCollectionOptin; } catch (error: unknown) { if (error && typeof error === 'object' && 'response' in error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const gaxiosError = error as { response?: { status?: unknown; diff --git a/packages/cli/src/ui/hooks/useReactToolScheduler.ts b/packages/cli/src/ui/hooks/useReactToolScheduler.ts index 79b15fb293..cd17b305b5 100644 --- a/packages/cli/src/ui/hooks/useReactToolScheduler.ts +++ b/packages/cli/src/ui/hooks/useReactToolScheduler.ts @@ -127,6 +127,7 @@ export function useReactToolScheduler( existingTrackedCall?.responseSubmittedToGemini ?? false; if (coreTc.status === 'executing') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const liveOutput = (existingTrackedCall as TrackedExecutingToolCall) ?.liveOutput; return { diff --git a/packages/cli/src/ui/keyMatchers.ts b/packages/cli/src/ui/keyMatchers.ts index 07b6acf173..7c61db1016 100644 --- a/packages/cli/src/ui/keyMatchers.ts +++ b/packages/cli/src/ui/keyMatchers.ts @@ -56,6 +56,7 @@ export type KeyMatchers = { export function createKeyMatchers( config: KeyBindingConfig = defaultKeyBindings, ): KeyMatchers { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const matchers = {} as { [C in Command]: KeyMatcher }; for (const command of Object.values(Command)) { diff --git a/packages/cli/src/ui/themes/theme-manager.ts b/packages/cli/src/ui/themes/theme-manager.ts index 60c7873e52..7452d093f8 100644 --- a/packages/cli/src/ui/themes/theme-manager.ts +++ b/packages/cli/src/ui/themes/theme-manager.ts @@ -383,6 +383,7 @@ class ThemeManager { // 3. Read, parse, and validate the theme file. const themeContent = fs.readFileSync(canonicalPath, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const customThemeConfig = JSON.parse(themeContent) as CustomTheme; const validation = validateCustomTheme(customThemeConfig); diff --git a/packages/cli/src/ui/utils/CodeColorizer.tsx b/packages/cli/src/ui/utils/CodeColorizer.tsx index ed5326eec7..1034e7372e 100644 --- a/packages/cli/src/ui/utils/CodeColorizer.tsx +++ b/packages/cli/src/ui/utils/CodeColorizer.tsx @@ -41,6 +41,7 @@ function renderHastNode( // Handle Element Nodes: Determine color and pass it down, don't wrap if (node.type === 'element') { const nodeClasses: string[] = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (node.properties?.['className'] as string[]) || []; let elementColor: string | undefined = undefined; diff --git a/packages/cli/src/ui/utils/commandUtils.ts b/packages/cli/src/ui/utils/commandUtils.ts index 1f6d6f86bb..f87a4f583a 100644 --- a/packages/cli/src/ui/utils/commandUtils.ts +++ b/packages/cli/src/ui/utils/commandUtils.ts @@ -194,6 +194,7 @@ const writeAll = (stream: Writable, data: string): Promise => // On Windows, writing directly to the underlying file descriptor bypasses // application-level stream interception (e.g., by the Ink UI framework). // This ensures the raw OSC-52 escape sequence reaches the terminal host uncorrupted. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const fd = (stream as unknown as { fd?: number }).fd; if ( process.platform === 'win32' && @@ -214,6 +215,7 @@ const writeAll = (stream: Writable, data: string): Promise => const onError = (err: unknown) => { cleanup(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion reject(err as Error); }; const onDrain = () => { @@ -251,6 +253,7 @@ export const copyToClipboard = async (text: string): Promise => { await writeAll(tty!.stream, payload); if (tty!.closeAfter) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (tty!.stream as fs.WriteStream).end(); } return; diff --git a/packages/cli/src/ui/utils/rewindFileOps.ts b/packages/cli/src/ui/utils/rewindFileOps.ts index 3009dca622..7eaebe90ed 100644 --- a/packages/cli/src/ui/utils/rewindFileOps.ts +++ b/packages/cli/src/ui/utils/rewindFileOps.ts @@ -174,6 +174,7 @@ export async function revertFileChanges( try { currentContent = await fs.readFile(filePath, 'utf8'); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; if ('code' in error && error.code === 'ENOENT') { // File does not exist, which is fine in some revert scenarios. diff --git a/packages/cli/src/ui/utils/terminalSetup.ts b/packages/cli/src/ui/utils/terminalSetup.ts index 5114c006fa..820497cc2f 100644 --- a/packages/cli/src/ui/utils/terminalSetup.ts +++ b/packages/cli/src/ui/utils/terminalSetup.ts @@ -245,6 +245,7 @@ async function configureVSCodeStyle( const results = targetBindings.map((target) => { const hasOurBinding = keybindings.some((kb) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const binding = kb as { command?: string; args?: { text?: string }; @@ -258,6 +259,7 @@ async function configureVSCodeStyle( }); const existingBinding = keybindings.find((kb) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const binding = kb as { key?: string }; return binding.key === target.key; }); diff --git a/packages/cli/src/ui/utils/textUtils.ts b/packages/cli/src/ui/utils/textUtils.ts index 63ca672989..c56f2f4430 100644 --- a/packages/cli/src/ui/utils/textUtils.ts +++ b/packages/cli/src/ui/utils/textUtils.ts @@ -203,6 +203,7 @@ export function escapeAnsiCtrlCodes(obj: T): T { } regex.lastIndex = 0; // needed for global regex + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return obj.replace(regex, (match) => JSON.stringify(match).slice(1, -1), ) as T; @@ -225,6 +226,7 @@ export function escapeAnsiCtrlCodes(obj: T): T { newArr[i] = escapedValue; } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (newArr !== null ? newArr : obj) as T; } @@ -232,6 +234,7 @@ export function escapeAnsiCtrlCodes(obj: T): T { const keys = Object.keys(obj); for (const key of keys) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const value = (obj as Record)[key]; const escapedValue = escapeAnsiCtrlCodes(value); @@ -239,6 +242,7 @@ export function escapeAnsiCtrlCodes(obj: T): T { if (newObj === null) { newObj = { ...obj }; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (newObj as Record)[key] = escapedValue; } } diff --git a/packages/cli/src/utils/activityLogger.ts b/packages/cli/src/utils/activityLogger.ts index 4e88dd5c60..721b0d1cb5 100644 --- a/packages/cli/src/utils/activityLogger.ts +++ b/packages/cli/src/utils/activityLogger.ts @@ -147,7 +147,8 @@ export class ActivityLogger extends EventEmitter { ? input : input instanceof URL ? input.toString() - : (input as any).url; + : // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (input as any).url; if (url.includes('127.0.0.1') || url.includes('localhost')) return originalFetch(input, init); @@ -311,6 +312,7 @@ export class ActivityLogger extends EventEmitter { req.write = function (chunk: any, ...etc: any[]) { if (chunk) { const encoding = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion typeof etc[0] === 'string' ? (etc[0] as BufferEncoding) : undefined; requestChunks.push( Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding), @@ -322,6 +324,7 @@ export class ActivityLogger extends EventEmitter { req.end = function (this: any, chunk: any, ...etc: any[]) { if (chunk && typeof chunk !== 'function') { const encoding = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion typeof etc[0] === 'string' ? (etc[0] as BufferEncoding) : undefined; requestChunks.push( Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding), diff --git a/packages/cli/src/utils/commentJson.ts b/packages/cli/src/utils/commentJson.ts index 5c1f9bebb2..c60011b81f 100644 --- a/packages/cli/src/utils/commentJson.ts +++ b/packages/cli/src/utils/commentJson.ts @@ -29,6 +29,7 @@ export function updateSettingsFilePreservingFormat( let parsed: Record; try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion parsed = parse(originalContent) as Record; } catch (error) { coreEvents.emitFeedback( @@ -61,7 +62,9 @@ function preserveCommentsOnPropertyDeletion( const beforeSym = Symbol.for(`before:${propName}`); const afterSym = Symbol.for(`after:${propName}`); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const beforeComments = target[beforeSym] as unknown[] | undefined; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const afterComments = target[afterSym] as unknown[] | undefined; if (!beforeComments && !afterComments) return; @@ -137,7 +140,9 @@ function applyKeyDiff( if (isObj && isBaseObj) { applyKeyDiff( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion baseVal as Record, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion nextVal as Record, ); } else if (isArr && isBaseArr) { diff --git a/packages/cli/src/utils/deepMerge.ts b/packages/cli/src/utils/deepMerge.ts index f4fec4d3c8..740021361f 100644 --- a/packages/cli/src/utils/deepMerge.ts +++ b/packages/cli/src/utils/deepMerge.ts @@ -67,6 +67,7 @@ function mergeRecursively( } else if (isPlainObject(srcValue)) { target[key] = {}; mergeRecursively( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion target[key] as MergeableObject, srcValue, getMergeStrategyForPath, diff --git a/packages/cli/src/utils/envVarResolver.ts b/packages/cli/src/utils/envVarResolver.ts index 1343a6d92b..fac43682a5 100644 --- a/packages/cli/src/utils/envVarResolver.ts +++ b/packages/cli/src/utils/envVarResolver.ts @@ -82,6 +82,7 @@ function resolveEnvVarsInObjectInternal( } if (typeof obj === 'string') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return resolveEnvVarsInString(obj, customEnv) as unknown as T; } @@ -89,10 +90,12 @@ function resolveEnvVarsInObjectInternal( // Check for circular reference if (visited.has(obj)) { // Return a shallow copy to break the cycle + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return [...obj] as unknown as T; } visited.add(obj); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const result = obj.map((item) => resolveEnvVarsInObjectInternal(item, visited, customEnv), ) as unknown as T; diff --git a/packages/cli/src/utils/errors.ts b/packages/cli/src/utils/errors.ts index b70ccfa3d1..89c0fe6b22 100644 --- a/packages/cli/src/utils/errors.ts +++ b/packages/cli/src/utils/errors.ts @@ -38,6 +38,7 @@ interface ErrorWithCode extends Error { * Extracts the appropriate error code from an error object. */ function extractErrorCode(error: unknown): string | number { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const errorWithCode = error as ErrorWithCode; // Prioritize exitCode for FatalError types, fall back to other codes diff --git a/packages/cli/src/utils/sessionCleanup.ts b/packages/cli/src/utils/sessionCleanup.ts index 8f38792ac6..6004cb8c5d 100644 --- a/packages/cli/src/utils/sessionCleanup.ts +++ b/packages/cli/src/utils/sessionCleanup.ts @@ -273,6 +273,7 @@ function parseRetentionPeriod(period: string): number { ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return value * MULTIPLIERS[unit as keyof typeof MULTIPLIERS]; } @@ -293,6 +294,7 @@ function validateRetentionConfig( try { maxAgeMs = parseRetentionPeriod(retentionConfig.maxAge); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (error as Error | string).toString(); } diff --git a/packages/cli/src/utils/sessionUtils.ts b/packages/cli/src/utils/sessionUtils.ts index b49a461ce2..6a132f42cc 100644 --- a/packages/cli/src/utils/sessionUtils.ts +++ b/packages/cli/src/utils/sessionUtils.ts @@ -617,7 +617,8 @@ export function convertSessionToHistoryFormats( clientHistory.push({ role: 'user', parts: Array.isArray(msg.content) - ? (msg.content as Part[]) + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (msg.content as Part[]) : [{ text: contentString }], }); } else if (msg.type === 'gemini') { @@ -670,6 +671,7 @@ export function convertSessionToHistoryFormats( } else if (Array.isArray(toolCall.result)) { // toolCall.result is an array containing properly formatted // function responses + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion functionResponseParts.push(...(toolCall.result as Part[])); continue; } else { diff --git a/packages/cli/src/utils/settingsUtils.ts b/packages/cli/src/utils/settingsUtils.ts index 7a0a4cd84b..f5aa18a41e 100644 --- a/packages/cli/src/utils/settingsUtils.ts +++ b/packages/cli/src/utils/settingsUtils.ts @@ -145,6 +145,7 @@ export function getNestedValue( return value; } if (value && typeof value === 'object' && value !== null) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return getNestedValue(value as Record, rest); } return undefined; @@ -169,12 +170,14 @@ export function getEffectiveValue( // Check the current scope's settings first let value = getNestedValue(settings as Record, path); if (value !== undefined) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return value as SettingsValue; } // Check the merged settings for an inherited value value = getNestedValue(mergedSettings as Record, path); if (value !== undefined) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return value as SettingsValue; } @@ -354,6 +357,7 @@ function setNestedValue( obj[first] = {}; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion setNestedValue(obj[first] as Record, rest, value); return obj; } diff --git a/packages/cli/src/zed-integration/zedIntegration.ts b/packages/cli/src/zed-integration/zedIntegration.ts index ea5a9dc039..57d8dec3a8 100644 --- a/packages/cli/src/zed-integration/zedIntegration.ts +++ b/packages/cli/src/zed-integration/zedIntegration.ts @@ -62,6 +62,7 @@ export async function runZedIntegration( ) { const { stdout: workingStdout } = createWorkingStdio(); const stdout = Writable.toWeb(workingStdout) as WritableStream; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const stdin = Readable.toWeb(process.stdin) as ReadableStream; const stream = acp.ndJsonStream(stdout, stdin); diff --git a/packages/core/src/agents/agentLoader.ts b/packages/core/src/agents/agentLoader.ts index d5478ddb6b..8d5e44b93c 100644 --- a/packages/core/src/agents/agentLoader.ts +++ b/packages/core/src/agents/agentLoader.ts @@ -185,6 +185,7 @@ export async function parseAgentMarkdown( } catch (error) { throw new AgentLoadError( filePath, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion `YAML frontmatter parsing failed: ${(error as Error).message}`, ); } @@ -328,12 +329,14 @@ export async function loadAgentsFromDirectory( dirEntries = await fs.readdir(dir, { withFileTypes: true }); } catch (error) { // If directory doesn't exist, just return empty + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code === 'ENOENT') { return result; } result.errors.push( new AgentLoadError( dir, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion `Could not list directory: ${(error as Error).message}`, ), ); @@ -364,6 +367,7 @@ export async function loadAgentsFromDirectory( result.errors.push( new AgentLoadError( filePath, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion `Unexpected error: ${(error as Error).message}`, ), ); diff --git a/packages/core/src/agents/local-executor.ts b/packages/core/src/agents/local-executor.ts index 30a7e59f99..e9fee219e3 100644 --- a/packages/core/src/agents/local-executor.ts +++ b/packages/core/src/agents/local-executor.ts @@ -822,6 +822,7 @@ export class LocalAgentExecutor { for (const [index, functionCall] of functionCalls.entries()) { const callId = functionCall.id ?? `${promptId}-${index}`; const args = functionCall.args ?? {}; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const toolName = functionCall.name as string; this.emitActivity('TOOL_CALL_START', { @@ -1107,6 +1108,7 @@ export class LocalAgentExecutor { ...schema } = jsonSchema; completeTool.parameters!.properties![outputConfig.outputName] = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion schema as Schema; completeTool.parameters!.required!.push(outputConfig.outputName); } else { diff --git a/packages/core/src/availability/testUtils.ts b/packages/core/src/availability/testUtils.ts index 8b76c0f053..d27cfc7ee9 100644 --- a/packages/core/src/availability/testUtils.ts +++ b/packages/core/src/availability/testUtils.ts @@ -26,5 +26,6 @@ export function createAvailabilityServiceMock( selectFirstAvailable: vi.fn().mockReturnValue(selection), }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return service as unknown as ModelAvailabilityService; } diff --git a/packages/core/src/code_assist/converter.ts b/packages/core/src/code_assist/converter.ts index 8dcfe80d78..1f2b4417ac 100644 --- a/packages/core/src/code_assist/converter.ts +++ b/packages/core/src/code_assist/converter.ts @@ -208,6 +208,7 @@ function toContent(content: ContentUnion): Content { // it's a Part return { role: 'user', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion parts: [toPart(content as Part)], }; } diff --git a/packages/core/src/code_assist/experiments/experiments.ts b/packages/core/src/code_assist/experiments/experiments.ts index ecb98491eb..614fbda43e 100644 --- a/packages/core/src/code_assist/experiments/experiments.ts +++ b/packages/core/src/code_assist/experiments/experiments.ts @@ -44,6 +44,7 @@ export async function getExperiments( 'Invalid format for experiments file: `flags` and `experimentIds` must be arrays if present.', ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return parseExperiments(response as ListExperimentsResponse); } catch (e) { debugLogger.debug('Failed to read experiments from GEMINI_EXP', e); diff --git a/packages/core/src/code_assist/oauth-credential-storage.ts b/packages/core/src/code_assist/oauth-credential-storage.ts index 149f53b97f..836fe1c4c3 100644 --- a/packages/core/src/code_assist/oauth-credential-storage.ts +++ b/packages/core/src/code_assist/oauth-credential-storage.ts @@ -125,6 +125,7 @@ export class OAuthCredentialStorage { throw error; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const credentials = JSON.parse(credsJson) as Credentials; // Save to new storage diff --git a/packages/core/src/code_assist/oauth2.ts b/packages/core/src/code_assist/oauth2.ts index 0e4cb50ab6..9676f2aa74 100644 --- a/packages/core/src/code_assist/oauth2.ts +++ b/packages/core/src/code_assist/oauth2.ts @@ -115,6 +115,7 @@ async function initOauthClient( if ( credentials && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (credentials as { type?: string }).type === 'external_account_authorized_user' ) { @@ -602,6 +603,7 @@ export function getAvailablePort(): Promise { } const server = net.createServer(); server.listen(0, () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const address = server.address()! as net.AddressInfo; port = address.port; }); diff --git a/packages/core/src/code_assist/server.ts b/packages/core/src/code_assist/server.ts index fa34464444..055c041d2b 100644 --- a/packages/core/src/code_assist/server.ts +++ b/packages/core/src/code_assist/server.ts @@ -301,6 +301,7 @@ export class CodeAssistServer implements ContentGenerator { body: JSON.stringify(req), signal, }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return res.data as T; } @@ -318,6 +319,7 @@ export class CodeAssistServer implements ContentGenerator { responseType: 'json', signal, }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return res.data as T; } @@ -351,6 +353,7 @@ export class CodeAssistServer implements ContentGenerator { return (async function* (): AsyncGenerator { const rl = readline.createInterface({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion input: res.data as NodeJS.ReadableStream, crlfDelay: Infinity, // Recognizes '\r\n' and '\n' as line breaks }); @@ -363,6 +366,7 @@ export class CodeAssistServer implements ContentGenerator { if (bufferedLines.length === 0) { continue; // no data to yield } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion yield JSON.parse(bufferedLines.join('\n')) as T; bufferedLines = []; // Reset the buffer after yielding } @@ -390,11 +394,13 @@ export class CodeAssistServer implements ContentGenerator { function isVpcScAffectedUser(error: unknown): boolean { if (error && typeof error === 'object' && 'response' in error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const gaxiosError = error as { response?: { data?: unknown; }; }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const response = gaxiosError.response?.data as | GoogleRpcResponse | undefined; diff --git a/packages/core/src/commands/restore.ts b/packages/core/src/commands/restore.ts index 06c2013845..4824c99fe3 100644 --- a/packages/core/src/commands/restore.ts +++ b/packages/core/src/commands/restore.ts @@ -42,6 +42,7 @@ export async function* performRestore< content: 'Restored project to the state before the tool call.', }; } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; if (error.message.includes('unable to read tree')) { yield { diff --git a/packages/core/src/confirmation-bus/message-bus.ts b/packages/core/src/confirmation-bus/message-bus.ts index 722cb37344..b9033fd67d 100644 --- a/packages/core/src/confirmation-bus/message-bus.ts +++ b/packages/core/src/confirmation-bus/message-bus.ts @@ -146,7 +146,7 @@ export class MessageBus extends EventEmitter { this.subscribe(responseType, responseHandler); // Publish the request with correlation ID - // eslint-disable-next-line @typescript-eslint/no-floating-promises + // eslint-disable-next-line @typescript-eslint/no-floating-promises, @typescript-eslint/no-unsafe-type-assertion this.publish({ ...request, correlationId } as TRequest); }); } diff --git a/packages/core/src/core/coreToolHookTriggers.ts b/packages/core/src/core/coreToolHookTriggers.ts index 551c6aef1f..0ed947623c 100644 --- a/packages/core/src/core/coreToolHookTriggers.ts +++ b/packages/core/src/core/coreToolHookTriggers.ts @@ -73,6 +73,7 @@ export async function executeToolWithHooks( setPidCallback?: (pid: number) => void, config?: Config, ): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const toolInput = (invocation.params || {}) as Record; let inputWasModified = false; let modifiedKeys: string[] = []; diff --git a/packages/core/src/core/coreToolScheduler.ts b/packages/core/src/core/coreToolScheduler.ts index 96cb05d970..d3346c9ffa 100644 --- a/packages/core/src/core/coreToolScheduler.ts +++ b/packages/core/src/core/coreToolScheduler.ts @@ -224,6 +224,7 @@ export class CoreToolScheduler { tool: toolInstance, invocation, status: 'success', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion response: auxiliaryData as ToolCallResponseInfo, durationMs, outcome, @@ -237,6 +238,7 @@ export class CoreToolScheduler { request: currentCall.request, status: 'error', tool: toolInstance, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion response: auxiliaryData as ToolCallResponseInfo, durationMs, outcome, @@ -247,6 +249,7 @@ export class CoreToolScheduler { request: currentCall.request, tool: toolInstance, status: 'awaiting_approval', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion confirmationDetails: auxiliaryData as ToolCallConfirmationDetails, startTime: existingStartTime, outcome, @@ -347,6 +350,7 @@ export class CoreToolScheduler { const invocationOrError = this.buildInvocation( call.tool, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion args as Record, ); if (invocationOrError instanceof Error) { @@ -356,6 +360,7 @@ export class CoreToolScheduler { ToolErrorType.INVALID_TOOL_PARAMS, ); return { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion request: { ...call.request, args: args as Record }, status: 'error', tool: call.tool, @@ -365,6 +370,7 @@ export class CoreToolScheduler { return { ...call, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion request: { ...call.request, args: args as Record }, invocation: invocationOrError, }; @@ -749,6 +755,7 @@ export class CoreToolScheduler { this.cancelAll(signal); return; // `cancelAll` calls `checkAndNotifyCompletion`, so we can exit here. } else if (outcome === ToolConfirmationOutcome.ModifyWithEditor) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const waitingToolCall = toolCall as WaitingToolCall; const editorType = this.getPreferredEditor(); @@ -756,6 +763,7 @@ export class CoreToolScheduler { return; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.setStatusInternal(callId, 'awaiting_approval', signal, { ...waitingToolCall.confirmationDetails, isModifying: true, @@ -770,12 +778,14 @@ export class CoreToolScheduler { // Restore status (isModifying: false) and update diff if result exists if (result) { this.setArgsInternal(callId, result.updatedParams); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.setStatusInternal(callId, 'awaiting_approval', signal, { ...waitingToolCall.confirmationDetails, fileDiff: result.updatedDiff, isModifying: false, } as ToolCallConfirmationDetails); } else { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.setStatusInternal(callId, 'awaiting_approval', signal, { ...waitingToolCall.confirmationDetails, isModifying: false, @@ -786,13 +796,16 @@ export class CoreToolScheduler { // re-confirmation. if (payload && 'newContent' in payload && toolCall) { const result = await this.toolModifier.applyInlineModify( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion toolCall as WaitingToolCall, payload, signal, ); if (result) { this.setArgsInternal(callId, result.updatedParams); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.setStatusInternal(callId, 'awaiting_approval', signal, { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(toolCall as WaitingToolCall).confirmationDetails, fileDiff: result.updatedDiff, } as ToolCallConfirmationDetails); diff --git a/packages/core/src/core/fakeContentGenerator.ts b/packages/core/src/core/fakeContentGenerator.ts index e6d7bbf8ff..a6185b3eae 100644 --- a/packages/core/src/core/fakeContentGenerator.ts +++ b/packages/core/src/core/fakeContentGenerator.ts @@ -51,6 +51,7 @@ export class FakeContentGenerator implements ContentGenerator { const responses = fileContent .split('\n') .filter((line) => line.trim() !== '') + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion .map((line) => JSON.parse(line) as FakeResponse); return new FakeContentGenerator(responses); } @@ -71,6 +72,7 @@ export class FakeContentGenerator implements ContentGenerator { `Unexpected response type, next response was for ${response.method} but expected ${method}`, ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return response.response as R; } diff --git a/packages/core/src/core/geminiChat.ts b/packages/core/src/core/geminiChat.ts index 8f2c4b9267..70a2a00282 100644 --- a/packages/core/src/core/geminiChat.ts +++ b/packages/core/src/core/geminiChat.ts @@ -560,6 +560,7 @@ export class GeminiChat { beforeModelResult.modifiedContents && Array.isArray(beforeModelResult.modifiedContents) ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion contentsToUse = beforeModelResult.modifiedContents as Content[]; } @@ -577,6 +578,7 @@ export class GeminiChat { toolSelectionResult.tools && Array.isArray(toolSelectionResult.tools) ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion config.tools = toolSelectionResult.tools as Tool[]; } } @@ -820,6 +822,7 @@ export class GeminiChat { (candidate) => candidate.finishReason, ); if (candidateWithReason) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion finishReason = candidateWithReason.finishReason as FinishReason; } diff --git a/packages/core/src/core/logger.ts b/packages/core/src/core/logger.ts index 595ca919fd..83f4183ce4 100644 --- a/packages/core/src/core/logger.ts +++ b/packages/core/src/core/logger.ts @@ -96,6 +96,7 @@ export class Logger { await this._backupCorruptedLogFile('malformed_array'); return []; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return parsedLogs.filter( (entry) => typeof entry.sessionId === 'string' && @@ -105,6 +106,7 @@ export class Logger { typeof entry.message === 'string', ) as LogEntry[]; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code === 'ENOENT') { return []; @@ -298,6 +300,7 @@ export class Logger { await fs.access(newPath); return newPath; // Found it, use the new path. } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code !== 'ENOENT') { throw error; // A real error occurred, rethrow it. @@ -311,6 +314,7 @@ export class Logger { await fs.access(oldPath); return oldPath; // Found it, use the old path. } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code !== 'ENOENT') { throw error; // A real error occurred, rethrow it. @@ -352,6 +356,7 @@ export class Logger { // Handle legacy format (just an array of Content) if (Array.isArray(parsedContent)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return { history: parsedContent as Content[] }; } @@ -360,6 +365,7 @@ export class Logger { parsedContent !== null && 'history' in parsedContent ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return parsedContent as Checkpoint; } @@ -368,6 +374,7 @@ export class Logger { ); return { history: [] }; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code === 'ENOENT') { // This is okay, it just means the checkpoint doesn't exist in either format. @@ -397,6 +404,7 @@ export class Logger { await fs.unlink(newPath); deletedSomething = true; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code !== 'ENOENT') { debugLogger.error( @@ -415,6 +423,7 @@ export class Logger { await fs.unlink(oldPath); deletedSomething = true; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code !== 'ENOENT') { debugLogger.error( @@ -444,6 +453,7 @@ export class Logger { await fs.access(filePath); return true; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nodeError = error as NodeJS.ErrnoException; if (nodeError.code === 'ENOENT') { return false; // It truly doesn't exist in either format. diff --git a/packages/core/src/core/loggingContentGenerator.ts b/packages/core/src/core/loggingContentGenerator.ts index fd89f86f54..e3cf9d3ec5 100644 --- a/packages/core/src/core/loggingContentGenerator.ts +++ b/packages/core/src/core/loggingContentGenerator.ts @@ -177,7 +177,8 @@ export class LoggingContentGenerator implements ContentGenerator { this.config.getContentGeneratorConfig()?.authType, errorType, isStructuredError(error) - ? (error as StructuredError).status + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (error as StructuredError).status : undefined, ), ); diff --git a/packages/core/src/core/recordingContentGenerator.ts b/packages/core/src/core/recordingContentGenerator.ts index 510a20b8c1..71d783a9d2 100644 --- a/packages/core/src/core/recordingContentGenerator.ts +++ b/packages/core/src/core/recordingContentGenerator.ts @@ -48,6 +48,7 @@ export class RecordingContentGenerator implements ContentGenerator { ); const recordedResponse: FakeResponse = { method: 'generateContent', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion response: { candidates: response.candidates, usageMetadata: response.usageMetadata, @@ -73,6 +74,7 @@ export class RecordingContentGenerator implements ContentGenerator { async function* stream(filePath: string) { for await (const response of realResponses) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (recordedResponse.response as GenerateContentResponse[]).push({ candidates: response.candidates, usageMetadata: response.usageMetadata, diff --git a/packages/core/src/core/turn.ts b/packages/core/src/core/turn.ts index fc1619c05d..a0f5fbd7bf 100644 --- a/packages/core/src/core/turn.ts +++ b/packages/core/src/core/turn.ts @@ -384,7 +384,8 @@ export class Turn { error !== null && 'status' in error && typeof (error as { status: unknown }).status === 'number' - ? (error as { status: number }).status + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (error as { status: number }).status : undefined; const structuredError: StructuredError = { message: getErrorMessage(error), diff --git a/packages/core/src/hooks/hookAggregator.ts b/packages/core/src/hooks/hookAggregator.ts index 0583c08776..b8a280cca1 100644 --- a/packages/core/src/hooks/hookAggregator.ts +++ b/packages/core/src/hooks/hookAggregator.ts @@ -102,6 +102,7 @@ export class HookAggregator { case HookEventName.BeforeToolSelection: return this.mergeToolSelectionOutputs( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion outputs as BeforeToolSelectionOutput[], ); diff --git a/packages/core/src/hooks/hookRegistry.ts b/packages/core/src/hooks/hookRegistry.ts index 36987f2c6a..8ae142231a 100644 --- a/packages/core/src/hooks/hookRegistry.ts +++ b/packages/core/src/hooks/hookRegistry.ts @@ -226,6 +226,7 @@ please review the project settings (.gemini/settings.json) and remove them.`; this.validateHookConfig(hookConfig, eventName, source) ) { // Check if this hook is in the disabled list + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookName = this.getHookName({ config: hookConfig, } as HookRegistryEntry); @@ -282,6 +283,7 @@ please review the project settings (.gemini/settings.json) and remove them.`; */ private isValidEventName(eventName: string): eventName is HookEventName { const validEventNames = Object.values(HookEventName); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return validEventNames.includes(eventName as HookEventName); } diff --git a/packages/core/src/hooks/hookRunner.ts b/packages/core/src/hooks/hookRunner.ts index 2a54313d8c..d98d84faa7 100644 --- a/packages/core/src/hooks/hookRunner.ts +++ b/packages/core/src/hooks/hookRunner.ts @@ -174,6 +174,7 @@ export class HookRunner { typeof additionalContext === 'string' && 'prompt' in modifiedInput ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (modifiedInput as BeforeAgentInput).prompt += '\n\n' + additionalContext; } @@ -183,16 +184,19 @@ export class HookRunner { case HookEventName.BeforeModel: if ('llm_request' in hookOutput.hookSpecificOutput) { // For BeforeModel, we update the LLM request + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookBeforeModelOutput = hookOutput as BeforeModelOutput; if ( hookBeforeModelOutput.hookSpecificOutput?.llm_request && 'llm_request' in modifiedInput ) { // Merge the partial request with the existing request + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const currentRequest = (modifiedInput as BeforeModelInput) .llm_request; const partialRequest = hookBeforeModelOutput.hookSpecificOutput.llm_request; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (modifiedInput as BeforeModelInput).llm_request = { ...currentRequest, ...partialRequest, @@ -203,11 +207,14 @@ export class HookRunner { case HookEventName.BeforeTool: if ('tool_input' in hookOutput.hookSpecificOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const newToolInput = hookOutput.hookSpecificOutput[ 'tool_input' ] as Record; if (newToolInput && 'tool_input' in modifiedInput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (modifiedInput as BeforeToolInput).tool_input = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ...(modifiedInput as BeforeToolInput).tool_input, ...newToolInput, }; @@ -355,6 +362,7 @@ export class HookRunner { parsed = JSON.parse(parsed); } if (parsed) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion output = parsed as HookOutput; } } catch { diff --git a/packages/core/src/hooks/hookSystem.ts b/packages/core/src/hooks/hookSystem.ts index e3d14b4a62..1d5f346210 100644 --- a/packages/core/src/hooks/hookSystem.ts +++ b/packages/core/src/hooks/hookSystem.ts @@ -262,6 +262,7 @@ export class HookSystem { const blockingError = hookOutput?.getBlockingError(); if (blockingError?.blocked) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const beforeModelOutput = hookOutput as BeforeModelHookOutput; const syntheticResponse = beforeModelOutput.getSyntheticResponse(); return { @@ -273,6 +274,7 @@ export class HookSystem { } if (hookOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const beforeModelOutput = hookOutput as BeforeModelHookOutput; const modifiedRequest = beforeModelOutput.applyLLMRequestModifications(llmRequest); @@ -319,6 +321,7 @@ export class HookSystem { } if (hookOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const afterModelOutput = hookOutput as AfterModelHookOutput; const modifiedResponse = afterModelOutput.getModifiedResponse(); if (modifiedResponse) { diff --git a/packages/core/src/hooks/hookTranslator.ts b/packages/core/src/hooks/hookTranslator.ts index 56036a16db..82cd1a5850 100644 --- a/packages/core/src/hooks/hookTranslator.ts +++ b/packages/core/src/hooks/hookTranslator.ts @@ -282,6 +282,7 @@ export class HookTranslatorGenAIv1 extends HookTranslator { parts: textParts, }, finishReason: + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion candidate.finishReason as LLMResponse['candidates'][0]['finishReason'], index: candidate.index, safetyRatings: candidate.safetyRatings?.map((rating) => ({ @@ -306,6 +307,7 @@ export class HookTranslatorGenAIv1 extends HookTranslator { */ fromHookLLMResponse(hookResponse: LLMResponse): GenerateContentResponse { // Build response object with proper structure + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const response: GenerateContentResponse = { text: hookResponse.text, candidates: hookResponse.candidates.map((candidate) => ({ @@ -315,6 +317,7 @@ export class HookTranslatorGenAIv1 extends HookTranslator { text: part, })), }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion finishReason: candidate.finishReason as FinishReason, index: candidate.index, safetyRatings: candidate.safetyRatings, @@ -330,6 +333,7 @@ export class HookTranslatorGenAIv1 extends HookTranslator { */ toHookToolConfig(sdkToolConfig: ToolConfig): HookToolConfig { return { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion mode: sdkToolConfig.functionCallingConfig?.mode as HookToolConfig['mode'], allowedFunctionNames: sdkToolConfig.functionCallingConfig?.allowedFunctionNames, @@ -342,7 +346,8 @@ export class HookTranslatorGenAIv1 extends HookTranslator { fromHookToolConfig(hookToolConfig: HookToolConfig): ToolConfig { const functionCallingConfig: FunctionCallingConfig | undefined = hookToolConfig.mode || hookToolConfig.allowedFunctionNames - ? ({ + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + ({ mode: hookToolConfig.mode, allowedFunctionNames: hookToolConfig.allowedFunctionNames, } as FunctionCallingConfig) diff --git a/packages/core/src/hooks/trustedHooks.ts b/packages/core/src/hooks/trustedHooks.ts index e87382090c..1c9b5b5f18 100644 --- a/packages/core/src/hooks/trustedHooks.ts +++ b/packages/core/src/hooks/trustedHooks.ts @@ -71,6 +71,7 @@ export class TrustedHooksManager { const untrusted: string[] = []; for (const eventName of Object.keys(hooks)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const definitions = hooks[eventName as HookEventName]; if (!Array.isArray(definitions)) continue; @@ -99,6 +100,7 @@ export class TrustedHooksManager { const currentTrusted = new Set(this.trustedHooks[projectPath] || []); for (const eventName of Object.keys(hooks)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const definitions = hooks[eventName as HookEventName]; if (!Array.isArray(definitions)) continue; diff --git a/packages/core/src/hooks/types.ts b/packages/core/src/hooks/types.ts index 04616a18af..b4a8ce27e8 100644 --- a/packages/core/src/hooks/types.ts +++ b/packages/core/src/hooks/types.ts @@ -270,6 +270,7 @@ export class BeforeToolHookOutput extends DefaultHookOutput { input !== null && !Array.isArray(input) ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return input as Record; } } @@ -286,6 +287,7 @@ export class BeforeModelHookOutput extends DefaultHookOutput { */ getSyntheticResponse(): GenerateContentResponse | undefined { if (this.hookSpecificOutput && 'llm_response' in this.hookSpecificOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookResponse = this.hookSpecificOutput[ 'llm_response' ] as LLMResponse; @@ -304,12 +306,14 @@ export class BeforeModelHookOutput extends DefaultHookOutput { target: GenerateContentParameters, ): GenerateContentParameters { if (this.hookSpecificOutput && 'llm_request' in this.hookSpecificOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookRequest = this.hookSpecificOutput[ 'llm_request' ] as Partial; if (hookRequest) { // Convert hook format to SDK format const sdkRequest = defaultHookTranslator.fromHookLLMRequest( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion hookRequest as LLMRequest, target, ); @@ -335,6 +339,7 @@ export class BeforeToolSelectionHookOutput extends DefaultHookOutput { tools?: ToolListUnion; }): { toolConfig?: GenAIToolConfig; tools?: ToolListUnion } { if (this.hookSpecificOutput && 'toolConfig' in this.hookSpecificOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookToolConfig = this.hookSpecificOutput[ 'toolConfig' ] as HookToolConfig; @@ -362,12 +367,14 @@ export class AfterModelHookOutput extends DefaultHookOutput { */ getModifiedResponse(): GenerateContentResponse | undefined { if (this.hookSpecificOutput && 'llm_response' in this.hookSpecificOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const hookResponse = this.hookSpecificOutput[ 'llm_response' ] as Partial; if (hookResponse?.candidates?.[0]?.content?.parts?.length) { // Convert hook format to SDK format return defaultHookTranslator.fromHookLLMResponse( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion hookResponse as LLMResponse, ); } diff --git a/packages/core/src/ide/ide-connection-utils.ts b/packages/core/src/ide/ide-connection-utils.ts index 2b00f593c0..041c4c984a 100644 --- a/packages/core/src/ide/ide-connection-utils.ts +++ b/packages/core/src/ide/ide-connection-utils.ts @@ -213,8 +213,10 @@ export async function createProxyAwareFetch(ideServerHost: string) { ...init, dispatcher: agent, }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const options = fetchOptions as unknown as import('undici').RequestInit; const response = await fetchFn(url, options); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return new Response(response.body as ReadableStream | null, { status: response.status, statusText: response.statusText, diff --git a/packages/core/src/mcp/oauth-provider.ts b/packages/core/src/mcp/oauth-provider.ts index 9f6ee36c2f..64ccd5e71b 100644 --- a/packages/core/src/mcp/oauth-provider.ts +++ b/packages/core/src/mcp/oauth-provider.ts @@ -143,6 +143,7 @@ export class MCPOAuthProvider { ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (await response.json()) as OAuthClientRegistrationResponse; } @@ -377,6 +378,7 @@ export class MCPOAuthProvider { } server.listen(listenPort, () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const address = server.address() as net.AddressInfo; serverPort = address.port; debugLogger.log( @@ -580,6 +582,7 @@ export class MCPOAuthProvider { // Try to parse as JSON first, fall back to form-urlencoded try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return JSON.parse(responseText) as OAuthTokenResponse; } catch { // Parse form-urlencoded response @@ -702,6 +705,7 @@ export class MCPOAuthProvider { // Try to parse as JSON first, fall back to form-urlencoded try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return JSON.parse(responseText) as OAuthTokenResponse; } catch { // Parse form-urlencoded response diff --git a/packages/core/src/mcp/oauth-token-storage.ts b/packages/core/src/mcp/oauth-token-storage.ts index fd11299c8b..4316a67779 100644 --- a/packages/core/src/mcp/oauth-token-storage.ts +++ b/packages/core/src/mcp/oauth-token-storage.ts @@ -61,6 +61,7 @@ export class MCPOAuthTokenStorage implements TokenStorage { try { const tokenFile = this.getTokenFilePath(); const data = await fs.readFile(tokenFile, 'utf-8'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const tokens = JSON.parse(data) as OAuthCredentials[]; for (const credential of tokens) { @@ -68,6 +69,7 @@ export class MCPOAuthTokenStorage implements TokenStorage { } } catch (error) { // File doesn't exist or is invalid, return empty map + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { coreEvents.emitFeedback( 'error', @@ -222,6 +224,7 @@ export class MCPOAuthTokenStorage implements TokenStorage { const tokenFile = this.getTokenFilePath(); await fs.unlink(tokenFile); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { coreEvents.emitFeedback( 'error', diff --git a/packages/core/src/mcp/oauth-utils.ts b/packages/core/src/mcp/oauth-utils.ts index 98c39f4261..5a6dbcb9af 100644 --- a/packages/core/src/mcp/oauth-utils.ts +++ b/packages/core/src/mcp/oauth-utils.ts @@ -101,6 +101,7 @@ export class OAuthUtils { if (!response.ok) { return null; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (await response.json()) as OAuthProtectedResourceMetadata; } catch (error) { debugLogger.debug( @@ -124,6 +125,7 @@ export class OAuthUtils { if (!response.ok) { return null; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (await response.json()) as OAuthAuthorizationServerMetadata; } catch (error) { debugLogger.debug( diff --git a/packages/core/src/mcp/sa-impersonation-provider.ts b/packages/core/src/mcp/sa-impersonation-provider.ts index 837601c0db..4eab75e678 100644 --- a/packages/core/src/mcp/sa-impersonation-provider.ts +++ b/packages/core/src/mcp/sa-impersonation-provider.ts @@ -114,6 +114,7 @@ export class ServiceAccountImpersonationProvider implements McpAuthProvider { coreEvents.emitFeedback( 'error', 'Failed to obtain authentication token.', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion e as Error, ); return undefined; diff --git a/packages/core/src/mcp/token-storage/file-token-storage.ts b/packages/core/src/mcp/token-storage/file-token-storage.ts index 7a806de4a1..0dbc31a308 100644 --- a/packages/core/src/mcp/token-storage/file-token-storage.ts +++ b/packages/core/src/mcp/token-storage/file-token-storage.ts @@ -72,9 +72,11 @@ export class FileTokenStorage extends BaseTokenStorage { try { const data = await fs.readFile(this.tokenFilePath, 'utf-8'); const decrypted = this.decrypt(data); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const tokens = JSON.parse(decrypted) as Record; return new Map(Object.entries(tokens)); } catch (error: unknown) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const err = error as NodeJS.ErrnoException & { message?: string }; if (err.code === 'ENOENT') { return new Map(); @@ -144,6 +146,7 @@ export class FileTokenStorage extends BaseTokenStorage { try { await fs.unlink(this.tokenFilePath); } catch (error: unknown) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const err = error as NodeJS.ErrnoException; if (err.code !== 'ENOENT') { throw error; @@ -176,6 +179,7 @@ export class FileTokenStorage extends BaseTokenStorage { try { await fs.unlink(this.tokenFilePath); } catch (error: unknown) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const err = error as NodeJS.ErrnoException; if (err.code !== 'ENOENT') { throw error; diff --git a/packages/core/src/mcp/token-storage/keychain-token-storage.ts b/packages/core/src/mcp/token-storage/keychain-token-storage.ts index ac1d0266fc..a06e44fb1d 100644 --- a/packages/core/src/mcp/token-storage/keychain-token-storage.ts +++ b/packages/core/src/mcp/token-storage/keychain-token-storage.ts @@ -70,6 +70,7 @@ export class KeychainTokenStorage return null; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const credentials = JSON.parse(data) as OAuthCredentials; if (this.isTokenExpired(credentials)) { @@ -179,6 +180,7 @@ export class KeychainTokenStorage for (const cred of credentials) { try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const data = JSON.parse(cred.password) as OAuthCredentials; if (!this.isTokenExpired(data)) { result.set(cred.account, data); @@ -223,6 +225,7 @@ export class KeychainTokenStorage try { await this.deleteCredentials(server); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion errors.push(error as Error); } } diff --git a/packages/core/src/policy/config.ts b/packages/core/src/policy/config.ts index e08ebe43eb..78cf1e85ac 100644 --- a/packages/core/src/policy/config.ts +++ b/packages/core/src/policy/config.ts @@ -382,6 +382,7 @@ export function createPolicyUpdater( const fileContent = await fs.readFile(policyFile, 'utf-8'); existingData = toml.parse(fileContent) as { rule?: TomlRule[] }; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { debugLogger.warn( `Failed to parse ${policyFile}, overwriting with new policy.`, @@ -424,6 +425,7 @@ export function createPolicyUpdater( // Serialize back to TOML // @iarna/toml stringify might not produce beautiful output but it handles escaping correctly + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const newContent = toml.stringify(existingData as toml.JsonMap); // Atomic write: write to tmp then rename diff --git a/packages/core/src/policy/policy-engine.ts b/packages/core/src/policy/policy-engine.ts index c0baf3e5c7..8a643c8930 100644 --- a/packages/core/src/policy/policy-engine.ts +++ b/packages/core/src/policy/policy-engine.ts @@ -312,6 +312,7 @@ export class PolicyEngine { if (toolName && SHELL_TOOL_NAMES.includes(toolName)) { isShellCommand = true; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const args = toolCall.args as { command?: string; dir_path?: string }; command = args?.command; shellDirPath = args?.dir_path; diff --git a/packages/core/src/policy/stable-stringify.ts b/packages/core/src/policy/stable-stringify.ts index 78db692eab..8925bc5304 100644 --- a/packages/core/src/policy/stable-stringify.ts +++ b/packages/core/src/policy/stable-stringify.ts @@ -111,6 +111,7 @@ export function stableStringify(obj: unknown): string { const pairs: string[] = []; for (const key of sortedKeys) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const value = (currentObj as Record)[key]; // Skip undefined and function values in objects (per JSON spec) if (value !== undefined && typeof value !== 'function') { diff --git a/packages/core/src/policy/toml-loader.ts b/packages/core/src/policy/toml-loader.ts index 8e3d265a9a..df3bc4e9ba 100644 --- a/packages/core/src/policy/toml-loader.ts +++ b/packages/core/src/policy/toml-loader.ts @@ -234,6 +234,7 @@ export async function loadPoliciesFromToml( .filter((entry) => entry.isFile() && entry.name.endsWith('.toml')) .map((entry) => entry.name); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as NodeJS.ErrnoException; if (error.code === 'ENOENT') { // Directory doesn't exist, skip it (not an error) @@ -262,6 +263,7 @@ export async function loadPoliciesFromToml( try { parsed = toml.parse(fileContent); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; errors.push({ filePath, @@ -356,6 +358,7 @@ export async function loadPoliciesFromToml( try { policyRule.argsPattern = new RegExp(argsPattern); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; errors.push({ filePath, @@ -411,6 +414,7 @@ export async function loadPoliciesFromToml( const safetyCheckerRule: SafetyCheckerRule = { toolName: effectiveToolName, priority: checker.priority, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion checker: checker.checker as SafetyCheckerConfig, modes: checker.modes, }; @@ -419,6 +423,7 @@ export async function loadPoliciesFromToml( try { safetyCheckerRule.argsPattern = new RegExp(argsPattern); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; errors.push({ filePath, @@ -440,6 +445,7 @@ export async function loadPoliciesFromToml( checkers.push(...parsedCheckers); } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as NodeJS.ErrnoException; // Catch-all for unexpected errors if (error.code !== 'ENOENT') { diff --git a/packages/core/src/policy/types.ts b/packages/core/src/policy/types.ts index 6ccabd504a..e758aaf417 100644 --- a/packages/core/src/policy/types.ts +++ b/packages/core/src/policy/types.ts @@ -35,8 +35,10 @@ export function getHookSource(input: Record): HookSource { const source = input['hook_source']; if ( typeof source === 'string' && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion VALID_HOOK_SOURCES.includes(source as HookSource) ) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return source as HookSource; } return 'project'; diff --git a/packages/core/src/prompts/promptProvider.ts b/packages/core/src/prompts/promptProvider.ts index 1e6ee4206f..5c21f6fa16 100644 --- a/packages/core/src/prompts/promptProvider.ts +++ b/packages/core/src/prompts/promptProvider.ts @@ -183,11 +183,11 @@ export class PromptProvider { })), } as snippets.SystemPromptOptions; - basePrompt = ( - activeSnippets.getCoreSystemPrompt as ( - options: snippets.SystemPromptOptions, - ) => string - )(options); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + const getCoreSystemPrompt = activeSnippets.getCoreSystemPrompt as ( + options: snippets.SystemPromptOptions, + ) => string; + basePrompt = getCoreSystemPrompt(options); } // --- Finalization (Shell) --- diff --git a/packages/core/src/routing/strategies/compositeStrategy.ts b/packages/core/src/routing/strategies/compositeStrategy.ts index 0b3856a4bd..29e6b96355 100644 --- a/packages/core/src/routing/strategies/compositeStrategy.ts +++ b/packages/core/src/routing/strategies/compositeStrategy.ts @@ -49,6 +49,7 @@ export class CompositeStrategy implements TerminalStrategy { 0, -1, ) as RoutingStrategy[]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const terminalStrategy = this.strategies[ this.strategies.length - 1 ] as TerminalStrategy; diff --git a/packages/core/src/safety/built-in.ts b/packages/core/src/safety/built-in.ts index 57a22d55e3..540af36290 100644 --- a/packages/core/src/safety/built-in.ts +++ b/packages/core/src/safety/built-in.ts @@ -23,6 +23,7 @@ export interface InProcessChecker { export class AllowedPathChecker implements InProcessChecker { async check(input: SafetyCheckInput): Promise { const { toolCall, context } = input; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const config = input.config as AllowedPathConfig | undefined; // Build list of allowed directories diff --git a/packages/core/src/safety/context-builder.ts b/packages/core/src/safety/context-builder.ts index 9c20a1d7ab..f857104197 100644 --- a/packages/core/src/safety/context-builder.ts +++ b/packages/core/src/safety/context-builder.ts @@ -23,6 +23,7 @@ export class ContextBuilder { return { environment: { cwd: process.cwd(), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion workspaces: this.config .getWorkspaceContext() .getDirectories() as string[], @@ -44,11 +45,12 @@ export class ContextBuilder { for (const key of requiredKeys) { if (key in fullContext) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion (minimalContext as any)[key] = fullContext[key]; } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return minimalContext as SafetyCheckInput['context']; } } diff --git a/packages/core/src/scheduler/confirmation.ts b/packages/core/src/scheduler/confirmation.ts index ce431d1eca..8840900bdd 100644 --- a/packages/core/src/scheduler/confirmation.ts +++ b/packages/core/src/scheduler/confirmation.ts @@ -70,6 +70,7 @@ export async function awaitConfirmation( MessageBusType.TOOL_CONFIRMATION_RESPONSE, { signal }, )) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const response = msg as ToolConfirmationResponse; if (response.correlationId === correlationId) { return { @@ -84,6 +85,7 @@ export async function awaitConfirmation( } } } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if (signal.aborted || (error as Error).name === 'AbortError') { throw new Error('Operation cancelled'); } @@ -232,6 +234,7 @@ async function handleExternalModification( } const result = await modifier.handleModifyWithEditor( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion state.firstActiveCall as WaitingToolCall, editor, signal, @@ -258,6 +261,7 @@ async function handleInlineModification( ): Promise { const { state, modifier } = deps; const result = await modifier.applyInlineModify( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion state.firstActiveCall as WaitingToolCall, payload, signal, diff --git a/packages/core/src/scheduler/scheduler.ts b/packages/core/src/scheduler/scheduler.ts index 94842e1139..1cd8dc3317 100644 --- a/packages/core/src/scheduler/scheduler.ts +++ b/packages/core/src/scheduler/scheduler.ts @@ -476,6 +476,7 @@ export class Scheduler { if (signal.aborted) throw new Error('Operation cancelled'); this.state.updateStatus(callId, 'executing'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const activeCall = this.state.firstActiveCall as ExecutingToolCall; const result = await runWithToolCallContext( diff --git a/packages/core/src/scheduler/state-manager.ts b/packages/core/src/scheduler/state-manager.ts index 625d58a463..21e931a18a 100644 --- a/packages/core/src/scheduler/state-manager.ts +++ b/packages/core/src/scheduler/state-manager.ts @@ -370,6 +370,7 @@ export class SchedulerStateManager { confirmationDetails = data.confirmationDetails; } else { // TODO: Remove legacy callback shape once event-driven migration is complete + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion confirmationDetails = data as ToolCallConfirmationDetails; } @@ -489,6 +490,7 @@ export class SchedulerStateManager { private toExecuting(call: ToolCall, data?: unknown): ExecutingToolCall { this.validateHasToolAndInvocation(call, 'executing'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const execData = data as Partial | undefined; const liveOutput = execData?.liveOutput ?? diff --git a/packages/core/src/scheduler/tool-modifier.ts b/packages/core/src/scheduler/tool-modifier.ts index d964372bde..ac6e8f3337 100644 --- a/packages/core/src/scheduler/tool-modifier.ts +++ b/packages/core/src/scheduler/tool-modifier.ts @@ -48,6 +48,7 @@ export class ToolModificationHandler { typeof toolCall.request.args >( toolCall.request.args, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion modifyContext as ModifyContext, editorType, signal, @@ -76,6 +77,7 @@ export class ToolModificationHandler { return undefined; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const modifyContext = toolCall.tool.getModifyContext( signal, ) as ModifyContext; diff --git a/packages/core/src/services/chatRecordingService.ts b/packages/core/src/services/chatRecordingService.ts index ebe66edf01..bdce4f5f9e 100644 --- a/packages/core/src/services/chatRecordingService.ts +++ b/packages/core/src/services/chatRecordingService.ts @@ -191,6 +191,7 @@ export class ChatRecordingService { if ( error instanceof Error && 'code' in error && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (error as NodeJS.ErrnoException).code === 'ENOSPC' ) { this.conversationFile = null; @@ -420,6 +421,7 @@ export class ChatRecordingService { this.cachedLastConvData = fs.readFileSync(this.conversationFile!, 'utf8'); return JSON.parse(this.cachedLastConvData); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { debugLogger.error('Error reading conversation file.', error); throw error; @@ -460,6 +462,7 @@ export class ChatRecordingService { if ( error instanceof Error && 'code' in error && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (error as NodeJS.ErrnoException).code === 'ENOSPC' ) { this.conversationFile = null; diff --git a/packages/core/src/services/loopDetectionService.ts b/packages/core/src/services/loopDetectionService.ts index 378b0faaa3..23541a3903 100644 --- a/packages/core/src/services/loopDetectionService.ts +++ b/packages/core/src/services/loopDetectionService.ts @@ -449,6 +449,7 @@ export class LoopDetectionService { return false; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const flashConfidence = flashResult[ 'unproductive_state_confidence' ] as number; @@ -490,7 +491,8 @@ export class LoopDetectionService { ); const mainModelConfidence = mainModelResult - ? (mainModelResult['unproductive_state_confidence'] as number) + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (mainModelResult['unproductive_state_confidence'] as number) : 0; logLlmLoopCheck( diff --git a/packages/core/src/services/modelConfigService.ts b/packages/core/src/services/modelConfigService.ts index a73764e75a..c43cbdcc91 100644 --- a/packages/core/src/services/modelConfigService.ts +++ b/packages/core/src/services/modelConfigService.ts @@ -245,6 +245,7 @@ export class ModelConfigService { let matchedLevel = 0; // Default to Global const isMatch = matchEntries.every(([key, value]) => { if (key === 'model') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const level = modelToLevel.get(value as string); if (level === undefined) return false; matchedLevel = level; @@ -253,6 +254,7 @@ export class ModelConfigService { if (key === 'overrideScope' && value === 'core') { return context.overrideScope === 'core' || !context.overrideScope; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return context[key as keyof ModelConfigKey] === value; }); @@ -291,6 +293,7 @@ export class ModelConfigService { ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return { model: resolved.model, generateContentConfig: resolved.generateContentConfig, @@ -321,7 +324,9 @@ export class ModelConfigService { config2: GenerateContentConfig | undefined, ): GenerateContentConfig { return ModelConfigService.genericDeepMerge( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion config1 as Record | undefined, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion config2 as Record | undefined, ) as GenerateContentConfig; } diff --git a/packages/core/src/services/modelConfigServiceTestUtils.ts b/packages/core/src/services/modelConfigServiceTestUtils.ts index f6d0b9fbfc..5a1d2c8e53 100644 --- a/packages/core/src/services/modelConfigServiceTestUtils.ts +++ b/packages/core/src/services/modelConfigServiceTestUtils.ts @@ -13,6 +13,7 @@ export const makeResolvedModelConfig = ( model: string, overrides: Partial = {}, ): ResolvedModelConfig => + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion ({ model, generateContentConfig: { diff --git a/packages/core/src/services/shellExecutionService.ts b/packages/core/src/services/shellExecutionService.ts index 2e94bb1858..23ac63f772 100644 --- a/packages/core/src/services/shellExecutionService.ts +++ b/packages/core/src/services/shellExecutionService.ts @@ -510,6 +510,7 @@ export class ShellExecutionService { return { pid: child.pid, result }; } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; return { pid: undefined, @@ -778,6 +779,7 @@ export class ShellExecutionService { this.activePtys.delete(ptyProcess.pid); // Attempt to destroy the PTY to ensure FD is closed try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (ptyProcess as IPty & { destroy?: () => void }).destroy?.(); } catch { // Ignore errors during cleanup @@ -860,6 +862,7 @@ export class ShellExecutionService { return { pid: ptyProcess.pid, result }; } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; if (error.message.includes('posix_spawnp failed')) { onOutputEvent({ @@ -1105,6 +1108,7 @@ export class ShellExecutionService { } catch (e) { // Ignore errors if the pty has already exited, which can happen // due to a race condition between the exit event and this call. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const err = e as { code?: string; message?: string }; const isEsrch = err.code === 'ESRCH'; const isWindowsPtyError = err.message?.includes( diff --git a/packages/core/src/services/toolOutputMaskingService.ts b/packages/core/src/services/toolOutputMaskingService.ts index 5c7ff3500b..8a7ae0090d 100644 --- a/packages/core/src/services/toolOutputMaskingService.ts +++ b/packages/core/src/services/toolOutputMaskingService.ts @@ -189,6 +189,7 @@ export class ToolOutputMaskingService { await fsPromises.writeFile(filePath, content, 'utf-8'); const originalResponse = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (part.functionResponse.response as Record) || {}; const totalLines = content.split('\n').length; @@ -268,6 +269,7 @@ export class ToolOutputMaskingService { private getToolOutputContent(part: Part): string | null { if (!part.functionResponse) return null; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const response = part.functionResponse.response as Record; if (!response) return null; @@ -286,6 +288,7 @@ export class ToolOutputMaskingService { } private formatShellPreview(response: Record): string { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const content = (response['output'] || response['stdout'] || '') as string; if (typeof content !== 'string') { return typeof content === 'object' diff --git a/packages/core/src/skills/skillLoader.ts b/packages/core/src/skills/skillLoader.ts index 1293dab702..08374ec93a 100644 --- a/packages/core/src/skills/skillLoader.ts +++ b/packages/core/src/skills/skillLoader.ts @@ -42,6 +42,7 @@ function parseFrontmatter( try { const parsed = yaml.load(content); if (parsed && typeof parsed === 'object') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const { name, description } = parsed as Record; if (typeof name === 'string' && typeof description === 'string') { return { name, description }; diff --git a/packages/core/src/telemetry/activity-monitor.ts b/packages/core/src/telemetry/activity-monitor.ts index 2c9393bdb4..15b96cb1e3 100644 --- a/packages/core/src/telemetry/activity-monitor.ts +++ b/packages/core/src/telemetry/activity-monitor.ts @@ -174,6 +174,7 @@ export class ActivityMonitor { eventTypes: Record; timeRange: { start: number; end: number } | null; } { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const eventTypes = {} as Record; let start = Number.MAX_SAFE_INTEGER; let end = 0; diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts index 4a7f1db8d0..b63cac58eb 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts @@ -450,6 +450,7 @@ export class ClearcutLogger { if (this.config?.getDebugMode()) { debugLogger.log('Flushing log events to Clearcut.'); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const eventsToSend = this.events.toArray() as LogEventEntry[][]; this.events.clear(); @@ -493,6 +494,7 @@ export class ClearcutLogger { } } catch (e: unknown) { if (this.config?.getDebugMode()) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion debugLogger.warn('Error flushing log events:', e as Error); } diff --git a/packages/core/src/telemetry/gcp-exporters.ts b/packages/core/src/telemetry/gcp-exporters.ts index 16b83ff465..528b15b22e 100644 --- a/packages/core/src/telemetry/gcp-exporters.ts +++ b/packages/core/src/telemetry/gcp-exporters.ts @@ -104,6 +104,7 @@ export class GcpLogExporter implements LogRecordExporter { } catch (error) { resultCallback({ code: ExportResultCode.FAILED, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion error: error as Error, }); } diff --git a/packages/core/src/telemetry/integration.test.circular.ts b/packages/core/src/telemetry/integration.test.circular.ts index 9ff8a58eca..af09b3f8b0 100644 --- a/packages/core/src/telemetry/integration.test.circular.ts +++ b/packages/core/src/telemetry/integration.test.circular.ts @@ -15,6 +15,7 @@ import type { Config } from '../config/config.js'; describe('Circular Reference Integration Test', () => { it('should handle HttpsProxyAgent-like circular references in clearcut logging', () => { // Create a mock config with proxy + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getTelemetryEnabled: () => true, getUsageStatisticsEnabled: () => true, @@ -56,7 +57,7 @@ describe('Circular Reference Integration Test', () => { const logger = ClearcutLogger.getInstance(mockConfig); expect(() => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion logger?.enqueueLogEvent(problematicEvent as any); }).not.toThrow(); }); diff --git a/packages/core/src/telemetry/loggers.test.circular.ts b/packages/core/src/telemetry/loggers.test.circular.ts index 060c70ffec..6da8b31cd3 100644 --- a/packages/core/src/telemetry/loggers.test.circular.ts +++ b/packages/core/src/telemetry/loggers.test.circular.ts @@ -22,6 +22,7 @@ import { MockTool } from '../test-utils/mock-tool.js'; describe('Circular Reference Handling', () => { it('should handle circular references in tool function arguments', () => { // Create a mock config + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getTelemetryEnabled: () => true, getUsageStatisticsEnabled: () => true, @@ -78,6 +79,7 @@ describe('Circular Reference Handling', () => { }); it('should handle normal objects without circular references', () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockConfig = { getTelemetryEnabled: () => true, getUsageStatisticsEnabled: () => true, diff --git a/packages/core/src/telemetry/loggers.ts b/packages/core/src/telemetry/loggers.ts index c5ab6887d1..c3d1dbf6c6 100644 --- a/packages/core/src/telemetry/loggers.ts +++ b/packages/core/src/telemetry/loggers.ts @@ -111,6 +111,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 = { ...event, 'event.name': EVENT_TOOL_CALL, @@ -242,6 +243,7 @@ export function logRipgrepFallback( } export function logApiError(config: Config, event: ApiErrorEvent): void { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { ...event, 'event.name': EVENT_API_ERROR, @@ -273,6 +275,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 = { ...event, 'event.name': EVENT_API_RESPONSE, @@ -372,6 +375,7 @@ export function logSlashCommand( } export function logRewind(config: Config, event: RewindEvent): void { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const uiEvent = { ...event, 'event.name': EVENT_REWIND, diff --git a/packages/core/src/telemetry/metrics.ts b/packages/core/src/telemetry/metrics.ts index c6da448f54..73234f8daf 100644 --- a/packages/core/src/telemetry/metrics.ts +++ b/packages/core/src/telemetry/metrics.ts @@ -77,6 +77,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts tool calls, tagged by function name and success.', valueType: ValueType.INT, assign: (c: Counter) => (toolCallCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { function_name: string; success: boolean; @@ -88,6 +89,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts API requests, tagged by model and status.', valueType: ValueType.INT, assign: (c: Counter) => (apiRequestCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { model: string; status_code?: number | string; @@ -98,6 +100,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts the total number of tokens used.', valueType: ValueType.INT, assign: (c: Counter) => (tokenUsageCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { model: string; type: 'input' | 'output' | 'thought' | 'cache' | 'tool'; @@ -113,6 +116,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts file operations (create, read, update).', valueType: ValueType.INT, assign: (c: Counter) => (fileOperationCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { operation: FileOperation; lines?: number; @@ -125,6 +129,7 @@ const COUNTER_DEFINITIONS = { description: 'Number of lines changed (from file diffs).', valueType: ValueType.INT, assign: (c: Counter) => (linesChangedCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { function_name?: string; type: 'added' | 'removed'; @@ -152,6 +157,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts model routing failures.', valueType: ValueType.INT, assign: (c: Counter) => (modelRoutingFailureCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { 'routing.decision_source': string; 'routing.error_message': string; @@ -161,6 +167,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts model slash command calls.', valueType: ValueType.INT, assign: (c: Counter) => (modelSlashCommandCallCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { 'slash_command.model.model_name': string; }, @@ -169,6 +176,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts chat compression events.', valueType: ValueType.INT, assign: (c: Counter) => (chatCompressionCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { tokens_before: number; tokens_after: number; @@ -178,6 +186,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts agent runs, tagged by name and termination reason.', valueType: ValueType.INT, assign: (c: Counter) => (agentRunCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { agent_name: string; terminate_reason: string; @@ -187,6 +196,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts agent recovery attempts.', valueType: ValueType.INT, assign: (c: Counter) => (agentRecoveryAttemptCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { agent_name: string; reason: string; @@ -210,6 +220,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts plan executions (switching from Plan Mode).', valueType: ValueType.INT, assign: (c: Counter) => (planExecutionCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { approval_mode: string; }, @@ -218,6 +229,7 @@ const COUNTER_DEFINITIONS = { description: 'Counts hook calls, tagged by hook event name and success.', valueType: ValueType.INT, assign: (c: Counter) => (hookCallCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { hook_event_name: string; hook_name: string; @@ -232,6 +244,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (toolCallLatencyHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { function_name: string; }, @@ -241,6 +254,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (apiRequestLatencyHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { model: string; }, @@ -250,6 +264,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (modelRoutingLatencyHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { 'routing.decision_model': string; 'routing.decision_source': string; @@ -260,6 +275,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (agentDurationHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { agent_name: string; }, @@ -276,6 +292,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'turns', valueType: ValueType.INT, assign: (h: Histogram) => (agentTurnsHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { agent_name: string; }, @@ -285,6 +302,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (agentRecoveryAttemptDurationHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { agent_name: string; }, @@ -294,6 +312,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'token', valueType: ValueType.INT, assign: (h: Histogram) => (genAiClientTokenUsageHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { 'gen_ai.operation.name': string; 'gen_ai.provider.name': string; @@ -309,6 +328,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 's', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (genAiClientOperationDurationHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { 'gen_ai.operation.name': string; 'gen_ai.provider.name': string; @@ -324,6 +344,7 @@ const HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (c: Histogram) => (hookCallLatencyHistogram = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { hook_event_name: string; hook_name: string; @@ -337,6 +358,7 @@ const PERFORMANCE_COUNTER_DEFINITIONS = { description: 'Performance regression detection events.', valueType: ValueType.INT, assign: (c: Counter) => (regressionDetectionCounter = c), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { metric: string; severity: 'low' | 'medium' | 'high'; @@ -353,6 +375,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (startupTimeHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { phase: string; details?: Record; @@ -363,6 +386,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'bytes', valueType: ValueType.INT, assign: (h: Histogram) => (memoryUsageGauge = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { memory_type: MemoryMetricType; component?: string; @@ -389,6 +413,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (toolExecutionBreakdownHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { function_name: string; phase: ToolExecutionPhase; @@ -400,6 +425,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'ratio', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (tokenEfficiencyHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { model: string; metric: string; @@ -411,6 +437,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'ms', valueType: ValueType.INT, assign: (h: Histogram) => (apiRequestBreakdownHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { model: string; phase: ApiRequestPhase; @@ -421,6 +448,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'score', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (performanceScoreGauge = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { category: string; baseline?: number; @@ -432,6 +460,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'percent', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (regressionPercentageChangeHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { metric: string; severity: 'low' | 'medium' | 'high'; @@ -445,6 +474,7 @@ const PERFORMANCE_HISTOGRAM_DEFINITIONS = { unit: 'percent', valueType: ValueType.DOUBLE, assign: (h: Histogram) => (baselineComparisonHistogram = h), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion attributes: {} as { metric: string; category: string; diff --git a/packages/core/src/telemetry/semantic.ts b/packages/core/src/telemetry/semantic.ts index 31520eb802..23623b5b3e 100644 --- a/packages/core/src/telemetry/semantic.ts +++ b/packages/core/src/telemetry/semantic.ts @@ -65,8 +65,10 @@ function getStringReferences(parts: AnyPart[]): StringReference[] { } else if (part instanceof GenericPart) { if (part.type === 'executableCode' && typeof part['code'] === 'string') { refs.push({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion get: () => part['code'] as string, set: (val: string) => (part['code'] = val), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion len: () => (part['code'] as string).length, }); } else if ( @@ -74,8 +76,10 @@ function getStringReferences(parts: AnyPart[]): StringReference[] { typeof part['output'] === 'string' ) { refs.push({ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion get: () => part['output'] as string, set: (val: string) => (part['output'] = val), + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion len: () => (part['output'] as string).length, }); } diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index 7a7399fd74..0c438764f1 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -316,6 +316,7 @@ export class ToolCallEvent implements BaseTelemetryEvent { } } } else { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.function_name = function_name as string; this.function_args = function_args!; this.duration_ms = duration_ms!; diff --git a/packages/core/src/test-utils/mock-message-bus.ts b/packages/core/src/test-utils/mock-message-bus.ts index c28f077bf2..05ed8cb32d 100644 --- a/packages/core/src/test-utils/mock-message-bus.ts +++ b/packages/core/src/test-utils/mock-message-bus.ts @@ -62,6 +62,7 @@ export class MockMessageBus { if (!this.subscriptions.has(type)) { this.subscriptions.set(type, new Set()); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this.subscriptions.get(type)!.add(listener as (message: Message) => void); }, ); @@ -73,6 +74,7 @@ export class MockMessageBus { (type: T['type'], listener: (message: T) => void) => { const listeners = this.subscriptions.get(type); if (listeners) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion listeners.delete(listener as (message: Message) => void); } }, @@ -101,6 +103,7 @@ export class MockMessageBus { * Create a mock MessageBus for testing */ export function createMockMessageBus(): MessageBus { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return new MockMessageBus() as unknown as MessageBus; } @@ -110,5 +113,6 @@ export function createMockMessageBus(): MessageBus { export function getMockMessageBusInstance( messageBus: MessageBus, ): MockMessageBus { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return messageBus as unknown as MockMessageBus; } diff --git a/packages/core/src/test-utils/mockWorkspaceContext.ts b/packages/core/src/test-utils/mockWorkspaceContext.ts index 67c614e9f5..640b51f616 100644 --- a/packages/core/src/test-utils/mockWorkspaceContext.ts +++ b/packages/core/src/test-utils/mockWorkspaceContext.ts @@ -19,6 +19,7 @@ export function createMockWorkspaceContext( ): WorkspaceContext { const allDirs = [rootDir, ...additionalDirs]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mockWorkspaceContext = { addDirectory: vi.fn(), getDirectories: vi.fn().mockReturnValue(allDirs), diff --git a/packages/core/src/tools/activate-skill.ts b/packages/core/src/tools/activate-skill.ts index 381ad66976..cc9ba3048d 100644 --- a/packages/core/src/tools/activate-skill.ts +++ b/packages/core/src/tools/activate-skill.ts @@ -175,6 +175,7 @@ export class ActivateSkillTool extends BaseDeclarativeTool< } else { schema = z.object({ name: z + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion .enum(skillNames as [string, ...string[]]) .describe('The name of the skill to activate.'), }); diff --git a/packages/core/src/tools/mcp-client.ts b/packages/core/src/tools/mcp-client.ts index 3a009d37d6..16d89f4e47 100644 --- a/packages/core/src/tools/mcp-client.ts +++ b/packages/core/src/tools/mcp-client.ts @@ -875,6 +875,7 @@ class LenientJsonSchemaValidator implements jsonSchemaValidator { ); return (input: unknown) => ({ valid: true as const, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion data: input as T, errorMessage: undefined, }); @@ -889,6 +890,7 @@ export function populateMcpServerCommand( ): Record { if (mcpServerCommand) { const cmd = mcpServerCommand; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const args = parse(cmd, process.env) as string[]; if (args.some((arg) => typeof arg !== 'string')) { throw new Error('failed to parse mcpServerCommand: ' + cmd); @@ -1068,6 +1070,7 @@ export async function discoverTools( 'error', `Error discovering tool: '${ toolDef.name + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion }' from MCP server '${mcpServerName}': ${(error as Error).message}`, error, ); @@ -1121,6 +1124,7 @@ class McpCallableTool implements CallableTool { const result = await this.client.callTool( { name: call.name!, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion arguments: call.args as Record, }, undefined, @@ -1550,6 +1554,7 @@ export async function connectToMcpServer( return { client: mcpClient, transport }; } catch (error) { await transport.close(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion firstAttemptError = error as Error; throw error; } @@ -1589,6 +1594,7 @@ export async function connectToMcpServer( ); return { client: mcpClient, transport: sseTransport }; } catch (sseFallbackError) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion sseError = sseFallbackError as Error; // If SSE also returned 401, handle OAuth below @@ -1929,6 +1935,7 @@ export async function createTransport( let transport: Transport = new StdioClientTransport({ command: mcpServerConfig.command, args: mcpServerConfig.args || [], + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion env: sanitizeEnvironment( { ...process.env, @@ -1965,7 +1972,7 @@ export async function createTransport( const underlyingTransport = transport instanceof XcodeMcpBridgeFixTransport - ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion (transport as any).transport : transport; diff --git a/packages/core/src/tools/mcp-tool.ts b/packages/core/src/tools/mcp-tool.ts index 96d14fd525..c4d7a32038 100644 --- a/packages/core/src/tools/mcp-tool.ts +++ b/packages/core/src/tools/mcp-tool.ts @@ -373,6 +373,7 @@ function transformResourceLinkBlock(block: McpResourceLinkBlock): Part { */ function transformMcpContentToParts(sdkResponse: Part[]): Part[] { const funcResponse = sdkResponse?.[0]?.functionResponse; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mcpContent = funcResponse?.response?.['content'] as McpContentBlock[]; const toolName = funcResponse?.name || 'unknown tool'; @@ -410,6 +411,7 @@ function transformMcpContentToParts(sdkResponse: Part[]): Part[] { * @returns A formatted string representing the tool's output. */ function getStringifiedResultForDisplay(rawResponse: Part[]): string { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const mcpContent = rawResponse?.[0]?.functionResponse?.response?.[ 'content' ] as McpContentBlock[]; diff --git a/packages/core/src/tools/memoryTool.ts b/packages/core/src/tools/memoryTool.ts index 4cc3014357..032d012850 100644 --- a/packages/core/src/tools/memoryTool.ts +++ b/packages/core/src/tools/memoryTool.ts @@ -94,6 +94,7 @@ async function readMemoryFileContent(): Promise { try { return await fs.readFile(getGlobalMemoryFilePath(), 'utf-8'); } catch (err) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = err as Error & { code?: string }; if (!(error instanceof Error) || error.code !== 'ENOENT') throw err; return ''; diff --git a/packages/core/src/tools/tool-registry.ts b/packages/core/src/tools/tool-registry.ts index 94082dcb57..60b1451838 100644 --- a/packages/core/src/tools/tool-registry.ts +++ b/packages/core/src/tools/tool-registry.ts @@ -265,7 +265,9 @@ export class ToolRegistry { } if (priorityA === 2) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const serverA = (toolA as DiscoveredMCPTool).serverName; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const serverB = (toolB as DiscoveredMCPTool).serverName; return serverA.localeCompare(serverB); } @@ -319,6 +321,7 @@ export class ToolRegistry { 'Tool discovery command is empty or contains only whitespace.', ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const proc = spawn(cmdParts[0] as string, cmdParts.slice(1) as string[]); let stdout = ''; const stdoutDecoder = new StringDecoder('utf8'); @@ -398,6 +401,7 @@ export class ToolRegistry { } else if (Array.isArray(tool['functionDeclarations'])) { functions.push(...tool['functionDeclarations']); } else if (tool['name']) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion functions.push(tool as FunctionDeclaration); } } @@ -420,6 +424,7 @@ export class ToolRegistry { func.name, DISCOVERED_TOOL_PREFIX + func.name, func.description ?? '', + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion parameters as Record, this.messageBus, ), @@ -552,6 +557,7 @@ export class ToolRegistry { getToolsByServer(serverName: string): AnyDeclarativeTool[] { const serverTools: AnyDeclarativeTool[] = []; for (const tool of this.getActiveTools()) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((tool as DiscoveredMCPTool)?.serverName === serverName) { serverTools.push(tool); } diff --git a/packages/core/src/tools/tools.ts b/packages/core/src/tools/tools.ts index 2811653b20..3d90e80699 100644 --- a/packages/core/src/tools/tools.ts +++ b/packages/core/src/tools/tools.ts @@ -195,6 +195,7 @@ export abstract class BaseToolInvocation< correlationId, toolCall: { name: this._toolName, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion args: this.params as Record, }, serverName: this._serverName, @@ -536,6 +537,7 @@ export function isTool(obj: unknown): obj is AnyDeclarativeTool { obj !== null && 'name' in obj && 'build' in obj && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion typeof (obj as AnyDeclarativeTool).build === 'function' ); } @@ -590,8 +592,10 @@ export function hasCycleInSchema(schema: object): boolean { ) { return null; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion current = (current as Record)[segment]; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return current as object; } @@ -639,6 +643,7 @@ export function hasCycleInSchema(schema: object): boolean { if (Object.prototype.hasOwnProperty.call(node, key)) { if ( traverse( + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (node as Record)[key], visitedRefs, pathRefs, diff --git a/packages/core/src/tools/web-fetch.ts b/packages/core/src/tools/web-fetch.ts index 3f8df7fa14..254a90aa7b 100644 --- a/packages/core/src/tools/web-fetch.ts +++ b/packages/core/src/tools/web-fetch.ts @@ -194,6 +194,7 @@ ${textContent} returnDisplay: `Content for ${url} processed using fallback fetch.`, }; } catch (e) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const error = e as Error; const errorMessage = `Error during fallback fetch for ${url}: ${error.message}`; return { @@ -291,6 +292,7 @@ ${textContent} const sources = groundingMetadata?.groundingChunks as | GroundingChunkItem[] | undefined; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const groundingSupports = groundingMetadata?.groundingSupports as | GroundingSupportItem[] | undefined; diff --git a/packages/core/src/tools/web-search.ts b/packages/core/src/tools/web-search.ts index 5a1eeffb6d..4a1a6d0ae8 100644 --- a/packages/core/src/tools/web-search.ts +++ b/packages/core/src/tools/web-search.ts @@ -91,6 +91,7 @@ class WebSearchToolInvocation extends BaseToolInvocation< const sources = groundingMetadata?.groundingChunks as | GroundingChunkItem[] | undefined; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const groundingSupports = groundingMetadata?.groundingSupports as | GroundingSupportItem[] | undefined; diff --git a/packages/core/src/tools/xcode-mcp-fix-transport.ts b/packages/core/src/tools/xcode-mcp-fix-transport.ts index d7936e7e09..7daabef87e 100644 --- a/packages/core/src/tools/xcode-mcp-fix-transport.ts +++ b/packages/core/src/tools/xcode-mcp-fix-transport.ts @@ -75,7 +75,7 @@ export class XcodeMcpBridgeFixTransport // We can cast because we verified 'result' is in response, // but TS might still be picky if the type is a strict union. // Let's treat it safely. - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion const result = response.result as any; // Check if we have content but missing structuredContent diff --git a/packages/core/src/utils/bfsFileSearch.ts b/packages/core/src/utils/bfsFileSearch.ts index 781e988d30..460abfec27 100644 --- a/packages/core/src/utils/bfsFileSearch.ts +++ b/packages/core/src/utils/bfsFileSearch.ts @@ -80,6 +80,7 @@ export async function bfsFileSearch( return { currentDir, entries }; } catch (error) { // Warn user that a directory could not be read, as this affects search results. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const message = (error as Error)?.message ?? 'Unknown error'; debugLogger.warn( `[WARN] Skipping unreadable directory: ${currentDir} (${message})`, @@ -153,6 +154,7 @@ export function bfsFileSearchSync( foundFiles, ); } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const message = (error as Error)?.message ?? 'Unknown error'; debugLogger.warn( `[WARN] Skipping unreadable directory: ${currentDir} (${message})`, diff --git a/packages/core/src/utils/checkpointUtils.ts b/packages/core/src/utils/checkpointUtils.ts index 5bd66d7be9..2252fdf70b 100644 --- a/packages/core/src/utils/checkpointUtils.ts +++ b/packages/core/src/utils/checkpointUtils.ts @@ -49,6 +49,7 @@ export function generateCheckpointFileName( toolCall: ToolCallRequestInfo, ): string | null { const toolArgs = toolCall.args; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const toolFilePath = toolArgs['file_path'] as string; if (!toolFilePath) { @@ -167,6 +168,7 @@ export function getCheckpointInfoList( for (const [file, content] of checkpointFiles) { try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const toolCallData = JSON.parse(content) as ToolCallData; if (toolCallData.messageId) { checkpointInfoList.push({ diff --git a/packages/core/src/utils/editor.ts b/packages/core/src/utils/editor.ts index 08cb359a49..cdc1e1d4a5 100644 --- a/packages/core/src/utils/editor.ts +++ b/packages/core/src/utils/editor.ts @@ -208,9 +208,12 @@ export async function resolveEditorAsync( coreEvents.emit(CoreEvent.RequestEditorSelection); - return once(coreEvents, CoreEvent.EditorSelected, { signal }) - .then(([payload]) => (payload as EditorSelectedPayload).editor) - .catch(() => undefined); + return ( + once(coreEvents, CoreEvent.EditorSelected, { signal }) + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + .then(([payload]) => (payload as EditorSelectedPayload).editor) + .catch(() => undefined) + ); } /** diff --git a/packages/core/src/utils/errors.ts b/packages/core/src/utils/errors.ts index bd6512e04b..2bba4f8abe 100644 --- a/packages/core/src/utils/errors.ts +++ b/packages/core/src/utils/errors.ts @@ -98,6 +98,7 @@ interface ResponseData { export function toFriendlyError(error: unknown): unknown { if (error && typeof error === 'object' && 'response' in error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const gaxiosError = error as GaxiosError; const data = parseResponseData(gaxiosError); if (data && data.error && data.error.message && data.error.code) { @@ -122,11 +123,13 @@ function parseResponseData(error: GaxiosError): ResponseData | undefined { // Inexplicably, Gaxios sometimes doesn't JSONify the response data. if (typeof error.response?.data === 'string') { try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return JSON.parse(error.response?.data) as ResponseData; } catch { return undefined; } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return error.response?.data as ResponseData | undefined; } diff --git a/packages/core/src/utils/events.ts b/packages/core/src/utils/events.ts index 33d137980a..194de57531 100644 --- a/packages/core/src/utils/events.ts +++ b/packages/core/src/utils/events.ts @@ -199,14 +199,14 @@ export class CoreEventEmitter extends EventEmitter { if (this._eventBacklog.length >= CoreEventEmitter.MAX_BACKLOG_SIZE) { this._eventBacklog.shift(); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion this._eventBacklog.push({ event, args } as EventBacklogItem); } else { - ( - this.emit as ( - event: K, - ...args: CoreEvents[K] - ) => boolean - )(event, ...args); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (this.emit as (event: K, ...args: CoreEvents[K]) => boolean)( + event, + ...args, + ); } } @@ -319,12 +319,11 @@ export class CoreEventEmitter extends EventEmitter { const backlog = [...this._eventBacklog]; this._eventBacklog.length = 0; // Clear in-place for (const item of backlog) { - ( - this.emit as ( - event: K, - ...args: CoreEvents[K] - ) => boolean - )(item.event, ...item.args); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (this.emit as (event: keyof CoreEvents, ...args: unknown[]) => boolean)( + item.event, + ...item.args, + ); } } } diff --git a/packages/core/src/utils/generateContentResponseUtilities.ts b/packages/core/src/utils/generateContentResponseUtilities.ts index 5151da9f6d..fdd5dff81a 100644 --- a/packages/core/src/utils/generateContentResponseUtilities.ts +++ b/packages/core/src/utils/generateContentResponseUtilities.ts @@ -102,6 +102,7 @@ export function convertToFunctionResponse( if (inlineDataParts.length > 0) { if (isMultimodalFRSupported) { // Nest inlineData if supported by the model + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (part.functionResponse as unknown as { parts: Part[] }).parts = inlineDataParts; } else { @@ -151,6 +152,7 @@ export function getFunctionCalls( } const functionCallParts = parts .filter((part) => !!part.functionCall) + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion .map((part) => part.functionCall as FunctionCall); return functionCallParts.length > 0 ? functionCallParts : undefined; } @@ -163,6 +165,7 @@ export function getFunctionCallsFromParts( } const functionCallParts = parts .filter((part) => !!part.functionCall) + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion .map((part) => part.functionCall as FunctionCall); return functionCallParts.length > 0 ? functionCallParts : undefined; } diff --git a/packages/core/src/utils/googleErrors.ts b/packages/core/src/utils/googleErrors.ts index 56e20a95cd..70c7098118 100644 --- a/packages/core/src/utils/googleErrors.ts +++ b/packages/core/src/utils/googleErrors.ts @@ -195,6 +195,7 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null { if (Array.isArray(errorDetails)) { for (const detail of errorDetails) { if (detail && typeof detail === 'object') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const detailObj = detail as Record; const typeKey = Object.keys(detailObj).find( (key) => key.trim() === '@type', @@ -205,6 +206,7 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null { delete detailObj[typeKey]; } // We can just cast it; the consumer will have to switch on @type + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion details.push(detailObj as unknown as GoogleApiErrorDetail); } } @@ -253,6 +255,7 @@ function fromGaxiosError(errorObj: object): ErrorShape | undefined { if (typeof data === 'object' && data !== null) { if ('error' in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion outerError = (data as { error: ErrorShape }).error; } } @@ -309,6 +312,7 @@ function fromApiError(errorObj: object): ErrorShape | undefined { if (typeof data === 'object' && data !== null) { if ('error' in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion outerError = (data as { error: ErrorShape }).error; } } diff --git a/packages/core/src/utils/httpErrors.ts b/packages/core/src/utils/httpErrors.ts index a29732737b..08bd7e9fdb 100644 --- a/packages/core/src/utils/httpErrors.ts +++ b/packages/core/src/utils/httpErrors.ts @@ -24,9 +24,10 @@ export function getErrorStatus(error: unknown): number | undefined { typeof (error as { response?: unknown }).response === 'object' && (error as { response?: unknown }).response !== null ) { - const response = ( - error as { response: { status?: unknown; headers?: unknown } } - ).response; + const response = + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + (error as { response: { status?: unknown; headers?: unknown } }) + .response; if ('status' in response && typeof response.status === 'number') { return response.status; } diff --git a/packages/core/src/utils/llm-edit-fixer.ts b/packages/core/src/utils/llm-edit-fixer.ts index 79e0858f8f..05cd1b3e55 100644 --- a/packages/core/src/utils/llm-edit-fixer.ts +++ b/packages/core/src/utils/llm-edit-fixer.ts @@ -107,6 +107,7 @@ async function generateJsonWithTimeout( timeoutSignal, ]), }); + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return result as T; } catch (err) { debugLogger.debug( diff --git a/packages/core/src/utils/memoryDiscovery.ts b/packages/core/src/utils/memoryDiscovery.ts index 4997f543a0..650347d979 100644 --- a/packages/core/src/utils/memoryDiscovery.ts +++ b/packages/core/src/utils/memoryDiscovery.ts @@ -54,6 +54,7 @@ async function findProjectRoot(startDir: string): Promise { typeof error === 'object' && error !== null && 'code' in error && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (error as { code: string }).code === 'ENOENT'; // Only log unexpected errors in non-test environments @@ -63,6 +64,7 @@ async function findProjectRoot(startDir: string): Promise { if (!isENOENT && !isTestEnv) { if (typeof error === 'object' && error !== null && 'code' in error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const fsError = error as { code: string; message: string }; logger.warn( `Error checking for .git directory at ${gitPath}: ${fsError.message}`, @@ -311,6 +313,7 @@ export function concatenateInstructions( return instructionContents .filter((item) => typeof item.content === 'string') .map((item) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const trimmedContent = (item.content as string).trim(); if (trimmedContent.length === 0) { return null; @@ -359,6 +362,7 @@ export async function loadGlobalMemory( .filter((item) => item.content !== null) .map((item) => ({ path: item.filePath, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion content: item.content as string, })), }; @@ -456,6 +460,7 @@ export async function loadEnvironmentMemory( .filter((item) => item.content !== null) .map((item) => ({ path: item.filePath, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion content: item.content as string, })), }; @@ -640,6 +645,7 @@ export async function loadJitSubdirectoryMemory( .filter((item) => item.content !== null) .map((item) => ({ path: item.filePath, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion content: item.content as string, })), }; diff --git a/packages/core/src/utils/nextSpeakerChecker.ts b/packages/core/src/utils/nextSpeakerChecker.ts index 76b1c6a440..39d9c37f7a 100644 --- a/packages/core/src/utils/nextSpeakerChecker.ts +++ b/packages/core/src/utils/nextSpeakerChecker.ts @@ -109,6 +109,7 @@ export async function checkNextSpeaker( ]; try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const parsedResponse = (await baseLlmClient.generateJson({ modelConfigKey: { model: 'next-speaker-checker' }, contents, diff --git a/packages/core/src/utils/partUtils.ts b/packages/core/src/utils/partUtils.ts index 5afa60d5b5..52a59258bd 100644 --- a/packages/core/src/utils/partUtils.ts +++ b/packages/core/src/utils/partUtils.ts @@ -30,6 +30,7 @@ export function partToString( } // Cast to Part, assuming it might contain project-specific fields + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const part = value as Part & { videoMetadata?: unknown; thought?: string; diff --git a/packages/core/src/utils/quotaErrorDetection.ts b/packages/core/src/utils/quotaErrorDetection.ts index 893e48b0f2..b40e89005a 100644 --- a/packages/core/src/utils/quotaErrorDetection.ts +++ b/packages/core/src/utils/quotaErrorDetection.ts @@ -20,7 +20,9 @@ export function isApiError(error: unknown): error is ApiError { typeof error === 'object' && error !== null && 'error' in error && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion typeof (error as ApiError).error === 'object' && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion 'message' in (error as ApiError).error ); } @@ -30,6 +32,7 @@ export function isStructuredError(error: unknown): error is StructuredError { typeof error === 'object' && error !== null && 'message' in error && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion typeof (error as StructuredError).message === 'string' ); } diff --git a/packages/core/src/utils/retry.ts b/packages/core/src/utils/retry.ts index 8e9454e496..8b3fb1f200 100644 --- a/packages/core/src/utils/retry.ts +++ b/packages/core/src/utils/retry.ts @@ -68,6 +68,7 @@ function getNetworkErrorCode(error: unknown): string | undefined { return undefined; } if ('code' in obj && typeof (obj as { code: unknown }).code === 'string') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return (obj as { code: string }).code; } return undefined; @@ -196,6 +197,7 @@ export async function retryWithBackoff( if ( shouldRetryOnContent && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion shouldRetryOnContent(result as GenerateContentResponse) ) { const jitter = currentDelay * 0.3 * (Math.random() * 2 - 1); @@ -327,6 +329,7 @@ export async function retryWithBackoff( // Generic retry logic for other errors if ( attempt >= maxAttempts || + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion !shouldRetryOnError(error as Error, retryFetchErrors) ) { throw error; diff --git a/packages/core/src/utils/safeJsonStringify.ts b/packages/core/src/utils/safeJsonStringify.ts index 00eeee8cdf..fd03e7965d 100644 --- a/packages/core/src/utils/safeJsonStringify.ts +++ b/packages/core/src/utils/safeJsonStringify.ts @@ -56,6 +56,7 @@ function removeEmptyObjects(data: any): object { export function safeJsonStringifyBooleanValuesOnly(obj: any): string { let configSeen = false; return JSON.stringify(removeEmptyObjects(obj), (key, value) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((value as Config) !== null && !configSeen) { configSeen = true; return value; diff --git a/packages/core/src/utils/schemaValidator.ts b/packages/core/src/utils/schemaValidator.ts index 3bbdbe9e92..8d8579f647 100644 --- a/packages/core/src/utils/schemaValidator.ts +++ b/packages/core/src/utils/schemaValidator.ts @@ -12,9 +12,9 @@ import * as addFormats from 'ajv-formats'; import { debugLogger } from './debugLogger.js'; // Ajv's ESM/CJS interop: use 'any' for compatibility as recommended by Ajv docs -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion const AjvClass = (AjvPkg as any).default || AjvPkg; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion const Ajv2020Class = (Ajv2020Pkg as any).default || Ajv2020Pkg; const ajvOptions = { @@ -34,7 +34,7 @@ const ajvDefault: Ajv = new AjvClass(ajvOptions); // Draft-2020-12 validator for MCP servers using rmcp const ajv2020: Ajv = new Ajv2020Class(ajvOptions); -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion const addFormatsFunc = (addFormats as any).default || addFormats; addFormatsFunc(ajvDefault); addFormatsFunc(ajv2020); @@ -90,6 +90,7 @@ export class SchemaValidator { // This matches LenientJsonSchemaValidator behavior in mcp-client.ts. debugLogger.warn( `Failed to compile schema (${ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (schema as Record)?.['$schema'] ?? '' }): ${error instanceof Error ? error.message : String(error)}. ` + 'Skipping parameter validation.', @@ -121,6 +122,7 @@ export class SchemaValidator { // Skip validation rather than blocking tool usage. debugLogger.warn( `Failed to validate schema (${ + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (schema as Record)?.['$schema'] ?? '' }): ${error instanceof Error ? error.message : String(error)}. ` + 'Skipping schema validation.', diff --git a/packages/core/src/utils/security.ts b/packages/core/src/utils/security.ts index cd08a34dac..448776e1b1 100644 --- a/packages/core/src/utils/security.ts +++ b/packages/core/src/utils/security.ts @@ -66,6 +66,7 @@ export async function isDirectorySecure( } catch (error) { return { secure: false, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion reason: `A security check for the system policy directory '${dirPath}' failed and could not be completed. Please file a bug report. Original error: ${(error as Error).message}`, }; } @@ -93,11 +94,13 @@ export async function isDirectorySecure( return { secure: true }; } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion if ((error as NodeJS.ErrnoException).code === 'ENOENT') { return { secure: true }; } return { secure: false, + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion reason: `Failed to access directory: ${(error as Error).message}`, }; } diff --git a/packages/core/src/utils/shell-utils.ts b/packages/core/src/utils/shell-utils.ts index 3a002f2895..7daeb063f5 100644 --- a/packages/core/src/utils/shell-utils.ts +++ b/packages/core/src/utils/shell-utils.ts @@ -237,6 +237,7 @@ function parseCommandTree( progressCallback: () => { if (performance.now() > deadline) { timedOut = true; + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return true as unknown as void; // Returning true cancels parsing, but type says void } }, diff --git a/packages/core/src/utils/testUtils.ts b/packages/core/src/utils/testUtils.ts index c5ba1ac470..8187b9ee3f 100644 --- a/packages/core/src/utils/testUtils.ts +++ b/packages/core/src/utils/testUtils.ts @@ -52,6 +52,26 @@ export function disableSimulationAfterFallback(): void { fallbackOccurred = true; } +/** + * Create a simulated 429 error response + */ +export function createSimulated429Error(): Error { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + const error = new Error('Rate limit exceeded (simulated)') as Error & { + status: number; + }; + error.status = 429; + return error; +} + +/** + * Reset simulation state when switching auth methods + */ +export function resetSimulationState(): void { + fallbackOccurred = false; + resetRequestCounter(); +} + /** * Enable/disable 429 simulation programmatically (for tests) */ diff --git a/packages/core/src/utils/tokenCalculation.ts b/packages/core/src/utils/tokenCalculation.ts index 447424531e..d5a7fdc9eb 100644 --- a/packages/core/src/utils/tokenCalculation.ts +++ b/packages/core/src/utils/tokenCalculation.ts @@ -88,6 +88,7 @@ function estimateFunctionResponseTokens(part: Part, depth: number): number { } // Gemini 3: Handle nested multimodal parts recursively. + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const nestedParts = (fr as unknown as { parts?: Part[] }).parts; if (nestedParts && nestedParts.length > 0) { totalTokens += estimateTokenCountSync(nestedParts, depth + 1); diff --git a/packages/core/src/utils/tool-utils.ts b/packages/core/src/utils/tool-utils.ts index 0d2dec8625..ed9c11f34e 100644 --- a/packages/core/src/utils/tool-utils.ts +++ b/packages/core/src/utils/tool-utils.ts @@ -104,6 +104,7 @@ export function doesToolInvocationMatch( // This invocation has no command - nothing to check. continue; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion command = String((invocation.params as { command: string }).command); } diff --git a/packages/core/src/utils/userAccountManager.ts b/packages/core/src/utils/userAccountManager.ts index 83d27d947b..4434a18027 100644 --- a/packages/core/src/utils/userAccountManager.ts +++ b/packages/core/src/utils/userAccountManager.ts @@ -37,6 +37,7 @@ export class UserAccountManager { debugLogger.log('Invalid accounts file schema, starting fresh.'); return defaultState; } + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const { active, old } = parsed as Partial; const isValid = (active === undefined || active === null || typeof active === 'string') && diff --git a/packages/vscode-ide-companion/src/diff-manager.ts b/packages/vscode-ide-companion/src/diff-manager.ts index 9bbebbaead..d5d3a91ada 100644 --- a/packages/vscode-ide-companion/src/diff-manager.ts +++ b/packages/vscode-ide-companion/src/diff-manager.ts @@ -243,6 +243,7 @@ export class DiffManager { // Find and close the tab corresponding to the diff view for (const tabGroup of vscode.window.tabGroups.all) { for (const tab of tabGroup.tabs) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const input = tab.input as { modified?: vscode.Uri; original?: vscode.Uri; diff --git a/packages/vscode-ide-companion/src/ide-server.ts b/packages/vscode-ide-companion/src/ide-server.ts index 4e4ef443f6..2596189277 100644 --- a/packages/vscode-ide-companion/src/ide-server.ts +++ b/packages/vscode-ide-companion/src/ide-server.ts @@ -206,6 +206,7 @@ export class IDEServer { context.subscriptions.push(onDidChangeDiffSubscription); app.post('/mcp', async (req: Request, res: Response) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const sessionId = req.headers[MCP_SESSION_ID_HEADER] as | string | undefined; @@ -290,6 +291,7 @@ export class IDEServer { }); const handleSessionRequest = async (req: Request, res: Response) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const sessionId = req.headers[MCP_SESSION_ID_HEADER] as | string | undefined; @@ -337,6 +339,7 @@ export class IDEServer { }); this.server = app.listen(0, '127.0.0.1', async () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion const address = (this.server as HTTPServer).address(); if (address && typeof address !== 'string') { this.port = address.port;