This commit is contained in:
Deleted user 2026-05-27 11:36:17 +08:00 committed by GitHub
commit 49448a945f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 92 additions and 32 deletions

View file

@ -128,10 +128,9 @@ export class ApplyDiffTool extends BaseTool<"apply_diff"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
// Check if file is write-protected
const isWriteProtected = task.rooProtectedController?.isWriteProtected(relPath) || false

View file

@ -173,10 +173,9 @@ export class ApplyPatchTool extends BaseTool<"apply_patch"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
const sanitizedDiff = sanitizeUnifiedDiff(diff || "")
const diffStats = computeDiffStats(sanitizedDiff) || undefined
@ -329,10 +328,9 @@ export class ApplyPatchTool extends BaseTool<"apply_patch"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
const sanitizedDiff = sanitizeUnifiedDiff(diff)
const diffStats = computeDiffStats(sanitizedDiff) || undefined

View file

@ -392,10 +392,9 @@ export class EditFileTool extends BaseTool<"edit_file"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
const sanitizedDiff = sanitizeUnifiedDiff(diff || "")
const diffStats = computeDiffStats(sanitizedDiff) || undefined

View file

@ -167,10 +167,9 @@ export class EditTool extends BaseTool<"edit"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
const sanitizedDiff = sanitizeUnifiedDiff(diff)
const diffStats = computeDiffStats(sanitizedDiff) || undefined

View file

@ -163,10 +163,9 @@ export class SearchReplaceTool extends BaseTool<"search_replace"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
const sanitizedDiff = sanitizeUnifiedDiff(diff)
const diffStats = computeDiffStats(sanitizedDiff) || undefined

View file

@ -103,10 +103,9 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> {
const state = await provider?.getState()
const diagnosticsEnabled = state?.diagnosticsEnabled ?? true
const writeDelayMs = state?.writeDelayMs ?? DEFAULT_WRITE_DELAY_MS
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
if (isPreventFocusDisruptionEnabled) {
task.diffViewProvider.editType = fileExists ? "modify" : "create"
@ -204,10 +203,9 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> {
const provider = task.providerRef.deref()
const state = await provider?.getState()
const isPreventFocusDisruptionEnabled = experiments.isEnabled(
state?.experiments ?? {},
EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION,
)
const isPreventFocusDisruptionEnabled =
experiments.isEnabled(state?.experiments ?? {}, EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION) ||
(state?.autoApprovalEnabled === true && state?.alwaysAllowWrite === true)
if (isPreventFocusDisruptionEnabled) {
return

View file

@ -148,6 +148,11 @@ describe("writeToFileTool", () => {
userEdits: null,
finalContent: "final content",
}),
saveDirectly: vi.fn().mockResolvedValue({
newProblemsMessage: "",
userEdits: null,
finalContent: "final content",
}),
scrollToFirstDiff: vi.fn(),
updateDiagnosticSettings: vi.fn(),
pushToolWriteResult: vi.fn().mockImplementation(async function (
@ -442,6 +447,69 @@ describe("writeToFileTool", () => {
})
})
describe("auto-approve write skips diff view", () => {
it("uses saveDirectly when autoApprovalEnabled and alwaysAllowWrite are both true", async () => {
mockCline.providerRef = {
deref: vi.fn().mockReturnValue({
getState: vi.fn().mockResolvedValue({
diagnosticsEnabled: true,
writeDelayMs: 1000,
autoApprovalEnabled: true,
alwaysAllowWrite: true,
}),
}),
}
await executeWriteFileTool({}, { fileExists: false })
// Should NOT open diff view
expect(mockCline.diffViewProvider.open).not.toHaveBeenCalled()
// Should use saveDirectly instead of saveChanges
expect(mockCline.diffViewProvider.saveDirectly).toHaveBeenCalled()
expect(mockCline.diffViewProvider.saveChanges).not.toHaveBeenCalled()
})
it("uses diff view when autoApprovalEnabled is true but alwaysAllowWrite is false", async () => {
mockCline.providerRef = {
deref: vi.fn().mockReturnValue({
getState: vi.fn().mockResolvedValue({
diagnosticsEnabled: true,
writeDelayMs: 1000,
autoApprovalEnabled: true,
alwaysAllowWrite: false,
}),
}),
}
await executeWriteFileTool({}, { fileExists: false })
// Should open diff view (normal path)
expect(mockCline.diffViewProvider.open).toHaveBeenCalled()
expect(mockCline.diffViewProvider.saveChanges).toHaveBeenCalled()
expect(mockCline.diffViewProvider.saveDirectly).not.toHaveBeenCalled()
})
it("uses diff view when autoApprovalEnabled is false even if alwaysAllowWrite is true", async () => {
mockCline.providerRef = {
deref: vi.fn().mockReturnValue({
getState: vi.fn().mockResolvedValue({
diagnosticsEnabled: true,
writeDelayMs: 1000,
autoApprovalEnabled: false,
alwaysAllowWrite: true,
}),
}),
}
await executeWriteFileTool({}, { fileExists: false })
// Should open diff view (normal path)
expect(mockCline.diffViewProvider.open).toHaveBeenCalled()
expect(mockCline.diffViewProvider.saveChanges).toHaveBeenCalled()
expect(mockCline.diffViewProvider.saveDirectly).not.toHaveBeenCalled()
})
})
describe("error handling", () => {
it("handles general file operation errors", async () => {
mockCline.diffViewProvider.open.mockRejectedValue(new Error("General error"))