Merge pull request #145 from RooVetGit/more_diff_iterations

More diff iterations
This commit is contained in:
Matt Rubens
2024-12-17 08:07:10 -05:00
committed by GitHub
15 changed files with 170 additions and 186 deletions

View File

@@ -1,5 +1,9 @@
# Roo Cline Changelog
## [2.2.14]
- Make diff editing more robust to transient errors
## [2.2.13]
- Fixes to sound playing and applying diffs

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "roo-cline",
"version": "2.2.13",
"version": "2.2.14",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "roo-cline",
"version": "2.2.13",
"version": "2.2.14",
"dependencies": {
"@anthropic-ai/bedrock-sdk": "^0.10.2",
"@anthropic-ai/sdk": "^0.26.0",

View File

@@ -3,7 +3,7 @@
"displayName": "Roo Cline",
"description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.",
"publisher": "RooVeterinaryInc",
"version": "2.2.13",
"version": "2.2.14",
"icon": "assets/icons/rocket.png",
"galleryBanner": {
"color": "#617A91",

View File

@@ -75,6 +75,7 @@ export class Cline {
private askResponseImages?: string[]
private lastMessageTs?: number
private consecutiveMistakeCount: number = 0
private consecutiveMistakeCountForApplyDiff: Map<string, number> = new Map()
private providerRef: WeakRef<ClineProvider>
private abort: boolean = false
didFinishAborting = false
@@ -97,7 +98,6 @@ export class Cline {
apiConfiguration: ApiConfiguration,
customInstructions?: string,
diffEnabled?: boolean,
debugDiffEnabled?: boolean,
task?: string,
images?: string[],
historyItem?: HistoryItem,
@@ -110,7 +110,7 @@ export class Cline {
this.diffViewProvider = new DiffViewProvider(cwd)
this.customInstructions = customInstructions
if (diffEnabled && this.api.getModel().id) {
this.diffStrategy = getDiffStrategy(this.api.getModel().id, debugDiffEnabled)
this.diffStrategy = getDiffStrategy(this.api.getModel().id)
}
if (historyItem) {
this.taskId = historyItem.id
@@ -1230,8 +1230,9 @@ export class Cline {
if (!fileExists) {
this.consecutiveMistakeCount++
await this.say("error", `File does not exist at path: ${absolutePath}`)
pushToolResult(`Error: File does not exist at path: ${absolutePath}`)
const formattedError = `File does not exist at path: ${absolutePath}\n\n<error_details>\nThe specified file could not be found. Please verify the file path and try again.\n</error_details>`
await this.say("error", formattedError)
pushToolResult(formattedError)
break
}
@@ -1249,15 +1250,19 @@ export class Cline {
}
if (!diffResult.success) {
this.consecutiveMistakeCount++
const errorDetails = diffResult.details ? `\n\nDetails:\n${JSON.stringify(diffResult.details, null, 2)}` : ''
await this.say("error", `Unable to apply diff to file: ${absolutePath}\n${diffResult.error}${errorDetails}`)
pushToolResult(`Error applying diff to file: ${absolutePath}\n${diffResult.error}${errorDetails}`)
const currentCount = (this.consecutiveMistakeCountForApplyDiff.get(relPath) || 0) + 1
this.consecutiveMistakeCountForApplyDiff.set(relPath, currentCount)
const errorDetails = diffResult.details ? JSON.stringify(diffResult.details, null, 2) : ''
const formattedError = `Unable to apply diff to file: ${absolutePath}\n\n<error_details>\n${diffResult.error}${errorDetails ? `\n\nDetails:\n${errorDetails}` : ''}\n</error_details>`
if (currentCount >= 2) {
await this.say("error", formattedError)
}
pushToolResult(formattedError)
break
}
const newContent = diffResult.content
this.consecutiveMistakeCount = 0
this.consecutiveMistakeCountForApplyDiff.delete(relPath)
// Show diff view before asking for approval
this.diffViewProvider.editType = "modify"
await this.diffViewProvider.open(relPath);

View File

@@ -279,8 +279,9 @@ describe('Cline', () => {
mockApiConfig,
'custom instructions',
false, // diffEnabled
false, // debugDiffEnabled
'test task'
'test task', // task
undefined, // images
undefined // historyItem
);
expect(cline.customInstructions).toBe('custom instructions');

View File

@@ -6,10 +6,10 @@ import { SearchReplaceDiffStrategy } from './strategies/search-replace'
* @param model The name of the model being used (e.g., 'gpt-4', 'claude-3-opus')
* @returns The appropriate diff strategy for the model
*/
export function getDiffStrategy(model: string, debugEnabled?: boolean): DiffStrategy {
export function getDiffStrategy(model: string): DiffStrategy {
// For now, return SearchReplaceDiffStrategy for all models (with a fuzzy threshold of 0.9)
// This architecture allows for future optimizations based on model capabilities
return new SearchReplaceDiffStrategy(0.9, debugEnabled)
return new SearchReplaceDiffStrategy(0.9)
}
export type { DiffStrategy }

View File

@@ -5,7 +5,7 @@ describe('SearchReplaceDiffStrategy', () => {
let strategy: SearchReplaceDiffStrategy
beforeEach(() => {
strategy = new SearchReplaceDiffStrategy() // Default 1.0 threshold for exact matching
strategy = new SearchReplaceDiffStrategy(1.0, 5) // Default 1.0 threshold for exact matching, 5 line buffer for tests
})
it('should replace matching content', () => {
@@ -562,6 +562,63 @@ this.init();
}`);
}
});
it('should find matches from middle out', () => {
const originalContent = `
function one() {
return "target";
}
function two() {
return "target";
}
function three() {
return "target";
}
function four() {
return "target";
}
function five() {
return "target";
}`.trim()
const diffContent = `test.ts
<<<<<<< SEARCH
return "target";
=======
return "updated";
>>>>>>> REPLACE`
// Search around the middle (function three)
// Even though all functions contain the target text,
// it should match the one closest to line 9 first
const result = strategy.applyDiff(originalContent, diffContent, 9, 9)
expect(result.success).toBe(true)
if (result.success) {
expect(result.content).toBe(`function one() {
return "target";
}
function two() {
return "target";
}
function three() {
return "updated";
}
function four() {
return "target";
}
function five() {
return "target";
}`)
}
})
})
describe('line number stripping', () => {
@@ -915,7 +972,7 @@ function test() {
}
})
it('should insert at the start of the file if no start_line is provided for insertion', () => {
it('should error if no start_line is provided for insertion', () => {
const originalContent = `function test() {
return true;
}`
@@ -926,22 +983,15 @@ console.log("test");
>>>>>>> REPLACE`
const result = strategy.applyDiff(originalContent, diffContent)
expect(result.success).toBe(true)
if (result.success) {
expect(result.content).toBe(`console.log("test");
function test() {
return true;
}`)
}
expect(result.success).toBe(false)
})
})
})
describe('fuzzy matching', () => {
let strategy: SearchReplaceDiffStrategy
beforeEach(() => {
strategy = new SearchReplaceDiffStrategy(0.9) // 90% similarity threshold
strategy = new SearchReplaceDiffStrategy(0.9, 5) // 90% similarity threshold, 5 line buffer for tests
})
it('should match content with small differences (>90% similar)', () => {
@@ -959,6 +1009,8 @@ function getData() {
}
>>>>>>> REPLACE`
strategy = new SearchReplaceDiffStrategy(0.9, 5) // Use 5 line buffer for tests
const result = strategy.applyDiff(originalContent, diffContent)
expect(result.success).toBe(true)
if (result.success) {
@@ -1008,7 +1060,7 @@ function sum(a, b) {
let strategy: SearchReplaceDiffStrategy
beforeEach(() => {
strategy = new SearchReplaceDiffStrategy()
strategy = new SearchReplaceDiffStrategy(0.9, 5)
})
it('should find and replace within specified line range', () => {
@@ -1467,8 +1519,8 @@ function two() {
it('should document start_line and end_line parameters', () => {
const description = strategy.getToolDescription('/test')
expect(description).toContain('start_line: (required) The line number where the search block starts (inclusive).')
expect(description).toContain('end_line: (required) The line number where the search block ends (inclusive).')
expect(description).toContain('start_line: (required) The line number where the search block starts.')
expect(description).toContain('end_line: (required) The line number where the search block ends.')
})
})
})

View File

@@ -1,7 +1,7 @@
import { DiffStrategy, DiffResult } from "../types"
import { addLineNumbers } from "../../../integrations/misc/extract-text"
const BUFFER_LINES = 5; // Number of extra context lines to show before and after matches
const BUFFER_LINES = 20; // Number of extra context lines to show before and after matches
function levenshteinDistance(a: string, b: string): number {
const matrix: number[][] = [];
@@ -55,12 +55,12 @@ function getSimilarity(original: string, search: string): number {
export class SearchReplaceDiffStrategy implements DiffStrategy {
private fuzzyThreshold: number;
public debugEnabled: boolean;
private bufferLines: number;
constructor(fuzzyThreshold?: number, debugEnabled?: boolean) {
constructor(fuzzyThreshold?: number, bufferLines?: number) {
// Default to exact matching (1.0) unless fuzzy threshold specified
this.fuzzyThreshold = fuzzyThreshold ?? 1.0;
this.debugEnabled = debugEnabled ?? false;
this.bufferLines = bufferLines ?? BUFFER_LINES;
}
getToolDescription(cwd: string): string {
@@ -75,8 +75,8 @@ If you're not confident in the exact content to search for, use the read_file to
Parameters:
- path: (required) The path of the file to modify (relative to the current working directory ${cwd})
- diff: (required) The search/replace block defining the changes.
- start_line: (required) The line number where the search block starts (inclusive).
- end_line: (required) The line number where the search block ends (inclusive).
- start_line: (required) The line number where the search block starts.
- end_line: (required) The line number where the search block ends.
Diff format:
\`\`\`
@@ -98,90 +98,39 @@ Original file:
5 | return total
\`\`\`
1. Search/replace a specific chunk of code:
Search/Replace content:
\`\`\`
<apply_diff>
<path>File path here</path>
<diff>
<<<<<<< SEARCH
def calculate_total(items):
total = 0
for item in items:
total += item
return total
=======
def calculate_total(items):
"""Calculate total with 10% markup"""
return sum(item * 1.1 for item in items)
>>>>>>> REPLACE
</diff>
<start_line>2</start_line>
<end_line>5</end_line>
</apply_diff>
\`\`\`
Result:
\`\`\`
1 | def calculate_total(items):
2 | """Calculate total with 10% markup"""
3 | return sum(item * 1.1 for item in items)
\`\`\`
2. Insert code at a specific line (start_line and end_line must be the same, and the content gets inserted before whatever is currently at that line):
\`\`\`
Usage:
<apply_diff>
<path>File path here</path>
<diff>
<<<<<<< SEARCH
=======
"""TODO: Write a test for this"""
>>>>>>> REPLACE
Your search/replace content here
</diff>
<start_line>2</start_line>
<end_line>2</end_line>
</apply_diff>
\`\`\`
Result:
\`\`\`
1 | def calculate_total(items):
2 | """TODO: Write a test for this"""
3 | """Calculate total with 10% markup"""
4 | return sum(item * 1.1 for item in items)
\`\`\`
3. Delete code at a specific line range:
\`\`\`
<apply_diff>
<path>File path here</path>
<diff>
<<<<<<< SEARCH
total = 0
for item in items:
total += item
return total
=======
>>>>>>> REPLACE
</diff>
<start_line>2</start_line>
<start_line>1</start_line>
<end_line>5</end_line>
</apply_diff>
\`\`\`
Result:
\`\`\`
1 | def calculate_total(items):
\`\`\`
`
</apply_diff>`
}
applyDiff(originalContent: string, diffContent: string, startLine?: number, endLine?: number): DiffResult {
// Extract the search and replace blocks
const match = diffContent.match(/<<<<<<< SEARCH\n([\s\S]*?)\n?=======\n([\s\S]*?)\n?>>>>>>> REPLACE/);
if (!match) {
const debugInfo = this.debugEnabled ? `\n\nDebug Info:\n- Expected Format: <<<<<<< SEARCH\\n[search content]\\n=======\\n[replace content]\\n>>>>>>> REPLACE\n- Tip: Make sure to include both SEARCH and REPLACE sections with correct markers` : '';
return {
success: false,
error: `Invalid diff format - missing required SEARCH/REPLACE sections${debugInfo}`
error: `Invalid diff format - missing required SEARCH/REPLACE sections\n\nDebug Info:\n- Expected Format: <<<<<<< SEARCH\\n[search content]\\n=======\\n[replace content]\\n>>>>>>> REPLACE\n- Tip: Make sure to include both SEARCH and REPLACE sections with correct markers`
};
}
@@ -210,69 +159,89 @@ Result:
const replaceLines = replaceContent === '' ? [] : replaceContent.split(/\r?\n/);
const originalLines = originalContent.split(/\r?\n/);
// First try exact line range if provided
// Validate that empty search requires start line
if (searchLines.length === 0 && !startLine) {
return {
success: false,
error: `Empty search content requires start_line to be specified\n\nDebug Info:\n- Empty search content is only valid for insertions at a specific line\n- For insertions, specify the line number where content should be inserted`
};
}
// Validate that empty search requires same start and end line
if (searchLines.length === 0 && startLine && endLine && startLine !== endLine) {
return {
success: false,
error: `Empty search content requires start_line and end_line to be the same (got ${startLine}-${endLine})\n\nDebug Info:\n- Empty search content is only valid for insertions at a specific line\n- For insertions, use the same line number for both start_line and end_line`
};
}
// Initialize search variables
let matchIndex = -1;
let bestMatchScore = 0;
let bestMatchContent = "";
const searchChunk = searchLines.join('\n');
// Determine search bounds
let searchStartIndex = 0;
let searchEndIndex = originalLines.length;
// Validate and handle line range if provided
if (startLine && endLine) {
// Convert to 0-based index
const exactStartIndex = startLine - 1;
const exactEndIndex = endLine - 1;
if (exactStartIndex < 0 || exactEndIndex > originalLines.length || exactStartIndex > exactEndIndex) {
const debugInfo = this.debugEnabled ? `\n\nDebug Info:\n- Requested Range: lines ${startLine}-${endLine}\n- File Bounds: lines 1-${originalLines.length}` : '';
// Log detailed debug information
console.log('Invalid Line Range Debug:', {
requestedRange: { start: startLine, end: endLine },
fileBounds: { start: 1, end: originalLines.length }
});
return {
success: false,
error: `Line range ${startLine}-${endLine} is invalid (file has ${originalLines.length} lines)${debugInfo}`,
error: `Line range ${startLine}-${endLine} is invalid (file has ${originalLines.length} lines)\n\nDebug Info:\n- Requested Range: lines ${startLine}-${endLine}\n- File Bounds: lines 1-${originalLines.length}`,
};
}
// Check exact range first
// Try exact match first
const originalChunk = originalLines.slice(exactStartIndex, exactEndIndex + 1).join('\n');
const searchChunk = searchLines.join('\n');
const similarity = getSimilarity(originalChunk, searchChunk);
if (similarity >= this.fuzzyThreshold) {
matchIndex = exactStartIndex;
bestMatchScore = similarity;
bestMatchContent = originalChunk;
} else {
// Set bounds for buffered search
searchStartIndex = Math.max(0, startLine - (this.bufferLines + 1));
searchEndIndex = Math.min(originalLines.length, endLine + this.bufferLines);
}
}
// If no match found in exact range, try expanded range
// If no match found yet, try middle-out search within bounds
if (matchIndex === -1) {
let searchStartIndex = 0;
let searchEndIndex = originalLines.length;
const midPoint = Math.floor((searchStartIndex + searchEndIndex) / 2);
let leftIndex = midPoint;
let rightIndex = midPoint + 1;
if (startLine || endLine) {
// Convert to 0-based index and add buffer
if (startLine) {
searchStartIndex = Math.max(0, startLine - (BUFFER_LINES + 1));
// Search outward from the middle within bounds
while (leftIndex >= searchStartIndex || rightIndex <= searchEndIndex - searchLines.length) {
// Check left side if still in range
if (leftIndex >= searchStartIndex) {
const originalChunk = originalLines.slice(leftIndex, leftIndex + searchLines.length).join('\n');
const similarity = getSimilarity(originalChunk, searchChunk);
if (similarity > bestMatchScore) {
bestMatchScore = similarity;
matchIndex = leftIndex;
bestMatchContent = originalChunk;
}
leftIndex--;
}
if (endLine) {
searchEndIndex = Math.min(originalLines.length, endLine + BUFFER_LINES);
}
}
// Find the search content in the expanded range using fuzzy matching
for (let i = searchStartIndex; i <= searchEndIndex - searchLines.length; i++) {
// Join the lines and calculate overall similarity
const originalChunk = originalLines.slice(i, i + searchLines.length).join('\n');
const searchChunk = searchLines.join('\n');
const similarity = getSimilarity(originalChunk, searchChunk);
if (similarity > bestMatchScore) {
bestMatchScore = similarity;
matchIndex = i;
bestMatchContent = originalChunk;
// Check right side if still in range
if (rightIndex <= searchEndIndex - searchLines.length) {
const originalChunk = originalLines.slice(rightIndex, rightIndex + searchLines.length).join('\n');
const similarity = getSimilarity(originalChunk, searchChunk);
if (similarity > bestMatchScore) {
bestMatchScore = similarity;
matchIndex = rightIndex;
bestMatchContent = originalChunk;
}
rightIndex++;
}
}
}
@@ -283,10 +252,10 @@ Result:
const originalContentSection = startLine !== undefined && endLine !== undefined
? `\n\nOriginal Content:\n${addLineNumbers(
originalLines.slice(
Math.max(0, startLine - 1 - BUFFER_LINES),
Math.min(originalLines.length, endLine + BUFFER_LINES)
Math.max(0, startLine - 1 - this.bufferLines),
Math.min(originalLines.length, endLine + this.bufferLines)
).join('\n'),
Math.max(1, startLine - BUFFER_LINES)
Math.max(1, startLine - this.bufferLines)
)}`
: `\n\nOriginal Content:\n${addLineNumbers(originalLines.join('\n'))}`;
@@ -294,13 +263,11 @@ Result:
? `\n\nBest Match Found:\n${addLineNumbers(bestMatchContent, matchIndex + 1)}`
: `\n\nBest Match Found:\n(no match)`;
const debugInfo = this.debugEnabled ? `\n\nDebug Info:\n- Similarity Score: ${Math.floor(bestMatchScore * 100)}%\n- Required Threshold: ${Math.floor(this.fuzzyThreshold * 100)}%\n- Search Range: ${startLine && endLine ? `lines ${startLine}-${endLine}` : 'start to end'}\n\nSearch Content:\n${searchChunk}${bestMatchSection}${originalContentSection}` : '';
const lineRange = startLine || endLine ?
` at ${startLine ? `start: ${startLine}` : 'start'} to ${endLine ? `end: ${endLine}` : 'end'}` : '';
return {
success: false,
error: `No sufficiently similar match found${lineRange} (${Math.floor(bestMatchScore * 100)}% similar, needs ${Math.floor(this.fuzzyThreshold * 100)}%)${debugInfo}`
error: `No sufficiently similar match found${lineRange} (${Math.floor(bestMatchScore * 100)}% similar, needs ${Math.floor(this.fuzzyThreshold * 100)}%)\n\nDebug Info:\n- Similarity Score: ${Math.floor(bestMatchScore * 100)}%\n- Required Threshold: ${Math.floor(this.fuzzyThreshold * 100)}%\n- Search Range: ${startLine && endLine ? `lines ${startLine}-${endLine}` : 'start to end'}\n\nSearch Content:\n${searchChunk}${bestMatchSection}${originalContentSection}`
};
}

View File

@@ -13,11 +13,6 @@ export type DiffResult =
}};
export interface DiffStrategy {
/**
* Whether to enable detailed debug logging
*/
debugEnabled?: boolean;
/**
* Get the tool description for this diff strategy
* @param cwd The current working directory

View File

@@ -61,7 +61,7 @@ Usage:
Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file.
Parameters:
- path: (required) The path of the file to write to (relative to the current working directory ${cwd.toPosix()})
- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.
- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file.
Usage:
<write_to_file>
<path>File path here</path>

View File

@@ -68,7 +68,6 @@ type GlobalStateKey =
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
| "debugDiffEnabled"
| "alwaysAllowMcp"
export const GlobalFileNames = {
@@ -217,8 +216,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
const {
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
diffEnabled
} = await this.getState()
this.cline = new Cline(
@@ -226,7 +224,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
task,
images
)
@@ -237,8 +234,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
const {
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
diffEnabled
} = await this.getState()
this.cline = new Cline(
@@ -246,10 +242,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
undefined,
undefined,
historyItem,
historyItem
)
}
@@ -614,11 +609,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("diffEnabled", diffEnabled)
await this.postStateToWebview()
break
case "debugDiffEnabled":
const debugDiffEnabled = message.bool ?? false
await this.updateGlobalState("debugDiffEnabled", debugDiffEnabled)
await this.postStateToWebview()
break
}
},
null,
@@ -945,7 +935,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
alwaysAllowMcp,
soundEnabled,
diffEnabled,
debugDiffEnabled,
taskHistory,
soundVolume,
} = await this.getState()
@@ -970,7 +959,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
.sort((a, b) => b.ts - a.ts),
soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? false,
debugDiffEnabled: debugDiffEnabled ?? false,
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
allowedCommands,
soundVolume: soundVolume ?? 0.5,
@@ -1066,7 +1054,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands,
soundEnabled,
diffEnabled,
debugDiffEnabled,
soundVolume,
] = await Promise.all([
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
@@ -1105,7 +1092,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("allowedCommands") as Promise<string[] | undefined>,
this.getGlobalState("soundEnabled") as Promise<boolean | undefined>,
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
this.getGlobalState("debugDiffEnabled") as Promise<boolean | undefined>,
this.getGlobalState("soundVolume") as Promise<number | undefined>,
])
@@ -1162,7 +1148,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands,
soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? false,
debugDiffEnabled: debugDiffEnabled ?? false,
soundVolume,
}
}

View File

@@ -53,7 +53,6 @@ export interface ExtensionState {
soundEnabled?: boolean
soundVolume?: number
diffEnabled?: boolean
debugDiffEnabled?: boolean
}
export interface ClineMessage {

View File

@@ -34,7 +34,6 @@ export interface WebviewMessage {
| "soundEnabled"
| "soundVolume"
| "diffEnabled"
| "debugDiffEnabled"
| "openMcpSettings"
| "restartMcpServer"
| "toggleToolAlwaysAllow"

View File

@@ -33,8 +33,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
setSoundVolume,
diffEnabled,
setDiffEnabled,
debugDiffEnabled,
setDebugDiffEnabled,
openRouterModels,
setAllowedCommands,
allowedCommands,
@@ -64,7 +62,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
vscode.postMessage({ type: "soundVolume", value: soundVolume })
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
vscode.postMessage({ type: "debugDiffEnabled", bool: debugDiffEnabled })
onDone()
}
}
@@ -358,20 +355,6 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
</div>
)}
</div>
<div style={{ marginBottom: 5 }}>
<VSCodeCheckbox checked={debugDiffEnabled} onChange={(e: any) => setDebugDiffEnabled(e.target.checked)}>
<span style={{ fontWeight: "500" }}>Debug diff operations</span>
</VSCodeCheckbox>
<p
style={{
fontSize: "12px",
marginTop: "5px",
color: "var(--vscode-descriptionForeground)",
}}>
When enabled, Cline will show detailed debug information when applying diffs fails.
</p>
</div>
</div>
{IS_DEV && (

View File

@@ -31,7 +31,6 @@ export interface ExtensionStateContextType extends ExtensionState {
setSoundEnabled: (value: boolean) => void
setSoundVolume: (value: number) => void
setDiffEnabled: (value: boolean) => void
setDebugDiffEnabled: (value: boolean) => void
}
const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
@@ -46,7 +45,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
soundEnabled: false,
soundVolume: 0.5,
diffEnabled: false,
debugDiffEnabled: false,
})
const [didHydrateState, setDidHydrateState] = useState(false)
const [showWelcome, setShowWelcome] = useState(false)
@@ -149,10 +147,6 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
setSoundVolume: (value) => setState((prevState) => ({ ...prevState, soundVolume: value })),
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
setDebugDiffEnabled: (value) => setState((prevState) => ({
...prevState,
debugDiffEnabled: value
})),
}
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>