Skip to content
6 changes: 5 additions & 1 deletion packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const globalSettingsSchema = z.object({
alwaysAllowWrite: z.boolean().optional(),
alwaysAllowWriteOutsideWorkspace: z.boolean().optional(),
alwaysAllowWriteProtected: z.boolean().optional(),
writeDelayMs: z.number().optional(),
writeDelayMs: z.number().min(0).optional(),
alwaysAllowBrowser: z.boolean().optional(),
alwaysApproveResubmit: z.boolean().optional(),
requestDelaySeconds: z.number().optional(),
Expand Down Expand Up @@ -86,6 +86,8 @@ export const globalSettingsSchema = z.object({
terminalZdotdir: z.boolean().optional(),
terminalCompressProgressBar: z.boolean().optional(),

diagnosticsEnabled: z.boolean().optional(),

rateLimitSeconds: z.number().optional(),
diffEnabled: z.boolean().optional(),
fuzzyMatchThreshold: z.number().optional(),
Expand Down Expand Up @@ -224,6 +226,8 @@ export const EVALS_SETTINGS: RooCodeSettings = {
terminalCompressProgressBar: true,
terminalShellIntegrationDisabled: true,

diagnosticsEnabled: true,

diffEnabled: true,
fuzzyMatchThreshold: 1,

Expand Down
8 changes: 8 additions & 0 deletions src/core/tools/__tests__/insertContentTool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ describe("insertContentTool", () => {
cwd: "/",
consecutiveMistakeCount: 0,
didEditFile: false,
providerRef: {
deref: vi.fn().mockReturnValue({
getState: vi.fn().mockResolvedValue({
diagnosticsEnabled: true,
writeDelayMs: 1000,
}),
}),
},
rooIgnoreController: {
validateAccess: vi.fn().mockReturnValue(true),
},
Expand Down
10 changes: 9 additions & 1 deletion src/core/tools/__tests__/writeToFileTool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ describe("writeToFileTool", () => {
mockCline.consecutiveMistakeCount = 0
mockCline.didEditFile = false
mockCline.diffStrategy = undefined
mockCline.providerRef = {
deref: vi.fn().mockReturnValue({
getState: vi.fn().mockResolvedValue({
diagnosticsEnabled: true,
writeDelayMs: 1000,
}),
}),
}
mockCline.rooIgnoreController = {
validateAccess: vi.fn().mockReturnValue(true),
}
Expand Down Expand Up @@ -376,7 +384,7 @@ describe("writeToFileTool", () => {
userEdits: userEditsValue,
finalContent: "modified content",
})
// Manually set the property on the mock instance because the original saveChanges is not called
// Set the userEdits property on the diffViewProvider mock to simulate user edits
mockCline.diffViewProvider.userEdits = userEditsValue

await executeWriteFileTool({}, { fileExists: true })
Expand Down
7 changes: 6 additions & 1 deletion src/core/tools/applyDiffTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from "path"
import fs from "fs/promises"

import { TelemetryService } from "@roo-code/telemetry"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"

import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
Expand Down Expand Up @@ -170,7 +171,11 @@ export async function applyDiffToolLegacy(
}

// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges()
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)

// Track file edit operation
if (relPath) {
Expand Down
7 changes: 6 additions & 1 deletion src/core/tools/insertContentTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ClineSayTool } from "../../shared/ExtensionMessage"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { fileExistsAtPath } from "../../utils/fs"
import { insertGroups } from "../diff/insert-groups"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"

export async function insertContentTool(
cline: Task,
Expand Down Expand Up @@ -155,7 +156,11 @@ export async function insertContentTool(
}

// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges()
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)

// Track file edit operation
if (relPath) {
Expand Down
7 changes: 6 additions & 1 deletion src/core/tools/multiApplyDiffTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from "path"
import fs from "fs/promises"

import { TelemetryService } from "@roo-code/telemetry"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"

import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
Expand Down Expand Up @@ -553,7 +554,11 @@ ${errorDetails ? `\nTechnical details:\n${errorDetails}\n` : ""}
}

// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges()
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)

// Track file edit operation
await cline.fileContextTracker.trackFileContext(relPath, "roo_edited" as RecordSource)
Expand Down
7 changes: 6 additions & 1 deletion src/core/tools/searchAndReplaceTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ClineSayTool } from "../../shared/ExtensionMessage"
import { getReadablePath } from "../../utils/path"
import { fileExistsAtPath } from "../../utils/fs"
import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"

/**
* Tool for performing search and replace operations on files
Expand Down Expand Up @@ -227,7 +228,11 @@ export async function searchAndReplaceTool(
}

// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges()
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)

// Track file edit operation
if (relPath) {
Expand Down
7 changes: 6 additions & 1 deletion src/core/tools/writeToFileTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { getReadablePath } from "../../utils/path"
import { isPathOutsideWorkspace } from "../../utils/pathUtils"
import { detectCodeOmission } from "../../integrations/editor/detect-omission"
import { unescapeHtmlEntities } from "../../utils/text-normalization"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"

export async function writeToFileTool(
cline: Task,
Expand Down Expand Up @@ -213,7 +214,11 @@ export async function writeToFileTool(
}

// Call saveChanges to update the DiffViewProvider properties
await cline.diffViewProvider.saveChanges()
const provider = cline.providerRef.deref()
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
await cline.diffViewProvider.saveChanges(diagnosticsEnabled, writeDelayMs)

// Track file edit operation
if (relPath) {
Expand Down
8 changes: 6 additions & 2 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { ExtensionMessage, MarketplaceInstalledMetadata } from "../../shared/Ext
import { Mode, defaultModeSlug } from "../../shared/modes"
import { experimentDefault, experiments, EXPERIMENT_IDS } from "../../shared/experiments"
import { formatLanguage } from "../../shared/language"
import { DEFAULT_WRITE_DELAY_MS } from "../../shared/constants"
import { Terminal } from "../../integrations/terminal/Terminal"
import { downloadTask } from "../../integrations/misc/export-markdown"
import { getTheme } from "../../integrations/theme/getTheme"
Expand Down Expand Up @@ -1436,6 +1437,7 @@ export class ClineProvider
profileThresholds,
alwaysAllowFollowupQuestions,
followupAutoApproveTimeoutMs,
diagnosticsEnabled,
} = await this.getState()

const telemetryKey = process.env.POSTHOG_API_KEY
Expand Down Expand Up @@ -1489,7 +1491,7 @@ export class ClineProvider
remoteBrowserHost,
remoteBrowserEnabled: remoteBrowserEnabled ?? false,
cachedChromeHostUrl: cachedChromeHostUrl,
writeDelayMs: writeDelayMs ?? 1000,
writeDelayMs: writeDelayMs ?? DEFAULT_WRITE_DELAY_MS,
terminalOutputLineLimit: terminalOutputLineLimit ?? 500,
terminalShellIntegrationTimeout: terminalShellIntegrationTimeout ?? Terminal.defaultShellIntegrationTimeout,
terminalShellIntegrationDisabled: terminalShellIntegrationDisabled ?? false,
Expand Down Expand Up @@ -1555,6 +1557,7 @@ export class ClineProvider
hasOpenedModeSelector: this.getGlobalState("hasOpenedModeSelector") ?? false,
alwaysAllowFollowupQuestions: alwaysAllowFollowupQuestions ?? false,
followupAutoApproveTimeoutMs: followupAutoApproveTimeoutMs ?? 60000,
diagnosticsEnabled: diagnosticsEnabled ?? true,
}
}

Expand Down Expand Up @@ -1638,6 +1641,7 @@ export class ClineProvider
alwaysAllowFollowupQuestions: stateValues.alwaysAllowFollowupQuestions ?? false,
alwaysAllowUpdateTodoList: stateValues.alwaysAllowUpdateTodoList ?? false,
followupAutoApproveTimeoutMs: stateValues.followupAutoApproveTimeoutMs ?? 60000,
diagnosticsEnabled: stateValues.diagnosticsEnabled ?? true,
allowedMaxRequests: stateValues.allowedMaxRequests,
autoCondenseContext: stateValues.autoCondenseContext ?? true,
autoCondenseContextPercent: stateValues.autoCondenseContextPercent ?? 100,
Expand All @@ -1656,7 +1660,7 @@ export class ClineProvider
remoteBrowserEnabled: stateValues.remoteBrowserEnabled ?? false,
cachedChromeHostUrl: stateValues.cachedChromeHostUrl as string | undefined,
fuzzyMatchThreshold: stateValues.fuzzyMatchThreshold ?? 1.0,
writeDelayMs: stateValues.writeDelayMs ?? 1000,
writeDelayMs: stateValues.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS,
terminalOutputLineLimit: stateValues.terminalOutputLineLimit ?? 500,
terminalShellIntegrationTimeout:
stateValues.terminalShellIntegrationTimeout ?? Terminal.defaultShellIntegrationTimeout,
Expand Down
57 changes: 48 additions & 9 deletions src/core/webview/__tests__/ClineProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { setTtsEnabled } from "../../../utils/tts"
import { ContextProxy } from "../../config/ContextProxy"
import { Task, TaskOptions } from "../../task/Task"
import { safeWriteJson } from "../../../utils/safeWriteJson"
import { DEFAULT_WRITE_DELAY_MS } from "../../../shared/constants"

import { ClineProvider } from "../ClineProvider"

Expand Down Expand Up @@ -500,24 +501,30 @@ describe("ClineProvider", () => {
alwaysAllowReadOnly: false,
alwaysAllowReadOnlyOutsideWorkspace: false,
alwaysAllowWrite: false,
codebaseIndexConfig: {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "",
codebaseIndexEmbedderProvider: "openai",
codebaseIndexEmbedderBaseUrl: "",
codebaseIndexEmbedderModelId: "",
},
alwaysAllowWriteOutsideWorkspace: false,
alwaysAllowWriteProtected: false,
alwaysAllowExecute: false,
alwaysAllowBrowser: false,
alwaysAllowMcp: false,
alwaysAllowModeSwitch: false,
alwaysAllowSubtasks: false,
alwaysAllowUpdateTodoList: false,
allowedCommands: [],
deniedCommands: [],
allowedMaxRequests: 100,
uriScheme: "vscode",
soundEnabled: false,
soundVolume: 0.5,
ttsEnabled: false,
ttsSpeed: 1.0,
diffEnabled: false,
enableCheckpoints: false,
writeDelayMs: 1000,
browserViewportSize: "900x600",
browserToolEnabled: true,
remoteBrowserEnabled: false,
remoteBrowserHost: "",
screenshotQuality: 0.8,
fuzzyMatchThreshold: 1.0,
mcpEnabled: true,
enableMcpServerCreation: false,
Expand All @@ -527,11 +534,23 @@ describe("ClineProvider", () => {
experiments: experimentDefault,
maxOpenTabsContext: 20,
maxWorkspaceFiles: 200,
browserToolEnabled: true,
maxReadFileLine: 500,
maxConcurrentFileReads: 10,
terminalOutputLineLimit: 1000,
terminalShellIntegrationTimeout: 5000,
terminalShellIntegrationDisabled: false,
terminalCommandDelay: 100,
terminalPowershellCounter: false,
terminalZshClearEolMark: false,
terminalZshOhMy: false,
terminalZshP10k: false,
terminalZdotdir: false,
terminalCompressProgressBar: false,
diagnosticsEnabled: true,
language: "en",
telemetrySetting: "unset",
showRooIgnoredFiles: true,
renderContext: "sidebar",
maxReadFileLine: 500,
cloudUserInfo: null,
organizationAllowList: ORGANIZATION_ALLOW_ALL,
autoCondenseContext: true,
Expand All @@ -540,6 +559,26 @@ describe("ClineProvider", () => {
sharingEnabled: false,
profileThresholds: {},
hasOpenedModeSelector: false,
// Add missing required properties
currentApiConfigName: "test-config",
listApiConfigMeta: [],
pinnedApiConfigs: {},
autoApprovalEnabled: false,
alwaysApproveResubmit: false,
customModePrompts: {},
customSupportPrompts: {},
modeApiConfigs: {},
enhancementApiConfigId: "",
condensingApiConfigId: "",
customCondensingPrompt: "",
codebaseIndexConfig: {
codebaseIndexEnabled: true,
codebaseIndexQdrantUrl: "",
codebaseIndexEmbedderProvider: "openai",
codebaseIndexEmbedderBaseUrl: "",
codebaseIndexEmbedderModelId: "",
},
codebaseIndexModels: {},
}

const message: ExtensionMessage = {
Expand Down
4 changes: 4 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,10 @@ export const webviewMessageHandler = async (
await updateGlobalState("writeDelayMs", message.value)
await provider.postStateToWebview()
break
case "diagnosticsEnabled":
await updateGlobalState("diagnosticsEnabled", message.bool ?? true)
await provider.postStateToWebview()
break
case "terminalOutputLineLimit":
await updateGlobalState("terminalOutputLineLimit", message.value)
await provider.postStateToWebview()
Expand Down
Loading