diff --git a/src/api/providers/anthropic-vertex.ts b/src/api/providers/anthropic-vertex.ts index 3ed5dd45cc..d00c88dd9c 100644 --- a/src/api/providers/anthropic-vertex.ts +++ b/src/api/providers/anthropic-vertex.ts @@ -68,7 +68,7 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple messages: Anthropic.Messages.MessageParam[], metadata?: ApiHandlerCreateMessageMetadata, ): ApiStream { - let { id, info, temperature, maxTokens, reasoning: thinking, betas } = this.getModel() + const { id, info, temperature, maxTokens, reasoning: thinking, betas } = this.getModel() const { supportsPromptCache } = info @@ -207,7 +207,7 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId + const id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId let info: ModelInfo = vertexModels[id] // Check if 1M context beta should be enabled for supported models @@ -261,7 +261,7 @@ export class AnthropicVertexHandler extends BaseProvider implements SingleComple async completePrompt(prompt: string) { try { - let { + const { id, info: { supportsPromptCache }, temperature, diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 68daeead28..6ec237f0b1 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -54,7 +54,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa ): ApiStream { let stream: AnthropicStream const cacheControl: CacheControlEphemeral = { type: "ephemeral" } - let { + const { id: modelId, betas = ["fine-grained-tool-streaming-2025-05-14"], maxTokens, @@ -348,7 +348,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in anthropicModels ? (modelId as AnthropicModelId) : anthropicDefaultModelId + const id = modelId && modelId in anthropicModels ? (modelId as AnthropicModelId) : anthropicDefaultModelId let info: ModelInfo = anthropicModels[id] // If 1M context beta is enabled for supported models, update the model info @@ -394,7 +394,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa } async completePrompt(prompt: string) { - let { id: model, temperature } = this.getModel() + const { id: model, temperature } = this.getModel() let message try { diff --git a/src/api/providers/bedrock.ts b/src/api/providers/bedrock.ts index 3ceb251003..f09092d695 100644 --- a/src/api/providers/bedrock.ts +++ b/src/api/providers/bedrock.ts @@ -205,7 +205,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH constructor(options: ProviderSettings) { super() this.options = options - let region = this.options.awsRegion + const region = this.options.awsRegion // process the various user input options, be opinionated about the intent of the options // and determine the model to use during inference and for cost calculations @@ -532,8 +532,11 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH //so that pricing, context window, caching etc have values that can be used //However, we want to keep the id of the model to be the ID for the router for //subsequent requests so they are sent back through the router - let invokedArnInfo = this.parseArn(streamEvent.trace.promptRouter.invokedModelId) - let invokedModel = this.getModelById(invokedArnInfo.modelId as string, invokedArnInfo.modelType) + const invokedArnInfo = this.parseArn(streamEvent.trace.promptRouter.invokedModelId) + const invokedModel = this.getModelById( + invokedArnInfo.modelId as string, + invokedArnInfo.modelType, + ) if (invokedModel) { invokedModel.id = modelConfig.id this.costModelConfig = invokedModel @@ -870,7 +873,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH } // Get cache point placements - let strategy = new MultiPointStrategy(config) + const strategy = new MultiPointStrategy(config) const cacheResult = strategy.determineOptimalCachePoints() // Store cache point placements for future use if conversation ID is provided @@ -934,7 +937,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH */ const arnRegex = /^arn:[^:]+:(?:bedrock|sagemaker):([^:]+):([^:]*):(?:([^\/]+)\/([\w\.\-:]+)|([^\/]+))$/ - let match = arn.match(arnRegex) + const match = arn.match(arnRegex) if (match && match[1] && match[3] && match[4]) { // Create the result object @@ -961,7 +964,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH // Check if the original model ID had a region prefix if (originalModelId && result.modelId !== originalModelId) { // If the model ID changed after parsing, it had a region prefix - let prefix = originalModelId.replace(result.modelId, "") + const prefix = originalModelId.replace(result.modelId, "") result.crossRegionInference = AwsBedrockHandler.isSystemInferenceProfile(prefix) } diff --git a/src/api/providers/fake-ai.ts b/src/api/providers/fake-ai.ts index c73752fc66..e69a1c84e8 100644 --- a/src/api/providers/fake-ai.ts +++ b/src/api/providers/fake-ai.ts @@ -38,7 +38,7 @@ interface FakeAI { * * We use the ID to lookup the original FakeAI object in the mapping. */ -let fakeAiMap: Map = new Map() +const fakeAiMap: Map = new Map() export class FakeAIHandler implements ApiHandler, SingleCompletionHandler { private ai: FakeAI diff --git a/src/api/providers/fetchers/ollama.ts b/src/api/providers/fetchers/ollama.ts index ba5b1c1d5d..a81a1e2896 100644 --- a/src/api/providers/fetchers/ollama.ts +++ b/src/api/providers/fetchers/ollama.ts @@ -81,7 +81,7 @@ export async function getOllamaModels( const response = await axios.get(`${baseUrl}/api/tags`, { headers }) const parsedResponse = OllamaModelsResponseSchema.safeParse(response.data) - let modelInfoPromises = [] + const modelInfoPromises = [] if (parsedResponse.success) { for (const ollamaModel of parsedResponse.data.models) { diff --git a/src/api/providers/gemini.ts b/src/api/providers/gemini.ts index a49073ea33..773940c9d9 100644 --- a/src/api/providers/gemini.ts +++ b/src/api/providers/gemini.ts @@ -348,7 +348,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl override getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in geminiModels ? (modelId as GeminiModelId) : geminiDefaultModelId + const id = modelId && modelId in geminiModels ? (modelId as GeminiModelId) : geminiDefaultModelId let info: ModelInfo = geminiModels[id] const params = getModelParams({ @@ -509,7 +509,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl // Bill both completion and reasoning ("thoughts") tokens as output. const billedOutputTokens = outputTokens + reasoningTokens - let cacheReadCost = cacheReadTokens > 0 ? cacheReadsPrice * (cacheReadTokens / 1_000_000) : 0 + const cacheReadCost = cacheReadTokens > 0 ? cacheReadsPrice * (cacheReadTokens / 1_000_000) : 0 const inputTokensCost = inputPrice * (uncachedInputTokens / 1_000_000) const outputTokensCost = outputPrice * (billedOutputTokens / 1_000_000) diff --git a/src/api/providers/lite-llm.ts b/src/api/providers/lite-llm.ts index cf8d16a112..02b45043f8 100644 --- a/src/api/providers/lite-llm.ts +++ b/src/api/providers/lite-llm.ts @@ -184,7 +184,7 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa } // Required by some providers; others default to max tokens allowed - let maxTokens: number | undefined = info.maxTokens ?? undefined + const maxTokens: number | undefined = info.maxTokens ?? undefined // Check if this is a GPT-5 model that requires max_completion_tokens instead of max_tokens const isGPT5Model = this.isGpt5(modelId) diff --git a/src/api/providers/minimax.ts b/src/api/providers/minimax.ts index bfcf4e3be4..1ecf4137b1 100644 --- a/src/api/providers/minimax.ts +++ b/src/api/providers/minimax.ts @@ -81,7 +81,6 @@ export class MiniMaxHandler extends BaseProvider implements SingleCompletionHand messages: Anthropic.Messages.MessageParam[], metadata?: ApiHandlerCreateMessageMetadata, ): ApiStream { - let stream: AnthropicStream const cacheControl: CacheControlEphemeral = { type: "ephemeral" } const { id: modelId, info, maxTokens, temperature } = this.getModel() @@ -113,7 +112,7 @@ export class MiniMaxHandler extends BaseProvider implements SingleCompletionHand tool_choice: convertOpenAIToolChoice(metadata?.tool_choice), } - stream = await this.client.messages.create(requestParams) + const stream = await this.client.messages.create(requestParams) let inputTokens = 0 let outputTokens = 0 diff --git a/src/api/providers/openai-codex.ts b/src/api/providers/openai-codex.ts index 9dfb37bc72..51a479501b 100644 --- a/src/api/providers/openai-codex.ts +++ b/src/api/providers/openai-codex.ts @@ -1117,7 +1117,7 @@ export class OpenAiCodexHandler extends BaseProvider implements SingleCompletion override getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in openAiCodexModels ? (modelId as OpenAiCodexModelId) : openAiCodexDefaultModelId + const id = modelId && modelId in openAiCodexModels ? (modelId as OpenAiCodexModelId) : openAiCodexDefaultModelId const info: ModelInfo = openAiCodexModels[id] diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 6ce9382763..26d0fc7c5b 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -674,8 +674,8 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio const decoder = new TextDecoder() let buffer = "" let hasContent = false - let totalInputTokens = 0 - let totalOutputTokens = 0 + const totalInputTokens = 0 + const totalOutputTokens = 0 try { while (true) { @@ -1435,7 +1435,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio override getModel() { const modelId = this.options.apiModelId - let id = + const id = modelId && modelId in openAiNativeModels ? (modelId as OpenAiNativeModelId) : openAiNativeDefaultModelId const info: ModelInfo = openAiNativeModels[id] diff --git a/src/api/providers/openrouter.ts b/src/api/providers/openrouter.ts index 7fcc24b15f..8a30454c3a 100644 --- a/src/api/providers/openrouter.ts +++ b/src/api/providers/openrouter.ts @@ -575,7 +575,7 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH } async completePrompt(prompt: string) { - let { id: modelId, maxTokens, temperature, reasoning } = await this.fetchModel() + const { id: modelId, maxTokens, temperature, reasoning } = await this.fetchModel() const completionParams: OpenRouterChatCompletionParams = { model: modelId, diff --git a/src/api/providers/requesty.ts b/src/api/providers/requesty.ts index b241c347b0..09e9c98929 100644 --- a/src/api/providers/requesty.ts +++ b/src/api/providers/requesty.ts @@ -199,7 +199,7 @@ export class RequestyHandler extends BaseProvider implements SingleCompletionHan async completePrompt(prompt: string): Promise { const { id: model, maxTokens: max_tokens, temperature } = await this.fetchModel() - let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] + const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] const completionParams: RequestyChatCompletionParams = { model, diff --git a/src/api/providers/unbound.ts b/src/api/providers/unbound.ts index d50bfcc85d..4612f65496 100644 --- a/src/api/providers/unbound.ts +++ b/src/api/providers/unbound.ts @@ -192,7 +192,7 @@ export class UnboundHandler extends BaseProvider implements SingleCompletionHand async completePrompt(prompt: string): Promise { const { id: model, maxTokens: max_tokens, temperature } = await this.fetchModel() - let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] + const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [{ role: "system", content: prompt }] const completionParams: UnboundChatCompletionParams = { model, diff --git a/src/api/providers/vertex.ts b/src/api/providers/vertex.ts index fd318d9b19..be08019576 100644 --- a/src/api/providers/vertex.ts +++ b/src/api/providers/vertex.ts @@ -14,7 +14,7 @@ export class VertexHandler extends GeminiHandler implements SingleCompletionHand override getModel() { const modelId = this.options.apiModelId - let id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId + const id = modelId && modelId in vertexModels ? (modelId as VertexModelId) : vertexDefaultModelId let info: ModelInfo = vertexModels[id] const params = getModelParams({ format: "gemini", diff --git a/src/api/transform/cache-strategy/__tests__/cache-strategy.spec.ts b/src/api/transform/cache-strategy/__tests__/cache-strategy.spec.ts index 1e702d88a0..50fc2c60ce 100644 --- a/src/api/transform/cache-strategy/__tests__/cache-strategy.spec.ts +++ b/src/api/transform/cache-strategy/__tests__/cache-strategy.spec.ts @@ -344,9 +344,8 @@ describe("Cache Strategy", () => { convertToBedrockConverseMessagesMock.lastConfig = config // Create a strategy based on the config - let strategy // Use MultiPointStrategy for all cases - strategy = new MultiPointStrategy(config as any) + const strategy = new MultiPointStrategy(config as any) // Store the result const result = strategy.determineOptimalCachePoints() @@ -488,9 +487,8 @@ describe("Cache Strategy", () => { convertToBedrockConverseMessagesMock.lastConfig = config // Create a strategy based on the config - let strategy // Use MultiPointStrategy for all cases - strategy = new MultiPointStrategy(config as any) + const strategy = new MultiPointStrategy(config as any) // Store the result const result = strategy.determineOptimalCachePoints() diff --git a/src/api/transform/cache-strategy/multi-point-strategy.ts b/src/api/transform/cache-strategy/multi-point-strategy.ts index dc82136997..cf7c9f567e 100644 --- a/src/api/transform/cache-strategy/multi-point-strategy.ts +++ b/src/api/transform/cache-strategy/multi-point-strategy.ts @@ -43,7 +43,7 @@ export class MultiPointStrategy extends CacheStrategy { const placements = this.determineMessageCachePoints(minTokensPerPoint, remainingCachePoints) const messages = this.messagesToContentBlocks(this.config.messages) - let cacheResult = this.formatResult(systemBlocks, this.applyCachePoints(messages, placements)) + const cacheResult = this.formatResult(systemBlocks, this.applyCachePoints(messages, placements)) // Store the placements for future use (to maintain consistency across consecutive messages) // This needs to be handled by the caller by passing these placements back in the next call diff --git a/src/api/transform/caching/vercel-ai-gateway.ts b/src/api/transform/caching/vercel-ai-gateway.ts index 82eff0cd7b..0d3834bbe5 100644 --- a/src/api/transform/caching/vercel-ai-gateway.ts +++ b/src/api/transform/caching/vercel-ai-gateway.ts @@ -19,7 +19,7 @@ export function addCacheBreakpoints(systemPrompt: string, messages: OpenAI.Chat. if (Array.isArray(msg.content)) { // Find the last text part in the message content - let lastTextPart = msg.content.filter((part) => part.type === "text").pop() + const lastTextPart = msg.content.filter((part) => part.type === "text").pop() if (lastTextPart && lastTextPart.text && lastTextPart.text.length > 0) { // @ts-ignore-next-line diff --git a/src/api/transform/model-params.ts b/src/api/transform/model-params.ts index 8db76c8c24..ce6f59f4d6 100644 --- a/src/api/transform/model-params.ts +++ b/src/api/transform/model-params.ts @@ -98,7 +98,7 @@ export function getModelParams({ let temperature = customTemperature ?? model.defaultTemperature ?? defaultTemperature let reasoningBudget: ModelParams["reasoningBudget"] = undefined let reasoningEffort: ModelParams["reasoningEffort"] = undefined - let verbosity: VerbosityLevel | undefined = customVerbosity + const verbosity: VerbosityLevel | undefined = customVerbosity if (shouldUseReasoningBudget({ model, settings })) { // Check if this is a Gemini 2.5 Pro model diff --git a/src/api/transform/openai-format.ts b/src/api/transform/openai-format.ts index 8974dd599b..38719feba1 100644 --- a/src/api/transform/openai-format.ts +++ b/src/api/transform/openai-format.ts @@ -346,7 +346,7 @@ export function convertToOpenAiMessages( ) // Process tool result messages FIRST since they must follow the tool use messages - let toolResultImages: Anthropic.Messages.ImageBlockParam[] = [] + const toolResultImages: Anthropic.Messages.ImageBlockParam[] = [] toolMessages.forEach((toolMessage) => { // The Anthropic SDK allows tool results to be a string or an array of text and image blocks, enabling rich and structured content. In contrast, the OpenAI SDK only supports tool results as a single string, so we map the Anthropic tool result parts into one concatenated string to maintain compatibility. let content: string @@ -462,7 +462,7 @@ export function convertToOpenAiMessages( } // Process tool use messages - let tool_calls: OpenAI.Chat.ChatCompletionMessageToolCall[] = toolMessages.map((toolMessage) => ({ + const tool_calls: OpenAI.Chat.ChatCompletionMessageToolCall[] = toolMessages.map((toolMessage) => ({ id: normalizeId(toolMessage.id), type: "function", function: { diff --git a/src/core/config/CustomModesManager.ts b/src/core/config/CustomModesManager.ts index a243a9236b..48d67e01c8 100644 --- a/src/core/config/CustomModesManager.ts +++ b/src/core/config/CustomModesManager.ts @@ -775,7 +775,7 @@ export class CustomModesManager { ? path.join(baseDir, `rules-${slug}`) : path.join(baseDir, ".roo", `rules-${slug}`) - let rulesFiles: RuleFile[] = [] + const rulesFiles: RuleFile[] = [] try { const stats = await fs.stat(modeRulesDir) if (stats.isDirectory()) { diff --git a/src/core/config/ProviderSettingsManager.ts b/src/core/config/ProviderSettingsManager.ts index 7195b11373..1a1da87ece 100644 --- a/src/core/config/ProviderSettingsManager.ts +++ b/src/core/config/ProviderSettingsManager.ts @@ -799,7 +799,7 @@ export class ProviderSettingsManager { existingNames.delete(existingName) // Handle name conflict - let finalName = cloudName + const finalName = cloudName if (existingNames.has(cloudName)) { // There's a conflict - rename the existing non-cloud profile const conflictingProfile = providerProfiles.apiConfigs[cloudName] @@ -840,7 +840,7 @@ export class ProviderSettingsManager { // If name is the same and profile hasn't changed, do nothing } else { // Step 4: Add new cloud profile - let finalName = cloudName + const finalName = cloudName // Handle name conflict with existing non-cloud profile if (existingNames.has(cloudName)) { diff --git a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts index 3b7b0d1d9f..3c9655ed08 100644 --- a/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.exportImportSlugChange.spec.ts @@ -226,8 +226,8 @@ describe("CustomModesManager - Export/Import with Slug Changes", () => { ], }) - let writtenFiles: Record = {} - let createdDirs: string[] = [] + const writtenFiles: Record = {} + const createdDirs: string[] = [] ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { @@ -286,7 +286,7 @@ describe("CustomModesManager - Export/Import with Slug Changes", () => { ], }) - let writtenFiles: Record = {} + const writtenFiles: Record = {} ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { @@ -346,7 +346,7 @@ describe("CustomModesManager - Export/Import with Slug Changes", () => { ], }) - let writtenFiles: Record = {} + const writtenFiles: Record = {} ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { @@ -413,7 +413,7 @@ describe("CustomModesManager - Export/Import with Slug Changes", () => { const modifiedYaml = yaml.stringify(exportData) // Step 4: Import with the new slug - let writtenFiles: Record = {} + const writtenFiles: Record = {} ;(fs.writeFile as Mock).mockImplementation(async (path: string, content: string) => { writtenFiles[path] = content return Promise.resolve() diff --git a/src/core/config/__tests__/CustomModesManager.spec.ts b/src/core/config/__tests__/CustomModesManager.spec.ts index b48ea7b65b..97835d5ecc 100644 --- a/src/core/config/__tests__/CustomModesManager.spec.ts +++ b/src/core/config/__tests__/CustomModesManager.spec.ts @@ -900,7 +900,7 @@ describe("CustomModesManager", () => { }) let roomodesContent: any = null - let writtenFiles: Record = {} + const writtenFiles: Record = {} ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { return yaml.stringify({ customModes: [] }) @@ -1063,7 +1063,7 @@ describe("CustomModesManager", () => { ], }) - let writtenFiles: string[] = [] + const writtenFiles: string[] = [] ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { return yaml.stringify({ customModes: [] }) @@ -1197,7 +1197,7 @@ describe("CustomModesManager", () => { }) let roomodesContent: any = null - let writtenFiles: Record = {} + const writtenFiles: Record = {} ;(fs.readFile as Mock).mockImplementation(async (path: string) => { if (path === mockSettingsPath) { return yaml.stringify({ customModes: [] }) diff --git a/src/core/context-tracking/FileContextTracker.ts b/src/core/context-tracking/FileContextTracker.ts index 4c5640afdf..4026ff2dbc 100644 --- a/src/core/context-tracking/FileContextTracker.ts +++ b/src/core/context-tracking/FileContextTracker.ts @@ -161,7 +161,7 @@ export class FileContextTracker { return relevantEntries.length > 0 ? (relevantEntries[0][field] as number) : null } - let newEntry: FileMetadataEntry = { + const newEntry: FileMetadataEntry = { path: filePath, record_state: "active", record_source: source, diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts index f43bbee0dc..7f1428378a 100644 --- a/src/core/diff/strategies/multi-search-replace.ts +++ b/src/core/diff/strategies/multi-search-replace.ts @@ -287,7 +287,7 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy { Matches the final ">>>>>>> REPLACE" marker on its own line (and requires a following newline or the end of file). */ - let matches = [ + const matches = [ ...diffContent.matchAll( /(?:^|\n)(??\s*\n((?:\:start_line:\s*(\d+)\s*\n))?((?:\:end_line:\s*(\d+)\s*\n))?((?>>>>>> REPLACE)(?=\n|$)/g, ), @@ -303,7 +303,7 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy { const lineEnding = originalContent.includes("\r\n") ? "\r\n" : "\n" let resultLines = originalContent.split(/\r?\n/) let delta = 0 - let diffResults: DiffResult[] = [] + const diffResults: DiffResult[] = [] let appliedCount = 0 const replacements = matches .map((match) => ({ @@ -361,13 +361,13 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy { continue } - let endLine = replacement.startLine + searchLines.length - 1 + const endLine = replacement.startLine + searchLines.length - 1 // Initialize search variables let matchIndex = -1 let bestMatchScore = 0 let bestMatchContent = "" - let searchChunk = searchLines.join("\n") + const searchChunk = searchLines.join("\n") // Determine search bounds let searchStartIndex = 0 diff --git a/src/core/environment/getEnvironmentDetails.ts b/src/core/environment/getEnvironmentDetails.ts index 99b3951cd1..141ffdf3e2 100644 --- a/src/core/environment/getEnvironmentDetails.ts +++ b/src/core/environment/getEnvironmentDetails.ts @@ -126,7 +126,7 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo // Process each terminal with output. for (const inactiveTerminal of terminalsWithOutput) { - let terminalOutputs: string[] = [] + const terminalOutputs: string[] = [] // Get output from completed processes queue. const completedProcesses = inactiveTerminal.getProcessesWithOutput() diff --git a/src/core/prompts/sections/system-info.ts b/src/core/prompts/sections/system-info.ts index 486e46ee23..a4af3c6ac9 100644 --- a/src/core/prompts/sections/system-info.ts +++ b/src/core/prompts/sections/system-info.ts @@ -15,7 +15,7 @@ export function getSystemInfoSection(cwd: string): string { osInfo = `${platform} ${release}` } - let details = `==== + const details = `==== SYSTEM INFORMATION diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index fcdfd0263d..16fce1acca 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1212,7 +1212,7 @@ export class Task extends EventEmitter implements TaskLike { await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text, isProtected }) } - let timeouts: NodeJS.Timeout[] = [] + const timeouts: NodeJS.Timeout[] = [] // Automatically approve if the ask according to the user's settings. const provider = this.providerRef.deref() @@ -1932,7 +1932,7 @@ export class Task extends EventEmitter implements TaskLike { // Make sure that the api conversation history can be resumed by the API, // even if it goes out of sync with cline messages. - let existingApiConversationHistory: ApiMessage[] = await this.getSavedApiConversationHistory() + const existingApiConversationHistory: ApiMessage[] = await this.getSavedApiConversationHistory() // Tool blocks are always preserved; native tool calling only. @@ -2029,7 +2029,7 @@ export class Task extends EventEmitter implements TaskLike { throw new Error("Unexpected: No existing API conversation history") } - let newUserContent: Anthropic.Messages.ContentBlockParam[] = [...modifiedOldUserContent] + const newUserContent: Anthropic.Messages.ContentBlockParam[] = [...modifiedOldUserContent] const agoText = ((): string => { const timestamp = lastClineMessage?.ts ?? Date.now() @@ -2499,7 +2499,7 @@ export class Task extends EventEmitter implements TaskLike { // Add environment details as its own text block, separate from tool // results. - let finalUserContent = [...contentWithoutEnvDetails, { type: "text" as const, text: environmentDetails }] + const finalUserContent = [...contentWithoutEnvDetails, { type: "text" as const, text: environmentDetails }] // Only add user message to conversation history if: // 1. This is the first attempt (retryAttempt === 0), AND // 2. The original userContent was not empty (empty signals delegation resume where @@ -2645,7 +2645,7 @@ export class Task extends EventEmitter implements TaskLike { const stream = this.attemptApiRequest(currentItem.retryAttempt ?? 0, { skipProviderRateLimit: true }) let assistantMessage = "" let reasoningMessage = "" - let pendingGroundingSources: GroundingSource[] = [] + const pendingGroundingSources: GroundingSource[] = [] this.isStreaming = true try { @@ -3530,7 +3530,7 @@ export class Task extends EventEmitter implements TaskLike { // apiConversationHistory at line 1876. Since the assistant failed to respond, // we need to remove that message before retrying to avoid having two consecutive // user messages (which would cause tool_result validation errors). - let state = await this.providerRef.deref()?.getState() + const state = await this.providerRef.deref()?.getState() if (this.apiConversationHistory.length > 0) { const lastMessage = this.apiConversationHistory[this.apiConversationHistory.length - 1] if (lastMessage.role === "user") { diff --git a/src/core/tools/ExecuteCommandTool.ts b/src/core/tools/ExecuteCommandTool.ts index 8fcb917b13..d92c602b57 100644 --- a/src/core/tools/ExecuteCommandTool.ts +++ b/src/core/tools/ExecuteCommandTool.ts @@ -278,9 +278,8 @@ export async function executeCommandInTerminal( // Track when onCompleted callback finishes to avoid race condition. // The callback is async but Terminal/ExecaTerminal don't await it, so we track completion // explicitly to ensure persistedResult is set before we use it. - let onCompletedPromise: Promise | undefined let resolveOnCompleted: (() => void) | undefined - onCompletedPromise = new Promise((resolve) => { + const onCompletedPromise = new Promise((resolve) => { resolveOnCompleted = resolve }) diff --git a/src/core/tools/WriteToFileTool.ts b/src/core/tools/WriteToFileTool.ts index c8455ef3d9..ae026b4b86 100644 --- a/src/core/tools/WriteToFileTool.ts +++ b/src/core/tools/WriteToFileTool.ts @@ -195,7 +195,7 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> { override async handlePartial(task: Task, block: ToolUse<"write_to_file">): Promise { const relPath: string | undefined = block.params.path - let newContent: string | undefined = block.params.content + const newContent: string | undefined = block.params.content // Wait for path to stabilize before showing UI (prevents truncated paths) if (!this.hasPathStabilized(relPath) || newContent === undefined) { diff --git a/src/core/tools/accessMcpResourceTool.ts b/src/core/tools/accessMcpResourceTool.ts index 9df3b2256c..57f6ecc27c 100644 --- a/src/core/tools/accessMcpResourceTool.ts +++ b/src/core/tools/accessMcpResourceTool.ts @@ -64,7 +64,7 @@ export class AccessMcpResourceTool extends BaseTool<"access_mcp_resource"> { .join("\n\n") || "(Empty response)" // Handle images (image must contain mimetype and blob) - let images: string[] = [] + const images: string[] = [] resourceResult?.contents.forEach((item) => { if (item.mimeType?.startsWith("image") && item.blob) { diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 37e99054b1..94f1d0cd16 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1608,7 +1608,7 @@ export class ClineProvider // OpenRouter async handleOpenRouterCallback(code: string) { - let { apiConfiguration, currentApiConfigName = "default" } = await this.getState() + const { apiConfiguration, currentApiConfigName = "default" } = await this.getState() let apiKey: string @@ -1653,7 +1653,7 @@ export class ClineProvider // Requesty async handleRequestyCallback(code: string, baseUrl: string | null) { - let { apiConfiguration } = await this.getState() + const { apiConfiguration } = await this.getState() const newConfiguration: ProviderSettings = { ...apiConfiguration, @@ -2344,9 +2344,9 @@ export class ClineProvider ) } - let sharingEnabled: boolean = false + const sharingEnabled: boolean = false - let publicSharingEnabled: boolean = false + const publicSharingEnabled: boolean = false let organizationSettingsVersion: number = -1 @@ -2361,7 +2361,7 @@ export class ClineProvider ) } - let taskSyncEnabled: boolean = false + const taskSyncEnabled: boolean = false // Return the same structure as before. return { diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index d0813406d9..2ceb00b650 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -5,11 +5,12 @@ export default [ ...config, { rules: { + "prefer-const": ["error", { destructuring: "all" }], + // TODO: These should be fixed and the rules re-enabled. "no-regex-spaces": "off", "no-useless-escape": "off", "no-empty": "off", - "prefer-const": "off", "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-explicit-any": "off", diff --git a/src/integrations/misc/extract-text.ts b/src/integrations/misc/extract-text.ts index f29fa915d1..1ff98d273b 100644 --- a/src/integrations/misc/extract-text.ts +++ b/src/integrations/misc/extract-text.ts @@ -391,7 +391,7 @@ export function processCarriageReturns(input: string): string { if (lineEnd === -1) lineEnd = len // Check if current line contains carriage returns (\r) - let crPos = input.indexOf("\r", i) + const crPos = input.indexOf("\r", i) if (crPos === -1 || crPos >= lineEnd) { // No carriage returns (\r) in this line, copy entire line output += input.substring(i, lineEnd) @@ -488,7 +488,7 @@ function processLineWithCarriageReturns( if (nextCrPos === -1 || nextCrPos >= lineEnd) nextCrPos = lineEnd // Extract segment after carriage return (\r) - let segment = input.substring(crPos + 1, nextCrPos) + const segment = input.substring(crPos + 1, nextCrPos) // Skip empty segments if (segment !== "") { diff --git a/src/integrations/terminal/ExecaTerminalProcess.ts b/src/integrations/terminal/ExecaTerminalProcess.ts index cc2af93802..cde5a1251f 100644 --- a/src/integrations/terminal/ExecaTerminalProcess.ts +++ b/src/integrations/terminal/ExecaTerminalProcess.ts @@ -224,7 +224,7 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { } public override getUnretrievedOutput() { - let output = this.fullOutput.slice(this.lastRetrievedIndex) + const output = this.fullOutput.slice(this.lastRetrievedIndex) let index = output.lastIndexOf("\n") if (index === -1) { diff --git a/src/integrations/workspace/__tests__/WorkspaceTracker.spec.ts b/src/integrations/workspace/__tests__/WorkspaceTracker.spec.ts index 856f4ece30..e59a9372be 100644 --- a/src/integrations/workspace/__tests__/WorkspaceTracker.spec.ts +++ b/src/integrations/workspace/__tests__/WorkspaceTracker.spec.ts @@ -20,7 +20,7 @@ vitest.mock("../../../utils/path", () => ({ // Handle both Windows and POSIX paths by using path.relative const relativePath = require("path").relative(cwd, path) // Convert to forward slashes for consistency - let normalizedPath = relativePath.replace(/\\/g, "/") + const normalizedPath = relativePath.replace(/\\/g, "/") // Add trailing slash if original path had one return path.endsWith("/") ? normalizedPath + "/" : normalizedPath }), diff --git a/src/services/code-index/embedders/bedrock.ts b/src/services/code-index/embedders/bedrock.ts index 7652840c29..00e774a0aa 100644 --- a/src/services/code-index/embedders/bedrock.ts +++ b/src/services/code-index/embedders/bedrock.ts @@ -188,7 +188,7 @@ export class BedrockEmbedder implements IEmbedder { model: string, ): Promise<{ embedding: number[]; inputTextTokenCount?: number }> { let requestBody: any - let modelId = model + const modelId = model // Prepare the request body based on the model if (model.startsWith("amazon.nova-2-multimodal")) { diff --git a/src/services/code-index/orchestrator.ts b/src/services/code-index/orchestrator.ts index cd65fceb5e..1efe647be9 100644 --- a/src/services/code-index/orchestrator.ts +++ b/src/services/code-index/orchestrator.ts @@ -157,7 +157,7 @@ export class CodeIndexOrchestrator { let cumulativeBlocksIndexed = 0 let cumulativeBlocksFoundSoFar = 0 - let batchErrors: Error[] = [] + const batchErrors: Error[] = [] const handleFileParsed = (fileBlockCount: number) => { cumulativeBlocksFoundSoFar += fileBlockCount @@ -219,7 +219,7 @@ export class CodeIndexOrchestrator { let cumulativeBlocksIndexed = 0 let cumulativeBlocksFoundSoFar = 0 - let batchErrors: Error[] = [] + const batchErrors: Error[] = [] const handleFileParsed = (fileBlockCount: number) => { cumulativeBlocksFoundSoFar += fileBlockCount diff --git a/src/services/glob/list-files.ts b/src/services/glob/list-files.ts index b7f81c1951..b2072eb143 100644 --- a/src/services/glob/list-files.ts +++ b/src/services/glob/list-files.ts @@ -651,7 +651,7 @@ async function execRipgrep(rgPath: string, args: string[], limit: number, cwd?: return new Promise((resolve, reject) => { const rgProcess = childProcess.spawn(rgPath, args, cwd ? { cwd } : undefined) let output = "" - let results: string[] = [] + const results: string[] = [] // Set timeout to avoid hanging const timeoutId = setTimeout(() => { diff --git a/src/services/mcp/McpHub.ts b/src/services/mcp/McpHub.ts index b151b7f073..18887752f9 100644 --- a/src/services/mcp/McpHub.ts +++ b/src/services/mcp/McpHub.ts @@ -1129,7 +1129,6 @@ export class McpHub { return new Promise((resolve) => { let disposed = false - let cancellationDisposable: vscode.Disposable | undefined const cleanup = () => { if (disposed) return @@ -1188,7 +1187,7 @@ export class McpHub { }, OAUTH_FLOW_TIMEOUT_MS) // --- Cancellation (progress bar's Cancel button) --- - cancellationDisposable = cancellationToken.onCancellationRequested(() => { + const cancellationDisposable = cancellationToken.onCancellationRequested(() => { if (disposed) return cleanup() void authProvider.close() diff --git a/src/services/ripgrep/index.ts b/src/services/ripgrep/index.ts index 5dd800ac6f..1664312733 100644 --- a/src/services/ripgrep/index.ts +++ b/src/services/ripgrep/index.ts @@ -231,7 +231,7 @@ export async function regexSearchFiles( function formatResults(fileResults: SearchFileResult[], cwd: string): string { const groupedResults: { [key: string]: SearchResult[] } = {} - let totalResults = fileResults.reduce((sum, file) => sum + file.searchResults.length, 0) + const totalResults = fileResults.reduce((sum, file) => sum + file.searchResults.length, 0) let output = "" if (totalResults >= MAX_RESULTS) { output += `Showing first ${MAX_RESULTS} of ${MAX_RESULTS}+ results. Use a more specific search if necessary.\n\n`