Skip to content

Commit 47e9f4b

Browse files
Merge branch 'main' into feat/label-stacked-prs
2 parents 7752417 + d7963fc commit 47e9f4b

8 files changed

Lines changed: 86 additions & 18 deletions

File tree

‎apps/vscode-e2e/src/visual/electron.visual.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@ for (const scenario of scenarios) {
236236
await expect.poll(() => contentFrame.evaluate(() => document.activeElement === document.body)).toBe(true)
237237
await contentFrame.evaluate(() => document.fonts.ready)
238238

239+
// The selected model's metadata resolves asynchronously: router models
240+
// arrive over the extension-host message channel after the webview
241+
// launches. Until they land, the context-window readout renders the `1`
242+
// fallback (see TaskHeader's `model?.contextWindow || 1`)
243+
// Wait for a resolved context window so the screenshot is deterministic.
244+
if (scenario.scene === "chat") {
245+
await expect(contentFrame.locator('[data-testid="context-window-size"]')).not.toHaveText("1", {
246+
timeout: 60_000,
247+
})
248+
}
249+
239250
const sidebar = running.page.locator(".part.sidebar")
240251
await expect(sidebar).toBeVisible()
241252

‎packages/types/src/global-settings.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ import { providerIdentifiers } from "./provider-identifiers.js"
1818

1919
/**
2020
* Default delay in milliseconds after writes to allow diagnostics to detect potential problems.
21-
* This delay is particularly important for Go and other languages where tools like goimports
22-
* need time to automatically clean up unused imports.
21+
* Defaults to 0: the write path adds no artificial pacing by default, and post-save
22+
* diagnostics are reported after the (zero) delay. Users who rely on auto-formatters that
23+
* settle asynchronously (e.g. goimports for Go) can raise this setting to give formatters
24+
* time to settle before diagnostics are captured.
2325
*/
24-
export const DEFAULT_WRITE_DELAY_MS = 1000
26+
export const DEFAULT_WRITE_DELAY_MS = 0
2527

2628
/**
2729
* Default values for the "auto-close files Zoo opened" settings.

‎src/core/tools/WriteToFileTool.ts‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import path from "path"
2-
import delay from "delay"
32
import fs from "fs/promises"
43

54
import { type ClineSayTool, DEFAULT_WRITE_DELAY_MS } from "@roo-code/types"
@@ -146,7 +145,6 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> {
146145
true,
147146
)
148147

149-
await delay(300)
150148
task.diffViewProvider.scrollToFirstDiff()
151149

152150
let unified = fileExists

‎src/core/webview/__tests__/ClineProvider.spec.ts‎

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,18 +1719,44 @@ describe("ClineProvider", () => {
17191719
expect(state.language).toBe("pt-BR")
17201720
})
17211721

1722-
test("writeDelayMs defaults to 1000ms", async () => {
1723-
// Mock globalState.get to return undefined for writeDelayMs
1724-
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
1722+
test("writeDelayMs defaults to DEFAULT_WRITE_DELAY_MS", async () => {
1723+
// Mock globalState.get to return undefined for writeDelayMs (typed reassignment,
1724+
// same pattern as the customModePrompts test below — Memento.get has no mock type)
1725+
mockContext.globalState.get = vi.fn((key: string) => {
17251726
return key === "writeDelayMs" ? undefined : null
17261727
})
17271728

17281729
const state = await provider.getState()
1729-
expect(state.writeDelayMs).toBe(1000)
1730+
expect(state.writeDelayMs).toBe(DEFAULT_WRITE_DELAY_MS)
1731+
})
1732+
1733+
test("getStateToPostToWebview returns the persisted writeDelayMs value", async () => {
1734+
await provider.resolveWebviewView(mockWebviewView)
1735+
1736+
// Simulate the updateSettings handler storing the value.
1737+
await provider.contextProxy.setValue("writeDelayMs", 500)
1738+
1739+
const state = await provider.getStateToPostToWebview()
1740+
1741+
expect(state.writeDelayMs).toBe(500)
1742+
})
1743+
1744+
test("getStateToPostToWebview defaults writeDelayMs to DEFAULT_WRITE_DELAY_MS when unset", async () => {
1745+
await provider.resolveWebviewView(mockWebviewView)
1746+
1747+
// Ensure the setting is not persisted.
1748+
await provider.contextProxy.setValue("writeDelayMs", undefined)
1749+
1750+
const state = await provider.getStateToPostToWebview()
1751+
1752+
expect(state.writeDelayMs).toBe(DEFAULT_WRITE_DELAY_MS)
17301753
})
17311754

17321755
test("getState applies fallback defaults for write, diff, and terminal settings", async () => {
1733-
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
1756+
// Mock globalState.get to return undefined for the fallback settings
1757+
// (typed reassignment — Memento.get has no mock type, same pattern as the
1758+
// writeDelayMs default test above)
1759+
mockContext.globalState.get = vi.fn((key: string) => {
17341760
if (
17351761
[
17361762
"writeDelayMs",

‎src/eslint-suppressions.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@
10361036
},
10371037
"core/webview/__tests__/ClineProvider.spec.ts": {
10381038
"@typescript-eslint/no-explicit-any": {
1039-
"count": 198
1039+
"count": 196
10401040
}
10411041
},
10421042
"core/webview/__tests__/ClineProvider.sticky-mode.spec.ts": {

‎src/integrations/editor/__tests__/DiffViewProvider.spec.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DiffViewProvider, DIFF_VIEW_URI_SCHEME, DIFF_VIEW_LABEL_CHANGES } from
22
import * as vscode from "vscode"
33
import * as path from "path"
44
import delay from "delay"
5+
import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types"
56

67
import { makeRange, makeTextDocument, makeTextEditor, makeUri } from "../../../test-utils/vscode"
78

@@ -918,12 +919,18 @@ describe("DiffViewProvider", () => {
918919

919920
const result = await diffViewProvider.saveChanges()
920921

921-
// Verify default behavior (enabled=true, delay=2000ms)
922-
expect(mockDelay).toHaveBeenCalledWith(1000)
922+
// Verify default behavior (enabled=true, delay falls back to DEFAULT_WRITE_DELAY_MS)
923+
expect(mockDelay).toHaveBeenCalledWith(0)
923924
expect(vscode.languages.getDiagnostics).toHaveBeenCalled()
924925
expect(result.newProblemsMessage).toBe("")
925926
})
926927

928+
it("pins the default write delay to zero", () => {
929+
// The tests above compare against the constant, so they would still pass if the
930+
// default were changed back to 1000. Pin the value the write path actually uses.
931+
expect(DEFAULT_WRITE_DELAY_MS).toBe(0)
932+
})
933+
927934
it("should handle custom delay values", async () => {
928935
const mockDelay = vi.mocked(delay)
929936
mockDelay.mockClear()

‎webview-ui/src/context/ExtensionStateContext.tsx‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
ORGANIZATION_ALLOW_ALL,
2424
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
2525
DEFAULT_DIFF_FUZZY_THRESHOLD,
26+
DEFAULT_WRITE_DELAY_MS,
2627
} from "@roo-code/types"
2728

2829
import { findLastIndex } from "@roo/array"
@@ -197,7 +198,7 @@ export const mergeExtensionState = (prevState: ExtensionState, newState: Partial
197198
}
198199
}
199200

200-
const createInitialExtensionState = (): ExtensionState => ({
201+
export const createInitialExtensionState = (): ExtensionState => ({
201202
apiConfiguration: {},
202203
version: "",
203204
clineMessages: [],
@@ -214,7 +215,10 @@ const createInitialExtensionState = (): ExtensionState => ({
214215
enableCheckpoints: true,
215216
checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, // Default to 15 seconds
216217
language: "en", // Default language code
217-
writeDelayMs: 1000,
218+
// Placeholder before the extension state hydrates: use the shared default
219+
// (the pre-hydration value must not disagree with the extension's own
220+
// DEFAULT_WRITE_DELAY_MS fallback).
221+
writeDelayMs: DEFAULT_WRITE_DELAY_MS,
218222
diffFuzzyThreshold: DEFAULT_DIFF_FUZZY_THRESHOLD,
219223
terminalShellIntegrationTimeout: 4000,
220224
mcpEnabled: true,

‎webview-ui/src/context/__tests__/ExtensionStateContext.spec.tsx‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@ import {
1212
type RouterModels,
1313
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
1414
DEFAULT_DIFF_FUZZY_THRESHOLD,
15+
DEFAULT_WRITE_DELAY_MS,
1516
} from "@roo-code/types"
1617

17-
import { ExtensionStateContextProvider, useExtensionState, mergeExtensionState } from "../ExtensionStateContext"
18+
import {
19+
ExtensionStateContextProvider,
20+
useExtensionState,
21+
mergeExtensionState,
22+
createInitialExtensionState,
23+
} from "../ExtensionStateContext"
1824

1925
const TestComponent = () => {
2026
const { allowedCommands, setAllowedCommands, soundEnabled, showRooIgnoredFiles, setShowRooIgnoredFiles } =
@@ -215,6 +221,16 @@ describe("ExtensionStateContext", () => {
215221
expect(JSON.parse(screen.getByTestId("show-rooignored-files").textContent!)).toBe(true)
216222
})
217223

224+
it("initializes the write delay to the pre-hydration default", () => {
225+
// The initializer itself (not a merge fixture) must carry the shared
226+
// default: a regression that dropped it from createInitialExtensionState
227+
// would otherwise stay hidden because the merge tests supply the key
228+
// manually.
229+
const state = createInitialExtensionState()
230+
231+
expect(state.writeDelayMs).toBe(DEFAULT_WRITE_DELAY_MS)
232+
})
233+
218234
it("initializes shadowed context fields from initialState", () => {
219235
const routerModels = {} as RouterModels
220236
const marketplaceItems: MarketplaceItem[] = [
@@ -410,7 +426,9 @@ describe("mergeExtensionState", () => {
410426
taskHistory: [],
411427
shouldShowAnnouncement: false,
412428
enableCheckpoints: true,
413-
writeDelayMs: 1000,
429+
// Matches the shared DEFAULT_WRITE_DELAY_MS (pre-hydration placeholder
430+
// must not disagree with the extension's own fallback).
431+
writeDelayMs: 0,
414432
mode: "default",
415433
experiments: {} as Record<ExperimentId, boolean>,
416434
customModes: [],
@@ -480,7 +498,9 @@ describe("mergeExtensionState", () => {
480498
taskHistory: [],
481499
shouldShowAnnouncement: false,
482500
enableCheckpoints: true,
483-
writeDelayMs: 1000,
501+
// Matches the shared DEFAULT_WRITE_DELAY_MS (pre-hydration placeholder
502+
// must not disagree with the extension's own fallback).
503+
writeDelayMs: 0,
484504
mode: "default",
485505
experiments: {} as Record<ExperimentId, boolean>,
486506
customModes: [],

0 commit comments

Comments
 (0)