From 04f4d8c0f09f9e86ee873c95e14a4db5a7df4b07 Mon Sep 17 00:00:00 2001 From: Roomote Date: Tue, 13 Oct 2026 04:02:25 +0000 Subject: [PATCH 1/3] chore(eslint): turn off no-unused-vars in src and remove dead code Turn off both no-unused-vars and @typescript-eslint/no-unused-vars in src/eslint.config.mjs, and clean up all existing violations so the tree stays tidy without the rule: - Remove unused imports across src (autofixed, then hand-reviewed). - Remove unused local variables, functions, interfaces, and type aliases. - Convert unused catch bindings to optional catch binding (catch { ... }). - Prefix intentionally unused function parameters with _ per the existing argsIgnorePattern convention, and drop unused destructured properties. - Remove never-read private members and convert never-read constructor parameter properties to plain parameters. - Prune reduced counts in eslint-suppressions.json (counts only decreased). No behavior changes: side-effecting calls whose results were unused are kept as expression statements. Validated with: - eslint with @typescript-eslint/no-unused-vars forced on: zero findings. - tsc --noEmit --noUnusedLocals --noUnusedParameters cross-check: clean. - pnpm lint, pnpm check-types, pnpm test (root, all workspaces): all pass. --- ...Provider.history-resume-delegation.spec.ts | 8 +- .../nested-delegation-resume.spec.ts | 2 +- .../removeClineFromStack-delegation.spec.ts | 20 +- src/__tests__/single-open-invariant.spec.ts | 2 +- src/activate/registerCommands.ts | 4 +- .../__tests__/anthropic-vertex.spec.ts | 8 +- src/api/providers/__tests__/anthropic.spec.ts | 4 +- .../base-openai-compatible-provider.spec.ts | 1 - .../__tests__/bedrock-error-handling.spec.ts | 2 +- .../__tests__/bedrock-reasoning.spec.ts | 2 +- .../__tests__/bedrock-vpc-endpoint.spec.ts | 2 +- src/api/providers/__tests__/bedrock.spec.ts | 4 - src/api/providers/__tests__/kimi-code.spec.ts | 24 +- src/api/providers/__tests__/lite-llm.spec.ts | 3 +- src/api/providers/__tests__/mimo.spec.ts | 2 +- src/api/providers/__tests__/minimax.spec.ts | 2 +- src/api/providers/__tests__/mistral.spec.ts | 2 +- .../providers/__tests__/openai-native.spec.ts | 6 +- src/api/providers/__tests__/openai.spec.ts | 14 +- src/api/providers/__tests__/vertex.spec.ts | 2 +- src/api/providers/__tests__/vscode-lm.spec.ts | 2 +- src/api/providers/__tests__/xai.spec.ts | 1 - src/api/providers/anthropic-vertex.ts | 2 +- src/api/providers/anthropic.ts | 4 +- .../base-openai-compatible-provider.ts | 2 +- src/api/providers/bedrock.ts | 22 -- src/api/providers/deepseek.ts | 1 - .../fetchers/__tests__/kimi-code.spec.ts | 2 +- .../fetchers/__tests__/litellm.spec.ts | 2 +- .../fetchers/__tests__/ollama.test.ts | 2 +- src/api/providers/fetchers/lmstudio.ts | 4 +- src/api/providers/fetchers/modelCache.ts | 10 - src/api/providers/fetchers/openrouter.ts | 1 - .../providers/fetchers/vercel-ai-gateway.ts | 2 +- src/api/providers/gemini.ts | 10 +- src/api/providers/kenari.ts | 2 +- src/api/providers/lite-llm.ts | 2 +- src/api/providers/lm-studio.ts | 8 +- src/api/providers/minimax.ts | 3 +- src/api/providers/mistral.ts | 3 +- src/api/providers/native-ollama.ts | 2 +- src/api/providers/openai-codex.ts | 5 +- src/api/providers/openai-compatible.ts | 2 +- src/api/providers/openai-native.ts | 15 +- src/api/providers/openai.ts | 6 +- src/api/providers/opencode-go.ts | 2 +- src/api/providers/openrouter.ts | 14 +- src/api/providers/poe.ts | 2 +- src/api/providers/qwen-code.ts | 4 +- src/api/providers/requesty.ts | 2 +- src/api/providers/unbound.ts | 2 +- src/api/providers/vercel-ai-gateway.ts | 4 +- src/api/providers/vscode-lm.ts | 2 +- src/api/providers/xai.ts | 2 +- src/api/providers/zai.ts | 2 +- src/api/providers/zoo-gateway.ts | 2 +- .../transform/__tests__/model-params.spec.ts | 2 +- src/api/transform/__tests__/reasoning.spec.ts | 1 - .../__tests__/responses-api-stream.spec.ts | 2 +- src/api/transform/model-params.ts | 3 - src/api/transform/openai-format.ts | 21 +- src/api/transform/reasoning.ts | 1 - src/api/transform/zai-format.ts | 1 - .../assistant-message/NativeToolCallParser.ts | 2 +- .../presentAssistantMessage-images.spec.ts | 11 - .../presentAssistantMessage.ts | 6 +- src/core/auto-approval/index.ts | 4 +- .../checkpoints/__tests__/checkpoint.test.ts | 8 +- src/core/checkpoints/index.ts | 8 +- .../__tests__/foldedFileContext.spec.ts | 1 - src/core/condense/foldedFileContext.ts | 2 +- src/core/condense/index.ts | 2 - src/core/config/ContextProxy.ts | 2 +- src/core/config/CustomModesManager.ts | 18 +- src/core/config/ProviderSettingsManager.ts | 4 +- ...odesManager.exportImportSlugChange.spec.ts | 2 - .../CustomModesManager.yamlEdgeCases.spec.ts | 2 - .../__tests__/ProviderSettingsManager.spec.ts | 2 +- .../config/__tests__/importExport.spec.ts | 1 - src/core/config/importExport.ts | 2 +- .../__tests__/context-management.spec.ts | 18 +- .../__tests__/truncation.spec.ts | 2 - src/core/context-management/index.ts | 2 - src/core/environment/getEnvironmentDetails.ts | 10 +- src/core/ignore/RooIgnoreController.ts | 2 +- src/core/mentions/__tests__/index.spec.ts | 2 - .../processUserContentMentions.spec.ts | 2 - src/core/mentions/index.ts | 4 +- .../mentions/processUserContentMentions.ts | 3 +- src/core/message-manager/index.ts | 2 - .../__tests__/add-custom-instructions.spec.ts | 7 +- .../__tests__/get-prompt-component.spec.ts | 2 +- .../prompts/__tests__/system-prompt.spec.ts | 4 +- .../__tests__/custom-instructions.spec.ts | 4 +- .../prompts/sections/custom-instructions.ts | 26 +- src/core/prompts/sections/system-info.ts | 2 +- src/core/prompts/system.ts | 14 +- .../__tests__/effective-tool-policy.spec.ts | 1 - .../native-tools/__tests__/converters.spec.ts | 1 - .../native-tools/__tests__/mcp_server.spec.ts | 5 - src/core/task-persistence/taskMetadata.ts | 2 +- src/core/task/Task.ts | 39 +- .../task/__tests__/RateLimitClock.spec.ts | 2 +- src/core/task/__tests__/Task.dispose.test.ts | 2 +- src/core/task/__tests__/Task.spec.ts | 7 +- .../Task.sticky-profile-race.spec.ts | 2 - .../Task.streaming-tool-calls.spec.ts | 7 +- .../__tests__/duplicate-tool-use-ids.spec.ts | 3 +- .../flushPendingToolResultsToHistory.spec.ts | 4 +- .../task/__tests__/grace-retry-errors.spec.ts | 2 +- .../task/__tests__/task-tool-history.spec.ts | 2 +- src/core/tools/ApplyPatchTool.ts | 2 +- src/core/tools/BaseTool.ts | 2 +- src/core/tools/CodebaseSearchTool.ts | 1 - src/core/tools/EditTool.ts | 2 +- src/core/tools/ExecuteCommandTool.ts | 2 +- src/core/tools/GenerateImageTool.ts | 6 +- src/core/tools/NewTaskTool.ts | 3 +- src/core/tools/SearchReplaceTool.ts | 2 +- .../__tests__/ReadCommandOutputTool.test.ts | 11 +- src/core/tools/__tests__/editFileTool.spec.ts | 2 +- .../tools/__tests__/executeCommand.spec.ts | 24 +- .../__tests__/executeCommandTool.spec.ts | 2 +- src/core/tools/__tests__/readFileTool.spec.ts | 11 +- .../tools/__tests__/searchReplaceTool.spec.ts | 2 +- .../__tests__/updateTodoListTool.spec.ts | 2 +- .../tools/__tests__/useMcpToolTool.spec.ts | 2 - .../tools/__tests__/writeToFileTool.spec.ts | 2 +- src/core/webview/ClineProvider.ts | 40 +-- .../ClineProvider.sticky-mode.spec.ts | 4 +- .../ClineProvider.sticky-profile.spec.ts | 14 - .../ClineProvider.taskHistory.spec.ts | 2 +- .../checkpointRestoreHandler.spec.ts | 2 +- .../webviewMessageHandler.delete.spec.ts | 1 - .../webviewMessageHandler.edit.spec.ts | 1 - src/core/webview/checkpointRestoreHandler.ts | 2 +- src/core/webview/messageEnhancer.ts | 3 +- src/core/webview/webviewMessageHandler.ts | 9 +- src/core/webview/worktree/handlers.ts | 2 +- src/eslint-suppressions.json | 21 +- src/eslint.config.mjs | 1 + .../__tests__/api-send-message.spec.ts | 1 - src/extension/api.ts | 11 +- .../editor/__tests__/DiffViewProvider.spec.ts | 7 +- .../misc/__tests__/indentation-reader.spec.ts | 1 - .../misc/__tests__/open-file.spec.ts | 2 +- src/integrations/misc/export-markdown.ts | 6 - .../misc/extract-text-from-xlsx.ts | 4 +- src/integrations/misc/extract-text.ts | 2 +- src/integrations/misc/indentation-reader.ts | 66 ---- src/integrations/misc/line-counter.ts | 6 +- src/integrations/misc/open-file.ts | 2 +- .../terminal/ExecaTerminalProcess.ts | 2 +- .../terminal/OutputInterceptor.ts | 2 +- .../__tests__/ExecaTerminalProcess.spec.ts | 4 +- .../__tests__/OutputInterceptor.test.ts | 1 - .../__tests__/TerminalProcess.test.ts | 1 - .../__tests__/TerminalProfile.spec.ts | 335 ++++++++---------- .../__tests__/TerminalRegistry.spec.ts | 2 +- .../terminal/__tests__/setupTerminalTests.ts | 2 +- src/services/__tests__/zoo-code-auth.test.ts | 3 +- .../__tests__/ShadowCheckpointService.spec.ts | 4 +- src/services/checkpoints/excludes.ts | 2 +- .../__tests__/config-manager.spec.ts | 6 +- .../code-index/__tests__/manager.spec.ts | 2 +- src/services/code-index/cache-manager.ts | 5 +- .../__tests__/openai-compatible.spec.ts | 2 +- .../embedders/__tests__/openai.spec.ts | 2 +- .../embedders/__tests__/openrouter.spec.ts | 1 - src/services/code-index/embedders/bedrock.ts | 2 +- src/services/code-index/embedders/ollama.ts | 2 +- .../code-index/embedders/openai-compatible.ts | 4 +- .../code-index/embedders/openrouter.ts | 4 +- src/services/code-index/manager.ts | 3 +- src/services/code-index/orchestrator.ts | 9 +- .../processors/__tests__/parser.spec.ts | 2 - .../code-index/processors/file-watcher.ts | 2 +- .../semble/__tests__/provider.spec.ts | 2 - .../__tests__/qdrant-client.spec.ts | 4 +- .../code-index/vector-store/qdrant-client.ts | 4 +- .../__tests__/symlink-commands.spec.ts | 1 - .../__tests__/gitignore-integration.spec.ts | 8 +- .../glob/__tests__/gitignore-test.spec.ts | 4 +- .../glob/__tests__/list-files-limit.spec.ts | 5 +- .../glob/__tests__/list-files.spec.ts | 10 +- .../marketplace/MarketplaceManager.ts | 10 +- src/services/marketplace/SimpleInstaller.ts | 23 +- src/services/mcp/McpHub.ts | 35 +- src/services/mcp/__tests__/McpHub.spec.ts | 9 - .../utils/__tests__/callbackServer.spec.ts | 2 +- src/services/roo-config/index.ts | 2 +- .../search/__tests__/file-search.spec.ts | 2 +- src/services/search/file-search.ts | 2 +- src/services/skills/SkillsManager.ts | 2 +- .../skills/__tests__/SkillsManager.spec.ts | 2 - src/services/tree-sitter/__tests__/helpers.ts | 5 +- .../__tests__/markdownParser.spec.ts | 2 +- src/shared/utils/requesty.ts | 2 +- .../__tests__/autoImportSettings.spec.ts | 9 - src/utils/__tests__/git.spec.ts | 52 +-- src/utils/__tests__/safeWriteJson.test.ts | 2 +- src/utils/git.ts | 10 +- src/utils/json-schema.ts | 2 +- src/utils/outputChannelLogger.ts | 4 +- src/utils/shell.ts | 1 - src/utils/storage.ts | 6 +- src/utils/tts.ts | 4 +- src/utils/vitest-verbosity.ts | 2 +- 208 files changed, 503 insertions(+), 977 deletions(-) diff --git a/src/__tests__/ClineProvider.history-resume-delegation.spec.ts b/src/__tests__/ClineProvider.history-resume-delegation.spec.ts index f50dada0d3..ee87830da0 100644 --- a/src/__tests__/ClineProvider.history-resume-delegation.spec.ts +++ b/src/__tests__/ClineProvider.history-resume-delegation.spec.ts @@ -1878,8 +1878,8 @@ describe("History resume delegation - parent metadata transitions", () => { const atomicUpdatePair = vi.fn( async ( - firstId: string, - secondId: string, + _firstId: string, + _secondId: string, firstUpdater: (h: HistoryItem) => HistoryItem, secondUpdater: (h: HistoryItem) => HistoryItem, ) => { @@ -1988,8 +1988,8 @@ describe("History resume delegation - parent metadata transitions", () => { const taskHistoryStore = { atomicUpdatePair: vi.fn( async ( - firstId: string, - secondId: string, + _firstId: string, + _secondId: string, firstUpdater: (h: any) => any, secondUpdater: (h: any) => any, ) => { diff --git a/src/__tests__/nested-delegation-resume.spec.ts b/src/__tests__/nested-delegation-resume.spec.ts index 57b831b4a2..7672174d7b 100644 --- a/src/__tests__/nested-delegation-resume.spec.ts +++ b/src/__tests__/nested-delegation-resume.spec.ts @@ -55,7 +55,7 @@ import { attemptCompletionTool } from "../core/tools/AttemptCompletionTool" import { ClineProvider } from "../core/webview/ClineProvider" import type { Task } from "../core/task/Task" import { readTaskMessages } from "../core/task-persistence/taskMessages" -import { readApiMessages, saveApiMessages, saveTaskMessages } from "../core/task-persistence" +import { readApiMessages } from "../core/task-persistence" describe("Nested delegation resume (A → B → C)", () => { beforeEach(() => { diff --git a/src/__tests__/removeClineFromStack-delegation.spec.ts b/src/__tests__/removeClineFromStack-delegation.spec.ts index bc5b8a4426..0db228662e 100644 --- a/src/__tests__/removeClineFromStack-delegation.spec.ts +++ b/src/__tests__/removeClineFromStack-delegation.spec.ts @@ -1,17 +1,11 @@ // npx vitest run __tests__/removeClineFromStack-delegation.spec.ts -import { describe, it, expect, vi, type MockedFunction } from "vitest" +import { describe, it, expect, vi } from "vitest" import { ClineProvider } from "../core/webview/ClineProvider" import { TaskRegistry } from "../core/task/TaskRegistry" import { PendingActionSettlementError, type Task } from "../core/task/Task" import { makeProviderStub } from "./helpers/provider-stub" -type MockTask = Pick & - Partial> & { - emit: ReturnType - abortTask: ReturnType - } - type PrivateClineProviderMethods = { removeClineFromStack: (this: ClineProvider) => ReturnType cleanupFailedHistoryTask: (this: ClineProvider, task: Task, error: unknown) => Promise @@ -686,18 +680,6 @@ describe("onTaskCompleted callback — writes completed status before re-emittin // Wire up the real taskCreationCallback by calling the closure that ClineProvider // sets on `this.taskCreationCallback` during construction. We extract it from the // prototype's init code by calling the relevant portion directly. - const listeners: Record unknown)[]> = {} - const fakeTask = { - taskId: "task-1", - on: vi.fn((event: string, fn: (...args: unknown[]) => unknown) => { - listeners[event] = listeners[event] || [] - listeners[event].push(fn) - }), - emit: vi.fn((event: string, ...args: unknown[]) => { - listeners[event]?.forEach((fn) => fn(...args)) - }), - } - const provider = makeProviderStub({ taskHistoryStore: { get: taskHistoryStoreGet }, updateTaskHistory, diff --git a/src/__tests__/single-open-invariant.spec.ts b/src/__tests__/single-open-invariant.spec.ts index bbcc2b1b11..540b977d69 100644 --- a/src/__tests__/single-open-invariant.spec.ts +++ b/src/__tests__/single-open-invariant.spec.ts @@ -398,7 +398,7 @@ describe("Single-open-task invariant", () => { createTask, getValues: vi.fn(() => ({})), providerSettingsManager: { saveConfig: vi.fn() }, - on: vi.fn((ev: unknown, cb: unknown) => { + on: vi.fn((ev: unknown, _cb: unknown) => { if (ev === "taskCreated") { // no-op for this test } diff --git a/src/activate/registerCommands.ts b/src/activate/registerCommands.ts index 79e629f479..9ee3443f9a 100644 --- a/src/activate/registerCommands.ts +++ b/src/activate/registerCommands.ts @@ -4,7 +4,6 @@ import delay from "delay" import type { CommandId } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" -import { Package } from "../shared/package" import { getCommand } from "../utils/commands" import { ClineProvider } from "../core/webview/ClineProvider" import type { WebviewFocusTracker } from "../core/webview/WebviewFocusTracker" @@ -14,7 +13,6 @@ import { handleNewTask } from "./handleTask" import { importSettingsWithFeedback } from "../core/config/importExport" import { MdmService } from "../services/mdm/MdmService" import { registerRipgrepDiagnosticCommand } from "../services/ripgrep/diagnostic" -import { t } from "../i18n" /** * Helper to get the visible ClineProvider instance or log if not found. @@ -239,7 +237,7 @@ export const openClineInNewTab = async ({ context, outputChannel, webviewFocusTr let mdmService: MdmService | undefined try { mdmService = MdmService.getInstance() - } catch (error) { + } catch { // MDM service not initialized, which is fine - extension can work without it mdmService = undefined } diff --git a/src/api/providers/__tests__/anthropic-vertex.spec.ts b/src/api/providers/__tests__/anthropic-vertex.spec.ts index ba5780a12f..339fa36a07 100644 --- a/src/api/providers/__tests__/anthropic-vertex.spec.ts +++ b/src/api/providers/__tests__/anthropic-vertex.spec.ts @@ -626,7 +626,7 @@ describe("VertexHandler", () => { vertexRegion: "us-central1", }) - const mockCreate = vitest.fn().mockImplementation(async (options) => + const mockCreate = vitest.fn().mockImplementation(async (_options) => asyncStreamFrom([ { type: "message_start", @@ -675,7 +675,7 @@ describe("VertexHandler", () => { ] const stream = handler.createMessage(systemPrompt, messagesWithReasoning) - const chunks = await collectStream(stream) + await collectStream(stream) // Verify the API was called with filtered messages (no reasoning blocks) const calledMessages = mockCreate.mock.calls[0][0].messages @@ -702,7 +702,7 @@ describe("VertexHandler", () => { vertexRegion: "us-central1", }) - const mockCreate = vitest.fn().mockImplementation(async (options) => + const mockCreate = vitest.fn().mockImplementation(async (_options) => asyncStreamFrom([ { type: "message_start", @@ -739,7 +739,7 @@ describe("VertexHandler", () => { ] const stream = handler.createMessage(systemPrompt, messagesWithOnlyReasoning) - const chunks = await collectStream(stream) + await collectStream(stream) // Verify empty message was filtered out const calledMessages = mockCreate.mock.calls[0][0].messages diff --git a/src/api/providers/__tests__/anthropic.spec.ts b/src/api/providers/__tests__/anthropic.spec.ts index d6d7f3b1f3..30fc120684 100644 --- a/src/api/providers/__tests__/anthropic.spec.ts +++ b/src/api/providers/__tests__/anthropic.spec.ts @@ -1096,7 +1096,7 @@ describe("AnthropicHandler", () => { ] const stream = handler.createMessage(systemPrompt, messagesWithReasoning) - const chunks: any[] = await collectStream(stream) + await collectStream(stream) // Verify the API was called with filtered messages (no reasoning blocks) const calledMessages = mockCreate.mock.calls[mockCreate.mock.calls.length - 1][0].messages @@ -1139,7 +1139,7 @@ describe("AnthropicHandler", () => { ] const stream = handler.createMessage(systemPrompt, messagesWithOnlyReasoning) - const chunks: any[] = await collectStream(stream) + await collectStream(stream) // Verify empty message was filtered out const calledMessages = mockCreate.mock.calls[mockCreate.mock.calls.length - 1][0].messages diff --git a/src/api/providers/__tests__/base-openai-compatible-provider.spec.ts b/src/api/providers/__tests__/base-openai-compatible-provider.spec.ts index c057173aff..1ffd63aa12 100644 --- a/src/api/providers/__tests__/base-openai-compatible-provider.spec.ts +++ b/src/api/providers/__tests__/base-openai-compatible-provider.spec.ts @@ -1,7 +1,6 @@ // npx vitest run api/providers/__tests__/base-openai-compatible-provider.spec.ts import { Anthropic } from "@anthropic-ai/sdk" -import OpenAI from "openai" import { type ModelInfo, openAiModelInfoSaneDefaults } from "@roo-code/types" diff --git a/src/api/providers/__tests__/bedrock-error-handling.spec.ts b/src/api/providers/__tests__/bedrock-error-handling.spec.ts index 36893de3eb..4420947e50 100644 --- a/src/api/providers/__tests__/bedrock-error-handling.spec.ts +++ b/src/api/providers/__tests__/bedrock-error-handling.spec.ts @@ -328,7 +328,7 @@ describe("AwsBedrockHandler Error Handling", () => { for await (const chunk of generator) { chunks.push(chunk) } - } catch (error) { + } catch { // Expected to throw after yielding chunks } diff --git a/src/api/providers/__tests__/bedrock-reasoning.spec.ts b/src/api/providers/__tests__/bedrock-reasoning.spec.ts index d0ee0b8169..e4f30a1d96 100644 --- a/src/api/providers/__tests__/bedrock-reasoning.spec.ts +++ b/src/api/providers/__tests__/bedrock-reasoning.spec.ts @@ -173,7 +173,7 @@ describe("AwsBedrockHandler - Extended Thinking", () => { const messages = [{ role: "user" as const, content: "Test" }] const stream = handler.createMessage("System prompt", messages) - for await (const chunk of stream) { + for await (const _chunk of stream) { // consume stream } diff --git a/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts b/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts index bb2f71ddd7..76a256a600 100644 --- a/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts +++ b/src/api/providers/__tests__/bedrock-vpc-endpoint.spec.ts @@ -182,7 +182,7 @@ describe("Amazon Bedrock VPC Endpoint Functionality", () => { // Make a request to ensure the endpoint configuration persists try { await handler.completePrompt("Test prompt") - } catch (error) { + } catch { // Ignore errors, we're just testing the client configuration persistence } diff --git a/src/api/providers/__tests__/bedrock.spec.ts b/src/api/providers/__tests__/bedrock.spec.ts index 6845aa82cd..248149a303 100644 --- a/src/api/providers/__tests__/bedrock.spec.ts +++ b/src/api/providers/__tests__/bedrock.spec.ts @@ -1506,12 +1506,8 @@ describe("AwsBedrockHandler", () => { }) describe("error telemetry", () => { - let mockSend: ReturnType - beforeEach(() => { mockCaptureException.mockClear() - // Get access to the mock send function from the mocked client - mockSend = vi.mocked(BedrockRuntimeClient).mock.results[0]?.value?.send }) it("should capture telemetry on createMessage error", async () => { diff --git a/src/api/providers/__tests__/kimi-code.spec.ts b/src/api/providers/__tests__/kimi-code.spec.ts index fe229910b8..c8e1130b30 100644 --- a/src/api/providers/__tests__/kimi-code.spec.ts +++ b/src/api/providers/__tests__/kimi-code.spec.ts @@ -49,13 +49,13 @@ describe("KimiCodeHandler", () => { it("uses API key when auth method is api-key", async () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key", kimiCodeApiKey: "my-api-key" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) - const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce( + vi.spyOn(globalThis, "fetch").mockResolvedValueOnce( new Response(JSON.stringify({ choices: [{ message: { content: "response" }, finish_reason: "stop" }] }), { status: 200, }), ) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { @@ -68,7 +68,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "oauth" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { @@ -82,7 +82,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "oauth" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) await expect(async () => { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } }).rejects.toThrow("Not authenticated with Kimi Code") @@ -92,7 +92,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) await expect(async () => { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } }).rejects.toThrow("Kimi Code API key is required") @@ -109,7 +109,7 @@ describe("KimiCodeHandler", () => { ) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { @@ -133,10 +133,10 @@ describe("KimiCodeHandler", () => { it("does not retry on 401 when using API key auth", async () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key", kimiCodeApiKey: "key" }) - const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce(new Response(null, { status: 401 })) + vi.spyOn(globalThis, "fetch").mockResolvedValueOnce(new Response(null, { status: 401 })) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) await expect(async () => { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } }).rejects.toThrow() @@ -148,7 +148,7 @@ describe("KimiCodeHandler", () => { vi.spyOn(globalThis, "fetch").mockResolvedValueOnce(new Response(null, { status: 500 })) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) await expect(async () => { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } }).rejects.toThrow() @@ -160,7 +160,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key", kimiCodeApiKey: "key" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { @@ -174,7 +174,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key", kimiCodeApiKey: "key" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { @@ -204,7 +204,7 @@ describe("KimiCodeHandler", () => { const handler = new KimiCodeHandler({ kimiCodeAuthMethod: "api-key", kimiCodeApiKey: "key" }) const gen = handler.createMessage("system", [{ role: "user", content: "test" }]) try { - for await (const chunk of gen) { + for await (const _chunk of gen) { // consume } } catch { diff --git a/src/api/providers/__tests__/lite-llm.spec.ts b/src/api/providers/__tests__/lite-llm.spec.ts index 84edeccde9..dd582e5c2c 100644 --- a/src/api/providers/__tests__/lite-llm.spec.ts +++ b/src/api/providers/__tests__/lite-llm.spec.ts @@ -1,4 +1,3 @@ -import OpenAI from "openai" import { Anthropic } from "@anthropic-ai/sdk" import { LiteLLMHandler } from "../lite-llm" @@ -212,7 +211,7 @@ describe("LiteLLMHandler", () => { }) const generator = handler.createMessage(systemPrompt, messages) - const results = await collectStream(generator) + await collectStream(generator) // Verify that create was called with max_completion_tokens instead of max_tokens const createCall = mockCreate.mock.calls[0][0] diff --git a/src/api/providers/__tests__/mimo.spec.ts b/src/api/providers/__tests__/mimo.spec.ts index 65e78f4673..062d2fd922 100644 --- a/src/api/providers/__tests__/mimo.spec.ts +++ b/src/api/providers/__tests__/mimo.spec.ts @@ -8,7 +8,7 @@ vi.mock("openai", () => { return { chat: { completions: { - create: mockCreate.mockImplementation(async (options) => + create: mockCreate.mockImplementation(async (_options) => asyncStreamFrom([ { choices: [{ delta: { content: "Test response" }, index: 0 }], diff --git a/src/api/providers/__tests__/minimax.spec.ts b/src/api/providers/__tests__/minimax.spec.ts index 01102b0457..063932b303 100644 --- a/src/api/providers/__tests__/minimax.spec.ts +++ b/src/api/providers/__tests__/minimax.spec.ts @@ -13,7 +13,7 @@ import { Anthropic } from "@anthropic-ai/sdk" import { type MinimaxModelId, minimaxDefaultModelId, minimaxModels } from "@roo-code/types" import { MiniMaxHandler } from "../minimax" -import { asyncStreamFrom, collectStream } from "../../../test-utils/stream" +import { asyncStreamFrom } from "../../../test-utils/stream" import { clearAllMocks } from "../../../test-utils/reset" vitest.mock("@anthropic-ai/sdk", () => { diff --git a/src/api/providers/__tests__/mistral.spec.ts b/src/api/providers/__tests__/mistral.spec.ts index f2a7591bd8..10c2d7ed98 100644 --- a/src/api/providers/__tests__/mistral.spec.ts +++ b/src/api/providers/__tests__/mistral.spec.ts @@ -11,7 +11,7 @@ vi.mock("@roo-code/telemetry", () => ({ // Mock Mistral client - must come before other imports const mockCreate = vi.fn() const mockComplete = vi.fn() -import { asyncStreamFrom, collectStream } from "../../../test-utils/stream" +import { asyncStreamFrom } from "../../../test-utils/stream" vi.mock("@mistralai/mistralai", () => { return { Mistral: vi.fn().mockImplementation(function () { diff --git a/src/api/providers/__tests__/openai-native.spec.ts b/src/api/providers/__tests__/openai-native.spec.ts index ef682146fe..8a086b48db 100644 --- a/src/api/providers/__tests__/openai-native.spec.ts +++ b/src/api/providers/__tests__/openai-native.spec.ts @@ -1432,7 +1432,7 @@ describe("OpenAiNativeHandler", () => { const stream = gpt5Handler.createMessage(systemPrompt, messages, { taskId: "task1", }) - for await (const chunk of stream) { + for await (const _chunk of stream) { // consume } @@ -1477,7 +1477,7 @@ describe("OpenAiNativeHandler", () => { const stream = handler.createMessage(systemPrompt, messages) await expect(async () => { - for await (const chunk of stream) { + for await (const _chunk of stream) { // Should throw before yielding anything } }).rejects.toThrow(expectedMessage) @@ -1942,7 +1942,7 @@ describe("GPT-5 streaming event coverage (additional)", () => { // Should throw an error (using the same error format as GPT-5) await expect(async () => { - for await (const chunk of stream) { + for await (const _chunk of stream) { // consume stream } }).rejects.toThrow("Rate limit exceeded") diff --git a/src/api/providers/__tests__/openai.spec.ts b/src/api/providers/__tests__/openai.spec.ts index 12b20da8ee..7c45f22180 100644 --- a/src/api/providers/__tests__/openai.spec.ts +++ b/src/api/providers/__tests__/openai.spec.ts @@ -414,7 +414,7 @@ describe("OpenAiHandler", () => { }) it("should handle tool calls in streaming responses", async () => { - mockCreate.mockImplementation(async (options) => + mockCreate.mockImplementation(async (_options) => asyncStreamFrom([ { choices: [ @@ -491,7 +491,7 @@ describe("OpenAiHandler", () => { }) it("should yield tool calls even when finish_reason is not set (fallback behavior)", async () => { - mockCreate.mockImplementation(async (options) => + mockCreate.mockImplementation(async (_options) => asyncStreamFrom([ { choices: [ @@ -1461,7 +1461,7 @@ describe("OpenAiHandler", () => { ] const stream = o3Handler.createMessage(systemPrompt, messages) - const chunks = await collectStream(stream) + await collectStream(stream) expect(mockCreate).toHaveBeenCalledWith( expect.objectContaining({ @@ -1544,7 +1544,7 @@ describe("OpenAiHandler", () => { it("should handle tool calls with O3 model in streaming mode", async () => { const o3Handler = new OpenAiHandler(o3Options) - mockCreate.mockImplementation(async (options) => + mockCreate.mockImplementation(async (_options) => asyncStreamFrom([ { choices: [ @@ -1604,7 +1604,7 @@ describe("OpenAiHandler", () => { it("should yield tool calls for O3 model even when finish_reason is not set (fallback behavior)", async () => { const o3Handler = new OpenAiHandler(o3Options) - mockCreate.mockImplementation(async (options) => + mockCreate.mockImplementation(async (_options) => asyncStreamFrom([ { choices: [ @@ -1663,7 +1663,7 @@ describe("OpenAiHandler", () => { ] const stream = o3Handler.createMessage(systemPrompt, messages) - const chunks = await collectStream(stream) + await collectStream(stream) expect(mockCreate).toHaveBeenCalledWith( expect.objectContaining({ @@ -1704,7 +1704,7 @@ describe("OpenAiHandler", () => { ] const stream = o3Handler.createMessage(systemPrompt, messages) - const chunks = await collectStream(stream) + await collectStream(stream) expect(mockCreate).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/src/api/providers/__tests__/vertex.spec.ts b/src/api/providers/__tests__/vertex.spec.ts index a304518ca7..cdc038cbab 100644 --- a/src/api/providers/__tests__/vertex.spec.ts +++ b/src/api/providers/__tests__/vertex.spec.ts @@ -4,7 +4,7 @@ vitest.mock("vscode", () => ({ workspace: { getConfiguration: vitest.fn(() => ({ - get: vitest.fn((key: string, defaultValue: any) => defaultValue), + get: vitest.fn((_key: string, defaultValue: any) => defaultValue), })), }, })) diff --git a/src/api/providers/__tests__/vscode-lm.spec.ts b/src/api/providers/__tests__/vscode-lm.spec.ts index f6aecf391b..c15be285ca 100644 --- a/src/api/providers/__tests__/vscode-lm.spec.ts +++ b/src/api/providers/__tests__/vscode-lm.spec.ts @@ -27,7 +27,7 @@ vi.mock("vscode", () => { return { workspace: { getConfiguration: vi.fn(() => ({ - get: vi.fn((key: string, defaultValue: unknown) => defaultValue), + get: vi.fn((_key: string, defaultValue: unknown) => defaultValue), })), onDidChangeConfiguration: vi.fn((_callback) => ({ dispose: vi.fn(), diff --git a/src/api/providers/__tests__/xai.spec.ts b/src/api/providers/__tests__/xai.spec.ts index 366898e6bc..d0524ff0e4 100644 --- a/src/api/providers/__tests__/xai.spec.ts +++ b/src/api/providers/__tests__/xai.spec.ts @@ -18,7 +18,6 @@ vitest.mock("openai", async () => { }) import OpenAI from "openai" -import type { Anthropic } from "@anthropic-ai/sdk" import { xaiDefaultModelId, xaiModels } from "@roo-code/types" diff --git a/src/api/providers/anthropic-vertex.ts b/src/api/providers/anthropic-vertex.ts index 5d21ac3ffd..6ceaad2256 100644 --- a/src/api/providers/anthropic-vertex.ts +++ b/src/api/providers/anthropic-vertex.ts @@ -280,7 +280,7 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple } } - async completePrompt(prompt: string, options?: CompletePromptOptions) { + async completePrompt(prompt: string, _options?: CompletePromptOptions) { try { const { id, diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 3970b25941..9dddc75248 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -1,7 +1,6 @@ import { Anthropic } from "@anthropic-ai/sdk" import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming" import { CacheControlEphemeral } from "@anthropic-ai/sdk/resources" -import OpenAI from "openai" import { type ModelInfo, @@ -19,7 +18,6 @@ import { ApiStream } from "../transform/stream" import { getModelParams } from "../transform/model-params" import { filterNonAnthropicBlocks } from "../transform/anthropic-filter" import { getAnthropicProviderReasoning } from "../transform/reasoning" -import { handleProviderError } from "./utils/error-handler" import { BaseProvider } from "./base-provider" import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata, CompletePromptOptions } from "../index" @@ -463,7 +461,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa } } - async completePrompt(prompt: string, options?: CompletePromptOptions) { + async completePrompt(prompt: string, _options?: CompletePromptOptions) { const { id: model, temperature } = this.getModel() let message diff --git a/src/api/providers/base-openai-compatible-provider.ts b/src/api/providers/base-openai-compatible-provider.ts index 63cf7ccb29..b177726f85 100644 --- a/src/api/providers/base-openai-compatible-provider.ts +++ b/src/api/providers/base-openai-compatible-provider.ts @@ -212,7 +212,7 @@ export abstract class BaseOpenAiCompatibleProvider } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: modelId, info: modelInfo } = this.getModel() const params: OpenAI.Chat.Completions.ChatCompletionCreateParams = { diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index dba90b8ef0..dd038d3398 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -881,13 +881,6 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH try { const modelConfig = this.getModel() - // For completePrompt, thinking is typically not used, but we should still check - // if thinking was somehow enabled in the model config - const thinkingEnabled = - shouldUseReasoningBudget({ model: modelConfig.info, settings: this.options }) && - modelConfig.reasoning && - modelConfig.reasoningBudget - const inferenceConfig: BedrockInferenceConfig = { maxTokens: modelConfig.maxTokens || (modelConfig.info.maxTokens as number), // Claude 4.7+ (including 4.8) removed sampling parameters entirely — @@ -1369,21 +1362,6 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH ) } - /** - * Removes any existing cachePoint nodes from content blocks - */ - private removeCachePoints(content: any): any { - if (Array.isArray(content)) { - return content.map((block) => { - // Use destructuring to remove cachePoint property - const { cachePoint: _, ...rest } = block - return rest - }) - } - - return content - } - /************************************************************************************ * * NATIVE TOOLS diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index a72dff1655..b65973ac96 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -6,7 +6,6 @@ import { deepSeekDefaultModelId, DEEP_SEEK_DEFAULT_TEMPERATURE, OPENAI_AZURE_AI_INFERENCE_PATH, - type ModelInfo, type ModelRecord, DeepSeekModelId, } from "@roo-code/types" diff --git a/src/api/providers/fetchers/__tests__/kimi-code.spec.ts b/src/api/providers/fetchers/__tests__/kimi-code.spec.ts index a96e760253..cae0f01eef 100644 --- a/src/api/providers/fetchers/__tests__/kimi-code.spec.ts +++ b/src/api/providers/fetchers/__tests__/kimi-code.spec.ts @@ -138,7 +138,7 @@ describe("Kimi Code model discovery", () => { }) it("rejects fractional max_tokens from server response", () => { - const mapped = mapKimiCodeModel({ + mapKimiCodeModel({ id: "kimi-for-coding", max_tokens: 131072.5, }) diff --git a/src/api/providers/fetchers/__tests__/litellm.spec.ts b/src/api/providers/fetchers/__tests__/litellm.spec.ts index 0d8798c6eb..ce278489b5 100644 --- a/src/api/providers/fetchers/__tests__/litellm.spec.ts +++ b/src/api/providers/fetchers/__tests__/litellm.spec.ts @@ -708,7 +708,7 @@ describe("getLiteLLMModels", () => { mockedAxios.get.mockResolvedValue(mockResponse) - const result = await getLiteLLMModels("test-api-key", "http://localhost:4000") + await getLiteLLMModels("test-api-key", "http://localhost:4000") }) it("prefers max_output_tokens over max_tokens when both are present", async () => { diff --git a/src/api/providers/fetchers/__tests__/ollama.test.ts b/src/api/providers/fetchers/__tests__/ollama.test.ts index 49be678f1e..29e5e33fd3 100644 --- a/src/api/providers/fetchers/__tests__/ollama.test.ts +++ b/src/api/providers/fetchers/__tests__/ollama.test.ts @@ -238,7 +238,7 @@ describe("Ollama Fetcher", () => { it("should return an empty list if the initial /api/tags call fails", async () => { const baseUrl = "http://localhost:11434" mockedAxios.get.mockRejectedValueOnce(new Error("Network error")) - const consoleInfoSpy = vi.spyOn(console, "error").mockImplementation(function () {}) // Spy and suppress output + vi.spyOn(console, "error").mockImplementation(function () {}) // Spy and suppress output const result = await getOllamaModels(baseUrl) diff --git a/src/api/providers/fetchers/lmstudio.ts b/src/api/providers/fetchers/lmstudio.ts index 16521e6298..87cec5cc76 100644 --- a/src/api/providers/fetchers/lmstudio.ts +++ b/src/api/providers/fetchers/lmstudio.ts @@ -7,7 +7,7 @@ import { throwIfAborted } from "../utils/abort-signal" import type { ApiHandler } from "../../index" -import { flushModels, getModels } from "./modelCache" +import { flushModels } from "./modelCache" const modelsWithLoadedDetails = new Set() @@ -91,7 +91,7 @@ export async function getLMStudioModels( // Use the model path as the key since that's what users select models[model.path] = parseLMStudioModel(model) } - } catch (error) { + } catch { console.warn("Failed to list downloaded models, falling back to loaded models only") } diff --git a/src/api/providers/fetchers/modelCache.ts b/src/api/providers/fetchers/modelCache.ts index 32c7e024e1..53fd875b06 100644 --- a/src/api/providers/fetchers/modelCache.ts +++ b/src/api/providers/fetchers/modelCache.ts @@ -1,5 +1,4 @@ import * as path from "path" -import fs from "fs/promises" import * as fsSync from "fs" import { pbkdf2Sync } from "crypto" @@ -15,7 +14,6 @@ import { safeWriteJson } from "../../../utils/safeWriteJson" import { ContextProxy } from "../../../core/config/ContextProxy" import { getCacheDirectoryPath } from "../../../utils/storage" import type { RouterName } from "../../../shared/api" -import { fileExistsAtPath } from "../../../utils/fs" import { mergeAbortSignals, throwIfAborted } from "../utils/abort-signal" @@ -171,14 +169,6 @@ async function writeModels(cacheKey: string, data: ModelRecord) { await safeWriteJson(path.join(cacheDir, filename), data) } -async function readModels(cacheKey: string): Promise { - const filename = `${cacheKeyToFilename(cacheKey)}_models.json` - const cacheDir = await getCacheDirectoryPath(ContextProxy.instance.globalStorageUri.fsPath) - const filePath = path.join(cacheDir, filename) - const exists = await fileExistsAtPath(filePath) - return exists ? JSON.parse(await fs.readFile(filePath, "utf8")) : undefined -} - /** * Fetch models from the provider API. * Extracted to avoid duplication between getModels() and refreshModels(). diff --git a/src/api/providers/fetchers/openrouter.ts b/src/api/providers/fetchers/openrouter.ts index 710d55b890..426ba89d8c 100644 --- a/src/api/providers/fetchers/openrouter.ts +++ b/src/api/providers/fetchers/openrouter.ts @@ -197,7 +197,6 @@ export const parseOpenRouterModel = ({ id, model, inputModality, - outputModality, maxTokens, supportedParameters, }: { diff --git a/src/api/providers/fetchers/vercel-ai-gateway.ts b/src/api/providers/fetchers/vercel-ai-gateway.ts index e0bf5861c7..e9271f07af 100644 --- a/src/api/providers/fetchers/vercel-ai-gateway.ts +++ b/src/api/providers/fetchers/vercel-ai-gateway.ts @@ -58,7 +58,7 @@ type VercelAiGatewayModelsResponse = z.infer> { const models: Record = {} diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index 7674521d13..2adf2b5416 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -352,21 +352,17 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl let lastUsageMetadata: GenerateContentResponseUsageMetadata | undefined let pendingGroundingMetadata: GroundingMetadata | undefined let finalResponse: { responseId?: string } | undefined - let finishReason: string | undefined // Gemini provides no call ID, so one is synthesized here. The // request-unique component keeps persisted pending-action IDs (#1714) // distinct across requests even though the counter restarts at zero. const toolCallRequestId = crypto.randomUUID() let toolCallCounter = 0 - let hasContent = false - let hasReasoning = false for await (const chunk of result) { // Track the final structured response (per SDK pattern: candidate.finishReason) if (chunk.candidates && chunk.candidates[0]?.finishReason) { finalResponse = chunk as { responseId?: string } - finishReason = chunk.candidates[0].finishReason } // Process candidates and their parts to separate thoughts from content if (chunk.candidates && chunk.candidates.length > 0) { @@ -395,11 +391,9 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl if (part.thought) { // This is a thinking/reasoning part if (part.text) { - hasReasoning = true yield { type: "reasoning", text: part.text } } } else if (part.functionCall) { - hasContent = true // Gemini sends complete function calls in a single chunk // Emit as partial chunks for consistent handling with NativeToolCallParser const callId = `${part.functionCall.name}-${toolCallRequestId}-${toolCallCounter}` @@ -427,7 +421,6 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl } else { // This is regular content if (part.text) { - hasContent = true yield { type: "text", text: part.text } } } @@ -437,7 +430,6 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl // Fallback to the original text property if no candidates structure else if (chunk.text) { - hasContent = true yield { type: "text", text: chunk.text } } @@ -581,7 +573,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl return citationLinks.join(", ") } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: model, info } = this.getModel() try { diff --git a/src/api/providers/kenari.ts b/src/api/providers/kenari.ts index 407f84df53..22ca50c916 100644 --- a/src/api/providers/kenari.ts +++ b/src/api/providers/kenari.ts @@ -140,7 +140,7 @@ export class KenariHandler extends RouterProvider implements SingleCompletionHan * @returns The model's reply text, or an empty string if no content is returned. * @throws Error with a Kenari-specific prefix if the request fails. */ - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: modelId, info } = await this.fetchModel() try { diff --git a/src/api/providers/lite-llm.ts b/src/api/providers/lite-llm.ts index ec6c24adc0..6b46694126 100644 --- a/src/api/providers/lite-llm.ts +++ b/src/api/providers/lite-llm.ts @@ -362,7 +362,7 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: modelId, info } = await this.fetchModel() // Check if this is a GPT-5 model that requires max_completion_tokens instead of max_tokens diff --git a/src/api/providers/lm-studio.ts b/src/api/providers/lm-studio.ts index 5be239f1e4..57bf9adefa 100644 --- a/src/api/providers/lm-studio.ts +++ b/src/api/providers/lm-studio.ts @@ -204,7 +204,7 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan inputTokens, outputTokens, } as const - } catch (error) { + } catch { throw new Error( "Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Zoo Code's prompts.", ) @@ -232,7 +232,7 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { // Create params object with optional draft model const params: any = { @@ -254,7 +254,7 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan throw handleOpenAIError(error, this.providerName) } return response.choices[0]?.message.content || "" - } catch (error) { + } catch { throw new Error( "Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Zoo Code's prompts.", ) @@ -271,7 +271,7 @@ export async function getLmStudioModels(baseUrl = "http://localhost:1234") { const response = await axios.get(`${baseUrl}/v1/models`) const modelsArray = response.data?.data?.map((model: any) => model.id) || [] return [...new Set(modelsArray)] - } catch (error) { + } catch { return [] } } diff --git a/src/api/providers/minimax.ts b/src/api/providers/minimax.ts index e209add72d..b79e96568a 100644 --- a/src/api/providers/minimax.ts +++ b/src/api/providers/minimax.ts @@ -1,5 +1,4 @@ import { Anthropic } from "@anthropic-ai/sdk" -import { Stream as AnthropicStream } from "@anthropic-ai/sdk/streaming" import { CacheControlEphemeral } from "@anthropic-ai/sdk/resources" import OpenAI from "openai" @@ -289,7 +288,7 @@ export class MiniMaxHandler extends BaseProvider implements SingleCompletionHand } } - async completePrompt(prompt: string, options?: CompletePromptOptions) { + async completePrompt(prompt: string, _options?: CompletePromptOptions) { const { id: model, temperature } = this.getModel() const message = await this.client.messages.create({ diff --git a/src/api/providers/mistral.ts b/src/api/providers/mistral.ts index c7816feaa2..e7023513b0 100644 --- a/src/api/providers/mistral.ts +++ b/src/api/providers/mistral.ts @@ -15,7 +15,6 @@ import { ApiHandlerOptions } from "../../shared/api" import { convertToMistralMessages } from "../transform/mistral-format" import { ApiStream } from "../transform/stream" -import { handleProviderError } from "./utils/error-handler" import { BaseProvider } from "./base-provider" import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata, CompletePromptOptions } from "../index" @@ -192,7 +191,7 @@ export class MistralHandler extends BaseProvider implements SingleCompletionHand return { id, info, maxTokens, temperature } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: model, temperature } = this.getModel() try { diff --git a/src/api/providers/native-ollama.ts b/src/api/providers/native-ollama.ts index 71968d1ac0..36b422eac9 100644 --- a/src/api/providers/native-ollama.ts +++ b/src/api/providers/native-ollama.ts @@ -564,7 +564,7 @@ export class NativeOllamaHandler extends BaseProvider implements SingleCompletio } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { const client = this.ensureClient() const { id: modelId } = await this.fetchModel() diff --git a/src/api/providers/openai-codex.ts b/src/api/providers/openai-codex.ts index 8f49ad1337..71c84d5f99 100644 --- a/src/api/providers/openai-codex.ts +++ b/src/api/providers/openai-codex.ts @@ -11,7 +11,6 @@ import { OpenAiCodexModelId, openAiCodexModels, SERVICE_TIER_KEY, - type ReasoningEffort, type ReasoningEffortExtended, type VerbosityLevel, ApiProviderError, @@ -191,7 +190,7 @@ export class OpenAiCodexHandler extends BaseProvider implements SingleCompletion this.sessionId = uuidv7() } - private normalizeUsage(usage: any, model: OpenAiCodexModel): ApiStreamUsageChunk | undefined { + private normalizeUsage(usage: any, _model: OpenAiCodexModel): ApiStreamUsageChunk | undefined { if (!usage) return undefined const inputDetails = usage.input_tokens_details ?? usage.prompt_tokens_details @@ -607,7 +606,7 @@ export class OpenAiCodexHandler extends BaseProvider implements SingleCompletion } } - private formatFullConversation(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): any { + private formatFullConversation(_systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): any { const formattedInput: any[] = [] for (const message of messages) { diff --git a/src/api/providers/openai-compatible.ts b/src/api/providers/openai-compatible.ts index e2dbfae237..7f1d6b18c3 100644 --- a/src/api/providers/openai-compatible.ts +++ b/src/api/providers/openai-compatible.ts @@ -209,7 +209,7 @@ export abstract class OpenAICompatibleHandler extends BaseProvider implements Si /** * Complete a prompt using the AI SDK generateText. */ - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { const languageModel = this.getLanguageModel() diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 9784a2b6c6..fbbecf5760 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -10,7 +10,6 @@ import { OpenAiNativeModelId, openAiNativeModels, OPENAI_NATIVE_DEFAULT_TEMPERATURE, - type ReasoningEffort, type VerbosityLevel, type ReasoningEffortExtended, OpenAiServiceTier, @@ -210,7 +209,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio this.streamedToolCallIds.clear() // Use Responses API for ALL models - const { verbosity, reasoning } = this.getModel() + const { verbosity } = this.getModel() // Resolve reasoning effort for models that support it const reasoningEffort = this.getReasoningEffort(model) @@ -451,7 +450,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio yield outChunk } } - } catch (sdkErr: any) { + } catch { // For errors, fallback to manual SSE via fetch yield* this.makeResponsesApiRequest(requestBody, model, metadata, systemPrompt, messages) } finally { @@ -459,7 +458,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio } } - private formatFullConversation(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): any { + private formatFullConversation(_systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): any { // Format the entire conversation history for the Responses API using structured format // The Responses API (like Realtime API) accepts a list of items, which can be messages, function calls, or function call outputs. const formattedInput: any[] = [] @@ -559,8 +558,8 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio requestBody: any, model: OpenAiNativeModel, metadata?: ApiHandlerCreateMessageMetadata, - systemPrompt?: string, - messages?: Anthropic.Messages.MessageParam[], + _systemPrompt?: string, + _messages?: Anthropic.Messages.MessageParam[], ): ApiStream { const apiKey = this.options.openAiNativeApiKey ?? NOT_PROVIDED const baseUrl = this.options.openAiNativeBaseUrl || "https://api.openai.com" @@ -682,8 +681,6 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio const decoder = new TextDecoder() let buffer = "" let hasContent = false - const totalInputTokens = 0 - const totalOutputTokens = 0 try { while (true) { @@ -1503,7 +1500,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio getResponseId(): string | undefined { return this.lastResponseId } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { this.abortController = new AbortController() diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 7b0493b4c9..ef30f6763a 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -331,7 +331,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { const isAzureAiInference = this._isAzureAiInference(this.options.openAiBaseUrl) const model = this.getModel() @@ -552,7 +552,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl protected _getUrlHost(baseUrl?: string): string { try { return new URL(baseUrl ?? "").hostname - } catch (error) { + } catch { return "" } } @@ -620,7 +620,7 @@ export async function getOpenAiModels(baseUrl?: string, apiKey?: string, openAiH const response = await axios.get(`${trimmedBaseUrl}/models`, config) const modelsArray = response.data?.data?.map((model: any) => model.id) || [] return [...new Set(modelsArray)] - } catch (error) { + } catch { return [] } } diff --git a/src/api/providers/opencode-go.ts b/src/api/providers/opencode-go.ts index 1339dccdf5..2939d5b001 100644 --- a/src/api/providers/opencode-go.ts +++ b/src/api/providers/opencode-go.ts @@ -326,7 +326,7 @@ export class OpencodeGoHandler extends RouterProvider implements SingleCompletio private async *streamResponsesMessage( modelId: string, info: ModelInfo, - temperature: number | undefined, + _temperature: number | undefined, maxTokens: number | undefined, reasoningEffort: ReasoningEffortExtended | undefined, systemPrompt: string, diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index a2878c0e18..96d42a001a 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -68,16 +68,6 @@ const OpenRouterErrorResponseSchema = z.object({ .optional(), }) -// OpenRouter error structure that may include error.metadata.raw with actual upstream error -// This is for caught exceptions which have the error wrapped in an "error" property -interface OpenRouterErrorResponse { - error?: { - message?: string - code?: number - metadata?: { raw?: string } - } -} - // Direct error object structure (for streaming errors passed directly) interface OpenRouterError { message?: string @@ -170,7 +160,7 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH return { urlScoped: false, keyScoped: false, authScoped: false } } - async fetchModels(options: GetModelsOptions, signal?: AbortSignal): Promise { + async fetchModels(_options: GetModelsOptions, signal?: AbortSignal): Promise { const fetchOpts: [] | [{ signal: AbortSignal }] = signal ? [{ signal }] : [] return getOpenRouterModels(undefined, ...fetchOpts) } @@ -603,7 +593,7 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH return { id, info, topP: isDeepSeekR1 ? 0.95 : undefined, ...params } } - async completePrompt(prompt: string, options?: CompletePromptOptions) { + async completePrompt(prompt: string, _options?: CompletePromptOptions) { const { id: modelId, maxTokens, temperature, reasoning } = await this.fetchModel() const completionParams: OpenRouterChatCompletionParams = { diff --git a/src/api/providers/poe.ts b/src/api/providers/poe.ts index 8648cf57fc..e4df8b98ed 100644 --- a/src/api/providers/poe.ts +++ b/src/api/providers/poe.ts @@ -168,7 +168,7 @@ export class PoeHandler extends BaseProvider implements SingleCompletionHandler } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id } = this.getModel() try { const { text } = await generateText({ diff --git a/src/api/providers/qwen-code.ts b/src/api/providers/qwen-code.ts index bba6d52537..8453867254 100644 --- a/src/api/providers/qwen-code.ts +++ b/src/api/providers/qwen-code.ts @@ -4,7 +4,7 @@ import OpenAI from "openai" import * as os from "os" import * as path from "path" -import { type ModelInfo, type QwenCodeModelId, qwenCodeModels, qwenCodeDefaultModelId } from "@roo-code/types" +import { type ModelInfo, qwenCodeModels, qwenCodeDefaultModelId } from "@roo-code/types" import type { ApiHandlerOptions } from "../../shared/api" @@ -334,7 +334,7 @@ export class QwenCodeHandler extends BaseProvider implements SingleCompletionHan return { id, info } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { await this.ensureAuthenticated() const client = this.ensureClient() const model = this.getModel() diff --git a/src/api/providers/requesty.ts b/src/api/providers/requesty.ts index b313c22a5a..3a9d5e064a 100644 --- a/src/api/providers/requesty.ts +++ b/src/api/providers/requesty.ts @@ -225,7 +225,7 @@ export class RequestyHandler extends BaseProvider implements SingleCompletionHan } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: model, maxTokens: max_tokens, temperature } = await this.fetchModel() const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] diff --git a/src/api/providers/unbound.ts b/src/api/providers/unbound.ts index b9b47c7b13..4b8ba242c5 100644 --- a/src/api/providers/unbound.ts +++ b/src/api/providers/unbound.ts @@ -219,7 +219,7 @@ export class UnboundHandler extends BaseProvider implements SingleCompletionHand } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: model, maxTokens: max_tokens, temperature } = await this.fetchModel() const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] diff --git a/src/api/providers/vercel-ai-gateway.ts b/src/api/providers/vercel-ai-gateway.ts index b8bd1f7d20..2f1586b928 100644 --- a/src/api/providers/vercel-ai-gateway.ts +++ b/src/api/providers/vercel-ai-gateway.ts @@ -64,7 +64,7 @@ export class VercelAiGatewayHandler extends RouterProvider implements SingleComp return { urlScoped: false, keyScoped: false, authScoped: false } } - async fetchModels(options: GetModelsOptions, signal?: AbortSignal): Promise { + async fetchModels(_options: GetModelsOptions, signal?: AbortSignal): Promise { const fetchOpts: [] | [{ signal: AbortSignal }] = signal ? [{ signal }] : [] return getVercelAiGatewayModels(undefined, ...fetchOpts) } @@ -154,7 +154,7 @@ export class VercelAiGatewayHandler extends RouterProvider implements SingleComp } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const { id: modelId, info } = await this.fetchModel() try { diff --git a/src/api/providers/vscode-lm.ts b/src/api/providers/vscode-lm.ts index 581f94a066..7326d3ec8a 100644 --- a/src/api/providers/vscode-lm.ts +++ b/src/api/providers/vscode-lm.ts @@ -1445,7 +1445,7 @@ export class VsCodeLmHandler extends BaseProvider implements SingleCompletionHan return this.getModel().info.contextWindow } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { try { const client = await this.getClient() const response = await client.sendRequest( diff --git a/src/api/providers/xai.ts b/src/api/providers/xai.ts index 189ec4e9ed..7dc4fa6b1b 100644 --- a/src/api/providers/xai.ts +++ b/src/api/providers/xai.ts @@ -144,7 +144,7 @@ export class XAIHandler extends BaseProvider implements SingleCompletionHandler yield* processResponsesApiStream(stream, normalizeUsage) } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { const model = this.getModel() try { diff --git a/src/api/providers/zai.ts b/src/api/providers/zai.ts index da057406b4..3e0a39a4df 100644 --- a/src/api/providers/zai.ts +++ b/src/api/providers/zai.ts @@ -58,7 +58,7 @@ export class ZAiHandler extends BaseOpenAiCompatibleProvider { metadata?: ApiHandlerCreateMessageMetadata, requestOptions?: OpenAI.RequestOptions, ) { - const { id: modelId, info } = this.getModel() + const { info } = this.getModel() // Check if this is a model with thinking support (e.g. GLM-4.7, GLM-5) const isThinkingModel = Array.isArray(info.supportsReasoningEffort) diff --git a/src/api/providers/zoo-gateway.ts b/src/api/providers/zoo-gateway.ts index cc6408e64b..66ccac5067 100644 --- a/src/api/providers/zoo-gateway.ts +++ b/src/api/providers/zoo-gateway.ts @@ -293,7 +293,7 @@ export class ZooGatewayHandler extends RouterProvider implements SingleCompletio } } - async completePrompt(prompt: string, options?: CompletePromptOptions): Promise { + async completePrompt(prompt: string, _options?: CompletePromptOptions): Promise { this.ensureAuthenticated() const { id: modelId, info } = await this.fetchModel() diff --git a/src/api/transform/__tests__/model-params.spec.ts b/src/api/transform/__tests__/model-params.spec.ts index d66fb66b76..d4f374ac09 100644 --- a/src/api/transform/__tests__/model-params.spec.ts +++ b/src/api/transform/__tests__/model-params.spec.ts @@ -912,7 +912,7 @@ describe("getModelParams", () => { reasoningEffort: "medium", } - const result = getModelParams({ + getModelParams({ ...anthropicParams, settings: {}, model, diff --git a/src/api/transform/__tests__/reasoning.spec.ts b/src/api/transform/__tests__/reasoning.spec.ts index af96896ec0..86533d35d0 100644 --- a/src/api/transform/__tests__/reasoning.spec.ts +++ b/src/api/transform/__tests__/reasoning.spec.ts @@ -15,7 +15,6 @@ import { AnthropicReasoningParams, AnthropicProviderReasoningParams, OpenAiReasoningParams, - RooReasoningParams, GeminiReasoningParams, GeminiThinkingLevel, } from "../reasoning" diff --git a/src/api/transform/__tests__/responses-api-stream.spec.ts b/src/api/transform/__tests__/responses-api-stream.spec.ts index 027956cae6..5d3b3827c0 100644 --- a/src/api/transform/__tests__/responses-api-stream.spec.ts +++ b/src/api/transform/__tests__/responses-api-stream.spec.ts @@ -434,7 +434,7 @@ describe("createUsageNormalizer", () => { }) it("should compute totalCost when calculateCost is provided", () => { - const calculateCost = (input: number, output: number, cached: number) => 0.42 + const calculateCost = (_input: number, _output: number, _cached: number) => 0.42 const normalize = createUsageNormalizer(calculateCost) const result = normalize({ input_tokens: 100, output_tokens: 50 }) diff --git a/src/api/transform/model-params.ts b/src/api/transform/model-params.ts index fb3e6b5f18..08c066f21a 100644 --- a/src/api/transform/model-params.ts +++ b/src/api/transform/model-params.ts @@ -3,11 +3,9 @@ import { type ProviderSettings, type VerbosityLevel, type ReasoningEffortExtended, - ANTHROPIC_DEFAULT_MAX_TOKENS, } from "@roo-code/types" import { - DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS, DEFAULT_HYBRID_REASONING_MODEL_THINKING_TOKENS, GEMINI_25_PRO_MIN_THINKING_TOKENS, shouldUseReasoningBudget, @@ -80,7 +78,6 @@ export function getModelParams({ defaultTemperature, }: GetModelParamsOptions): ModelParams { const { - modelMaxTokens: customMaxTokens, modelMaxThinkingTokens: customMaxThinkingTokens, modelTemperature: customTemperature, reasoningEffort: customReasoningEffort, diff --git a/src/api/transform/openai-format.ts b/src/api/transform/openai-format.ts index 9b799e5c3d..d0f0df172b 100644 --- a/src/api/transform/openai-format.ts +++ b/src/api/transform/openai-format.ts @@ -256,21 +256,12 @@ export function sanitizeGeminiMessages( } /** - * A reasoning content block (DeepSeek / Z.ai interleaved thinking) that may - * appear in an assistant message's content array. Not part of Anthropic's - * ContentBlockParam union, so it's declared separately here. - */ -interface ReasoningContentBlock { - type: "reasoning" - text?: string -} - -/** - * Extracts the reasoning text if `part` is a {@link ReasoningContentBlock}, or `undefined` - * otherwise. Providers like DeepSeek / Z.ai emit a `"reasoning"` content block that isn't part of - * Anthropic's `ContentBlockParam` union, so `part` is treated as `unknown` and its shape is + * Extracts the reasoning text if `part` is a reasoning content block (DeepSeek / Z.ai interleaved + * thinking, i.e. `{ type: "reasoning", text?: string }`), or `undefined` otherwise. Providers like + * DeepSeek / Z.ai emit a `"reasoning"` content block that isn't part of Anthropic's + * `ContentBlockParam` union, so `part` is treated as `unknown` and its shape is * validated at runtime rather than assumed via a cast. A boolean type-guard isn't viable here: - * TypeScript can't narrow `part` to `ReasoningContentBlock` because their `type` literals don't + * TypeScript can't narrow `part` to a reasoning block because their `type` literals don't * overlap with any variant of `ContentBlockParam`, so the narrowed type collapses to `never`. */ function getReasoningBlockText(part: unknown): string | undefined { @@ -338,7 +329,7 @@ export function convertToOpenAiMessages( // conversation state client-side, we don't use `store: true`, and sending // back the `id` field causes a 404 error. if (detail?.format === "openai-responses-v1" && detail?.id) { - const { id, ...rest } = detail + const { id: _id, ...rest } = detail return rest } return detail diff --git a/src/api/transform/reasoning.ts b/src/api/transform/reasoning.ts index da2bdd6f30..0cf0bf05cd 100644 --- a/src/api/transform/reasoning.ts +++ b/src/api/transform/reasoning.ts @@ -172,7 +172,6 @@ export const getOpenAiReasoning = ({ export const getGeminiReasoning = ({ model, reasoningBudget, - reasoningEffort, settings, }: GetModelReasoningOptions): GeminiReasoningParams | undefined => { // Budget-based (2.5) models: use thinkingBudget, not thinkingLevel. diff --git a/src/api/transform/zai-format.ts b/src/api/transform/zai-format.ts index 0bc8353d8e..6b9985e955 100644 --- a/src/api/transform/zai-format.ts +++ b/src/api/transform/zai-format.ts @@ -5,7 +5,6 @@ type ContentPartText = OpenAI.Chat.ChatCompletionContentPartText type ContentPartImage = OpenAI.Chat.ChatCompletionContentPartImage type UserMessage = OpenAI.Chat.ChatCompletionUserMessageParam type AssistantMessage = OpenAI.Chat.ChatCompletionAssistantMessageParam -type SystemMessage = OpenAI.Chat.ChatCompletionSystemMessageParam type ToolMessage = OpenAI.Chat.ChatCompletionToolMessageParam type Message = OpenAI.Chat.ChatCompletionMessageParam type AnthropicMessage = Anthropic.Messages.MessageParam diff --git a/src/core/assistant-message/NativeToolCallParser.ts b/src/core/assistant-message/NativeToolCallParser.ts index d55d69b431..90da07cc8d 100644 --- a/src/core/assistant-message/NativeToolCallParser.ts +++ b/src/core/assistant-message/NativeToolCallParser.ts @@ -446,7 +446,7 @@ export class NativeToolCallParser { * @param originalName - The original tool name as called by the model (if different from canonical name) */ private static createPartialToolUse( - id: string, + _id: string, name: ToolName, partialArgs: Record, partial: boolean, diff --git a/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts b/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts index 695c40818c..864a113fdf 100644 --- a/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts +++ b/src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts @@ -1,9 +1,7 @@ // npx vitest src/core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts import { describe, it, expect, beforeEach, vi } from "vitest" -import { Anthropic } from "@anthropic-ai/sdk" import { presentAssistantMessage } from "../presentAssistantMessage" -import { Task } from "../../task/Task" import { validateToolUse } from "../../tools/validateToolUse" import type { RequestPolicySnapshot } from "../../prompts/tools/effective-tool-policy" @@ -102,15 +100,6 @@ describe("presentAssistantMessage - Image Handling in Native Tool Calling", () = ] // Create a mock askApproval that includes images in the response - const imageBlock: Anthropic.ImageBlockParam = { - type: "image", - source: { - type: "base64", - media_type: "image/png", - data: "base64ImageData", - }, - } - mockTask.ask = vi.fn().mockResolvedValue({ response: "yesButtonClicked", text: "I see a cat", diff --git a/src/core/assistant-message/presentAssistantMessage.ts b/src/core/assistant-message/presentAssistantMessage.ts index 5dd14e535b..68cc7a3dd0 100644 --- a/src/core/assistant-message/presentAssistantMessage.ts +++ b/src/core/assistant-message/presentAssistantMessage.ts @@ -9,7 +9,7 @@ import { customToolRegistry } from "@roo-code/core" import { t } from "../../i18n" import { defaultModeSlug, getModeBySlug } from "../../shared/modes" -import type { AutoApprovalContext, ToolParamName, ToolResponse, ToolUse, McpToolUse } from "../../shared/tools" +import type { AutoApprovalContext, ToolResponse, ToolUse, McpToolUse } from "../../shared/tools" import { buildAutoDenyReason } from "../auto-approval" @@ -191,7 +191,7 @@ async function presentAssistantMessageBlock(cline: Task, policySnapshot: Request // Store approval feedback to merge into tool result (GitHub #10465) let approvalFeedback: { text: string; images?: string[] } | undefined - const pushToolResult = (content: ToolResponse, feedbackImages?: string[]) => { + const pushToolResult = (content: ToolResponse, _feedbackImages?: string[]) => { if (hasToolResult) { console.warn( `[presentAssistantMessage] Skipping duplicate tool_result for mcp_tool_use: ${toolCallId}`, @@ -239,8 +239,6 @@ async function presentAssistantMessageBlock(cline: Task, policySnapshot: Request hasToolResult = true } - const toolDescription = () => `[mcp_tool: ${mcpBlock.serverName}/${mcpBlock.toolName}]` - const askApproval = async ( type: ClineAsk, partialMessage?: string, diff --git a/src/core/auto-approval/index.ts b/src/core/auto-approval/index.ts index 2aa5008fc8..3539eef24d 100644 --- a/src/core/auto-approval/index.ts +++ b/src/core/auto-approval/index.ts @@ -221,7 +221,7 @@ export async function checkAutoApproval({ } else { return { decision: "ask" } } - } catch (error) { + } catch { return { decision: "ask" } } } else { @@ -244,7 +244,7 @@ export async function checkAutoApproval({ } else if (mcpServerUse.type === "access_mcp_resource") { return state.alwaysAllowMcp === true ? { decision: "approve" } : { decision: "ask" } } - } catch (error) { + } catch { return { decision: "ask" } } diff --git a/src/core/checkpoints/__tests__/checkpoint.test.ts b/src/core/checkpoints/__tests__/checkpoint.test.ts index 299ff823b8..9b2fc1d1aa 100644 --- a/src/core/checkpoints/__tests__/checkpoint.test.ts +++ b/src/core/checkpoints/__tests__/checkpoint.test.ts @@ -1,6 +1,4 @@ -import { describe, it, expect, vi, beforeEach, afterEach, Mock } from "vitest" -import { Task } from "../../task/Task" -import { ClineProvider } from "../../webview/ClineProvider" +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest" import { checkpointSave, checkpointRestore, checkpointDiff, getCheckpointService } from "../index" import { MessageManager } from "../../message-manager" import * as vscode from "vscode" @@ -14,7 +12,7 @@ vi.mock("vscode", () => ({ }, Uri: { file: vi.fn((path: string) => ({ fsPath: path })), - parse: vi.fn((uri: string) => ({ with: vi.fn(() => ({})) })), + parse: vi.fn((_uri: string) => ({ with: vi.fn(() => ({})) })), }, commands: { executeCommand: vi.fn(), @@ -428,7 +426,7 @@ describe("Checkpoint functionality", () => { mockTask.checkpointService = undefined mockTask.checkpointServiceInitializing = false - const service = getCheckpointService(mockTask) + getCheckpointService(mockTask) const checkpointsModule = await import("../../../services/checkpoints") expect(vi.mocked(checkpointsModule.RepoPerTaskCheckpointService.create)).toHaveBeenCalledWith({ diff --git a/src/core/checkpoints/index.ts b/src/core/checkpoints/index.ts index 26a137b939..de424b03f7 100644 --- a/src/core/checkpoints/index.ts +++ b/src/core/checkpoints/index.ts @@ -44,7 +44,7 @@ export async function getCheckpointService(task: Task, { interval = 250 }: { int try { provider?.log(message) - } catch (err) { + } catch { // NO-OP } } @@ -295,7 +295,7 @@ export async function checkpointRestore( // task flow and the communication between the webview and the // `Task` instance. provider?.cancelTask() - } catch (err) { + } catch { provider?.log("[checkpointRestore] disabling checkpoints for this task") task.enableCheckpoints = false } @@ -314,7 +314,7 @@ export type CheckpointDiffOptions = { mode: "from-init" | "checkpoint" | "to-current" | "full" } -export async function checkpointDiff(task: Task, { ts, previousCommitHash, commitHash, mode }: CheckpointDiffOptions) { +export async function checkpointDiff(task: Task, { commitHash, mode }: CheckpointDiffOptions) { const service = await getCheckpointService(task) if (!service) { @@ -384,7 +384,7 @@ export async function checkpointDiff(task: Task, { ts, previousCommitHash, commi }), ]), ) - } catch (err) { + } catch { const provider = task.providerRef.deref() provider?.log("[checkpointDiff] disabling checkpoints for this task") task.enableCheckpoints = false diff --git a/src/core/condense/__tests__/foldedFileContext.spec.ts b/src/core/condense/__tests__/foldedFileContext.spec.ts index 3bd9b390f5..30f2960872 100644 --- a/src/core/condense/__tests__/foldedFileContext.spec.ts +++ b/src/core/condense/__tests__/foldedFileContext.spec.ts @@ -1,6 +1,5 @@ // npx vitest src/core/condense/__tests__/foldedFileContext.spec.ts -import * as path from "path" import { Anthropic } from "@anthropic-ai/sdk" import type { ModelInfo } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" diff --git a/src/core/condense/foldedFileContext.ts b/src/core/condense/foldedFileContext.ts index 360dd7fc76..4e73e9970d 100644 --- a/src/core/condense/foldedFileContext.ts +++ b/src/core/condense/foldedFileContext.ts @@ -144,7 +144,7 @@ ${truncatedDefinitions} foldedSections.push(sectionContent) currentCharCount += sectionContent.length result.filesProcessed++ - } catch (error) { + } catch { // Collect failed files for batch logging to reduce noise failedFiles.push(filePath) result.filesSkipped++ diff --git a/src/core/condense/index.ts b/src/core/condense/index.ts index 0438bf6bcb..1c680aa9c2 100644 --- a/src/core/condense/index.ts +++ b/src/core/condense/index.ts @@ -329,7 +329,6 @@ export async function summarizeConversation(options: SummarizeConversationOption let summary = "" let cost = 0 - let outputTokens = 0 try { const stream = apiHandler.createMessage(promptToUse, requestMessages, metadata) @@ -340,7 +339,6 @@ export async function summarizeConversation(options: SummarizeConversationOption } else if (chunk.type === "usage") { // Record final usage chunk only cost = chunk.totalCost ?? 0 - outputTokens = chunk.outputTokens ?? 0 } } } catch (error) { diff --git a/src/core/config/ContextProxy.ts b/src/core/config/ContextProxy.ts index 97d4104afc..1250a7baca 100644 --- a/src/core/config/ContextProxy.ts +++ b/src/core/config/ContextProxy.ts @@ -501,7 +501,7 @@ export class ContextProxy { `[ContextProxy] Sanitizing invalid provider "${sanitizedValues.apiProvider}" - resetting to undefined`, ) // Return a new values object without the invalid apiProvider - const { apiProvider, ...restValues } = sanitizedValues + const { apiProvider: _apiProvider, ...restValues } = sanitizedValues return restValues as RooCodeSettings } return sanitizedValues diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 48d67e01c8..698d4f1db0 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -159,7 +159,7 @@ export class CustomModesManager { try { // Try parsing the original content as JSON (not the cleaned content) return JSON.parse(content) - } catch (jsonError) { + } catch { // JSON also failed, show the original YAML error const errorMsg = yamlError instanceof Error ? yamlError.message : String(yamlError) console.error(`[CustomModesManager] Failed to parse YAML from ${filePath}:`, errorMsg) @@ -467,7 +467,7 @@ export class CustomModesManager { try { content = await fs.readFile(filePath, "utf-8") - } catch (error) { + } catch { // File might not exist yet. content = yaml.stringify({ customModes: [] }, { lineWidth: 0 }) } @@ -476,7 +476,7 @@ export class CustomModesManager { try { settings = this.parseYamlSafely(content, filePath) - } catch (error) { + } catch { // Error already logged in parseYamlSafely settings = { customModes: [] } } @@ -648,7 +648,7 @@ export class CustomModesManager { } else { return false // No .roomodes file and not in custom modes } - } catch (error) { + } catch { return false // Cannot read .roomodes and not in custom modes } } @@ -675,7 +675,7 @@ export class CustomModesManager { if (!stats.isDirectory()) { return false } - } catch (error) { + } catch { return false } @@ -695,7 +695,7 @@ export class CustomModesManager { } return false // No files with content found - } catch (error) { + } catch { return false } } catch (error) { @@ -738,7 +738,7 @@ export class CustomModesManager { // Find the mode in .roomodes mode = roomodesModes.find((m: any) => m.slug === slug) } - } catch (error) { + } catch { // Continue to check built-in modes } } @@ -798,7 +798,7 @@ export class CustomModesManager { } } } - } catch (error) { + } catch { // Directory doesn't exist, which is fine - mode might not have rules } @@ -866,7 +866,7 @@ export class CustomModesManager { try { await fs.rm(rulesFolderPath, { recursive: true, force: true }) logger.info(`Removed existing ${source} rules folder for mode ${importMode.slug}`) - } catch (error) { + } catch { // It's okay if the folder doesn't exist logger.debug(`No existing ${source} rules folder to remove for mode ${importMode.slug}`) } diff --git a/src/core/config/ProviderSettingsManager.ts b/src/core/config/ProviderSettingsManager.ts index e99592df3c..e0f272a578 100644 --- a/src/core/config/ProviderSettingsManager.ts +++ b/src/core/config/ProviderSettingsManager.ts @@ -273,7 +273,7 @@ export class ProviderSettingsManager { private async migrateConsecutiveMistakeLimit(providerProfiles: ProviderProfiles) { try { - for (const [name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) { + for (const [, apiConfig] of Object.entries(providerProfiles.apiConfigs)) { if (apiConfig.consecutiveMistakeLimit == null) { apiConfig.consecutiveMistakeLimit = DEFAULT_CONSECUTIVE_MISTAKE_LIMIT } @@ -731,7 +731,7 @@ export class ProviderSettingsManager { ) // Return a new config object without the invalid apiProvider // This effectively resets the profile so the user can select a valid provider - const { apiProvider, ...restConfig } = config + const { apiProvider: _apiProvider, ...restConfig } = config return restConfig } diff --git a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts index b141006c85..1b6256c5e6 100644 --- a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts @@ -8,8 +8,6 @@ import * as fs from "fs/promises" import * as yaml from "yaml" import * as vscode from "vscode" -import type { ModeConfig } from "@roo-code/types" - import { fileExistsAtPath } from "../../../utils/fs" import { getWorkspacePath } from "../../../utils/path" import { GlobalFileNames } from "../../../shared/globalFileNames" diff --git a/src/core/config/__tests__/CustomModesManager.yamlEdgeCases.spec.ts b/src/core/config/__tests__/CustomModesManager.yamlEdgeCases.spec.ts index eab01eee41..736e644031 100644 --- a/src/core/config/__tests__/CustomModesManager.yamlEdgeCases.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.yamlEdgeCases.spec.ts @@ -8,8 +8,6 @@ import * as fs from "fs/promises" import * as yaml from "yaml" import * as vscode from "vscode" -import type { ModeConfig } from "@roo-code/types" - import { fileExistsAtPath } from "../../../utils/fs" import { getWorkspacePath } from "../../../utils/path" import { GlobalFileNames } from "../../../shared/globalFileNames" diff --git a/src/core/config/__tests__/ProviderSettingsManager.spec.ts b/src/core/config/__tests__/ProviderSettingsManager.spec.ts index 1a54342df2..3e5a0cd22c 100644 --- a/src/core/config/__tests__/ProviderSettingsManager.spec.ts +++ b/src/core/config/__tests__/ProviderSettingsManager.spec.ts @@ -12,7 +12,7 @@ import { import { clearAllMocks } from "../../../test-utils/reset" import { makeExtensionContext } from "../../../test-utils/vscode" -import { ProviderSettingsManager, ProviderProfiles, SyncCloudProfilesResult } from "../ProviderSettingsManager" +import { ProviderSettingsManager, ProviderProfiles } from "../ProviderSettingsManager" // `export()` builds an API handler per profile to read model capabilities. Mock // buildApiHandler with the real @roo-code/types model definitions so the token-field diff --git a/src/core/config/__tests__/importExport.spec.ts b/src/core/config/__tests__/importExport.spec.ts index 0287b26511..f50fb29d11 100644 --- a/src/core/config/__tests__/importExport.spec.ts +++ b/src/core/config/__tests__/importExport.spec.ts @@ -5,7 +5,6 @@ import * as path from "path" import * as vscode from "vscode" -import type { ProviderName } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" import { clearAllMocks } from "../../../test-utils/reset" diff --git a/src/core/config/importExport.ts b/src/core/config/importExport.ts index 3c213fedf4..0db0e9c9ea 100644 --- a/src/core/config/importExport.ts +++ b/src/core/config/importExport.ts @@ -62,7 +62,7 @@ function sanitizeProviderConfig(configName: string, apiConfig: unknown): { confi if (config.apiProvider !== undefined && !isProviderName(config.apiProvider)) { const invalidProvider = config.apiProvider // Return a new config object without the invalid apiProvider - const { apiProvider, ...restConfig } = config + const { apiProvider: _apiProvider, ...restConfig } = config return { config: restConfig, warning: `Profile "${configName}": Invalid provider "${invalidProvider}" was removed. Please reconfigure this profile.`, diff --git a/src/core/context-management/__tests__/context-management.spec.ts b/src/core/context-management/__tests__/context-management.spec.ts index ce7db70fa7..38c941cf4f 100644 --- a/src/core/context-management/__tests__/context-management.spec.ts +++ b/src/core/context-management/__tests__/context-management.spec.ts @@ -653,14 +653,6 @@ describe("Context Management", () => { { ...messages[messages.length - 1], content: "" }, ] - // When truncating, always uses 0.5 fraction - // With 4 messages after the first, 0.5 fraction means remove 2 messages - const expectedMessages = [ - messagesWithSmallContent[0], - messagesWithSmallContent[3], - messagesWithSmallContent[4], - ] - const result = await manageContext({ messages: messagesWithSmallContent, totalTokens, @@ -703,14 +695,6 @@ describe("Context Management", () => { { ...messages[messages.length - 1], content: "" }, ] - // When truncating, always uses 0.5 fraction - // With 4 messages after the first, 0.5 fraction means remove 2 messages - const expectedMessages = [ - messagesWithSmallContent[0], - messagesWithSmallContent[3], - messagesWithSmallContent[4], - ] - const result = await manageContext({ messages: messagesWithSmallContent, totalTokens, @@ -1025,7 +1009,7 @@ describe("Context Management", () => { { ...messages[messages.length - 1], content: "" }, ] - const result = await manageContext({ + await manageContext({ messages: messagesWithSmallContent, totalTokens, contextWindow: modelInfo.contextWindow, diff --git a/src/core/context-management/__tests__/truncation.spec.ts b/src/core/context-management/__tests__/truncation.spec.ts index 2e6cbed5b6..76fc49b06b 100644 --- a/src/core/context-management/__tests__/truncation.spec.ts +++ b/src/core/context-management/__tests__/truncation.spec.ts @@ -276,7 +276,6 @@ describe("Non-Destructive Sliding Window Truncation", () => { const firstTruncation = truncateConversation(messages, 0.5, "task-1") // Step 2: Get effective history and simulate more messages being added - const effectiveAfterFirst = getEffectiveApiHistory(firstTruncation.messages) const moreMessages: ApiMessage[] = [ ...firstTruncation.messages, { role: "user", content: "New message 1", ts: 3000 }, @@ -319,7 +318,6 @@ describe("Non-Destructive Sliding Window Truncation", () => { // Step 2: Add more messages AFTER getting effective history // This simulates real usage where we only send effective messages to API - const effectiveAfterFirst = getEffectiveApiHistory(firstTruncation.messages) const moreMessages: ApiMessage[] = [ ...firstTruncation.messages, // Keep full history with tagged messages { role: "user", content: "New message 1", ts: 3000 }, diff --git a/src/core/context-management/index.ts b/src/core/context-management/index.ts index 82cb4fdf2e..2050cef373 100644 --- a/src/core/context-management/index.ts +++ b/src/core/context-management/index.ts @@ -129,8 +129,6 @@ export function truncateConversation(messages: ApiMessage[], fracToRemove: numbe return msg }) - // Find the actual boundary - the index right after the last truncated message - const lastTruncatedVisibleIndex = visibleIndices[messagesToRemove] // Last visible message being truncated // If all visible messages except the first are truncated, insert marker at the end const firstKeptVisibleIndex = visibleIndices[messagesToRemove + 1] ?? taggedMessages.length diff --git a/src/core/environment/getEnvironmentDetails.ts b/src/core/environment/getEnvironmentDetails.ts index 73b934be30..8940690679 100644 --- a/src/core/environment/getEnvironmentDetails.ts +++ b/src/core/environment/getEnvironmentDetails.ts @@ -5,8 +5,6 @@ import * as vscode from "vscode" import pWaitFor from "p-wait-for" import delay from "delay" -import type { ExperimentId } from "@roo-code/types" - import { formatLanguage } from "../../shared/language" import { getFullModeDetails } from "../../shared/modes" import { getApiMetrics } from "../../shared/getApiMetrics" @@ -204,13 +202,7 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo const { id: modelId } = cline.api.getModel() // Add current mode and any mode-specific warnings. - const { - customModes, - customModePrompts, - experiments = {} as Record, - customInstructions: globalCustomInstructions, - language, - } = state ?? {} + const { customModes, customModePrompts, customInstructions: globalCustomInstructions, language } = state ?? {} // Read the task-local mode, not the shared provider mode. // A delegated child task may run in a different mode than its parent. diff --git a/src/core/ignore/RooIgnoreController.ts b/src/core/ignore/RooIgnoreController.ts index 45054cce96..ddab36ce47 100644 --- a/src/core/ignore/RooIgnoreController.ts +++ b/src/core/ignore/RooIgnoreController.ts @@ -109,7 +109,7 @@ export class RooIgnoreController { // Check if the real path is ignored return !this.ignoreInstance.ignores(relativePath) - } catch (error) { + } catch { // Allow access to files outside cwd or on errors (backward compatibility) return true } diff --git a/src/core/mentions/__tests__/index.spec.ts b/src/core/mentions/__tests__/index.spec.ts index fa96a396dc..aa4ebeaff2 100644 --- a/src/core/mentions/__tests__/index.spec.ts +++ b/src/core/mentions/__tests__/index.spec.ts @@ -1,7 +1,5 @@ // npx vitest core/mentions/__tests__/index.spec.ts -import * as vscode from "vscode" - import { parseMentions } from "../index" // Mock vscode diff --git a/src/core/mentions/__tests__/processUserContentMentions.spec.ts b/src/core/mentions/__tests__/processUserContentMentions.spec.ts index c7e25f438a..1995c36bc0 100644 --- a/src/core/mentions/__tests__/processUserContentMentions.spec.ts +++ b/src/core/mentions/__tests__/processUserContentMentions.spec.ts @@ -11,13 +11,11 @@ vi.mock("../index", () => ({ describe("processUserContentMentions", () => { let mockFileContextTracker: FileContextTracker - let mockRooIgnoreController: any beforeEach(() => { vi.clearAllMocks() mockFileContextTracker = {} as FileContextTracker - mockRooIgnoreController = {} // Default mock implementation - returns ParseMentionsResult object vi.mocked(parseMentions).mockImplementation(async (text) => ({ diff --git a/src/core/mentions/index.ts b/src/core/mentions/index.ts index 1bfb90d23f..23a27f39b5 100644 --- a/src/core/mentions/index.ts +++ b/src/core/mentions/index.ts @@ -127,7 +127,7 @@ export async function parseMentions( const skillContent = await resolveSkillContentForMode(skillsManager, commandName, currentMode) return { commandName, command: undefined, skillContent } - } catch (error) { + } catch { // If there's an error checking command existence, treat it as non-existent return { commandName, command: undefined, skillContent: null } } @@ -355,7 +355,7 @@ async function getFileOrFolderContentWithMetadata( const result = await extractTextFromFileWithMetadata(absoluteFilePath) fileReadResults.push(formatFileReadResult(filePath.toPosix(), result)) } - } catch (error) { + } catch { // Skip files that can't be read } } diff --git a/src/core/mentions/processUserContentMentions.ts b/src/core/mentions/processUserContentMentions.ts index ab51783936..0a8ad40dfa 100644 --- a/src/core/mentions/processUserContentMentions.ts +++ b/src/core/mentions/processUserContentMentions.ts @@ -1,13 +1,12 @@ import Anthropic from "@anthropic-ai/sdk" -import { parseMentions, ParseMentionsResult, MentionContentBlock } from "./index" +import { parseMentions, MentionContentBlock } from "./index" import { FileContextTracker } from "../context-tracking/FileContextTracker" import type { SkillLookup } from "../../services/skills/skillInvocation" // Internal aliases for the Anthropic content block subtypes used during processing. type TextPart = Anthropic.Messages.TextBlockParam type ImagePart = Anthropic.Messages.ImageBlockParam -type ToolResultPart = Anthropic.Messages.ToolResultBlockParam export interface ProcessUserContentMentionsResult { content: Anthropic.Messages.ContentBlockParam[] diff --git a/src/core/message-manager/index.ts b/src/core/message-manager/index.ts index 4b68be0825..2d4666e9ee 100644 --- a/src/core/message-manager/index.ts +++ b/src/core/message-manager/index.ts @@ -1,7 +1,5 @@ import * as path from "path" import { Task } from "../task/Task" -import { ClineMessage } from "@roo-code/types" -import { ApiMessage } from "../task-persistence/apiMessages" import { cleanupAfterTruncation } from "../condense" import { OutputInterceptor } from "../../integrations/terminal/OutputInterceptor" import { getTaskDirectoryPath } from "../../utils/storage" diff --git a/src/core/prompts/__tests__/add-custom-instructions.spec.ts b/src/core/prompts/__tests__/add-custom-instructions.spec.ts index 5c9d7edf2c..5cdfd4be69 100644 --- a/src/core/prompts/__tests__/add-custom-instructions.spec.ts +++ b/src/core/prompts/__tests__/add-custom-instructions.spec.ts @@ -41,14 +41,11 @@ vi.mock("fs/promises") import * as vscode from "vscode" -import { ModeConfig } from "@roo-code/types" - import { SYSTEM_PROMPT } from "../system" import { McpHub } from "../../../services/mcp/McpHub" -import { defaultModeSlug, modes, Mode } from "../../../shared/modes" +import { defaultModeSlug, modes } from "../../../shared/modes" import "../../../utils/path" import { addCustomInstructions } from "../sections/custom-instructions" -import { MultiSearchReplaceDiffStrategy } from "../../diff/strategies/multi-search-replace" // Mock the sections vi.mock("../sections/modes", () => ({ @@ -73,7 +70,7 @@ __setMockImplementation( async ( modeCustomInstructions: string, globalCustomInstructions: string, - cwd: string, + _cwd: string, mode: string, options?: { language?: string }, ) => { diff --git a/src/core/prompts/__tests__/get-prompt-component.spec.ts b/src/core/prompts/__tests__/get-prompt-component.spec.ts index 814270f9db..6ec839fb14 100644 --- a/src/core/prompts/__tests__/get-prompt-component.spec.ts +++ b/src/core/prompts/__tests__/get-prompt-component.spec.ts @@ -41,7 +41,7 @@ describe("getPromptComponent", () => { ["customInstructions", { customInstructions: "Test instructions" }], ["whenToUse", { whenToUse: "Test when to use" }], ["description", { description: "Test description" }], - ])("should return the component when it has %s", (property, component) => { + ])("should return the component when it has %s", (_property, component) => { const customModePrompts: CustomModePrompts = { architect: component, } diff --git a/src/core/prompts/__tests__/system-prompt.spec.ts b/src/core/prompts/__tests__/system-prompt.spec.ts index 900a8748ce..2c0da48a11 100644 --- a/src/core/prompts/__tests__/system-prompt.spec.ts +++ b/src/core/prompts/__tests__/system-prompt.spec.ts @@ -48,8 +48,6 @@ import { McpHub } from "../../../services/mcp/McpHub" import { defaultModeSlug, modes, Mode } from "../../../shared/modes" import type { SystemPromptSettings } from "../types" import "../../../utils/path" -import { addCustomInstructions } from "../sections/custom-instructions" -import { MultiSearchReplaceDiffStrategy } from "../../diff/strategies/multi-search-replace" // Mock the sections vi.mock("../sections/modes", () => ({ @@ -74,7 +72,7 @@ __setMockImplementation( async ( modeCustomInstructions: string, globalCustomInstructions: string, - cwd: string, + _cwd: string, mode: string, options?: { language?: string; rooIgnoreInstructions?: string; settings?: Record }, ) => { diff --git a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts index 8adbe4f3a5..26ed24a08a 100644 --- a/src/core/prompts/sections/__tests__/custom-instructions.spec.ts +++ b/src/core/prompts/sections/__tests__/custom-instructions.spec.ts @@ -284,7 +284,7 @@ describe("loadRuleFiles", () => { }, ] as any) - statMock.mockImplementation((path) => { + statMock.mockImplementation((_path) => { return Promise.resolve({ isFile: vi.fn().mockReturnValue(true), }) as any @@ -1460,7 +1460,7 @@ describe("Rules directory reading", () => { { name: "Beta.txt", isFile: () => true, parentPath: "/fake/path/.roo/rules" }, // Test case-insensitive sorting ] as any) - statMock.mockImplementation((path) => { + statMock.mockImplementation((_path) => { return Promise.resolve({ isFile: vi.fn().mockReturnValue(true), }) as any diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index 0d72e568b8..91c00a3e25 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -1,6 +1,5 @@ import fs from "fs/promises" import path from "path" -import * as os from "os" import { Dirent } from "fs" import { isLanguage } from "@roo-code/types" @@ -12,7 +11,6 @@ import { getRooDirectoriesForCwd, getAllRooDirectoriesForCwd, getAgentsDirectoriesForCwd, - getGlobalRooDirectory, } from "../../../services/roo-config" /** @@ -38,7 +36,7 @@ async function directoryExists(dirPath: string): Promise { try { const stats = await fs.stat(dirPath) return stats.isDirectory() - } catch (err) { + } catch { return false } } @@ -122,7 +120,7 @@ async function resolveSymLink( // Handle nested symlinks by awaiting the recursive call await resolveSymLink(resolvedTarget, fileInfo, depth + 1) } - } catch (err) { + } catch { // Skip invalid symlinks } } @@ -165,7 +163,7 @@ async function readTextFilesFromDirectory(dirPath: string): Promise ({ filename, content })) - } catch (err) { + } catch { return [] } } @@ -277,7 +275,7 @@ async function readAgentRulesFile(filePath: string): Promise { resolvedPath = fileInfo[0].resolvedPath } } - } catch (err) { + } catch { // If lstat fails (file doesn't exist), return empty return "" } @@ -321,7 +319,7 @@ async function loadAgentRulesFileFromDirectory( // Found a standard file, don't check alternative break } - } catch (err) { + } catch { // Silently ignore errors - agent rules files are optional } } @@ -338,23 +336,13 @@ async function loadAgentRulesFileFromDirectory( : `# Agent Rules Local (${localFilename}):` results.push(`${localHeader}\n${localContent}`) } - } catch (err) { + } catch { // Silently ignore errors - local agent rules file is optional } return results.join("\n\n") } -/** - * Load AGENTS.md or AGENT.md file from the project root if it exists - * Checks for both AGENTS.md (standard) and AGENT.md (alternative) for compatibility - * - * @deprecated Use loadAllAgentRulesFiles for loading from all directories - */ -async function loadAgentRulesFile(cwd: string): Promise { - return loadAgentRulesFileFromDirectory(cwd, false, cwd) -} - /** * Load all AGENTS.md files from project root and optionally subdirectories with .roo folders * Returns combined content with clear path headers for each file diff --git a/src/core/prompts/sections/system-info.ts b/src/core/prompts/sections/system-info.ts index 98112cd4ed..003c555d75 100644 --- a/src/core/prompts/sections/system-info.ts +++ b/src/core/prompts/sections/system-info.ts @@ -20,7 +20,7 @@ export function getSystemInfoSection(cwd: string, policy: EffectiveToolPolicy): let osInfo: string try { osInfo = osName() - } catch (error) { + } catch { // Fallback when os-name fails (e.g., PowerShell not available on Windows) const platform = os.platform() const release = os.release() diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 9c0c2efa27..ecbdf2629a 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -18,7 +18,6 @@ import { CodeIndexManagerRegistry } from "../../services/code-index/code-index-m import { SkillsManager } from "../../services/skills/SkillsManager" import type { SystemPromptSettings } from "./types" -import type { EffectiveToolPolicy } from "./tools/effective-tool-policy" import { resolveEffectiveToolPolicy } from "./tools/effective-tool-policy" import { getRulesSection, @@ -49,10 +48,10 @@ export function getPromptComponent( async function generatePrompt( context: vscode.ExtensionContext, cwd: string, - supportsComputerUse: boolean, + _supportsComputerUse: boolean, mode: Mode, mcpHub?: McpHub, - diffStrategy?: DiffStrategy, + _diffStrategy?: DiffStrategy, promptComponent?: PromptComponent, customModeConfigs?: ModeConfig[], globalCustomInstructions?: string, @@ -60,8 +59,8 @@ async function generatePrompt( language?: string, rooIgnoreInstructions?: string, settings?: SystemPromptSettings, - todoList?: TodoItem[], - modelId?: string, + _todoList?: TodoItem[], + _modelId?: string, skillsManager?: SkillsManager, disabledTools?: string[], modelInfo?: ModelInfo, @@ -70,8 +69,6 @@ async function generatePrompt( throw new Error("Extension context is required for generating system prompt") } - // Get the full mode config to ensure we have the role definition (used for groups, etc.) - const modeConfig = getModeBySlug(mode, customModeConfigs) || modes.find((m) => m.slug === mode) || modes[0] const { roleDefinition, baseInstructions } = getModeSelection(mode, promptComponent, customModeConfigs) const codeIndexManager = CodeIndexManagerRegistry.getOrCreate(context, cwd) @@ -91,9 +88,6 @@ async function generatePrompt( codeIndexManager, }) - // Tool calling is native-only. - const effectiveProtocol = "native" - const [modesSection, skillsSection] = await Promise.all([ getModesSection(context), getSkillsSection(skillsManager, mode as string, policy), diff --git a/src/core/prompts/tools/__tests__/effective-tool-policy.spec.ts b/src/core/prompts/tools/__tests__/effective-tool-policy.spec.ts index 8e2c3cb80f..a562d12667 100644 --- a/src/core/prompts/tools/__tests__/effective-tool-policy.spec.ts +++ b/src/core/prompts/tools/__tests__/effective-tool-policy.spec.ts @@ -9,7 +9,6 @@ import { buildToolRequirements, isToolDisabledOrExcluded, } from "../effective-tool-policy" -import { getModeBySlug, defaultModeSlug } from "../../../../shared/modes" import type { CodeIndexManager } from "../../../../services/code-index/manager" /** Build a policy by giving the custom mode `groups` (derived from a real custom mode config). */ diff --git a/src/core/prompts/tools/native-tools/__tests__/converters.spec.ts b/src/core/prompts/tools/native-tools/__tests__/converters.spec.ts index c0c7a4f08f..29b54ceabf 100644 --- a/src/core/prompts/tools/native-tools/__tests__/converters.spec.ts +++ b/src/core/prompts/tools/native-tools/__tests__/converters.spec.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from "vitest" import type OpenAI from "openai" -import type Anthropic from "@anthropic-ai/sdk" import { convertOpenAIToolToAnthropic, convertOpenAIToolsToAnthropic, diff --git a/src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts b/src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts index acdc2724fa..58c8514389 100644 --- a/src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts +++ b/src/core/prompts/tools/native-tools/__tests__/mcp_server.spec.ts @@ -70,11 +70,6 @@ describe("getMcpServerTools", () => { }) it("should deduplicate tools when same server exists in both global and project configs", () => { - const globalServer = createMockServer( - "context7", - [createMockTool("resolve-library-id", "Global description")], - "global", - ) const projectServer = createMockServer( "context7", [createMockTool("resolve-library-id", "Project description")], diff --git a/src/core/task-persistence/taskMetadata.ts b/src/core/task-persistence/taskMetadata.ts index ec2e6cceeb..c52b0bdc33 100644 --- a/src/core/task-persistence/taskMetadata.ts +++ b/src/core/task-persistence/taskMetadata.ts @@ -81,7 +81,7 @@ export async function taskMetadata({ try { taskDirSize = await getFolderSize.loose(taskDir) taskSizeCache.set(taskDir, taskDirSize) - } catch (error) { + } catch { taskDirSize = 0 } } else { diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index b84a449c1d..fdcc740998 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -15,7 +15,6 @@ import delay from "delay" import pWaitFor from "p-wait-for" import { serializeError } from "serialize-error" import { Package } from "../../shared/package" -import { formatToolInvocation } from "../tools/helpers/toolResultFormatting" import { type TaskLike, @@ -76,13 +75,7 @@ import { t } from "../../i18n" import { getApiMetrics, hasTokenUsageChanged, hasToolUsageChanged } from "../../shared/getApiMetrics" import { ClineAskResponse } from "../../shared/WebviewMessage" import { defaultModeSlug, getModeBySlug } from "../../shared/modes" -import { - DiffStrategy, - type AutoApprovalContext, - type ToolUse, - type ToolParamName, - toolParamNames, -} from "../../shared/tools" +import { DiffStrategy, type AutoApprovalContext, type ToolUse } from "../../shared/tools" import { getModelMaxOutputTokens } from "../../shared/api" // services @@ -92,7 +85,6 @@ import { RepoPerTaskCheckpointService } from "../../services/checkpoints" // integrations import { DiffViewProvider } from "../../integrations/editor/DiffViewProvider" -import { findToolName } from "../../integrations/misc/export-markdown" import { RooTerminalProcess } from "../../integrations/terminal/types" import { TerminalRegistry } from "../../integrations/terminal/TerminalRegistry" import { OutputInterceptor } from "../../integrations/terminal/OutputInterceptor" @@ -672,7 +664,7 @@ export class Task extends EventEmitter implements TaskLike { task, images, historyItem, - experiments: experimentsConfig, + experiments: _experimentsConfig, startTask = true, rootTask, parentTask, @@ -2635,7 +2627,6 @@ export class Task extends EventEmitter implements TaskLike { cost, newContextTokens = 0, error, - errorDetails, condenseId, } = await summarizeConversation({ messages: this.apiConversationHistory, @@ -3268,26 +3259,6 @@ export class Task extends EventEmitter implements TaskLike { const newUserContent: Anthropic.Messages.ContentBlockParam[] = [...modifiedOldUserContent] - const agoText = ((): string => { - const timestamp = lastClineMessage?.ts ?? Date.now() - const now = Date.now() - const diff = now - timestamp - const minutes = Math.floor(diff / 60000) - const hours = Math.floor(minutes / 60) - const days = Math.floor(hours / 24) - - if (days > 0) { - return `${days} day${days > 1 ? "s" : ""} ago` - } - if (hours > 0) { - return `${hours} hour${hours > 1 ? "s" : ""} ago` - } - if (minutes > 0) { - return `${minutes} minute${minutes > 1 ? "s" : ""} ago` - } - return "just now" - })() - if (responseText) { newUserContent.push({ type: "text", @@ -4048,7 +4019,6 @@ export class Task extends EventEmitter implements TaskLike { // This is especially important for tools and background usage collection this.cachedStreamingModel = this.api.getModel() const streamModelInfo = this.cachedStreamingModel.info - const cachedModelId = this.cachedStreamingModel.id // Yields only if the first chunk is successful, otherwise will // allow the user to retry the request (most likely due to rate @@ -4392,7 +4362,7 @@ export class Task extends EventEmitter implements TaskLike { total?: number }, messageIndex: number = apiReqIndex, - status: "completed" | "cancelled" = "completed", + _status: "completed" | "cancelled" = "completed", ) => { if ( tokens.input > 0 || @@ -5111,7 +5081,7 @@ export class Task extends EventEmitter implements TaskLike { // If we reach here without continuing, return false (will always be false for now) return false - } catch (error) { + } catch { // This should never happen since the only thing that can throw an // error is the attemptApiRequest, which is wrapped in a try catch // that sends an ask where if noButtonClicked, will clear current @@ -5471,7 +5441,6 @@ export class Task extends EventEmitter implements TaskLike { const { autoApprovalEnabled, - requestDelaySeconds, autoCondenseContext = true, autoCondenseContextPercent = 100, profileThresholds = {}, diff --git a/src/core/task/__tests__/RateLimitClock.spec.ts b/src/core/task/__tests__/RateLimitClock.spec.ts index 3a70bc75ea..7dac64a5ca 100644 --- a/src/core/task/__tests__/RateLimitClock.spec.ts +++ b/src/core/task/__tests__/RateLimitClock.spec.ts @@ -1,4 +1,4 @@ -import { RateLimitClock, createRateLimitClock } from "../RateLimitClock" +import { createRateLimitClock } from "../RateLimitClock" describe("RateLimitClock", () => { it("returns undefined when no request has been recorded", () => { diff --git a/src/core/task/__tests__/Task.dispose.test.ts b/src/core/task/__tests__/Task.dispose.test.ts index 472218fce5..606568b923 100644 --- a/src/core/task/__tests__/Task.dispose.test.ts +++ b/src/core/task/__tests__/Task.dispose.test.ts @@ -271,7 +271,7 @@ describe("Task dispose method", () => { // Add some event listeners using type assertion to bypass strict typing for testing const listener1 = vi.fn(() => {}) const listener2 = vi.fn(() => {}) - const listener3 = vi.fn((taskId: string) => {}) + const listener3 = vi.fn((_taskId: string) => {}) task.on(RooCodeEventName.TaskStarted, listener1) task.on(RooCodeEventName.TaskAborted, listener2) diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index 8d9e734fd9..85325b39ff 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -3181,9 +3181,6 @@ describe("Cline", () => { }) it("should enforce rate limiting across parent and subtask", async () => { - // Add a spy to track getState calls - const getStateSpy = vi.spyOn(mockProvider, "getState") - // Shared clock so parent and child see each other's timestamps const sharedClock = createRateLimitClock() @@ -3647,7 +3644,7 @@ describe("Cline", () => { apiProvider: providerIdentifiers.openai, openAiModelId: modelId, } - const task = new Task({ + new Task({ provider: mockProvider, apiConfiguration: config, task: "test task", @@ -4587,7 +4584,7 @@ describe("Cline", () => { value: { type: "text", text: "first chunk" }, }) } - return new Promise>((resolve, reject) => { + return new Promise>((_resolve, reject) => { if (metadata?.abortSignal?.aborted) { return reject(new Error("Request cancelled by user")) } diff --git a/src/core/task/__tests__/Task.sticky-profile-race.spec.ts b/src/core/task/__tests__/Task.sticky-profile-race.spec.ts index d0b4e4cdde..c4bfc1b6ac 100644 --- a/src/core/task/__tests__/Task.sticky-profile-race.spec.ts +++ b/src/core/task/__tests__/Task.sticky-profile-race.spec.ts @@ -1,7 +1,5 @@ // npx vitest run core/task/__tests__/Task.sticky-profile-race.spec.ts -import * as vscode from "vscode" - import type { ProviderSettings } from "@roo-code/types" import { Task } from "../Task" import { ClineProvider } from "../../webview/ClineProvider" diff --git a/src/core/task/__tests__/Task.streaming-tool-calls.spec.ts b/src/core/task/__tests__/Task.streaming-tool-calls.spec.ts index ed1be28442..bff09e9cab 100644 --- a/src/core/task/__tests__/Task.streaming-tool-calls.spec.ts +++ b/src/core/task/__tests__/Task.streaming-tool-calls.spec.ts @@ -7,8 +7,7 @@ import { ClineProvider } from "../../webview/ClineProvider" import { WebviewFocusTracker } from "../../webview/WebviewFocusTracker" import { providerIdentifiers } from "@roo-code/types/provider-identifiers" import type { ProviderSettings } from "@roo-code/types" -import type { ToolParamName } from "../../../shared/tools" -import { ApiStreamChunk, type ApiStreamToolCallPartialChunk } from "../../../api/transform/stream" +import { ApiStreamChunk } from "../../../api/transform/stream" import { ContextProxy } from "../../config/ContextProxy" import { TelemetryService } from "@roo-code/telemetry" import { asyncStreamFrom } from "../../../test-utils/stream" @@ -19,8 +18,6 @@ vi.mock("delay", () => ({ default: vi.fn().mockResolvedValue(undefined), })) -import delay from "delay" - vi.mock("uuid", async (importOriginal) => { const actual = await importOriginal() return { @@ -108,7 +105,7 @@ vi.mock("vscode", () => { stat: vi.fn().mockResolvedValue({ type: 1 }), }, onDidSaveTextDocument: vi.fn(() => mockDisposable), - getConfiguration: vi.fn(() => ({ get: (key: string, defaultValue: T) => defaultValue })), + getConfiguration: vi.fn(() => ({ get: (_key: string, defaultValue: T) => defaultValue })), }, env: { uriScheme: "vscode", diff --git a/src/core/task/__tests__/duplicate-tool-use-ids.spec.ts b/src/core/task/__tests__/duplicate-tool-use-ids.spec.ts index 33e5afe236..764dd516a6 100644 --- a/src/core/task/__tests__/duplicate-tool-use-ids.spec.ts +++ b/src/core/task/__tests__/duplicate-tool-use-ids.spec.ts @@ -12,7 +12,6 @@ */ import { sanitizeToolUseId } from "../../../utils/tool-id" -import type { ToolUse, McpToolUse } from "../../../shared/tools" describe("Duplicate tool_use ID Prevention", () => { describe("Pre-flight deduplication logic", () => { @@ -143,7 +142,7 @@ describe("Duplicate tool_use ID Prevention", () => { const streamingToolCallIndices = new Map() const processedEvents: string[] = [] - const processToolCallStart = (id: string, name: string): boolean => { + const processToolCallStart = (id: string, _name: string): boolean => { // Guard against duplicate tool_call_start events if (streamingToolCallIndices.has(id)) { // Would log: console.warn(`Ignoring duplicate tool_call_start for ID: ${id}`) diff --git a/src/core/task/__tests__/flushPendingToolResultsToHistory.spec.ts b/src/core/task/__tests__/flushPendingToolResultsToHistory.spec.ts index d8f9fba5db..f0df02865a 100644 --- a/src/core/task/__tests__/flushPendingToolResultsToHistory.spec.ts +++ b/src/core/task/__tests__/flushPendingToolResultsToHistory.spec.ts @@ -96,7 +96,7 @@ vi.mock("vscode", () => { stat: vi.fn().mockResolvedValue({ type: 1 }), }, onDidSaveTextDocument: vi.fn(() => mockDisposable), - getConfiguration: vi.fn(() => ({ get: (key: string, defaultValue: any) => defaultValue })), + getConfiguration: vi.fn(() => ({ get: (_key: string, defaultValue: any) => defaultValue })), }, env: { uriScheme: "vscode", @@ -173,7 +173,7 @@ describe("flushPendingToolResultsToHistory", () => { mockExtensionContext = { globalState: { - get: vi.fn().mockImplementation((key: keyof GlobalState) => undefined), + get: vi.fn().mockImplementation((_key: keyof GlobalState) => undefined), update: vi.fn().mockImplementation((_key, _value) => Promise.resolve()), keys: vi.fn().mockReturnValue([]), }, diff --git a/src/core/task/__tests__/grace-retry-errors.spec.ts b/src/core/task/__tests__/grace-retry-errors.spec.ts index dc057957bc..633664c625 100644 --- a/src/core/task/__tests__/grace-retry-errors.spec.ts +++ b/src/core/task/__tests__/grace-retry-errors.spec.ts @@ -97,7 +97,7 @@ vi.mock("vscode", () => { stat: vi.fn().mockResolvedValue({ type: 1 }), }, onDidSaveTextDocument: vi.fn(() => mockDisposable), - getConfiguration: vi.fn(() => ({ get: (key: string, defaultValue: any) => defaultValue })), + getConfiguration: vi.fn(() => ({ get: (_key: string, defaultValue: any) => defaultValue })), }, env: { uriScheme: "vscode", diff --git a/src/core/task/__tests__/task-tool-history.spec.ts b/src/core/task/__tests__/task-tool-history.spec.ts index df74393156..7db5b89ef7 100644 --- a/src/core/task/__tests__/task-tool-history.spec.ts +++ b/src/core/task/__tests__/task-tool-history.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi } from "vitest" +import { describe, it, expect } from "vitest" import { Anthropic } from "@anthropic-ai/sdk" describe("Task Tool History Handling", () => { diff --git a/src/core/tools/ApplyPatchTool.ts b/src/core/tools/ApplyPatchTool.ts index 56b2bf8909..2713e08ffe 100644 --- a/src/core/tools/ApplyPatchTool.ts +++ b/src/core/tools/ApplyPatchTool.ts @@ -54,7 +54,7 @@ export class ApplyPatchTool extends BaseTool<"apply_patch"> { async execute(params: ApplyPatchParams, task: Task, callbacks: ToolCallbacks): Promise { const { patch } = params - const { askApproval, handleError, pushToolResult } = callbacks + const { handleError, pushToolResult } = callbacks try { // Validate required parameters diff --git a/src/core/tools/BaseTool.ts b/src/core/tools/BaseTool.ts index 83a733c7b0..84d835bc40 100644 --- a/src/core/tools/BaseTool.ts +++ b/src/core/tools/BaseTool.ts @@ -58,7 +58,7 @@ export abstract class BaseTool { * @param task - Task instance * @param block - Partial ToolUse block */ - async handlePartial(task: Task, block: ToolUse): Promise { + async handlePartial(_task: Task, _block: ToolUse): Promise { // Default: no-op for partial messages // Tools can override to show streaming UI updates } diff --git a/src/core/tools/CodebaseSearchTool.ts b/src/core/tools/CodebaseSearchTool.ts index 6084dd6b74..2d1228794b 100644 --- a/src/core/tools/CodebaseSearchTool.ts +++ b/src/core/tools/CodebaseSearchTool.ts @@ -1,5 +1,4 @@ import * as vscode from "vscode" -import path from "path" import { Task } from "../task/Task" import { CodeIndexManagerRegistry } from "../../services/code-index/code-index-manager-registry" diff --git a/src/core/tools/EditTool.ts b/src/core/tools/EditTool.ts index 2ae8bf4ed0..b121fcc096 100644 --- a/src/core/tools/EditTool.ts +++ b/src/core/tools/EditTool.ts @@ -92,7 +92,7 @@ export class EditTool extends BaseTool<"edit"> { fileContent = await fs.readFile(absolutePath, "utf8") // Normalize line endings to LF for consistent matching fileContent = fileContent.replace(/\r\n/g, "\n") - } catch (error) { + } catch { task.consecutiveMistakeCount++ task.recordToolError("edit") const errorMessage = `Failed to read file '${relPath}'. Please verify file permissions and try again.` diff --git a/src/core/tools/ExecuteCommandTool.ts b/src/core/tools/ExecuteCommandTool.ts index a6034e4f4d..16b3fd012f 100644 --- a/src/core/tools/ExecuteCommandTool.ts +++ b/src/core/tools/ExecuteCommandTool.ts @@ -390,7 +390,7 @@ export async function executeCommandInTerminal( try { await fs.access(workingDir) - } catch (error) { + } catch { return [false, `Working directory '${workingDir}' does not exist.`] } diff --git a/src/core/tools/GenerateImageTool.ts b/src/core/tools/GenerateImageTool.ts index 99a0a8f5b1..dca63a1ef4 100644 --- a/src/core/tools/GenerateImageTool.ts +++ b/src/core/tools/GenerateImageTool.ts @@ -149,10 +149,6 @@ export class GenerateImageTool extends BaseTool<"generate_image"> { selectedModel = modelInfo?.value || IMAGE_GENERATION_MODEL_IDS[0] } - // Use the provider selection - const modelProvider = imageProvider - const apiMethod = modelInfo?.apiMethod - // Validate API key for OpenRouter const openRouterApiKey = state?.openRouterImageApiKey @@ -257,7 +253,7 @@ export class GenerateImageTool extends BaseTool<"generate_image"> { } } - override async handlePartial(task: Task, block: ToolUse<"generate_image">): Promise { + override async handlePartial(_task: Task, _block: ToolUse<"generate_image">): Promise { return } } diff --git a/src/core/tools/NewTaskTool.ts b/src/core/tools/NewTaskTool.ts index cef12f01f6..2e70cefb13 100644 --- a/src/core/tools/NewTaskTool.ts +++ b/src/core/tools/NewTaskTool.ts @@ -5,7 +5,6 @@ import type { PendingTaskAction, TodoItem } from "@roo-code/types" import { Task } from "../task/Task" import { getModeBySlug } from "../../shared/modes" import { formatResponse } from "../prompts/responses" -import { t } from "../../i18n" import { parseMarkdownChecklist } from "./UpdateTodoListTool" import { Package } from "../../shared/package" import { BaseTool, ToolCallbacks } from "./BaseTool" @@ -73,7 +72,7 @@ export class NewTaskTool extends BaseTool<"new_task"> { if (todos) { try { todoItems = parseMarkdownChecklist(todos) - } catch (error) { + } catch { task.consecutiveMistakeCount++ task.recordToolError("new_task") task.didToolFailInCurrentTurn = true diff --git a/src/core/tools/SearchReplaceTool.ts b/src/core/tools/SearchReplaceTool.ts index e29b124010..a0f2dadfcc 100644 --- a/src/core/tools/SearchReplaceTool.ts +++ b/src/core/tools/SearchReplaceTool.ts @@ -97,7 +97,7 @@ export class SearchReplaceTool extends BaseTool<"search_replace"> { fileContent = await fs.readFile(absolutePath, "utf8") // Normalize line endings to LF for consistent matching fileContent = fileContent.replace(/\r\n/g, "\n") - } catch (error) { + } catch { task.consecutiveMistakeCount++ task.recordToolError("search_replace") const errorMessage = `Failed to read file '${relPath}'. Please verify file permissions and try again.` diff --git a/src/core/tools/__tests__/ReadCommandOutputTool.test.ts b/src/core/tools/__tests__/ReadCommandOutputTool.test.ts index 3db99d84b3..9b79472336 100644 --- a/src/core/tools/__tests__/ReadCommandOutputTool.test.ts +++ b/src/core/tools/__tests__/ReadCommandOutputTool.test.ts @@ -3,7 +3,6 @@ import * as path from "path" import { vi, describe, it, expect, beforeEach, afterEach } from "vitest" import { ReadCommandOutputTool } from "../ReadCommandOutputTool" -import { Task } from "../../task/Task" // Mock filesystem operations vi.mock("fs/promises", () => ({ @@ -190,10 +189,8 @@ describe("ReadCommandOutputTool", () => { // Mock first read for offset calculation (returns content before offset) // Mock second read for actual content - let readCallCount = 0 mockFileHandle.read.mockImplementation( - (buf: Buffer, bufOffset: number, length: number, position: number | null) => { - readCallCount++ + (buf: Buffer, _bufOffset: number, _length: number, position: number | null) => { if (position === 0) { // First read: prefix for line number calculation const prefixContent = content.slice(0, offset) @@ -284,7 +281,7 @@ describe("ReadCommandOutputTool", () => { // Mock streaming read - return entire content in one chunk (simulates small file) mockFileHandle.read.mockImplementation( - (buf: Buffer, bufOffset: number, length: number, position: number | null) => { + (buf: Buffer, _bufOffset: number, length: number, position: number | null) => { const pos = position ?? 0 if (pos >= fileSize) { return Promise.resolve({ bytesRead: 0 }) @@ -551,10 +548,8 @@ describe("ReadCommandOutputTool", () => { vi.mocked(fs.stat).mockResolvedValue({ size: fileSize } as any) - let readCallCount = 0 mockFileHandle.read.mockImplementation( - (buf: Buffer, bufOffset: number, length: number, position: number | null) => { - readCallCount++ + (buf: Buffer, _bufOffset: number, _length: number, position: number | null) => { if (position === 0) { // Read prefix for line counting const prefix = content.slice(0, offset) diff --git a/src/core/tools/__tests__/editFileTool.spec.ts b/src/core/tools/__tests__/editFileTool.spec.ts index 1ff8d52a8d..e7ac792f05 100644 --- a/src/core/tools/__tests__/editFileTool.spec.ts +++ b/src/core/tools/__tests__/editFileTool.spec.ts @@ -24,7 +24,7 @@ vi.mock("path", async () => { return args.join(separator) }), isAbsolute: vi.fn().mockReturnValue(false), - relative: vi.fn().mockImplementation((from, to) => { + relative: vi.fn().mockImplementation((_from, to) => { return to }), } diff --git a/src/core/tools/__tests__/executeCommand.spec.ts b/src/core/tools/__tests__/executeCommand.spec.ts index 7146fa930b..f62032492f 100644 --- a/src/core/tools/__tests__/executeCommand.spec.ts +++ b/src/core/tools/__tests__/executeCommand.spec.ts @@ -92,7 +92,7 @@ describe("executeCommand", () => { mockTerminal.getCurrentWorkingDirectory.mockReturnValue(currentCwd) // Mock the terminal process to complete successfully - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { // Simulate command completion setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) @@ -132,7 +132,7 @@ describe("executeCommand", () => { mockVSCodeTerminal.getCurrentWorkingDirectory = vitest.fn().mockReturnValue("/test/project/changed-dir") mockVSCodeTerminal.runCommand = vitest .fn() - .mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + .mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -164,7 +164,7 @@ describe("executeCommand", () => { mockExecaTerminal.getCurrentWorkingDirectory = vitest.fn().mockReturnValue("/test/project") mockExecaTerminal.runCommand = vitest .fn() - .mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + .mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -194,7 +194,7 @@ describe("executeCommand", () => { const customCwd = "/custom/absolute/path" mockTerminal.getCurrentWorkingDirectory.mockReturnValue(customCwd) - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -223,7 +223,7 @@ describe("executeCommand", () => { const resolvedCwd = path.resolve(mockTask.cwd, relativeCwd) mockTerminal.getCurrentWorkingDirectory.mockReturnValue(resolvedCwd) - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -273,7 +273,7 @@ describe("executeCommand", () => { describe("Terminal Provider Selection", () => { it("posts fallback status when cmd.exe requires the Execa provider", async () => { vitest.spyOn(Terminal, "isActiveShellCmdExe").mockReturnValue(true) - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -296,7 +296,7 @@ describe("executeCommand", () => { }) it("should use vscode provider when shell integration is enabled", async () => { - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -318,7 +318,7 @@ describe("executeCommand", () => { }) it("should use execa provider when shell integration is disabled", async () => { - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command output", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -371,7 +371,7 @@ describe("executeCommand", () => { it("should handle completed command with exit code 0", async () => { mockTerminal.getCurrentWorkingDirectory.mockReturnValue("/test/project") - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command completed successfully", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) @@ -396,7 +396,7 @@ describe("executeCommand", () => { it("should handle completed command with non-zero exit code", async () => { mockTerminal.getCurrentWorkingDirectory.mockReturnValue("/test/project") - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command failed", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 1 }, mockProcess) @@ -422,7 +422,7 @@ describe("executeCommand", () => { it("should handle command terminated by signal", async () => { mockTerminal.getCurrentWorkingDirectory.mockReturnValue("/test/project") - mockTerminal.runCommand.mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + mockTerminal.runCommand.mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Command interrupted", mockProcess) callbacks.onShellExecutionComplete( @@ -467,7 +467,7 @@ describe("executeCommand", () => { ...mockTerminal, terminal: { show: vitest.fn() }, getCurrentWorkingDirectory: vitest.fn().mockReturnValue(updatedCwd), - runCommand: vitest.fn().mockImplementation((command: string, callbacks: RooTerminalCallbacks) => { + runCommand: vitest.fn().mockImplementation((_command: string, callbacks: RooTerminalCallbacks) => { setTimeout(() => { void callbacks.onCompleted("Directory changed", mockProcess) callbacks.onShellExecutionComplete({ exitCode: 0 }, mockProcess) diff --git a/src/core/tools/__tests__/executeCommandTool.spec.ts b/src/core/tools/__tests__/executeCommandTool.spec.ts index 98640fe969..be10905fdb 100644 --- a/src/core/tools/__tests__/executeCommandTool.spec.ts +++ b/src/core/tools/__tests__/executeCommandTool.spec.ts @@ -131,7 +131,7 @@ describe("executeCommandTool", () => { // Setup vscode config mock const mockConfig = { - get: vitest.fn().mockImplementation((key: string, defaultValue: any) => { + get: vitest.fn().mockImplementation((_key: string, defaultValue: any) => { return defaultValue }), } diff --git a/src/core/tools/__tests__/readFileTool.spec.ts b/src/core/tools/__tests__/readFileTool.spec.ts index 5f9033eb7c..a457ff87bc 100644 --- a/src/core/tools/__tests__/readFileTool.spec.ts +++ b/src/core/tools/__tests__/readFileTool.spec.ts @@ -19,15 +19,10 @@ import type { Task } from "../../task/Task" import { isBinaryFile } from "isbinaryfile" -import { readFileTool, ReadFileTool } from "../ReadFileTool" +import { readFileTool } from "../ReadFileTool" import { formatResponse } from "../../prompts/responses" -import { - validateImageForProcessing, - processImageFile, - isSupportedImageFormat, - ImageMemoryTracker, -} from "../helpers/imageHelpers" -import { extractTextFromFile, addLineNumbers, getSupportedBinaryFormats } from "../../../integrations/misc/extract-text" +import { validateImageForProcessing, processImageFile, isSupportedImageFormat } from "../helpers/imageHelpers" +import { extractTextFromFile, getSupportedBinaryFormats } from "../../../integrations/misc/extract-text" import { readWithIndentation, readWithSlice } from "../../../integrations/misc/indentation-reader" // ─── Mocks ──────────────────────────────────────────────────────────────────── diff --git a/src/core/tools/__tests__/searchReplaceTool.spec.ts b/src/core/tools/__tests__/searchReplaceTool.spec.ts index 5cf10790d4..2be4f3efe6 100644 --- a/src/core/tools/__tests__/searchReplaceTool.spec.ts +++ b/src/core/tools/__tests__/searchReplaceTool.spec.ts @@ -24,7 +24,7 @@ vi.mock("path", async () => { return args.join(separator) }), isAbsolute: vi.fn().mockReturnValue(false), - relative: vi.fn().mockImplementation((from, to) => { + relative: vi.fn().mockImplementation((_from, to) => { return to }), } diff --git a/src/core/tools/__tests__/updateTodoListTool.spec.ts b/src/core/tools/__tests__/updateTodoListTool.spec.ts index 6700764418..0e6e0302cc 100644 --- a/src/core/tools/__tests__/updateTodoListTool.spec.ts +++ b/src/core/tools/__tests__/updateTodoListTool.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi } from "vitest" +import { describe, it, expect, vi } from "vitest" import { parseMarkdownChecklist, setPendingTodoList, updateTodoListTool } from "../UpdateTodoListTool" import { TodoItem } from "@roo-code/types" import type { Task } from "../../task/Task" diff --git a/src/core/tools/__tests__/useMcpToolTool.spec.ts b/src/core/tools/__tests__/useMcpToolTool.spec.ts index 6af93be0f4..96ee2f2dbc 100644 --- a/src/core/tools/__tests__/useMcpToolTool.spec.ts +++ b/src/core/tools/__tests__/useMcpToolTool.spec.ts @@ -46,14 +46,12 @@ describe("useMcpToolTool", () => { let mockAskApproval: ReturnType> let mockHandleError: ReturnType> let mockPushToolResult: ReturnType> - let mockRemoveClosingTag: ReturnType let mockProviderRef: any beforeEach(() => { mockAskApproval = vi.fn() mockHandleError = vi.fn() mockPushToolResult = vi.fn() - mockRemoveClosingTag = vi.fn((tag: string, value?: string) => value || "") mockProviderRef = { deref: vi.fn().mockReturnValue({ diff --git a/src/core/tools/__tests__/writeToFileTool.spec.ts b/src/core/tools/__tests__/writeToFileTool.spec.ts index 52a7e3c052..81d5056d10 100644 --- a/src/core/tools/__tests__/writeToFileTool.spec.ts +++ b/src/core/tools/__tests__/writeToFileTool.spec.ts @@ -161,7 +161,7 @@ describe("writeToFileTool", () => { pushToolWriteResult: vi.fn().mockImplementation(async function ( this: any, task: any, - cwd: string, + _cwd: string, isNewFile: boolean, ) { // Simulate the behavior of pushToolWriteResult diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index b2f0ea8386..0701f0ea12 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -513,13 +513,6 @@ export class ClineProvider return super.off(event, listener as any) } - /** - * Initialize cloud profile synchronization - */ - private async initializeCloudProfileSync() { - this.log("Cloud profile synchronization is disabled in compatibility mode") - } - /** * Handle cloud settings updates */ @@ -527,13 +520,6 @@ export class ClineProvider this.log("Ignoring cloud settings update because cloud profile synchronization is disabled") } - /** - * Synchronize cloud profiles with local profiles. - */ - private async syncCloudProfiles() { - this.log("Skipping cloud profile synchronization because it is disabled") - } - /** * Initialize cloud profile synchronization when CloudService is ready * This method is called externally after CloudService has been initialized @@ -1335,15 +1321,8 @@ export class ClineProvider ) } - const { - apiConfiguration, - enableCheckpoints, - checkpointTimeout, - experiments, - cloudUserInfo, - taskSyncEnabled, - diffFuzzyThreshold, - } = await this.getState() + const { apiConfiguration, enableCheckpoints, checkpointTimeout, experiments, diffFuzzyThreshold } = + await this.getState() const task = new Task({ provider: this, apiConfiguration, @@ -1538,7 +1517,7 @@ export class ClineProvider // Check if local dev server is running. try { await axios.get(`http://${localServerUrl}`) - } catch (error) { + } catch { vscode.window.showErrorMessage(t("common:errors.hmr_not_running")) return this.getHtmlContent(webview) } @@ -2073,7 +2052,7 @@ export class ClineProvider try { await fs.mkdir(mcpServersDir, { recursive: true }) - } catch (error) { + } catch { // Fallback to a relative path if directory creation fails return path.join(os.homedir(), ".roo-code", "mcp") } @@ -2315,7 +2294,7 @@ export class ClineProvider useWorkspace: false, fallbackDir: path.join(os.homedir(), "Downloads"), }) - const saveUri = await downloadTask(historyItem.ts, apiConversationHistory, defaultUri) + const saveUri = await downloadTask(apiConversationHistory, defaultUri) if (saveUri) { await saveLastExportPath(this.contextProxy, "lastTaskExportPath", saveUri) @@ -2336,8 +2315,7 @@ export class ClineProvider // If the task has subtasks (childIds), they will also be deleted recursively async deleteTaskWithId(id: string, cascadeSubtasks: boolean = true) { try { - // get the task directory full path and history item - const { taskDirPath, historyItem } = await this.getTaskWithId(id) + await this.getTaskWithId(id) // Collect all task IDs to delete (parent + all subtasks) const allIdsToDelete: string[] = [id] @@ -2353,7 +2331,7 @@ export class ClineProvider await collectChildIds(childId) } } - } catch (error) { + } catch { // Child task may already be deleted or not found, continue console.log(`[deleteTaskWithId] child task ${taskId} not found, skipping`) } @@ -2702,7 +2680,7 @@ export class ClineProvider this.cloudOrganizationsCacheTimestamp = now } } - } catch (error) { + } catch { // Ignore this error. } @@ -3633,7 +3611,7 @@ export class ClineProvider try { const customModes = await this.customModesManager.getCustomModes() return [...DEFAULT_MODES, ...customModes].map(({ slug, name }) => ({ slug, name })) - } catch (error) { + } catch { return DEFAULT_MODES.map(({ slug, name }) => ({ slug, name })) } } diff --git a/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts b/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts index b60ec498fb..22aa4d7e97 100644 --- a/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.sticky-mode.spec.ts @@ -7,7 +7,7 @@ import { TelemetryService } from "@roo-code/telemetry" import { ClineProvider } from "../ClineProvider" import { ContextProxy } from "../../config/ContextProxy" import { Task } from "../../task/Task" -import type { HistoryItem, ProviderName } from "@roo-code/types" +import type { HistoryItem } from "@roo-code/types" import { providerIdentifiers } from "@roo-code/types/provider-identifiers" vi.mock("vscode", () => ({ @@ -1163,7 +1163,7 @@ describe("ClineProvider - Sticky Mode", () => { ]) // Mock updateTaskHistory - const updateTaskHistorySpy = vi.spyOn(provider, "updateTaskHistory").mockImplementation(() => { + vi.spyOn(provider, "updateTaskHistory").mockImplementation(() => { return Promise.resolve([]) }) diff --git a/src/core/webview/__tests__/ClineProvider.sticky-profile.spec.ts b/src/core/webview/__tests__/ClineProvider.sticky-profile.spec.ts index 01864c0234..ccf243f1e1 100644 --- a/src/core/webview/__tests__/ClineProvider.sticky-profile.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.sticky-profile.spec.ts @@ -816,20 +816,6 @@ describe("ClineProvider - Sticky Provider Profile", () => { updateApiConfiguration: vi.fn(), } - // Create task 2 with profile B - const task2 = { - taskId: "task-2", - _taskApiConfigName: "profile-b", - setTaskApiConfigName: vi.fn().mockImplementation(function (this: any, name: string) { - this._taskApiConfigName = name - }), - emit: vi.fn(), - saveClineMessages: vi.fn(), - clineMessages: [], - apiConversationHistory: [], - updateApiConfiguration: vi.fn(), - } - // Add task 1 to stack await provider.addClineToStack(task1 as any) diff --git a/src/core/webview/__tests__/ClineProvider.taskHistory.spec.ts b/src/core/webview/__tests__/ClineProvider.taskHistory.spec.ts index af2f506e5c..bec8a31040 100644 --- a/src/core/webview/__tests__/ClineProvider.taskHistory.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.taskHistory.spec.ts @@ -3,7 +3,7 @@ import { WebviewFocusTracker } from "../WebviewFocusTracker" import * as vscode from "vscode" import { makeCompositeDisposable } from "../../../test-utils/vscode" -import type { HistoryItem, ExtensionMessage } from "@roo-code/types" +import type { HistoryItem } from "@roo-code/types" import { providerIdentifiers, RooCodeEventName } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" diff --git a/src/core/webview/__tests__/checkpointRestoreHandler.spec.ts b/src/core/webview/__tests__/checkpointRestoreHandler.spec.ts index 6640c2ef07..21e9405125 100644 --- a/src/core/webview/__tests__/checkpointRestoreHandler.spec.ts +++ b/src/core/webview/__tests__/checkpointRestoreHandler.spec.ts @@ -60,7 +60,7 @@ describe("checkpointRestoreHandler", () => { } // Mock pWaitFor to resolve immediately - ;(pWaitFor as any).mockImplementation(async (condition: () => boolean) => { + ;(pWaitFor as any).mockImplementation(async (_condition: () => boolean) => { // Simulate the condition being met return Promise.resolve() }) diff --git a/src/core/webview/__tests__/webviewMessageHandler.delete.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.delete.spec.ts index ef2bee3f6d..dcc8465c39 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.delete.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.delete.spec.ts @@ -1,7 +1,6 @@ import { describe, it, expect, beforeEach, vi } from "vitest" import { webviewMessageHandler } from "../webviewMessageHandler" import * as vscode from "vscode" -import { ClineProvider } from "../ClineProvider" import { MessageManager } from "../../message-manager" // Mock the saveTaskMessages function diff --git a/src/core/webview/__tests__/webviewMessageHandler.edit.spec.ts b/src/core/webview/__tests__/webviewMessageHandler.edit.spec.ts index 523f03e1c2..61f24fae09 100644 --- a/src/core/webview/__tests__/webviewMessageHandler.edit.spec.ts +++ b/src/core/webview/__tests__/webviewMessageHandler.edit.spec.ts @@ -1,4 +1,3 @@ -import type { Mock } from "vitest" import { describe, it, expect, vi, beforeEach } from "vitest" // Mock dependencies first diff --git a/src/core/webview/checkpointRestoreHandler.ts b/src/core/webview/checkpointRestoreHandler.ts index 5a517cdcc0..c7e0fb9708 100644 --- a/src/core/webview/checkpointRestoreHandler.ts +++ b/src/core/webview/checkpointRestoreHandler.ts @@ -97,7 +97,7 @@ export async function waitForClineInitialization(provider: ClineProvider, timeou timeout: timeoutMs, }) return true - } catch (error) { + } catch { vscode.window.showErrorMessage(t("common:errors.checkpoint_timeout")) return false } diff --git a/src/core/webview/messageEnhancer.ts b/src/core/webview/messageEnhancer.ts index 89df7b5b59..90c1f3b37d 100644 --- a/src/core/webview/messageEnhancer.ts +++ b/src/core/webview/messageEnhancer.ts @@ -1,9 +1,8 @@ -import { ProviderSettings, ClineMessage, GlobalState, TelemetryEventName } from "@roo-code/types" +import { ProviderSettings, ClineMessage, TelemetryEventName } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" import { supportPrompt } from "../../shared/support-prompt" import { singleCompletionHandler } from "../../utils/single-completion-handler" import { ProviderSettingsManager } from "../config/ProviderSettingsManager" -import { ClineProvider } from "./ClineProvider" export interface MessageEnhancerOptions { text: string diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index a5e11931c8..13af5fc731 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -11,7 +11,6 @@ import { type GlobalState, type ClineMessage, type TelemetrySetting, - type UserSettingsConfig, type ModelRecord, type ProviderSettings, type Command as SlashCommand, @@ -1694,14 +1693,14 @@ export const webviewMessageHandler = async ( try { await pWaitFor(() => provider.getCurrentTask()?.isInitialized === true, { timeout: 3_000 }) - } catch (error) { + } catch { vscode.window.showErrorMessage(t("common:errors.checkpoint_timeout")) return } try { await provider.getCurrentTask()?.checkpointRestore(result.data) - } catch (error) { + } catch { vscode.window.showErrorMessage(t("common:errors.checkpoint_failed")) } } @@ -1732,7 +1731,7 @@ export const webviewMessageHandler = async ( try { await pWaitFor(() => provider.getCurrentTask()?.isInitialized === true, { timeout: 3_000 }) - } catch (error) { + } catch { vscode.window.showErrorMessage(t("common:errors.checkpoint_timeout")) return } @@ -2518,7 +2517,7 @@ export const webviewMessageHandler = async ( } } } - } catch (error) { + } catch { // Error already shown to user by updateCustomMode // Just prevent unhandled rejection and skip state updates } diff --git a/src/core/webview/worktree/handlers.ts b/src/core/webview/worktree/handlers.ts index 67c88b910e..6c09006c18 100644 --- a/src/core/webview/worktree/handlers.ts +++ b/src/core/webview/worktree/handlers.ts @@ -221,7 +221,7 @@ export async function handleGetAvailableBranches(provider: ClineProvider): Promi return worktreeService.getAvailableBranches(cwd, true) } -export async function handleGetWorktreeDefaults(provider: ClineProvider): Promise { +export async function handleGetWorktreeDefaults(_provider: ClineProvider): Promise { const suffix = generateRandomSuffix() const workspaceFolders = vscode.workspace.workspaceFolders const projectName = workspaceFolders?.[0]?.name || "project" diff --git a/src/eslint-suppressions.json b/src/eslint-suppressions.json index 10e1c94931..f1b2590f7f 100644 --- a/src/eslint-suppressions.json +++ b/src/eslint-suppressions.json @@ -91,7 +91,7 @@ }, "api/providers/__tests__/anthropic.spec.ts": { "@typescript-eslint/no-explicit-any": { - "count": 9 + "count": 7 } }, "api/providers/__tests__/base-openai-compatible-provider-timeout.spec.ts": { @@ -296,7 +296,7 @@ }, "api/providers/bedrock.ts": { "@typescript-eslint/no-explicit-any": { - "count": 34 + "count": 32 } }, "api/providers/deepseek.ts": { @@ -396,7 +396,7 @@ }, "api/providers/openai-native.ts": { "@typescript-eslint/no-explicit-any": { - "count": 28 + "count": 27 } }, "api/providers/openai.ts": { @@ -691,7 +691,7 @@ }, "core/mentions/__tests__/processUserContentMentions.spec.ts": { "@typescript-eslint/no-explicit-any": { - "count": 2 + "count": 1 } }, "core/mentions/index.ts": { @@ -1036,7 +1036,7 @@ }, "core/webview/__tests__/ClineProvider.sticky-profile.spec.ts": { "@typescript-eslint/no-explicit-any": { - "count": 16 + "count": 15 } }, "core/webview/__tests__/ClineProvider.taskHistory.spec.ts": { @@ -1231,7 +1231,7 @@ }, "integrations/terminal/__tests__/TerminalProfile.spec.ts": { "@typescript-eslint/no-explicit-any": { - "count": 35 + "count": 34 } }, "integrations/terminal/__tests__/TerminalRegistry.spec.ts": { @@ -1496,7 +1496,7 @@ }, "services/mcp/McpHub.ts": { "@typescript-eslint/no-explicit-any": { - "count": 10 + "count": 8 } }, "services/mcp/McpOAuthClientProvider.ts": { @@ -1641,7 +1641,7 @@ }, "utils/__tests__/autoImportSettings.spec.ts": { "@typescript-eslint/no-explicit-any": { - "count": 16 + "count": 15 } }, "utils/__tests__/enhance-prompt.spec.ts": { @@ -1704,11 +1704,6 @@ "count": 4 } }, - "utils/tts.ts": { - "@typescript-eslint/no-explicit-any": { - "count": 1 - } - }, "vitest.setup.ts": { "@typescript-eslint/no-explicit-any": { "count": 1 diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index 5cbaf1b795..41441251ca 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -15,6 +15,7 @@ export default [ "no-useless-escape": "off", "no-empty": "off", + "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "off", // Enforced; existing violations are suppressed in eslint-suppressions.json and cleaned up incrementally. "@typescript-eslint/no-explicit-any": "error", diff --git a/src/extension/__tests__/api-send-message.spec.ts b/src/extension/__tests__/api-send-message.spec.ts index 5158a218e7..d78872f8d4 100644 --- a/src/extension/__tests__/api-send-message.spec.ts +++ b/src/extension/__tests__/api-send-message.spec.ts @@ -3,7 +3,6 @@ import * as vscode from "vscode" import { API } from "../api" import { ClineProvider } from "../../core/webview/ClineProvider" -import { TaskCommandName } from "@roo-code/types" import { makeClineProviderFactory } from "../../test-utils/provider" vi.mock("vscode") diff --git a/src/extension/api.ts b/src/extension/api.ts index 8f619d70c7..78a9496a3f 100644 --- a/src/extension/api.ts +++ b/src/extension/api.ts @@ -31,7 +31,6 @@ import type { ClineProviderFactory } from "../core/webview/ClineProviderFactory" import { Terminal } from "../integrations/terminal/Terminal" import { TerminalRegistry } from "../integrations/terminal/TerminalRegistry" import { getCommands } from "../services/command/commands" -import { getModels } from "../api/providers/fetchers/modelCache" export class API extends EventEmitter implements RooCodeAPI { private readonly outputChannel: vscode.OutputChannel @@ -124,7 +123,7 @@ export class API extends EventEmitter implements RooCodeAPI { argumentHint: cmd.argumentHint, })), ]) - } catch (error) { + } catch { sendResponse(RooCodeEventName.CommandsResponse, [[]]) } @@ -133,7 +132,7 @@ export class API extends EventEmitter implements RooCodeAPI { try { const modes = await this.sidebarProvider.getModes() sendResponse(RooCodeEventName.ModesResponse, [modes]) - } catch (error) { + } catch { sendResponse(RooCodeEventName.ModesResponse, [[]]) } @@ -141,7 +140,7 @@ export class API extends EventEmitter implements RooCodeAPI { case TaskCommandName.GetModels: try { sendResponse(RooCodeEventName.ModelsResponse, [{}]) - } catch (error) { + } catch { sendResponse(RooCodeEventName.ModelsResponse, [{}]) } @@ -532,7 +531,7 @@ export class API extends EventEmitter implements RooCodeAPI { this.outputChannel.appendLine( JSON.stringify( arg, - (key, value) => { + (_key, value) => { if (typeof value === "bigint") return `BigInt(${value})` if (typeof value === "function") return `Function: ${value.name || "anonymous"}` if (typeof value === "symbol") return value.toString() @@ -541,7 +540,7 @@ export class API extends EventEmitter implements RooCodeAPI { 2, ), ) - } catch (error) { + } catch { this.outputChannel.appendLine(`[Non-serializable object: ${Object.prototype.toString.call(arg)}]`) } } diff --git a/src/integrations/editor/__tests__/DiffViewProvider.spec.ts b/src/integrations/editor/__tests__/DiffViewProvider.spec.ts index 00b3dcaf7a..a740ebed5c 100644 --- a/src/integrations/editor/__tests__/DiffViewProvider.spec.ts +++ b/src/integrations/editor/__tests__/DiffViewProvider.spec.ts @@ -1,6 +1,5 @@ import { DiffViewProvider, DIFF_VIEW_URI_SCHEME, DIFF_VIEW_LABEL_CHANGES } from "../DiffViewProvider" import * as vscode from "vscode" -import * as path from "path" import delay from "delay" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" @@ -118,7 +117,7 @@ vi.mock("vscode", () => ({ TabInputTextDiff: class TabInputTextDiff {}, Uri: { file: vi.fn((path) => ({ fsPath: path })), - parse: vi.fn((uri) => ({ with: vi.fn(() => ({})) })), + parse: vi.fn((_uri) => ({ with: vi.fn(() => ({})) })), }, })) @@ -243,7 +242,7 @@ describe("DiffViewProvider", () => { const callOrder: string[] = [] // Mock showTextDocument to track when it's called - vi.mocked(vscode.window.showTextDocument).mockImplementation(async (uri, options) => { + vi.mocked(vscode.window.showTextDocument).mockImplementation(async (_uri, options) => { callOrder.push("showTextDocument") expect(options).toEqual({ preview: false, viewColumn: vscode.ViewColumn.Active, preserveFocus: true }) return mockEditor as any @@ -938,7 +937,7 @@ describe("DiffViewProvider", () => { // Mock closeAllDiffViews ;(diffViewProvider as any).closeAllDiffViews = vi.fn().mockResolvedValue(undefined) - const result = await diffViewProvider.saveChanges(true, 5000) + await diffViewProvider.saveChanges(true, 5000) // Verify custom delay was used expect(mockDelay).toHaveBeenCalledWith(5000) diff --git a/src/integrations/misc/__tests__/indentation-reader.spec.ts b/src/integrations/misc/__tests__/indentation-reader.spec.ts index d46cb54277..b6c28365aa 100644 --- a/src/integrations/misc/__tests__/indentation-reader.spec.ts +++ b/src/integrations/misc/__tests__/indentation-reader.spec.ts @@ -6,7 +6,6 @@ import { readWithSlice, computeEffectiveIndents, type LineRecord, - type IndentationReadResult, } from "../indentation-reader" // ─── Test Fixtures ──────────────────────────────────────────────────────────── diff --git a/src/integrations/misc/__tests__/open-file.spec.ts b/src/integrations/misc/__tests__/open-file.spec.ts index 1adba1bc42..1cdd91d589 100644 --- a/src/integrations/misc/__tests__/open-file.spec.ts +++ b/src/integrations/misc/__tests__/open-file.spec.ts @@ -58,7 +58,7 @@ vi.mock("../../utils/path", () => { // Mock i18n vi.mock("../../i18n", () => ({ - t: vi.fn((key: string, params?: any) => { + t: vi.fn((key: string, _params?: any) => { // Return the key without namespace prefix to match actual behavior if (key.startsWith("common:")) { return key.replace("common:", "") diff --git a/src/integrations/misc/export-markdown.ts b/src/integrations/misc/export-markdown.ts index 0636a9e7b8..a400834c7b 100644 --- a/src/integrations/misc/export-markdown.ts +++ b/src/integrations/misc/export-markdown.ts @@ -1,6 +1,4 @@ import { Anthropic } from "@anthropic-ai/sdk" -import os from "os" -import * as path from "path" import * as vscode from "vscode" // Extended content block types to support new Anthropic API features @@ -34,13 +32,9 @@ export function getTaskFileName(dateTs: number): string { } export async function downloadTask( - dateTs: number, conversationHistory: Anthropic.MessageParam[], defaultUri: vscode.Uri, ): Promise { - // File name - const fileName = getTaskFileName(dateTs) - // Generate markdown const markdownContent = conversationHistory .map((message) => { diff --git a/src/integrations/misc/extract-text-from-xlsx.ts b/src/integrations/misc/extract-text-from-xlsx.ts index 9ff3078a0e..06d8bcee20 100644 --- a/src/integrations/misc/extract-text-from-xlsx.ts +++ b/src/integrations/misc/extract-text-from-xlsx.ts @@ -58,7 +58,7 @@ export async function extractTextFromXLSX(source: Buffer): Promise { export function formatWorkbook(workbook: ExcelJS.Workbook): string { let excelText = "" - workbook.eachSheet((worksheet, sheetId) => { + workbook.eachSheet((worksheet, _sheetId) => { if (worksheet.state === "hidden" || worksheet.state === "veryHidden") { return } @@ -74,7 +74,7 @@ export function formatWorkbook(workbook: ExcelJS.Workbook): string { const rowTexts: string[] = [] let hasContent = false - row.eachCell({ includeEmpty: true }, (cell, colNumber) => { + row.eachCell({ includeEmpty: true }, (cell, _colNumber) => { const cellText = formatCellValue(cell) if (cellText.trim()) { hasContent = true diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts index c757733b46..aa645dda67 100644 --- a/src/integrations/misc/extract-text.ts +++ b/src/integrations/misc/extract-text.ts @@ -79,7 +79,7 @@ export async function extractTextFromFileWithMetadata( ): Promise { try { await fs.access(filePath) - } catch (error) { + } catch { throw new Error(`File not found: ${filePath}`) } diff --git a/src/integrations/misc/indentation-reader.ts b/src/integrations/misc/indentation-reader.ts index ca3ba1b569..47ff4593bf 100644 --- a/src/integrations/misc/indentation-reader.ts +++ b/src/integrations/misc/indentation-reader.ts @@ -79,26 +79,6 @@ const BLOCK_START_PATTERNS = [ /\bdo\s*$/, // Ruby, Lua ] -/** Patterns for file header lines (imports, comments, etc.) */ -const HEADER_PATTERNS = [ - /^import\s/, // ES6 imports - /^from\s.*import/, // Python imports - /^const\s.*=\s*require/, // CommonJS requires - /^#!/, // Shebang - /^\/\*/, // Block comment start - /^\*/, // Block comment continuation - /^\s*\*\//, // Block comment end - /^\/\//, // Line comment - /^#(?!include)/, // Python/shell comment (not C #include) - /^"""/, // Python docstring - /^'''/, // Python docstring - /^use\s/, // Rust use - /^package\s/, // Go/Java package - /^require\s/, // Lua require - /^@/, // Decorators (Python, TypeScript) - /^"use\s/, // "use strict", "use client" -] - /** Comment prefixes for header detection (Codex standard) */ const COMMENT_PREFIXES = ["#", "//", "--", "/*", "*", "'''", '"""'] @@ -178,52 +158,6 @@ function trimEmptyLines(lines: LineRecord[]): void { lines.pop() } } - -/** - * Find the file header (imports, top-level comments, etc.). - * Returns the end index of the header section. - */ -function findHeaderEnd(lines: LineRecord[]): number { - let lastHeaderIdx = -1 - let inBlockComment = false - - for (let i = 0; i < lines.length; i++) { - const line = lines[i] - const trimmed = line.content.trim() - - // Track block comments - if (trimmed.startsWith("/*")) inBlockComment = true - if (trimmed.endsWith("*/")) { - inBlockComment = false - lastHeaderIdx = i - continue - } - if (inBlockComment) { - lastHeaderIdx = i - continue - } - - // Check if this is a header line - if (line.isBlank) { - // Blank lines are part of header if we haven't seen content yet - if (lastHeaderIdx === i - 1) { - lastHeaderIdx = i - } - continue - } - - const isHeader = HEADER_PATTERNS.some((pattern) => pattern.test(trimmed)) - if (isHeader) { - lastHeaderIdx = i - } else if (line.indentLevel === 0) { - // Hit first non-header top-level content - break - } - } - - return lastHeaderIdx -} - /** * Format lines with line numbers, applying truncation to long lines. */ diff --git a/src/integrations/misc/line-counter.ts b/src/integrations/misc/line-counter.ts index d066d565e8..8a54db0263 100644 --- a/src/integrations/misc/line-counter.ts +++ b/src/integrations/misc/line-counter.ts @@ -13,7 +13,7 @@ export async function countFileLines(filePath: string): Promise { // Check if file exists try { await fs.promises.access(filePath, fs.constants.F_OK) - } catch (error) { + } catch { throw new Error(`File not found: ${filePath}`) } @@ -77,7 +77,7 @@ export async function countFileLinesAndTokens( // Check if file exists try { await fs.promises.access(filePath, fs.constants.F_OK) - } catch (error) { + } catch { throw new Error(`File not found: ${filePath}`) } @@ -105,7 +105,7 @@ export async function countFileLinesAndTokens( const contentBlocks: Anthropic.Messages.ContentBlockParam[] = [{ type: "text", text: bufferText }] const chunkTokens = await countTokens(contentBlocks) tokenEstimate += chunkTokens - } catch (error) { + } catch { // On tokenizer error, use conservative estimate: 2 char ≈ 1 token tokenEstimate += Math.ceil(bufferText.length / 2) } diff --git a/src/integrations/misc/open-file.ts b/src/integrations/misc/open-file.ts index a9ab44f7e5..af5284aa56 100644 --- a/src/integrations/misc/open-file.ts +++ b/src/integrations/misc/open-file.ts @@ -58,7 +58,7 @@ export async function openFile(filePath: string, options: OpenFileOptions = {}) fileStat = await vscode.workspace.fs.stat(tempUri) successfulUri = tempUri // Path found break // Exit loop once a path is successfully stated - } catch (e) { + } catch { // Stat failed for this path, continue to the next one } } diff --git a/src/integrations/terminal/ExecaTerminalProcess.ts b/src/integrations/terminal/ExecaTerminalProcess.ts index 6e969ba8f3..e94edce18c 100644 --- a/src/integrations/terminal/ExecaTerminalProcess.ts +++ b/src/integrations/terminal/ExecaTerminalProcess.ts @@ -113,7 +113,7 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { timeoutId = setTimeout(() => { try { this.subprocess?.kill("SIGKILL") - } catch (e) {} + } catch {} resolve() }, 5_000) diff --git a/src/integrations/terminal/OutputInterceptor.ts b/src/integrations/terminal/OutputInterceptor.ts index d1725c6426..8a876aefe2 100644 --- a/src/integrations/terminal/OutputInterceptor.ts +++ b/src/integrations/terminal/OutputInterceptor.ts @@ -89,7 +89,7 @@ export class OutputInterceptor { * * @param options - Configuration options for the interceptor */ - constructor(private readonly options: OutputInterceptorOptions) { + constructor(options: OutputInterceptorOptions) { this.previewBytes = TERMINAL_PREVIEW_BYTES[options.previewSize] this.headBudget = Math.floor(this.previewBytes / 2) this.tailBudget = this.previewBytes - this.headBudget diff --git a/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts b/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts index 03747a4e52..a9dfe26cda 100644 --- a/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts +++ b/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts @@ -4,8 +4,8 @@ const mockPid = 12345 vitest.mock("execa", () => { const mockKill = vitest.fn() - const execa = vitest.fn(function (options: any) { - return (_template: TemplateStringsArray, ...args: any[]) => ({ + const execa = vitest.fn(function (_options: any) { + return (_template: TemplateStringsArray, ..._args: any[]) => ({ pid: mockPid, iterable: (_opts: any) => (async function* () { diff --git a/src/integrations/terminal/__tests__/OutputInterceptor.test.ts b/src/integrations/terminal/__tests__/OutputInterceptor.test.ts index ace293e811..2d32f12704 100644 --- a/src/integrations/terminal/__tests__/OutputInterceptor.test.ts +++ b/src/integrations/terminal/__tests__/OutputInterceptor.test.ts @@ -4,7 +4,6 @@ import { vi, describe, it, expect, beforeEach, afterEach } from "vitest" import { clearAllMocks, restoreGlobals } from "../../../test-utils/reset" import { OutputInterceptor } from "../OutputInterceptor" -import { TerminalOutputPreviewSize } from "@roo-code/types" // Mock filesystem operations vi.mock("fs", () => ({ diff --git a/src/integrations/terminal/__tests__/TerminalProcess.test.ts b/src/integrations/terminal/__tests__/TerminalProcess.test.ts index cf2e8dbb80..14b6ff14e2 100644 --- a/src/integrations/terminal/__tests__/TerminalProcess.test.ts +++ b/src/integrations/terminal/__tests__/TerminalProcess.test.ts @@ -1,4 +1,3 @@ -import * as vscode from "vscode" import { TerminalProcess } from "../TerminalProcess" import { Terminal } from "../Terminal" diff --git a/src/integrations/terminal/__tests__/TerminalProfile.spec.ts b/src/integrations/terminal/__tests__/TerminalProfile.spec.ts index 2510b5b89d..3d3993af86 100644 --- a/src/integrations/terminal/__tests__/TerminalProfile.spec.ts +++ b/src/integrations/terminal/__tests__/TerminalProfile.spec.ts @@ -22,7 +22,6 @@ const mockedExistsSync = existsSync as unknown as ReturnType describe("Terminal VS Code terminal profile (#277)", () => { // VS Code's getConfiguration/createTerminal are overloaded, so the precise // spy MockInstance type isn't worth fighting in a test — `any` keeps it simple. - let getConfigurationSpy: any let createTerminalSpy: any const mockTerminal = () => @@ -44,7 +43,7 @@ describe("Terminal VS Code terminal profile (#277)", () => { profilesByPlatform: Record, workspaceProfilesByPlatform: Record = {}, ) => { - getConfigurationSpy = vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { if (section === "terminal.integrated.profiles") { return { inspect: (platformKey: string) => ({ @@ -99,21 +98,19 @@ describe("Terminal VS Code terminal profile (#277)", () => { describe("getConfiguredProfiles / getAvailableProfileNames", () => { it("merges default and global profiles while ignoring workspace profiles", () => { - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: () => ({ - defaultValue: { bash: { path: "/bin/bash" } }, - globalValue: { zsh: { path: "/bin/zsh" } }, - workspaceValue: { malicious: { path: "/workspace/malicious-shell" } }, - }), - } as any - } + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: () => ({ + defaultValue: { bash: { path: "/bin/bash" } }, + globalValue: { zsh: { path: "/bin/zsh" } }, + workspaceValue: { malicious: { path: "/workspace/malicious-shell" } }, + }), + } as any + } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.getConfiguredProfiles("linux")).toEqual({ bash: { path: "/bin/bash" }, @@ -195,49 +192,45 @@ describe("Terminal VS Code terminal profile (#277)", () => { it("returns true when no override and default profile is cmd.exe", () => { Terminal.setTerminalProfile(undefined) stubProfiles({ windows: { "Command Prompt": { path: "C:\\Windows\\System32\\cmd.exe" } } }) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ - defaultValue: { "Command Prompt": { path: "C:\\Windows\\System32\\cmd.exe" } }, - globalValue: undefined, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.windows" ? { defaultValue: "Command Prompt" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ + defaultValue: { "Command Prompt": { path: "C:\\Windows\\System32\\cmd.exe" } }, + globalValue: undefined, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.windows" ? { defaultValue: "Command Prompt" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellCmdExe("win32")).toBe(true) }) it("returns false when no override and default profile is PowerShell", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ - defaultValue: { PowerShell: { path: "C:\\Program Files\\PowerShell\\pwsh.exe" } }, - globalValue: undefined, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.windows" ? { defaultValue: "PowerShell" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ + defaultValue: { PowerShell: { path: "C:\\Program Files\\PowerShell\\pwsh.exe" } }, + globalValue: undefined, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.windows" ? { defaultValue: "PowerShell" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellCmdExe("win32")).toBe(false) }) @@ -249,46 +242,42 @@ describe("Terminal VS Code terminal profile (#277)", () => { it("ignores a workspace default-profile override", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: () => ({ - defaultValue: { - PowerShell: { path: "C:\\Program Files\\PowerShell\\pwsh.exe" }, - "Command Prompt": { path: "C:\\Windows\\System32\\cmd.exe" }, - }, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: () => ({ - defaultValue: "PowerShell", - workspaceValue: "Command Prompt", - }), - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: () => ({ + defaultValue: { + PowerShell: { path: "C:\\Program Files\\PowerShell\\pwsh.exe" }, + "Command Prompt": { path: "C:\\Windows\\System32\\cmd.exe" }, + }, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: () => ({ + defaultValue: "PowerShell", + workspaceValue: "Command Prompt", + }), + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellCmdExe("win32")).toBe(false) }) it("returns false when the configured default profile entry is missing", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { inspect: () => ({ defaultValue: {} }) } as any - } - if (section === "terminal.integrated") { - return { inspect: () => ({ defaultValue: "Deleted Profile" }) } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { inspect: () => ({ defaultValue: {} }) } as any + } + if (section === "terminal.integrated") { + return { inspect: () => ({ defaultValue: "Deleted Profile" }) } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellCmdExe("win32")).toBe(false) }) @@ -318,52 +307,48 @@ describe("Terminal VS Code terminal profile (#277)", () => { it("returns true when no override and the default profile resolves to powershell.exe", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ - defaultValue: { - "Custom PS": { - path: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", - }, + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ + defaultValue: { + "Custom PS": { + path: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", }, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.windows" ? { defaultValue: "Custom PS" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + }, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.windows" ? { defaultValue: "Custom PS" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellPowerShell("win32")).toBe(true) }) it("recognizes source-only PowerShell default profiles", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ - defaultValue: { PowerShell: { source: "PowerShell" } }, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.windows" ? { defaultValue: "PowerShell" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ + defaultValue: { PowerShell: { source: "PowerShell" } }, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.windows" ? { defaultValue: "PowerShell" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellPowerShell("win32")).toBe(true) }) @@ -384,7 +369,7 @@ describe("Terminal VS Code terminal profile (#277)", () => { it("returns false when no override and no default profile name is configured", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({ + vi.spyOn(vscode.workspace, "getConfiguration").mockReturnValue({ get: (_key: string, defaultValue?: unknown) => defaultValue, inspect: () => undefined, } as any) @@ -393,45 +378,41 @@ describe("Terminal VS Code terminal profile (#277)", () => { it("returns false when the default profile entry is null", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ defaultValue: { "Fish Shell": null } }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.linux" ? { defaultValue: "Fish Shell" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ defaultValue: { "Fish Shell": null } }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.linux" ? { defaultValue: "Fish Shell" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellFish("linux")).toBe(false) }) it("returns true when the default profile resolves to fish", () => { Terminal.setTerminalProfile(undefined) - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: (_key: string) => ({ - defaultValue: { "Fish Shell": { path: "/usr/local/bin/fish" } }, - }), - } as any - } - if (section === "terminal.integrated") { - return { - inspect: (key: string) => - key === "defaultProfile.linux" ? { defaultValue: "Fish Shell" } : undefined, - } as any - } - return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any - }) + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { + return { + inspect: (_key: string) => ({ + defaultValue: { "Fish Shell": { path: "/usr/local/bin/fish" } }, + }), + } as any + } + if (section === "terminal.integrated") { + return { + inspect: (key: string) => + key === "defaultProfile.linux" ? { defaultValue: "Fish Shell" } : undefined, + } as any + } + return { get: (_key: string, defaultValue?: unknown) => defaultValue } as any + }) expect(Terminal.isActiveShellFish("linux")).toBe(true) }) }) @@ -589,24 +570,22 @@ describe("Terminal VS Code terminal profile (#277)", () => { }) it("resolves profiles defined only in user/global settings", () => { - getConfigurationSpy = vi - .spyOn(vscode.workspace, "getConfiguration") - .mockImplementation((section?: string) => { - if (section === "terminal.integrated.profiles") { - return { - inspect: () => ({ - defaultValue: undefined, - globalValue: { "User Bash": { path: "/usr/bin/bash" } }, - workspaceValue: { "User Bash": { path: "/workspace/bash" } }, - }), - } as any - } - + vi.spyOn(vscode.workspace, "getConfiguration").mockImplementation((section?: string) => { + if (section === "terminal.integrated.profiles") { return { - get: (_key: string, defaultValue?: unknown) => defaultValue, - inspect: () => undefined, + inspect: () => ({ + defaultValue: undefined, + globalValue: { "User Bash": { path: "/usr/bin/bash" } }, + workspaceValue: { "User Bash": { path: "/workspace/bash" } }, + }), } as any - }) + } + + return { + get: (_key: string, defaultValue?: unknown) => defaultValue, + inspect: () => undefined, + } as any + }) Terminal.setTerminalProfile("User Bash") diff --git a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts index f60c0d0722..b94a7f2ed8 100644 --- a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts +++ b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts @@ -22,7 +22,7 @@ describe("TerminalRegistry", () => { TerminalRegistry["terminals"] = [] Terminal.setTerminalProfile(undefined) mockCreateTerminal = vi.spyOn(vscode.window, "createTerminal").mockImplementation( - (...args: any[]) => + (..._args: any[]) => ({ exitStatus: undefined, name: "Zoo Code", diff --git a/src/integrations/terminal/__tests__/setupTerminalTests.ts b/src/integrations/terminal/__tests__/setupTerminalTests.ts index 5a5db9871b..332b58228b 100644 --- a/src/integrations/terminal/__tests__/setupTerminalTests.ts +++ b/src/integrations/terminal/__tests__/setupTerminalTests.ts @@ -10,7 +10,7 @@ function isPowerShellCoreAvailable() { stdio: "pipe", }) return true - } catch (error) { + } catch { return false } } diff --git a/src/services/__tests__/zoo-code-auth.test.ts b/src/services/__tests__/zoo-code-auth.test.ts index c08fcdedf3..78b81b1e67 100644 --- a/src/services/__tests__/zoo-code-auth.test.ts +++ b/src/services/__tests__/zoo-code-auth.test.ts @@ -1,5 +1,4 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" -import * as vscode from "vscode" import { clearZooCodeToken, @@ -19,7 +18,7 @@ import { vi.mock("vscode", () => ({ workspace: { getConfiguration: vi.fn(() => ({ - get: vi.fn((key: string, defaultValue?: string) => defaultValue), + get: vi.fn((_key: string, defaultValue?: string) => defaultValue), })), }, window: { diff --git a/src/services/checkpoints/__tests__/ShadowCheckpointService.spec.ts b/src/services/checkpoints/__tests__/ShadowCheckpointService.spec.ts index 1710cc97e8..76e98367a5 100644 --- a/src/services/checkpoints/__tests__/ShadowCheckpointService.spec.ts +++ b/src/services/checkpoints/__tests__/ShadowCheckpointService.spec.ts @@ -619,7 +619,7 @@ describe.each([[RepoPerTaskCheckpointService, "RepoPerTaskCheckpointService"]])( // Try to restore an invalid checkpoint. try { await service.restoreCheckpoint(invalidCommitHash) - } catch (error) { + } catch { // Expected to throw, we're testing the event emission. } @@ -972,7 +972,7 @@ describe.each([[RepoPerTaskCheckpointService, "RepoPerTaskCheckpointService"]])( // (In Dev Containers, the workspace repo already exists before GIT_DIR is set) const testShadowDir = path.join(tmpDir, `shadow-git-dir-test-${Date.now()}`) const testWorkspaceDir = path.join(tmpDir, `workspace-git-dir-test-${Date.now()}`) - const testRepo = await initWorkspaceRepo({ workspaceDir: testWorkspaceDir }) + await initWorkspaceRepo({ workspaceDir: testWorkspaceDir }) // Set GIT_DIR to point to the external repository BEFORE creating the service // This simulates the Dev Container environment where GIT_DIR is already set diff --git a/src/services/checkpoints/excludes.ts b/src/services/checkpoints/excludes.ts index 382e400f18..b9d78d0c32 100644 --- a/src/services/checkpoints/excludes.ts +++ b/src/services/checkpoints/excludes.ts @@ -193,7 +193,7 @@ const getLfsPatterns = async (workspacePath: string) => { .filter((line) => line.includes("filter=lfs")) .map((line) => line.split(" ")[0].trim()) } - } catch (error) {} + } catch {} return [] } diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index 9855f301cb..24a47c46df 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -467,7 +467,7 @@ describe("CodeIndexConfigManager", () => { it("should NOT require restart when models have same dimensions", async () => { // Mock both models to have same dimension - mockedGetModelDimension.mockImplementation((provider, modelId) => { + mockedGetModelDimension.mockImplementation((_provider, modelId) => { if (modelId === "text-embedding-3-small" || modelId === "text-embedding-ada-002") { return 1536 } @@ -1650,7 +1650,7 @@ describe("CodeIndexConfigManager", () => { configManager = new CodeIndexConfigManager(mockContextProxy) // Get the initial snapshot - const { configSnapshot: previousSnapshot } = await configManager.loadConfiguration() + await configManager.loadConfiguration() // Update the internal state to enabled with proper configuration mockContextProxy.getGlobalState.mockReturnValue({ @@ -1721,7 +1721,7 @@ describe("CodeIndexConfigManager", () => { configManager = new CodeIndexConfigManager(mockContextProxy) // Get initial configuration - const { configSnapshot: previousSnapshot } = await configManager.loadConfiguration() + await configManager.loadConfiguration() // Load again with same config - should not require restart const { requiresRestart } = await configManager.loadConfiguration() diff --git a/src/services/code-index/__tests__/manager.spec.ts b/src/services/code-index/__tests__/manager.spec.ts index 5038cc247e..1263aaef14 100644 --- a/src/services/code-index/__tests__/manager.spec.ts +++ b/src/services/code-index/__tests__/manager.spec.ts @@ -16,7 +16,7 @@ function mockUri(fsPath: string, scheme = "file") { scheme, authority: "", path: fsPath, - toString: (skipEncoding?: boolean) => `${scheme}://${fsPath}`, + toString: (_skipEncoding?: boolean) => `${scheme}://${fsPath}`, } } diff --git a/src/services/code-index/cache-manager.ts b/src/services/code-index/cache-manager.ts index eadaa9e346..7807aac69d 100644 --- a/src/services/code-index/cache-manager.ts +++ b/src/services/code-index/cache-manager.ts @@ -19,10 +19,7 @@ export class CacheManager implements ICacheManager { * @param context VS Code extension context * @param workspacePath Path to the workspace */ - constructor( - private context: vscode.ExtensionContext, - private workspacePath: string, - ) { + constructor(context: vscode.ExtensionContext, workspacePath: string) { this.cachePath = vscode.Uri.joinPath( context.globalStorageUri, `roo-index-cache-${createHash("sha256").update(workspacePath).digest("hex")}.json`, diff --git a/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts b/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts index 627c642432..859f2ceae1 100644 --- a/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts +++ b/src/services/code-index/embedders/__tests__/openai-compatible.spec.ts @@ -1,7 +1,7 @@ import type { MockedClass, MockedFunction } from "vitest" import { OpenAI } from "openai" import { OpenAICompatibleEmbedder } from "../openai-compatible" -import { MAX_ITEM_TOKENS, INITIAL_RETRY_DELAY_MS } from "../../constants" +import { MAX_ITEM_TOKENS } from "../../constants" import { clearAllMocks, restoreGlobals } from "../../../../test-utils/reset" // Mock the OpenAI SDK diff --git a/src/services/code-index/embedders/__tests__/openai.spec.ts b/src/services/code-index/embedders/__tests__/openai.spec.ts index af402f0766..4ad8239b53 100644 --- a/src/services/code-index/embedders/__tests__/openai.spec.ts +++ b/src/services/code-index/embedders/__tests__/openai.spec.ts @@ -73,7 +73,7 @@ describe("OpenAiEmbedder", () => { }) it("should use 'not-provided' if API key is not provided", () => { - const embedderWithoutKey = new OpenAiEmbedder({ + new OpenAiEmbedder({ openAiEmbeddingModelId: "text-embedding-3-small", }) diff --git a/src/services/code-index/embedders/__tests__/openrouter.spec.ts b/src/services/code-index/embedders/__tests__/openrouter.spec.ts index 3f8d526e19..d782ecd9cb 100644 --- a/src/services/code-index/embedders/__tests__/openrouter.spec.ts +++ b/src/services/code-index/embedders/__tests__/openrouter.spec.ts @@ -77,7 +77,6 @@ describe("OpenRouterEmbedder", () => { it("should use default model when none specified", () => { const embedder = new OpenRouterEmbedder(mockApiKey) - const expectedDefault = getDefaultModelId("openrouter") expect(embedder.embedderInfo.name).toBe("openrouter") }) diff --git a/src/services/code-index/embedders/bedrock.ts b/src/services/code-index/embedders/bedrock.ts index 833d4bf8f8..4d60440499 100644 --- a/src/services/code-index/embedders/bedrock.ts +++ b/src/services/code-index/embedders/bedrock.ts @@ -10,7 +10,7 @@ import { import { getDefaultModelId } from "../../../shared/embeddingModels" import { Package } from "../../../shared/package" import { t } from "../../../i18n" -import { withValidationErrorHandling, formatEmbeddingError, HttpError } from "../shared/validation-helpers" +import { withValidationErrorHandling, formatEmbeddingError } from "../shared/validation-helpers" import { TelemetryEventName } from "@roo-code/types" import { TelemetryService } from "@roo-code/telemetry" diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts index 9688a15ff0..654c41240f 100644 --- a/src/services/code-index/embedders/ollama.ts +++ b/src/services/code-index/embedders/ollama.ts @@ -89,7 +89,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { let errorBody = t("embeddings:ollama.couldNotReadErrorBody") try { errorBody = await response.text() - } catch (e) { + } catch { // Ignore error reading body } throw new Error( diff --git a/src/services/code-index/embedders/openai-compatible.ts b/src/services/code-index/embedders/openai-compatible.ts index e4e36a0272..9abc33711b 100644 --- a/src/services/code-index/embedders/openai-compatible.ts +++ b/src/services/code-index/embedders/openai-compatible.ts @@ -240,7 +240,7 @@ export class OpenAICompatibleEmbedder implements IEmbedder { try { return await response.json() - } catch (e) { + } catch { const error = new Error(`Failed to parse response JSON`) as HttpError error.status = response.status throw error @@ -445,7 +445,7 @@ export class OpenAICompatibleEmbedder implements IEmbedder { /** * Updates global rate limit state when a 429 error occurs */ - private async updateGlobalRateLimitState(error: HttpError): Promise { + private async updateGlobalRateLimitState(_error: HttpError): Promise { const release = await OpenAICompatibleEmbedder.globalRateLimitState.mutex.acquire() try { const state = OpenAICompatibleEmbedder.globalRateLimitState diff --git a/src/services/code-index/embedders/openrouter.ts b/src/services/code-index/embedders/openrouter.ts index d483d531ca..258ccdb4eb 100644 --- a/src/services/code-index/embedders/openrouter.ts +++ b/src/services/code-index/embedders/openrouter.ts @@ -38,7 +38,6 @@ interface OpenRouterEmbeddingResponse { export class OpenRouterEmbedder implements IEmbedder { private embeddingsClient: OpenAI private readonly defaultModelId: string - private readonly apiKey: string private readonly maxItemTokens: number private readonly baseUrl: string = "https://openrouter.ai/api/v1" private readonly specificProvider?: string @@ -65,7 +64,6 @@ export class OpenRouterEmbedder implements IEmbedder { throw new Error(t("embeddings:validation.apiKeyRequired")) } - this.apiKey = apiKey // Only set specificProvider if it's not the default value this.specificProvider = specificProvider && specificProvider !== OPENROUTER_DEFAULT_PROVIDER_NAME ? specificProvider : undefined @@ -381,7 +379,7 @@ export class OpenRouterEmbedder implements IEmbedder { /** * Updates global rate limit state when a 429 error occurs */ - private async updateGlobalRateLimitState(error: HttpError): Promise { + private async updateGlobalRateLimitState(_error: HttpError): Promise { const release = await OpenRouterEmbedder.globalRateLimitState.mutex.acquire() try { const state = OpenRouterEmbedder.globalRateLimitState diff --git a/src/services/code-index/manager.ts b/src/services/code-index/manager.ts index aa382e2131..26ce8de5cc 100644 --- a/src/services/code-index/manager.ts +++ b/src/services/code-index/manager.ts @@ -13,7 +13,6 @@ import { RooIgnoreController } from "../../core/ignore/RooIgnoreController" import fs from "fs/promises" import ignore from "ignore" import path from "path" -import { t } from "../../i18n" import { TelemetryService } from "@roo-code/telemetry" import { TelemetryEventName } from "@roo-code/types" @@ -117,7 +116,7 @@ export class CodeIndexManager { try { this.assertInitialized() return true - } catch (error) { + } catch { return false } } diff --git a/src/services/code-index/orchestrator.ts b/src/services/code-index/orchestrator.ts index 8d58b7fb8b..445db2364e 100644 --- a/src/services/code-index/orchestrator.ts +++ b/src/services/code-index/orchestrator.ts @@ -45,7 +45,7 @@ export class CodeIndexOrchestrator { await this.fileWatcher.initialize() this._fileWatcherSubscriptions = [ - this.fileWatcher.onDidStartBatchProcessing((filePaths: string[]) => {}), + this.fileWatcher.onDidStartBatchProcessing((_filePaths: string[]) => {}), this.fileWatcher.onBatchProgressUpdate(({ processedInBatch, totalInBatch, currentFile }) => { if (totalInBatch > 0 && this.stateManager.state !== "Indexing") { this.stateManager.setSystemState("Indexing", "Processing file changes...") @@ -71,13 +71,6 @@ export class CodeIndexOrchestrator { this.fileWatcher.onDidFinishBatchProcessing((summary: BatchProcessingSummary) => { if (summary.batchError) { console.error(`[CodeIndexOrchestrator] Batch processing failed:`, summary.batchError) - } else { - const successCount = summary.processedFiles.filter( - (f: { status: string }) => f.status === "success", - ).length - const errorCount = summary.processedFiles.filter( - (f: { status: string }) => f.status === "error" || f.status === "local_error", - ).length } }), ] diff --git a/src/services/code-index/processors/__tests__/parser.spec.ts b/src/services/code-index/processors/__tests__/parser.spec.ts index 7c640c0224..e17128d0c5 100644 --- a/src/services/code-index/processors/__tests__/parser.spec.ts +++ b/src/services/code-index/processors/__tests__/parser.spec.ts @@ -770,8 +770,6 @@ ${longParagraph} Final thoughts that need to be long enough to meet the minimum character requirement. This conclusion section contains multiple lines to ensure it exceeds 100 characters.` - const lines = markdownContent.split("\n") - vi.mocked(parseMarkdown).mockReturnValue([ { node: { diff --git a/src/services/code-index/processors/file-watcher.ts b/src/services/code-index/processors/file-watcher.ts index 933947bbe2..0a0514a891 100644 --- a/src/services/code-index/processors/file-watcher.ts +++ b/src/services/code-index/processors/file-watcher.ts @@ -66,7 +66,7 @@ export class FileWatcher implements IFileWatcher { */ constructor( private workspacePath: string, - private context: vscode.ExtensionContext, + _context: vscode.ExtensionContext, private readonly cacheManager: CacheManager, private embedder?: IEmbedder, private vectorStore?: IVectorStore, diff --git a/src/services/code-index/semble/__tests__/provider.spec.ts b/src/services/code-index/semble/__tests__/provider.spec.ts index ecf5fea520..9162313442 100644 --- a/src/services/code-index/semble/__tests__/provider.spec.ts +++ b/src/services/code-index/semble/__tests__/provider.spec.ts @@ -1,7 +1,5 @@ import { describe, it, expect, vi, beforeEach } from "vitest" -import * as path from "path" import { SembleProvider } from "../provider" -import { SembleCLI } from "../semble-cli" import { SEMBLE_DEFAULTS } from "../types" import { clearAllMocks } from "../../../../test-utils/reset" diff --git a/src/services/code-index/vector-store/__tests__/qdrant-client.spec.ts b/src/services/code-index/vector-store/__tests__/qdrant-client.spec.ts index 80a1fca835..17a5ae56c8 100644 --- a/src/services/code-index/vector-store/__tests__/qdrant-client.spec.ts +++ b/src/services/code-index/vector-store/__tests__/qdrant-client.spec.ts @@ -94,7 +94,7 @@ describe("QdrantVectorStore", () => { expect((vectorStore as any).vectorSize).toBe(mockVectorSize) }) it("should handle constructor with default URL when none provided", () => { - const vectorStoreWithDefaults = new QdrantVectorStore(mockWorkspacePath, undefined as any, mockVectorSize) + new QdrantVectorStore(mockWorkspacePath, undefined as any, mockVectorSize) expect(QdrantClient).toHaveBeenLastCalledWith({ host: "localhost", @@ -108,7 +108,7 @@ describe("QdrantVectorStore", () => { }) it("should handle constructor without API key", () => { - const vectorStoreWithoutKey = new QdrantVectorStore(mockWorkspacePath, mockQdrantUrl, mockVectorSize) + new QdrantVectorStore(mockWorkspacePath, mockQdrantUrl, mockVectorSize) expect(QdrantClient).toHaveBeenLastCalledWith({ host: "mock-qdrant", diff --git a/src/services/code-index/vector-store/qdrant-client.ts b/src/services/code-index/vector-store/qdrant-client.ts index 99e6b33deb..12c92f1aad 100644 --- a/src/services/code-index/vector-store/qdrant-client.ts +++ b/src/services/code-index/vector-store/qdrant-client.ts @@ -65,7 +65,7 @@ export class QdrantVectorStore implements IVectorStore { "User-Agent": "Zoo-Code", }, }) - } catch (urlError) { + } catch { // If URL parsing fails, fall back to URL-based config // Note: This fallback won't correctly handle prefixes, but it's a last resort for malformed URLs. this.client = new QdrantClient({ @@ -104,7 +104,7 @@ export class QdrantVectorStore implements IVectorStore { try { // Attempt to parse as complete URL - return as-is, let constructor handle ports - const parsedUrl = new URL(trimmedUrl) + new URL(trimmedUrl) return trimmedUrl } catch { // Failed to parse as URL - treat as hostname diff --git a/src/services/command/__tests__/symlink-commands.spec.ts b/src/services/command/__tests__/symlink-commands.spec.ts index 0d77967484..afbf34ae7e 100644 --- a/src/services/command/__tests__/symlink-commands.spec.ts +++ b/src/services/command/__tests__/symlink-commands.spec.ts @@ -1,5 +1,4 @@ import fs from "fs/promises" -import * as path from "path" import { getCommand, getCommands } from "../commands" diff --git a/src/services/glob/__tests__/gitignore-integration.spec.ts b/src/services/glob/__tests__/gitignore-integration.spec.ts index d9bab1c8de..2648c0938e 100644 --- a/src/services/glob/__tests__/gitignore-integration.spec.ts +++ b/src/services/glob/__tests__/gitignore-integration.spec.ts @@ -87,7 +87,7 @@ describe("list-files gitignore integration", () => { mockSpawn.mockReturnValue(createMockRipgrepProcess([rgFiles]) as any) // Call listFiles in recursive mode - const [files, didHitLimit] = await listFiles(tempDir, true, 100) + const [files] = await listFiles(tempDir, true, 100) // Filter out only directories from the results const directoriesInResult = files.filter((f) => f.endsWith("/")) @@ -120,7 +120,7 @@ describe("list-files gitignore integration", () => { mockSpawn.mockReturnValue(createMockRipgrepProcess() as any) // Call listFiles in recursive mode - const [files, didHitLimit] = await listFiles(tempDir, true, 100) + const [files] = await listFiles(tempDir, true, 100) // Filter out only directories from the results const directoriesInResult = files.filter((f) => f.endsWith("/")) @@ -149,10 +149,10 @@ describe("list-files gitignore integration", () => { mockSpawn.mockReturnValue(createMockRipgrepProcess([rgFiles]) as any) // Call listFiles in NON-recursive mode - const [files, didHitLimit] = await listFiles(tempDir, false, 100) + const [files] = await listFiles(tempDir, false, 100) // Verify ripgrep was called without --no-ignore-vcs (should respect .gitignore) - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] expect(args).not.toContain("--no-ignore-vcs") // Filter out only directories from the results diff --git a/src/services/glob/__tests__/gitignore-test.spec.ts b/src/services/glob/__tests__/gitignore-test.spec.ts index 3db33c1ed6..2dbb9fa98d 100644 --- a/src/services/glob/__tests__/gitignore-test.spec.ts +++ b/src/services/glob/__tests__/gitignore-test.spec.ts @@ -86,7 +86,7 @@ describe("list-files gitignore support", () => { mockSpawn.mockReturnValue(createMockRipgrepProcess([`${path.join(tempDir, "src", "index.ts")}\n`]) as any) // Call listFiles in recursive mode - const [files, didHitLimit] = await listFiles(tempDir, true, 100) + const [files] = await listFiles(tempDir, true, 100) // Verify that gitignored directories are not included const directoriesInResult = files.filter((f) => f.endsWith("/")) @@ -116,7 +116,7 @@ describe("list-files gitignore support", () => { mockSpawn.mockReturnValue(createMockRipgrepProcess() as any) // Call listFiles in recursive mode - const [files, didHitLimit] = await listFiles(tempDir, true, 100) + const [files] = await listFiles(tempDir, true, 100) // Verify that nested gitignored directories are not included const directoriesInResult = files.filter((f) => f.endsWith("/")) diff --git a/src/services/glob/__tests__/list-files-limit.spec.ts b/src/services/glob/__tests__/list-files-limit.spec.ts index 6f0ad85184..70fcadc536 100644 --- a/src/services/glob/__tests__/list-files-limit.spec.ts +++ b/src/services/glob/__tests__/list-files-limit.spec.ts @@ -1,4 +1,3 @@ -import * as path from "path" import * as fs from "fs" import { listFiles } from "../list-files" @@ -103,13 +102,11 @@ describe("listFiles limit handling for large projects", () => { // The key test: this should complete without throwing a stack overflow error let error: Error | null = null let results: string[] = [] - let limitReached = false try { - const [res, didHitLimit] = await listFiles("/test/large-project", true, limit) + const [res] = await listFiles("/test/large-project", true, limit) results = res - limitReached = didHitLimit } catch (e) { error = e as Error } diff --git a/src/services/glob/__tests__/list-files.spec.ts b/src/services/glob/__tests__/list-files.spec.ts index 9895fd8c87..3c57328172 100644 --- a/src/services/glob/__tests__/list-files.spec.ts +++ b/src/services/glob/__tests__/list-files.spec.ts @@ -325,7 +325,7 @@ describe("hidden directory exclusion", () => { const [files] = await listFiles("/test/.roo/temp", true, 100) // Verify ripgrep was called with correct arguments - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] expect(args).toContain("--no-ignore-vcs") expect(args).toContain("--no-ignore") @@ -358,7 +358,7 @@ describe("buildRecursiveArgs edge cases", () => { // Test with trailing slash on hidden directory await listFiles("/test/.hidden/", true, 100) - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] // When targeting a hidden directory, these flags should be present expect(args).toContain("--no-ignore-vcs") expect(args).toContain("--no-ignore") @@ -374,7 +374,7 @@ describe("buildRecursiveArgs edge cases", () => { // Test with redundant separators before hidden directory await listFiles("/test//.hidden", true, 100) - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] // When targeting a hidden directory, these flags should be present expect(args).toContain("--no-ignore-vcs") expect(args).toContain("--no-ignore") @@ -390,7 +390,7 @@ describe("buildRecursiveArgs edge cases", () => { // Test with complex path including hidden directory await listFiles("/test//normal/.hidden//subdir/", true, 100) - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] // When targeting a path containing a hidden directory, these flags should be present expect(args).toContain("--no-ignore-vcs") expect(args).toContain("--no-ignore") @@ -406,7 +406,7 @@ describe("buildRecursiveArgs edge cases", () => { // Test with a path that has dots but no hidden directories await listFiles("/test/file.with.dots/normal", true, 100) - const [rgPath, args] = mockSpawn.mock.calls[0] + const [, args] = mockSpawn.mock.calls[0] // Should NOT have the special flags for hidden directories expect(args).not.toContain("--no-ignore-vcs") expect(args).not.toContain("--no-ignore") diff --git a/src/services/marketplace/MarketplaceManager.ts b/src/services/marketplace/MarketplaceManager.ts index 1a9025cc78..76ec275f01 100644 --- a/src/services/marketplace/MarketplaceManager.ts +++ b/src/services/marketplace/MarketplaceManager.ts @@ -27,7 +27,7 @@ export class MarketplaceManager { constructor( private readonly context: vscode.ExtensionContext, - private readonly customModesManager?: CustomModesManager, + customModesManager?: CustomModesManager, ) { this.configLoader = new ConfigLoader(context.extensionUri.fsPath) this.installer = new SimpleInstaller(context, customModesManager) @@ -228,7 +228,7 @@ export class MarketplaceManager { } } } - } catch (error) { + } catch { // File doesn't exist or can't be read, skip } @@ -244,7 +244,7 @@ export class MarketplaceManager { } } } - } catch (error) { + } catch { // File doesn't exist or can't be read, skip } } catch (error) { @@ -273,7 +273,7 @@ export class MarketplaceManager { } } } - } catch (error) { + } catch { // File doesn't exist or can't be read, skip } @@ -289,7 +289,7 @@ export class MarketplaceManager { } } } - } catch (error) { + } catch { // File doesn't exist or can't be read, skip } } catch (error) { diff --git a/src/services/marketplace/SimpleInstaller.ts b/src/services/marketplace/SimpleInstaller.ts index be002e2f1d..b1735c0214 100644 --- a/src/services/marketplace/SimpleInstaller.ts +++ b/src/services/marketplace/SimpleInstaller.ts @@ -2,7 +2,7 @@ import * as vscode from "vscode" import * as path from "path" import * as fs from "fs/promises" import * as yaml from "yaml" -import type { MarketplaceItem, MarketplaceItemType, InstallMarketplaceItemOptions, McpParameter } from "@roo-code/types" +import type { MarketplaceItem, InstallMarketplaceItemOptions, McpParameter } from "@roo-code/types" import { GlobalFileNames } from "../../shared/globalFileNames" import { ensureSettingsDirectoryExists } from "../../utils/globalContext" import type { CustomModesManager } from "../../core/config/CustomModesManager" @@ -78,7 +78,7 @@ export class SimpleInstaller { line = slugLineIndex + 1 // Convert to 1-based line number } } - } catch (error) { + } catch { // If we can't find the line number, that's okay } @@ -293,7 +293,7 @@ export class SimpleInstaller { } } - private async removeMode(item: MarketplaceItem, target: "project" | "global"): Promise { + private async removeMode(item: MarketplaceItem, _target: "project" | "global"): Promise { if (!this.customModesManager) { throw new Error("CustomModesManager is not available") } @@ -311,7 +311,7 @@ export class SimpleInstaller { try { const modeData = yaml.parse(content) modeSlug = modeData.slug - } catch (error) { + } catch { throw new Error("Invalid mode content: unable to parse YAML") } @@ -319,10 +319,6 @@ export class SimpleInstaller { throw new Error("Mode missing slug identifier") } - // Get the current modes to determine the source - const modes = await this.customModesManager.getCustomModes() - const mode = modes.find((m) => m.slug === modeSlug) - // Use CustomModesManager to delete the mode configuration // This also handles rules folder deletion await this.customModesManager.deleteCustomMode(modeSlug, true) @@ -336,22 +332,13 @@ export class SimpleInstaller { const existingData = JSON.parse(existing) if (existingData?.mcpServers) { - // Parse the item content to get server names - let content: string - if (Array.isArray(item.content)) { - // Array of McpInstallationMethod objects - use first method - content = item.content[0].content - } else { - content = item.content - } - const serverName = item.id delete existingData.mcpServers[serverName] // Always write back the file, even if empty await fs.writeFile(filePath, JSON.stringify(existingData, null, 2), "utf-8") } - } catch (error) { + } catch { // File doesn't exist or other error, nothing to remove } } diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index 42786cfaa5..5e608fec73 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -550,7 +550,6 @@ export class McpHub { } const settingsPath = await this.getMcpSettingsFilePath() - const settingsUri = vscode.Uri.file(settingsPath) const settingsPattern = new vscode.RelativePattern(path.dirname(settingsPath), path.basename(settingsPath)) // Create a file system watcher for the global MCP settings file @@ -1303,7 +1302,7 @@ export class McpHub { private async _completeOAuthFlow( authProvider: McpOAuthClientProvider, - transport: StreamableHTTPClientTransport, + _transport: StreamableHTTPClientTransport, connection: ConnectedMcpConnection, name: string, source: "global" | "project", @@ -1513,7 +1512,7 @@ export class McpHub { } const response = await connection.client.request({ method: "resources/list" }, ListResourcesResultSchema) return response?.resources || [] - } catch (error) { + } catch { // console.error(`Failed to fetch resources for ${serverName}:`, error) return [] } @@ -1533,7 +1532,7 @@ export class McpHub { ListResourceTemplatesResultSchema, ) return response?.resourceTemplates || [] - } catch (error) { + } catch { // console.error(`Failed to fetch resource templates for ${serverName}:`, error) return [] } @@ -1801,30 +1800,6 @@ export class McpHub { this.isConnecting = true try { - const globalPath = await this.getMcpSettingsFilePath() - let globalServers: Record = {} - try { - const globalContent = await fs.readFile(globalPath, "utf-8") - const globalConfig = JSON.parse(globalContent) - globalServers = globalConfig.mcpServers || {} - const globalServerNames = Object.keys(globalServers) - } catch (error) { - console.log("Error reading global MCP config:", error) - } - - const projectPath = await this.getProjectMcpPath() - let projectServers: Record = {} - if (projectPath) { - try { - const projectContent = await fs.readFile(projectPath, "utf-8") - const projectConfig = JSON.parse(projectContent) - projectServers = projectConfig.mcpServers || {} - const projectServerNames = Object.keys(projectServers) - } catch (error) { - console.log("Error reading project MCP config:", error) - } - } - // Clear all existing connections first const existingConnections = [...this.connections] for (const conn of existingConnections) { @@ -1861,7 +1836,7 @@ export class McpHub { const projectContent = await fs.readFile(projectMcpPath, "utf-8") const projectConfig = JSON.parse(projectContent) projectServerOrder = Object.keys(projectConfig.mcpServers || {}) - } catch (error) { + } catch { // Silently continue with empty project server order } } @@ -2151,7 +2126,7 @@ export class McpHub { // Ensure the settings file exists and is accessible try { await fs.access(configPath) - } catch (error) { + } catch { throw new Error("Settings file not accessible") } diff --git a/src/services/mcp/__tests__/McpHub.spec.ts b/src/services/mcp/__tests__/McpHub.spec.ts index 441b0310e6..31ffc0ea60 100644 --- a/src/services/mcp/__tests__/McpHub.spec.ts +++ b/src/services/mcp/__tests__/McpHub.spec.ts @@ -31,7 +31,6 @@ vi.mock("fs/promises", () => { }) // Import safeWriteJson to use in mocks -import { safeWriteJson } from "../../../utils/safeWriteJson" // Mock safeWriteJson vi.mock("../../../utils/safeWriteJson", () => ({ @@ -294,8 +293,6 @@ describe("McpHub", () => { }) it("writes the default stub when the existing content has no mcpServers object", async () => { - const settingsPath = path.join("/mock/settings/path", "mcp_settings.json") - // Existence check sees an absent file, but the locked read finds content // that does not carry a mcpServers object (e.g. a torn or foreign write). vi.mocked(fs.access).mockRejectedValueOnce( @@ -311,8 +308,6 @@ describe("McpHub", () => { }) it("writes the default stub when the existing mcpServers value is not an object", async () => { - const settingsPath = path.join("/mock/settings/path", "mcp_settings.json") - vi.mocked(fs.access).mockRejectedValueOnce( Object.assign(new Error("ENOENT: no such file or directory"), { code: "ENOENT" }), ) @@ -326,8 +321,6 @@ describe("McpHub", () => { }) it("writes the default stub when the existing mcpServers value is an array", async () => { - const settingsPath = path.join("/mock/settings/path", "mcp_settings.json") - // Arrays satisfy `typeof === "object"`; an mcpServers map must be a // plain object, so an array is invalid and replaced by the stub // instead of being preserved and rejected by McpSettingsSchema later. @@ -384,8 +377,6 @@ describe("McpHub", () => { }) it("rejects creation when the locked read fails with an I/O error (EACCES)", async () => { - const settingsPath = path.join("/mock/settings/path", "mcp_settings.json") - vi.mocked(fs.access).mockRejectedValueOnce( Object.assign(new Error("ENOENT: no such file or directory"), { code: "ENOENT" }), ) diff --git a/src/services/mcp/utils/__tests__/callbackServer.spec.ts b/src/services/mcp/utils/__tests__/callbackServer.spec.ts index 09299ed4f4..e2ceb48723 100644 --- a/src/services/mcp/utils/__tests__/callbackServer.spec.ts +++ b/src/services/mcp/utils/__tests__/callbackServer.spec.ts @@ -8,7 +8,7 @@ vi.mock("http", () => ({ function createMockServer() { const mockServer = { - listen: vi.fn((port, host, callback) => { + listen: vi.fn((_port, _host, callback) => { callback() return mockServer }), diff --git a/src/services/roo-config/index.ts b/src/services/roo-config/index.ts index b97e01f5b5..f9874b0dff 100644 --- a/src/services/roo-config/index.ts +++ b/src/services/roo-config/index.ts @@ -232,7 +232,7 @@ export async function discoverSubfolderRooDirectories(cwd: string): Promise { it("should use default limit when configuration is not provided", async () => { const { Package } = await import("../../../shared/package") const mockRooConfig = { - get: vi.fn((key: string, defaultValue: number) => defaultValue), + get: vi.fn((_key: string, defaultValue: number) => defaultValue), } ;(vscode.workspace.getConfiguration as any).mockImplementation((section: string) => { diff --git a/src/services/search/file-search.ts b/src/services/search/file-search.ts index 4a97f29148..0687ace69e 100644 --- a/src/services/search/file-search.ts +++ b/src/services/search/file-search.ts @@ -49,7 +49,7 @@ export async function executeRipgrep({ } count++ - } catch (error) { + } catch { // Silently ignore errors processing individual paths. } } else { diff --git a/src/services/skills/SkillsManager.ts b/src/services/skills/SkillsManager.ts index 8dcc4f9e05..92ff4e0e09 100644 --- a/src/services/skills/SkillsManager.ts +++ b/src/services/skills/SkillsManager.ts @@ -316,7 +316,7 @@ export class SkillsManager { try { // Use gray-matter to parse frontmatter - const { data: frontmatter, content: body } = matter(fileContent) + const { data: frontmatter } = matter(fileContent) // Validate required fields (only name and description for now) if (!frontmatter.name || typeof frontmatter.name !== "string") { diff --git a/src/services/skills/__tests__/SkillsManager.spec.ts b/src/services/skills/__tests__/SkillsManager.spec.ts index f38f015a77..1d6727605e 100644 --- a/src/services/skills/__tests__/SkillsManager.spec.ts +++ b/src/services/skills/__tests__/SkillsManager.spec.ts @@ -2589,7 +2589,6 @@ Instructions`) const sourceDir = p(sourceSkillsDir, "test-skill") const testSkillMd = p(sourceDir, "SKILL.md") const destDir = p(GLOBAL_ROO_DIR, "skills-architect", "test-skill") - const destSkillsDir = p(GLOBAL_ROO_DIR, "skills-architect") // Setup: skill exists in code mode directory mockDirectoryExists.mockImplementation(async (dir: string) => { @@ -2652,7 +2651,6 @@ Instructions`) const sourceDir = p(sourceSkillsDir, "test-skill") const testSkillMd = p(sourceDir, "SKILL.md") const destDir = p(GLOBAL_ROO_DIR, "skills-architect", "test-skill") - const destSkillsDir = p(GLOBAL_ROO_DIR, "skills-architect") // Setup: skill exists in code mode directory along with another skill mockDirectoryExists.mockImplementation(async (dir: string) => { diff --git a/src/services/tree-sitter/__tests__/helpers.ts b/src/services/tree-sitter/__tests__/helpers.ts index 904137aaf7..707fa71a7f 100644 --- a/src/services/tree-sitter/__tests__/helpers.ts +++ b/src/services/tree-sitter/__tests__/helpers.ts @@ -64,7 +64,6 @@ export async function testParseSourceCodeDefinitions( // Clear any previous mocks and set up fs mock vi.clearAllMocks() vi.mock("fs/promises") - const mockedFs = (await vi.importActual("fs/promises")) as typeof import("fs/promises") ;(fs.readFile as any).mockResolvedValue(content) // Get the mock function @@ -72,7 +71,7 @@ export async function testParseSourceCodeDefinitions( const mockedLoadRequiredLanguageParsers = loadRequiredLanguageParsers as any // Initialize TreeSitter and create a real parser - const { Parser, Language } = await initializeTreeSitter() + const { Parser } = await initializeTreeSitter() const parser = new Parser() // Load language and configure parser @@ -102,7 +101,7 @@ export async function testParseSourceCodeDefinitions( // Helper function to inspect tree structure export async function inspectTreeStructure(content: string, language: string = "typescript"): Promise { - const { Parser, Language } = await initializeTreeSitter() + const { Parser } = await initializeTreeSitter() const parser = new Parser() const lang = await loadTestGrammar(`tree-sitter-${language}.wasm`) parser.setLanguage(lang) diff --git a/src/services/tree-sitter/__tests__/markdownParser.spec.ts b/src/services/tree-sitter/__tests__/markdownParser.spec.ts index 6413581a4d..dd9cd7d42d 100644 --- a/src/services/tree-sitter/__tests__/markdownParser.spec.ts +++ b/src/services/tree-sitter/__tests__/markdownParser.spec.ts @@ -500,7 +500,7 @@ Some content here. }) // Helper function to mimic the processCaptures function from index.ts -function processCaptures(captures: any[], lines: string[], minComponentLines: number = 4): string | null { +function processCaptures(captures: any[], _lines: string[], minComponentLines: number = 4): string | null { if (captures.length === 0) { return null } diff --git a/src/shared/utils/requesty.ts b/src/shared/utils/requesty.ts index 556a17cdb8..0cd05064a6 100644 --- a/src/shared/utils/requesty.ts +++ b/src/shared/utils/requesty.ts @@ -46,7 +46,7 @@ export const toRequestyServiceUrl = (baseUrl?: string | null, service: URLType = const validatedUrl = new URL(urlToUse).toString() // Apply service type transformation return replaceCname(validatedUrl, service) - } catch (error) { + } catch { // If the provided baseUrl is invalid, fall back to the default if (baseUrl && baseUrl !== REQUESTY_BASE_URL) { console.warn(`Invalid base URL "${baseUrl}", falling back to default`) diff --git a/src/utils/__tests__/autoImportSettings.spec.ts b/src/utils/__tests__/autoImportSettings.spec.ts index 010cb273b6..d8e8216783 100644 --- a/src/utils/__tests__/autoImportSettings.spec.ts +++ b/src/utils/__tests__/autoImportSettings.spec.ts @@ -84,7 +84,6 @@ describe("autoImportSettings", () => { let mockContextProxy: any let mockCustomModesManager: any let mockOutputChannel: any - let mockProvider: any beforeEach(() => { // Reset all mocks @@ -118,14 +117,6 @@ describe("autoImportSettings", () => { updateCustomMode: vi.fn().mockResolvedValue(undefined), } - // mockProvider must be initialized AFTER its dependencies - mockProvider = { - providerSettingsManager: mockProviderSettingsManager, - contextProxy: mockContextProxy, - upsertProviderProfile: vi.fn().mockResolvedValue({ success: true }), - postStateToWebview: vi.fn().mockResolvedValue({ success: true }), - } - // Reset fs mock vi.mocked(fsPromises.readFile).mockReset() vi.mocked(fileExistsAtPath).mockReset() diff --git a/src/utils/__tests__/git.spec.ts b/src/utils/__tests__/git.spec.ts index 95040a3d01..7490b3e95f 100644 --- a/src/utils/__tests__/git.spec.ts +++ b/src/utils/__tests__/git.spec.ts @@ -87,7 +87,7 @@ describe("git utils", () => { describe("checkGitInstalled", () => { it("should return true when git --version succeeds", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(null, { stdout: "git version 2.39.2", stderr: "" }) return {} as any @@ -102,7 +102,7 @@ describe("git utils", () => { }) it("should return false when git --version fails", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(new Error("git not found")) return {} as any @@ -117,7 +117,7 @@ describe("git utils", () => { }) it("should handle unexpected errors gracefully", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { // Simulate an unexpected error callback(new Error("Unexpected system error")) @@ -158,7 +158,7 @@ describe("git utils", () => { ], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { // Find matching response for (const [cmd, response] of responses) { if (command === cmd) { @@ -192,7 +192,7 @@ describe("git utils", () => { }) it("should return empty array when git is not installed", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(new Error("git not found")) return {} as any @@ -212,7 +212,7 @@ describe("git utils", () => { ["git rev-parse --git-dir", null], // null indicates error should be called ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { const response = responses.get(command) if (response === null) { callback(new Error("not a git repository")) @@ -246,7 +246,7 @@ describe("git utils", () => { ], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -293,7 +293,7 @@ describe("git utils", () => { ['git show --format="" abc123', { stdout: mockDiff, stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command.startsWith(cmd)) { callback(null, response) @@ -313,7 +313,7 @@ describe("git utils", () => { }) it("should return error message when git is not installed", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(new Error("git not found")) return {} as any @@ -332,7 +332,7 @@ describe("git utils", () => { ["git rev-parse --git-dir", null], // null indicates error should be called ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { const response = responses.get(command) if (response === null) { callback(new Error("not a git repository")) @@ -363,7 +363,7 @@ describe("git utils", () => { ["git diff HEAD", { stdout: mockDiff, stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -388,7 +388,7 @@ describe("git utils", () => { ["git status --short", { stdout: "", stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -404,7 +404,7 @@ describe("git utils", () => { }) it("should return error message when git is not installed", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(new Error("git not found")) return {} as any @@ -423,7 +423,7 @@ describe("git utils", () => { ["git rev-parse --git-dir", null], // null indicates error should be called ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { const response = responses.get(command) if (response === null) { callback(new Error("not a git repository")) @@ -493,7 +493,7 @@ describe("getGitRepositoryInfo", () => { const mockHead = "ref: refs/heads/main" // Setup the readFile mock to return different values based on the path - gitSpy.mockImplementation((path: any, encoding: any) => { + gitSpy.mockImplementation((path: any, _encoding: any) => { if (path === configPath) { return Promise.resolve(mockConfig) } else if (path === headPath) { @@ -538,7 +538,7 @@ describe("getGitRepositoryInfo", () => { const mockHead = "ref: refs/heads/main" // Setup the readFile mock to return different values based on the path - gitSpy.mockImplementation((path: any, encoding: any) => { + gitSpy.mockImplementation((path: any, _encoding: any) => { if (path === configPath) { return Promise.resolve(mockConfig) } else if (path === headPath) { @@ -565,7 +565,7 @@ describe("getGitRepositoryInfo", () => { vitest.mocked(fs.promises.access).mockResolvedValue(undefined) // Setup the readFile mock to return different values based on the path - gitSpy.mockImplementation((path: any, encoding: any) => { + gitSpy.mockImplementation((path: any, _encoding: any) => { if (path === configPath) { return Promise.reject(new Error("Failed to read config")) } else if (path === headPath) { @@ -592,7 +592,7 @@ describe("getGitRepositoryInfo", () => { vitest.mocked(fs.promises.access).mockResolvedValue(undefined) // Setup the readFile mock to return different values based on the path - gitSpy.mockImplementation((path: any, encoding: any) => { + gitSpy.mockImplementation((path: any, _encoding: any) => { if (path === configPath) { return Promise.resolve(` [remote "origin"] @@ -639,7 +639,7 @@ describe("getGitRepositoryInfo", () => { const mockHead = "ref: refs/heads/main" // Setup the readFile mock to return different values based on the path - gitSpy.mockImplementation((path: any, encoding: any) => { + gitSpy.mockImplementation((path: any, _encoding: any) => { if (path === configPath) { return Promise.resolve(mockConfig) } else if (path === headPath) { @@ -817,7 +817,7 @@ describe("getWorkspaceGitInfo", () => { ` // Setup the readFile mock to return config content - readFileSpy.mockImplementation((path: any, encoding: any) => { + readFileSpy.mockImplementation((path: any, _encoding: any) => { if (path.includes("config")) { return Promise.resolve(mockConfig) } @@ -858,7 +858,7 @@ MM src/both-modified.ts ["git status --porcelain=v1 --branch", { stdout: mockOutput, stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -885,7 +885,7 @@ M src/file1.ts ["git status --porcelain=v1 --branch", { stdout: mockOutput, stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -904,7 +904,7 @@ M src/file1.ts }) it("should return null when git is not installed", async () => { - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { if (command === "git --version") { callback(new Error("git not found")) return {} as any @@ -923,7 +923,7 @@ M src/file1.ts ["git rev-parse --git-dir", null], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { const response = responses.get(command) if (response === null) { callback(new Error("not a git repository")) @@ -953,7 +953,7 @@ M src/file1.ts ["git status --porcelain=v1 --branch", { stdout: mockOutput, stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) @@ -979,7 +979,7 @@ M src/file1.ts ["git status --porcelain=v1 --branch", { stdout: "", stderr: "" }], ]) - vitest.mocked(exec).mockImplementation((command: string, options: any, callback: any) => { + vitest.mocked(exec).mockImplementation((command: string, _options: any, callback: any) => { for (const [cmd, response] of responses) { if (command === cmd) { callback(null, response) diff --git a/src/utils/__tests__/safeWriteJson.test.ts b/src/utils/__tests__/safeWriteJson.test.ts index 79d08678a0..0ebdea281d 100644 --- a/src/utils/__tests__/safeWriteJson.test.ts +++ b/src/utils/__tests__/safeWriteJson.test.ts @@ -488,7 +488,7 @@ describe("safeWriteJson", () => { test("should pass null to merge callback when file does not exist", async () => { const newFilePath = path.join(tempDir, "nonexistent.json") - const mergeFn = vi.fn((existing, incoming) => incoming) + const mergeFn = vi.fn((_existing, incoming) => incoming) await safeWriteJson(newFilePath, { value: 42 }, { merge: mergeFn }) diff --git a/src/utils/git.ts b/src/utils/git.ts index 04c028c3d1..879dccd21d 100644 --- a/src/utils/git.ts +++ b/src/utils/git.ts @@ -54,7 +54,7 @@ export async function getGitRepositoryInfo(workspaceRoot: string): Promise { try { await execAsync("git rev-parse --git-dir", { cwd }) return true - } catch (error) { + } catch { return false } } @@ -213,7 +213,7 @@ export async function checkGitInstalled(): Promise { try { await execAsync("git --version") return true - } catch (error) { + } catch { return false } } diff --git a/src/utils/json-schema.ts b/src/utils/json-schema.ts index cbcd3486d2..9773a357d2 100644 --- a/src/utils/json-schema.ts +++ b/src/utils/json-schema.ts @@ -159,7 +159,7 @@ const NormalizedToolSchemaInternal: z.ZodType, z.ZodType type, required, properties, - additionalProperties, + additionalProperties: _additionalProperties, format, items, minItems, diff --git a/src/utils/outputChannelLogger.ts b/src/utils/outputChannelLogger.ts index 155a035f06..3b52449aee 100644 --- a/src/utils/outputChannelLogger.ts +++ b/src/utils/outputChannelLogger.ts @@ -22,7 +22,7 @@ export function createOutputChannelLogger(outputChannel: vscode.OutputChannel): outputChannel.appendLine( JSON.stringify( arg, - (key, value) => { + (_key, value) => { if (typeof value === "bigint") return `BigInt(${value})` if (typeof value === "function") return `Function: ${value.name || "anonymous"}` if (typeof value === "symbol") return value.toString() @@ -31,7 +31,7 @@ export function createOutputChannelLogger(outputChannel: vscode.OutputChannel): 2, ), ) - } catch (error) { + } catch { outputChannel.appendLine(`[Non-serializable object: ${Object.prototype.toString.call(arg)}]`) } } diff --git a/src/utils/shell.ts b/src/utils/shell.ts index 76a347fee1..812842b6b6 100644 --- a/src/utils/shell.ts +++ b/src/utils/shell.ts @@ -1,4 +1,3 @@ -import * as vscode from "vscode" import { existsSync } from "fs" import { userInfo } from "os" import * as path from "path" diff --git a/src/utils/storage.ts b/src/utils/storage.ts index 5125d6cf44..0cab638d81 100644 --- a/src/utils/storage.ts +++ b/src/utils/storage.ts @@ -19,7 +19,7 @@ export async function getStorageBasePath(defaultPath: string): Promise { // This is the line causing the error in tests const config = vscode.workspace.getConfiguration(Package.name) customStoragePath = config.get("customStoragePath", "") - } catch (error) { + } catch { console.warn("Could not access VSCode configuration - using default path") return defaultPath } @@ -91,7 +91,7 @@ export async function promptForCustomStoragePath(): Promise { try { const currentConfig = vscode.workspace.getConfiguration(Package.name) currentPath = currentConfig.get("customStoragePath", "") - } catch (error) { + } catch { console.error("Could not access configuration") return } @@ -115,7 +115,7 @@ export async function promptForCustomStoragePath(): Promise { } return null // Path format is valid - } catch (e) { + } catch { return t("common:storage.enter_valid_path") } }, diff --git a/src/utils/tts.ts b/src/utils/tts.ts index b544960571..abb3230f74 100644 --- a/src/utils/tts.ts +++ b/src/utils/tts.ts @@ -32,7 +32,7 @@ export const playTts = async (message: string, options: PlayTtsOptions = {}) => try { queue.push({ message, options }) await processQueue() - } catch (error) {} + } catch {} } export const stopTts = () => { @@ -74,7 +74,7 @@ const processQueue = async (): Promise => { }) await processQueue() - } catch (error: any) { + } catch { sayInstance = undefined await processQueue() } diff --git a/src/utils/vitest-verbosity.ts b/src/utils/vitest-verbosity.ts index bd44f977d3..6a6c8fda4d 100644 --- a/src/utils/vitest-verbosity.ts +++ b/src/utils/vitest-verbosity.ts @@ -1,4 +1,4 @@ -export function resolveVerbosity(argv = process.argv, env = process.env) { +export function resolveVerbosity(argv = process.argv, _env = process.env) { // Check if --no-silent flag is used (native vitest flag) const cliNoSilent = argv.includes("--no-silent") || argv.includes("--silent=false") const silent = !cliNoSilent // Silent by default From ca7b7b756f77f7421633f350cb61d6a952d2a2b1 Mon Sep 17 00:00:00 2001 From: Elliott de Launay Date: Tue, 13 Oct 2026 23:33:48 +0000 Subject: [PATCH 2/3] chore(eslint): turn on no-unused-vars in src --- src/api/providers/fetchers/ollama.ts | 4 ++-- src/api/providers/openai.ts | 1 - src/eslint.config.mjs | 2 -- src/shared/api.ts | 5 +++-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/api/providers/fetchers/ollama.ts b/src/api/providers/fetchers/ollama.ts index d16899dcce..68ecb5babd 100644 --- a/src/api/providers/fetchers/ollama.ts +++ b/src/api/providers/fetchers/ollama.ts @@ -22,7 +22,7 @@ const OllamaModelSchema = z.object({ size: z.number().optional(), }) -const OllamaModelInfoResponseSchema = z.object({ +const _OllamaModelInfoResponseSchema = z.object({ modelfile: z.string().optional(), parameters: z.string().optional(), template: z.string().optional(), @@ -37,7 +37,7 @@ const OllamaModelsResponseSchema = z.object({ type OllamaModelsResponse = z.infer -type OllamaModelInfoResponse = z.infer +type OllamaModelInfoResponse = z.infer export const parseOllamaModel = (rawModel: OllamaModelInfoResponse): ModelInfo | null => { const contextKey = Object.keys(rawModel.model_info).find((k) => k.includes("context_length")) diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index ef30f6763a..aaf3bab8fb 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -92,7 +92,6 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl const { info: modelInfo, reasoning } = this.getModel() const modelUrl = this.options.openAiBaseUrl ?? "" const modelId = this.options.openAiModelId ?? "" - const enabledR1Format = this.options.openAiR1FormatEnabled ?? false // Stryker disable next-line LogicalOperator: equivalent. An unset option makes `&&` // yield undefined, which the parameter default in convertToolsForOpenAI turns back into // the same strict value as `??`. diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index 41441251ca..c54733226e 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -15,8 +15,6 @@ export default [ "no-useless-escape": "off", "no-empty": "off", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "off", // Enforced; existing violations are suppressed in eslint-suppressions.json and cleaned up incrementally. "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-require-imports": "off", diff --git a/src/shared/api.ts b/src/shared/api.ts index a48844dff6..4f045b2add 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -183,7 +183,7 @@ type CommonFetchParams = { // Exhaustive, value-level map for all dynamic providers. // If a new dynamic provider is added in packages/types, this will fail to compile // until a corresponding entry is added here. -const dynamicProviderExtras = { +const _dynamicProviderExtras = { [providerIdentifiers.openrouter]: {} as {}, // eslint-disable-line @typescript-eslint/no-empty-object-type [providerIdentifiers.vercelAiGateway]: {} as {}, // eslint-disable-line @typescript-eslint/no-empty-object-type [providerIdentifiers.zooGateway]: {} as { apiKey?: string; baseUrl?: string }, @@ -204,5 +204,6 @@ const dynamicProviderExtras = { // Build the dynamic options union from the map, intersected with CommonFetchParams // so extra fields are always allowed while required ones are enforced. export type GetModelsOptions = { - [P in keyof typeof dynamicProviderExtras]: ({ provider: P } & (typeof dynamicProviderExtras)[P]) & CommonFetchParams + [P in keyof typeof _dynamicProviderExtras]: ({ provider: P } & (typeof _dynamicProviderExtras)[P]) & + CommonFetchParams }[RouterName] From 50e6383e63a1119c6caa20040becd47bab9b2479 Mon Sep 17 00:00:00 2001 From: Elliott de Launay Date: Wed, 14 Oct 2026 00:21:20 +0000 Subject: [PATCH 3/3] chore(eslint): enforce unused-vars rules in src and remove dead code --- src/__tests__/command-mentions.spec.ts | 12 ++++++------ src/api/providers/bedrock.ts | 2 +- src/core/config/CustomModesManager.ts | 2 +- ...omModesManager.exportImportSlugChange.spec.ts | 2 +- src/core/diff/strategies/multi-search-replace.ts | 2 +- src/core/prompts/sections/skills.ts | 2 +- src/core/tools/UseMcpToolTool.ts | 4 +++- src/core/tools/__tests__/newTaskTool.spec.ts | 2 +- src/core/webview/ClineProvider.ts | 6 +++--- src/eslint.config.mjs | 5 ----- src/integrations/misc/open-file.ts | 4 +++- .../terminal/ExecaTerminalProcess.ts | 4 +++- src/services/checkpoints/excludes.ts | 4 +++- .../code-index/embedders/openai-compatible.ts | 4 ++-- .../code-index/shared/validation-helpers.ts | 6 +++--- .../__tests__/fixtures/sample-dart.ts | 2 +- .../parseSourceCodeDefinitions.dart.spec.ts | 4 ++-- .../parseSourceCodeDefinitions.html.spec.ts | 16 ++++++++-------- .../parseSourceCodeDefinitions.rust.spec.ts | 2 +- src/services/tree-sitter/markdownParser.ts | 2 +- src/shared/context-mentions.ts | 2 +- src/utils/git.ts | 8 ++++---- src/utils/mcp-name.ts | 2 +- src/utils/tts.ts | 4 +++- 24 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/__tests__/command-mentions.spec.ts b/src/__tests__/command-mentions.spec.ts index 4f1f761307..98e2cc268a 100644 --- a/src/__tests__/command-mentions.spec.ts +++ b/src/__tests__/command-mentions.spec.ts @@ -272,7 +272,7 @@ npm install describe("command mention regex patterns", () => { it("should match valid command mention patterns anywhere", () => { - const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + const commandRegex = /\/([a-zA-Z0-9_.-]+)(?=\s|$)/g const validPatterns = ["/setup", "/build-prod", "/test_suite", "/my-command", "/command123"] @@ -284,19 +284,19 @@ npm install }) it("should match command patterns in middle of text", () => { - const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + const commandRegex = /\/([a-zA-Z0-9_.-]+)(?=\s|$)/g const validPatterns = ["Please /setup", "Run /build now", "Use /deploy here"] validPatterns.forEach((pattern) => { const match = pattern.match(commandRegex) expect(match).toBeTruthy() - expect(match![0]).toMatch(/^\/[a-zA-Z0-9_\.-]+$/) + expect(match![0]).toMatch(/^\/[a-zA-Z0-9_.-]+$/) }) }) it("should match commands at start of new lines", () => { - const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + const commandRegex = /\/([a-zA-Z0-9_.-]+)(?=\s|$)/g const multilineText = "First line\n/setup the project\nAnother line\n/deploy when ready" const matches = multilineText.match(commandRegex) @@ -309,7 +309,7 @@ npm install }) it("should match multiple commands in message", () => { - const commandRegex = /(?:^|\s)\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + const commandRegex = /(?:^|\s)\/([a-zA-Z0-9_.-]+)(?=\s|$)/g const validText = "/setup the project\nThen /deploy later" const matches = validText.match(commandRegex) @@ -321,7 +321,7 @@ npm install }) it("should not match invalid command patterns", () => { - const commandRegex = /\/([a-zA-Z0-9_\.-]+)(?=\s|$)/g + const commandRegex = /\/([a-zA-Z0-9_.-]+)(?=\s|$)/g const invalidPatterns = ["/ space", "/with space", "/with/slash", "//double", "/with@symbol"] diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index dd038d3398..5a66d6c193 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -1081,7 +1081,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH * match[4] - The resource ID (e.g., "anthropic.claude-3-sonnet-20240229-v1:0") */ - const arnRegex = /^arn:[^:]+:(?:bedrock|sagemaker):([^:]+):([^:]*):(?:([^\/]+)\/([\w\.\-:]+)|([^\/]+))$/ + const arnRegex = /^arn:[^:]+:(?:bedrock|sagemaker):([^:]+):([^:]*):(?:([^/]+)\/([\w.\-:]+)|([^/]+))$/ const match = arn.match(arnRegex) if (match && match[1] && match[3] && match[4]) { diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index 698d4f1db0..2e2e8dc8e2 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -890,7 +890,7 @@ export class CustomModesManager { // Check if path starts with a rules-* folder (old export format) let cleanedRelativePath = normalizedRelativePath - const rulesMatch = normalizedRelativePath.match(/^rules-[^\/\\]+[\/\\]/) + const rulesMatch = normalizedRelativePath.match(/^rules-[^/\\]+[/\\]/) if (rulesMatch) { // Strip the entire rules-* folder reference for backwards compatibility cleanedRelativePath = normalizedRelativePath.substring(rulesMatch[0].length) diff --git a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts index 1b6256c5e6..c62e815d8d 100644 --- a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts @@ -130,7 +130,7 @@ describe("CustomModesManager - Export/Import with Slug Changes", () => { // Check that no path starts with rules-test-mode rulesFiles.forEach((file: any) => { - expect(file.relativePath).not.toMatch(/^rules-test-mode[\/\\]/) + expect(file.relativePath).not.toMatch(/^rules-test-mode[/\\]/) }) // Verify the actual paths are just the file names (without rules folder) diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts index a8ba0215d3..b9b92ca135 100644 --- a/src/core/diff/strategies/multi-search-replace.ts +++ b/src/core/diff/strategies/multi-search-replace.ts @@ -396,7 +396,7 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy { const matches = [ ...repairedDiff.matchAll( - /(?:^|\n)(??\s*\n((?:\:start_line:\s*(\d+)\s*\n))?((?:\:end_line:\s*(\d+)\s*\n))?((?>>>>>> REPLACE)(?=\n|$)/g, + /(?:^|\n)(??\s*\n((?::start_line:\s*(\d+)\s*\n))?((?::end_line:\s*(\d+)\s*\n))?((?>>>>>> REPLACE)(?=\n|$)/g, ), ] diff --git a/src/core/prompts/sections/skills.ts b/src/core/prompts/sections/skills.ts index abb0f6b17f..99d782d221 100644 --- a/src/core/prompts/sections/skills.ts +++ b/src/core/prompts/sections/skills.ts @@ -8,7 +8,7 @@ function escapeXml(value: string): string { .replace(/&/g, "&") .replace(//g, ">") - .replace(/\"/g, """) + .replace(/"/g, """) .replace(/'/g, "'") } diff --git a/src/core/tools/UseMcpToolTool.ts b/src/core/tools/UseMcpToolTool.ts index cd7c3d469d..0bd53af3c2 100644 --- a/src/core/tools/UseMcpToolTool.ts +++ b/src/core/tools/UseMcpToolTool.ts @@ -147,7 +147,9 @@ export class UseMcpToolTool extends BaseTool<"use_mcp_tool"> { if (typeof params.arguments === "string") { try { params.arguments = JSON.parse(params.arguments) - } catch {} + } catch { + // Keep the raw string. The type check below reports the error. + } } let parsedArguments: Record | undefined diff --git a/src/core/tools/__tests__/newTaskTool.spec.ts b/src/core/tools/__tests__/newTaskTool.spec.ts index b7872cb714..bafeb93530 100644 --- a/src/core/tools/__tests__/newTaskTool.spec.ts +++ b/src/core/tools/__tests__/newTaskTool.spec.ts @@ -176,7 +176,7 @@ describe("newTaskTool", () => { expect(mockPushToolResult).toHaveBeenCalledWith(expect.stringContaining("Delegated to child task")) }) - it("should not un-escape single escaped \@", async () => { + it("should not un-escape single escaped @", async () => { const block: ToolUse<"new_task"> = { type: "tool_use", // Add required 'type' property name: "new_task", // Correct property name diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 0701f0ea12..cdd0975c5d 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1528,7 +1528,7 @@ export class ClineProvider const { apiConfiguration } = await this.getState() const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai" // Extract the domain for CSP - const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai" + const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^/]+)/)?.[1] || "https://openrouter.ai" const stylesUri = getUri(webview, this.contextProxy.extensionUri, [ "webview-ui", @@ -1644,7 +1644,7 @@ export class ClineProvider const { apiConfiguration } = await this.getState() const openRouterBaseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai" // Extract the domain for CSP - const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai" + const openRouterDomain = openRouterBaseUrl.match(/^(https?:\/\/[^/]+)/)?.[1] || "https://openrouter.ai" // Tip: Install the es6-string-html VS Code extension to enable code highlighting below return /*html*/ ` @@ -2075,7 +2075,7 @@ export class ClineProvider try { const baseUrl = apiConfiguration.openRouterBaseUrl || "https://openrouter.ai/api/v1" // Extract the base domain for the auth endpoint. - const baseUrlDomain = baseUrl.match(/^(https?:\/\/[^\/]+)/)?.[1] || "https://openrouter.ai" + const baseUrlDomain = baseUrl.match(/^(https?:\/\/[^/]+)/)?.[1] || "https://openrouter.ai" const response = await axios.post(`${baseUrlDomain}/api/v1/auth/keys`, { code }) if (response.data && response.data.key) { diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index c54733226e..691987b4fc 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -10,11 +10,6 @@ export default [ rules: { "prefer-const": ["error", { destructuring: "all" }], - // TODO: The rules listed below should be re-enabled once their existing violations are fixed. - "no-regex-spaces": "off", - "no-useless-escape": "off", - "no-empty": "off", - // Enforced; existing violations are suppressed in eslint-suppressions.json and cleaned up incrementally. "@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-require-imports": "off", diff --git a/src/integrations/misc/open-file.ts b/src/integrations/misc/open-file.ts index af5284aa56..630bba2901 100644 --- a/src/integrations/misc/open-file.ts +++ b/src/integrations/misc/open-file.ts @@ -132,7 +132,9 @@ export async function openFile(filePath: string, options: OpenFileOptions = {}) break } } - } catch {} // not essential, sometimes tab operations fail + } catch { + // not essential, sometimes tab operations fail + } const document = await vscode.workspace.openTextDocument(uriToProcess) const selection = diff --git a/src/integrations/terminal/ExecaTerminalProcess.ts b/src/integrations/terminal/ExecaTerminalProcess.ts index e94edce18c..8760dab4a7 100644 --- a/src/integrations/terminal/ExecaTerminalProcess.ts +++ b/src/integrations/terminal/ExecaTerminalProcess.ts @@ -113,7 +113,9 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { timeoutId = setTimeout(() => { try { this.subprocess?.kill("SIGKILL") - } catch {} + } catch { + // The process may already be gone. + } resolve() }, 5_000) diff --git a/src/services/checkpoints/excludes.ts b/src/services/checkpoints/excludes.ts index b9d78d0c32..dcf40d04b7 100644 --- a/src/services/checkpoints/excludes.ts +++ b/src/services/checkpoints/excludes.ts @@ -193,7 +193,9 @@ const getLfsPatterns = async (workspacePath: string) => { .filter((line) => line.includes("filter=lfs")) .map((line) => line.split(" ")[0].trim()) } - } catch {} + } catch { + // No readable attributes file. Fall through to no LFS patterns. + } return [] } diff --git a/src/services/code-index/embedders/openai-compatible.ts b/src/services/code-index/embedders/openai-compatible.ts index 9abc33711b..5cbbf67efc 100644 --- a/src/services/code-index/embedders/openai-compatible.ts +++ b/src/services/code-index/embedders/openai-compatible.ts @@ -179,9 +179,9 @@ export class OpenAICompatibleEmbedder implements IEmbedder { // Known patterns for major providers const patterns = [ // Azure OpenAI: /deployments/{deployment-name}/embeddings - /\/deployments\/[^\/]+\/embeddings(\?|$)/, + /\/deployments\/[^/]+\/embeddings(\?|$)/, // Azure Databricks: /serving-endpoints/{endpoint-name}/invocations - /\/serving-endpoints\/[^\/]+\/invocations(\?|$)/, + /\/serving-endpoints\/[^/]+\/invocations(\?|$)/, // Direct endpoints: ends with /embeddings (before query params) /\/embeddings(\?|$)/, // Some providers use /embed instead of /embeddings diff --git a/src/services/code-index/shared/validation-helpers.ts b/src/services/code-index/shared/validation-helpers.ts index 6b043d44d3..92a32d8578 100644 --- a/src/services/code-index/shared/validation-helpers.ts +++ b/src/services/code-index/shared/validation-helpers.ts @@ -16,12 +16,12 @@ export function sanitizeErrorMessage(errorMessage: string): string { // Replace URLs first (http, https, ftp, file protocols) // This needs to be done before file paths to avoid partial replacements sanitized = sanitized.replace( - /(?:https?|ftp|file):\/\/(?:localhost|[\w\-\.]+)(?::\d+)?(?:\/[\w\-\.\/\?\&\=\#]*)?/gi, + /(?:https?|ftp|file):\/\/(?:localhost|[\w\-.]+)(?::\d+)?(?:\/[\w\-./?&=#]*)?/gi, "[REDACTED_URL]", ) // Replace email addresses - sanitized = sanitized.replace(/[\w\-\.]+@[\w\-\.]+\.\w+/g, "[REDACTED_EMAIL]") + sanitized = sanitized.replace(/[\w\-.]+@[\w\-.]+\.\w+/g, "[REDACTED_EMAIL]") // Replace IP addresses (IPv4) sanitized = sanitized.replace(/\b(?:\d{1,3}\.){3}\d{1,3}\b/g, "[REDACTED_IP]") @@ -32,7 +32,7 @@ export function sanitizeErrorMessage(errorMessage: string): string { // Replace file paths (Unix and Windows style) // Matches paths like /Users/username/path, C:\Users\path, ./relative/path, ../relative/path sanitized = sanitized.replace( - /(?:\/[\w\-\.]+)+(?:\/[\w\-\.\s]*)*|(?:[A-Za-z]:\\[\w\-\.\\]+)|(?:\.{1,2}\/[\w\-\.\/]+)/g, + /(?:\/[\w\-.]+)+(?:\/[\w\-.\s]*)*|(?:[A-Za-z]:\\[\w\-.\\]+)|(?:\.{1,2}\/[\w\-./]+)/g, "[REDACTED_PATH]", ) diff --git a/src/services/tree-sitter/__tests__/fixtures/sample-dart.ts b/src/services/tree-sitter/__tests__/fixtures/sample-dart.ts index d09f12ac35..1a410ae745 100644 --- a/src/services/tree-sitter/__tests__/fixtures/sample-dart.ts +++ b/src/services/tree-sitter/__tests__/fixtures/sample-dart.ts @@ -56,7 +56,7 @@ class Dog extends Animal with Runner { @override String speak() { - return "\$name barks"; + return "$name barks"; } } diff --git a/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.dart.spec.ts b/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.dart.spec.ts index d7d681a263..44d65fdea0 100644 --- a/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.dart.spec.ts +++ b/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.dart.spec.ts @@ -94,8 +94,8 @@ describe("parseSourceCodeDefinitionsForFile with Dart", () => { expect(result).toMatch(/\d+--\d+ \|\s*factory Point\.origin\(\)/) expect(result).toMatch(/\d+--\d+ \|\s*Point\.fromCoordinates\(/) expect(result).toMatch(/\d+--\d+ \|\s*factory Point\.fromRecord\(/) - expect(result?.match(/\d+--\d+ \| Point\.fromCoordinates\(/g)).toHaveLength(1) - expect(result?.match(/\d+--\d+ \| factory Point\.fromRecord\(/g)).toHaveLength(1) + expect(result?.match(/\d+--\d+ \| {3}Point\.fromCoordinates\(/g)).toHaveLength(1) + expect(result?.match(/\d+--\d+ \| {3}factory Point\.fromRecord\(/g)).toHaveLength(1) expect(result).toMatch(/\d+--\d+ \|\s*int get x/) expect(result).toMatch(/\d+--\d+ \|\s*set x\(int value\)/) expect(result).toMatch(/\d+--\d+ \|\s*Point operator \+/) diff --git a/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.html.spec.ts b/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.html.spec.ts index 5b79a3a690..ba3bafa131 100644 --- a/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.html.spec.ts +++ b/src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.html.spec.ts @@ -24,23 +24,23 @@ describe("HTML Source Code Definition Tests", () => { }) it("should parse document definition", () => { - expect(parseResult).toMatch(/2--2 \|\s*/) + expect(parseResult).toMatch(/2--2 \|\s*/) }) it("should parse element definition", () => { - expect(parseResult).toMatch(/17--17 \|\s*
{ - expect(parseResult).toMatch(/32--32 \|\s*