Add configurable delay after auto-writes to allow diagnostics to catch up

This commit is contained in:
Matt Rubens
2024-12-26 09:46:50 -08:00
parent 6126cdf254
commit 03707d5dcc
9 changed files with 91 additions and 6 deletions

View File

@@ -72,6 +72,7 @@ type GlobalStateKey =
| "browserLargeViewport"
| "fuzzyMatchThreshold"
| "preferredLanguage" // Language setting for Cline's communication
| "writeDelayMs"
export const GlobalFileNames = {
apiConversationHistory: "api_conversation_history.json",
@@ -627,6 +628,10 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("preferredLanguage", message.text)
await this.postStateToWebview()
break
case "writeDelayMs":
await this.updateGlobalState("writeDelayMs", message.value)
await this.postStateToWebview()
break
}
},
null,
@@ -957,6 +962,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
soundVolume,
browserLargeViewport,
preferredLanguage,
writeDelayMs,
} = await this.getState()
const allowedCommands = vscode.workspace
@@ -984,6 +990,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
soundVolume: soundVolume ?? 0.5,
browserLargeViewport: browserLargeViewport ?? false,
preferredLanguage: preferredLanguage ?? 'English',
writeDelayMs: writeDelayMs ?? 1000,
}
}
@@ -1080,6 +1087,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
browserLargeViewport,
fuzzyMatchThreshold,
preferredLanguage,
writeDelayMs,
] = await Promise.all([
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
this.getGlobalState("apiModelId") as Promise<string | undefined>,
@@ -1121,6 +1129,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("browserLargeViewport") as Promise<boolean | undefined>,
this.getGlobalState("fuzzyMatchThreshold") as Promise<number | undefined>,
this.getGlobalState("preferredLanguage") as Promise<string | undefined>,
this.getGlobalState("writeDelayMs") as Promise<number | undefined>,
])
let apiProvider: ApiProvider
@@ -1179,6 +1188,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
soundVolume,
browserLargeViewport: browserLargeViewport ?? false,
fuzzyMatchThreshold: fuzzyMatchThreshold ?? 1.0,
writeDelayMs: writeDelayMs ?? 1000,
preferredLanguage: preferredLanguage ?? (() => {
// Get VSCode's locale setting
const vscodeLang = vscode.env.language;

View File

@@ -248,9 +248,13 @@ describe('ClineProvider', () => {
alwaysAllowWrite: false,
alwaysAllowExecute: false,
alwaysAllowBrowser: false,
alwaysAllowMcp: false,
uriScheme: 'vscode',
soundEnabled: false,
diffEnabled: false,
writeDelayMs: 1000,
browserLargeViewport: false,
fuzzyMatchThreshold: 1.0,
}
const message: ExtensionMessage = {
@@ -300,6 +304,7 @@ describe('ClineProvider', () => {
expect(state).toHaveProperty('taskHistory')
expect(state).toHaveProperty('soundEnabled')
expect(state).toHaveProperty('diffEnabled')
expect(state).toHaveProperty('writeDelayMs')
})
test('preferredLanguage defaults to VSCode language when not set', async () => {
@@ -308,7 +313,7 @@ describe('ClineProvider', () => {
const state = await provider.getState();
expect(state.preferredLanguage).toBe('Spanish');
});
})
test('preferredLanguage defaults to English for unsupported VSCode language', async () => {
// Mock VSCode language as an unsupported language
@@ -316,7 +321,7 @@ describe('ClineProvider', () => {
const state = await provider.getState();
expect(state.preferredLanguage).toBe('English');
});
})
test('diffEnabled defaults to true when not set', async () => {
// Mock globalState.get to return undefined for diffEnabled
@@ -327,6 +332,29 @@ describe('ClineProvider', () => {
expect(state.diffEnabled).toBe(true)
})
test('writeDelayMs defaults to 1000ms', async () => {
// Mock globalState.get to return undefined for writeDelayMs
(mockContext.globalState.get as jest.Mock).mockImplementation((key: string) => {
if (key === 'writeDelayMs') {
return undefined
}
return null
})
const state = await provider.getState()
expect(state.writeDelayMs).toBe(1000)
})
test('handles writeDelayMs message', async () => {
provider.resolveWebviewView(mockWebviewView)
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as jest.Mock).mock.calls[0][0]
await messageHandler({ type: 'writeDelayMs', value: 2000 })
expect(mockContext.globalState.update).toHaveBeenCalledWith('writeDelayMs', 2000)
expect(mockPostMessage).toHaveBeenCalled()
})
test('updates sound utility when sound setting changes', async () => {
provider.resolveWebviewView(mockWebviewView)