Merge pull request #132 from RooVetGit/debug_diff_enabled

Debug diff enabled
This commit is contained in:
Matt Rubens
2024-12-16 13:44:28 -05:00
committed by GitHub
16 changed files with 169 additions and 69 deletions

View File

@@ -1,5 +1,9 @@
# Roo Cline Changelog # Roo Cline Changelog
## [2.2.11]
- Added settings checkbox for verbose diff debugging
## [2.2.6 - 2.2.10] ## [2.2.6 - 2.2.10]
- More fixes to search/replace diffs - More fixes to search/replace diffs

4
package-lock.json generated
View File

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

View File

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

View File

@@ -97,6 +97,7 @@ export class Cline {
apiConfiguration: ApiConfiguration, apiConfiguration: ApiConfiguration,
customInstructions?: string, customInstructions?: string,
diffEnabled?: boolean, diffEnabled?: boolean,
debugDiffEnabled?: boolean,
task?: string, task?: string,
images?: string[], images?: string[],
historyItem?: HistoryItem, historyItem?: HistoryItem,
@@ -109,7 +110,7 @@ export class Cline {
this.diffViewProvider = new DiffViewProvider(cwd) this.diffViewProvider = new DiffViewProvider(cwd)
this.customInstructions = customInstructions this.customInstructions = customInstructions
if (diffEnabled && this.api.getModel().id) { if (diffEnabled && this.api.getModel().id) {
this.diffStrategy = getDiffStrategy(this.api.getModel().id) this.diffStrategy = getDiffStrategy(this.api.getModel().id, debugDiffEnabled)
} }
if (historyItem) { if (historyItem) {
this.taskId = historyItem.id this.taskId = historyItem.id
@@ -1237,7 +1238,12 @@ export class Cline {
const originalContent = await fs.readFile(absolutePath, "utf-8") const originalContent = await fs.readFile(absolutePath, "utf-8")
// Apply the diff to the original content // Apply the diff to the original content
const diffResult = this.diffStrategy?.applyDiff(originalContent, diffContent) ?? { const diffResult = this.diffStrategy?.applyDiff(
originalContent,
diffContent,
parseInt(block.params.start_line ?? ''),
parseInt(block.params.end_line ?? '')
) ?? {
success: false, success: false,
error: "No diff strategy available" error: "No diff strategy available"
} }

View File

@@ -278,7 +278,8 @@ describe('Cline', () => {
mockProvider, mockProvider,
mockApiConfig, mockApiConfig,
'custom instructions', 'custom instructions',
false, false, // diffEnabled
false, // debugDiffEnabled
'test task' 'test task'
); );

View File

@@ -44,6 +44,8 @@ export const toolParamNames = [
"question", "question",
"result", "result",
"diff", "diff",
"start_line",
"end_line",
] as const ] as const
export type ToolParamName = (typeof toolParamNames)[number] export type ToolParamName = (typeof toolParamNames)[number]

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

View File

@@ -1,4 +1,7 @@
import { DiffStrategy, DiffResult } from "../types" 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
function levenshteinDistance(a: string, b: string): number { function levenshteinDistance(a: string, b: string): number {
const matrix: number[][] = []; const matrix: number[][] = [];
@@ -48,10 +51,12 @@ function getSimilarity(original: string, search: string): number {
export class SearchReplaceDiffStrategy implements DiffStrategy { export class SearchReplaceDiffStrategy implements DiffStrategy {
private fuzzyThreshold: number; private fuzzyThreshold: number;
public debugEnabled: boolean;
constructor(fuzzyThreshold?: number) { constructor(fuzzyThreshold?: number, debugEnabled?: boolean) {
// Default to exact matching (1.0) unless fuzzy threshold specified // Default to exact matching (1.0) unless fuzzy threshold specified
this.fuzzyThreshold = fuzzyThreshold ?? 1.0; this.fuzzyThreshold = fuzzyThreshold ?? 1.0;
this.debugEnabled = debugEnabled ?? false;
} }
getToolDescription(cwd: string): string { getToolDescription(cwd: string): string {
@@ -119,15 +124,11 @@ Your search/replace content here
// Extract the search and replace blocks // Extract the search and replace blocks
const match = diffContent.match(/<<<<<<< SEARCH\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> REPLACE/); const match = diffContent.match(/<<<<<<< SEARCH\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> REPLACE/);
if (!match) { if (!match) {
// Log detailed format information 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` : '';
console.log('Invalid Diff Format Debug:', {
expectedFormat: "<<<<<<< SEARCH\\n[search content]\\n=======\\n[replace content]\\n>>>>>>> REPLACE",
tip: "Make sure to include both SEARCH and REPLACE sections with correct markers"
});
return { return {
success: false, success: false,
error: "Invalid diff format - missing required SEARCH/REPLACE sections" error: `Invalid diff format - missing required SEARCH/REPLACE sections${debugInfo}`
}; };
} }
@@ -161,21 +162,17 @@ Your search/replace content here
let bestMatchScore = 0; let bestMatchScore = 0;
let bestMatchContent = ""; let bestMatchContent = "";
if (startLine !== undefined && endLine !== undefined) { if (startLine && endLine) {
// Convert to 0-based index // Convert to 0-based index
const exactStartIndex = startLine - 1; const exactStartIndex = startLine - 1;
const exactEndIndex = endLine - 1; const exactEndIndex = endLine - 1;
if (exactStartIndex < 0 || exactEndIndex >= originalLines.length) { if (exactStartIndex < 0 || exactEndIndex >= originalLines.length || exactStartIndex > exactEndIndex) {
// Log detailed debug information const debugInfo = this.debugEnabled ? `\n\nDebug Info:\n- Requested Range: lines ${startLine}-${endLine}\n- File Bounds: lines 1-${originalLines.length}` : '';
console.log('Invalid Line Range Debug:', {
requestedRange: { start: startLine, end: endLine },
fileBounds: { start: 1, end: originalLines.length }
});
return { return {
success: false, success: false,
error: `Line range ${startLine}-${endLine} is invalid (file has ${originalLines.length} lines)`, error: `Line range ${startLine}-${endLine} is invalid (file has ${originalLines.length} lines)${debugInfo}`,
}; };
} }
@@ -196,13 +193,13 @@ Your search/replace content here
let searchStartIndex = 0; let searchStartIndex = 0;
let searchEndIndex = originalLines.length; let searchEndIndex = originalLines.length;
if (startLine !== undefined || endLine !== undefined) { if (startLine || endLine) {
// Convert to 0-based index and add buffer // Convert to 0-based index and add buffer
if (startLine !== undefined) { if (startLine) {
searchStartIndex = Math.max(0, startLine - 6); searchStartIndex = Math.max(0, startLine - (BUFFER_LINES + 1));
} }
if (endLine !== undefined) { if (endLine) {
searchEndIndex = Math.min(originalLines.length, endLine + 5); searchEndIndex = Math.min(originalLines.length, endLine + BUFFER_LINES);
} }
} }
@@ -224,17 +221,27 @@ Your search/replace content here
// Require similarity to meet threshold // Require similarity to meet threshold
if (matchIndex === -1 || bestMatchScore < this.fuzzyThreshold) { if (matchIndex === -1 || bestMatchScore < this.fuzzyThreshold) {
const searchChunk = searchLines.join('\n'); const searchChunk = searchLines.join('\n');
// Log detailed debug information to console const originalContentSection = startLine !== undefined && endLine !== undefined
console.log('Search/Replace Debug Info:', { ? `\n\nOriginal Content:\n${addLineNumbers(
similarity: bestMatchScore, originalLines.slice(
threshold: this.fuzzyThreshold, Math.max(0, startLine - 1 - BUFFER_LINES),
searchContent: searchChunk, Math.min(originalLines.length, endLine + BUFFER_LINES)
bestMatch: bestMatchContent || undefined ).join('\n'),
}); Math.max(1, startLine - BUFFER_LINES)
)}`
: `\n\nOriginal Content:\n${addLineNumbers(originalLines.join('\n'))}`;
const bestMatchSection = bestMatchContent
? `\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 { return {
success: false, success: false,
error: `No sufficiently similar match found${startLine !== undefined ? ` near lines ${startLine}-${endLine}` : ''} (${Math.round(bestMatchScore * 100)}% similar, needs ${Math.round(this.fuzzyThreshold * 100)}%)` error: `No sufficiently similar match found${lineRange} (${Math.floor(bestMatchScore * 100)}% similar, needs ${Math.floor(this.fuzzyThreshold * 100)}%)${debugInfo}`
}; };
} }

View File

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

View File

@@ -67,6 +67,7 @@ type GlobalStateKey =
| "allowedCommands" | "allowedCommands"
| "soundEnabled" | "soundEnabled"
| "diffEnabled" | "diffEnabled"
| "debugDiffEnabled"
| "alwaysAllowMcp" | "alwaysAllowMcp"
export const GlobalFileNames = { export const GlobalFileNames = {
@@ -207,28 +208,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
async initClineWithTask(task?: string, images?: string[]) { async initClineWithTask(task?: string, images?: string[]) {
await this.clearTask() await this.clearTask()
const { const {
apiConfiguration, apiConfiguration,
customInstructions, customInstructions,
diffEnabled,
} = await this.getState()
this.cline = new Cline(
this,
apiConfiguration,
customInstructions,
diffEnabled,
task,
images
)
}
async initClineWithHistoryItem(historyItem: HistoryItem) {
await this.clearTask()
const {
apiConfiguration,
customInstructions,
diffEnabled, diffEnabled,
debugDiffEnabled,
} = await this.getState() } = await this.getState()
this.cline = new Cline( this.cline = new Cline(
@@ -236,6 +220,27 @@ export class ClineProvider implements vscode.WebviewViewProvider {
apiConfiguration, apiConfiguration,
customInstructions, customInstructions,
diffEnabled, diffEnabled,
debugDiffEnabled,
task,
images
)
}
async initClineWithHistoryItem(historyItem: HistoryItem) {
await this.clearTask()
const {
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
} = await this.getState()
this.cline = new Cline(
this,
apiConfiguration,
customInstructions,
diffEnabled,
debugDiffEnabled,
undefined, undefined,
undefined, undefined,
historyItem, historyItem,
@@ -597,6 +602,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.updateGlobalState("diffEnabled", diffEnabled) await this.updateGlobalState("diffEnabled", diffEnabled)
await this.postStateToWebview() await this.postStateToWebview()
break break
case "debugDiffEnabled":
const debugDiffEnabled = message.bool ?? false
await this.updateGlobalState("debugDiffEnabled", debugDiffEnabled)
await this.postStateToWebview()
break
} }
}, },
null, null,
@@ -923,6 +933,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
alwaysAllowMcp, alwaysAllowMcp,
soundEnabled, soundEnabled,
diffEnabled, diffEnabled,
debugDiffEnabled,
taskHistory, taskHistory,
} = await this.getState() } = await this.getState()
@@ -946,6 +957,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
.sort((a, b) => b.ts - a.ts), .sort((a, b) => b.ts - a.ts),
soundEnabled: soundEnabled ?? false, soundEnabled: soundEnabled ?? false,
diffEnabled: diffEnabled ?? false, diffEnabled: diffEnabled ?? false,
debugDiffEnabled: debugDiffEnabled ?? false,
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId, shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
allowedCommands, allowedCommands,
} }
@@ -1040,6 +1052,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
allowedCommands, allowedCommands,
soundEnabled, soundEnabled,
diffEnabled, diffEnabled,
debugDiffEnabled,
] = await Promise.all([ ] = await Promise.all([
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>, this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
this.getGlobalState("apiModelId") as Promise<string | undefined>, this.getGlobalState("apiModelId") as Promise<string | undefined>,
@@ -1077,6 +1090,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
this.getGlobalState("allowedCommands") as Promise<string[] | undefined>, this.getGlobalState("allowedCommands") as Promise<string[] | undefined>,
this.getGlobalState("soundEnabled") as Promise<boolean | undefined>, this.getGlobalState("soundEnabled") as Promise<boolean | undefined>,
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>, this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
this.getGlobalState("debugDiffEnabled") as Promise<boolean | undefined>,
]) ])
let apiProvider: ApiProvider let apiProvider: ApiProvider
@@ -1130,8 +1144,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
alwaysAllowMcp: alwaysAllowMcp ?? false, alwaysAllowMcp: alwaysAllowMcp ?? false,
taskHistory, taskHistory,
allowedCommands, allowedCommands,
soundEnabled, soundEnabled: soundEnabled ?? false,
diffEnabled, diffEnabled: diffEnabled ?? false,
debugDiffEnabled: debugDiffEnabled ?? false,
} }
} }

View File

@@ -0,0 +1,32 @@
import { addLineNumbers } from '../extract-text';
describe('addLineNumbers', () => {
it('should add line numbers starting from 1 by default', () => {
const input = 'line 1\nline 2\nline 3';
const expected = '1 | line 1\n2 | line 2\n3 | line 3';
expect(addLineNumbers(input)).toBe(expected);
});
it('should add line numbers starting from specified line number', () => {
const input = 'line 1\nline 2\nline 3';
const expected = '10 | line 1\n11 | line 2\n12 | line 3';
expect(addLineNumbers(input, 10)).toBe(expected);
});
it('should handle empty content', () => {
expect(addLineNumbers('')).toBe('1 | ');
expect(addLineNumbers('', 5)).toBe('5 | ');
});
it('should handle single line content', () => {
expect(addLineNumbers('single line')).toBe('1 | single line');
expect(addLineNumbers('single line', 42)).toBe('42 | single line');
});
it('should pad line numbers based on the highest line number', () => {
const input = 'line 1\nline 2';
// When starting from 99, highest line will be 100, so needs 3 spaces padding
const expected = ' 99 | line 1\n100 | line 2';
expect(addLineNumbers(input, 99)).toBe(expected);
});
});

View File

@@ -53,15 +53,12 @@ async function extractTextFromIPYNB(filePath: string): Promise<string> {
return addLineNumbers(extractedText) return addLineNumbers(extractedText)
} }
export function addLineNumbers(content: string, startLine: number = 1): string {
export function addLineNumbers(content: string): string {
const lines = content.split('\n') const lines = content.split('\n')
const maxLineNumberWidth = String(lines.length).length const maxLineNumberWidth = String(startLine + lines.length - 1).length
return lines return lines
.map((line, index) => { .map((line, index) => {
const lineNumber = String(index + 1).padStart(maxLineNumberWidth, ' ') const lineNumber = String(startLine + index).padStart(maxLineNumberWidth, ' ')
return `${lineNumber} | ${line}` return `${lineNumber} | ${line}`
}).join('\n') }).join('\n')
} }

View File

@@ -52,6 +52,7 @@ export interface ExtensionState {
allowedCommands?: string[] allowedCommands?: string[]
soundEnabled?: boolean soundEnabled?: boolean
diffEnabled?: boolean diffEnabled?: boolean
debugDiffEnabled?: boolean
} }
export interface ClineMessage { export interface ClineMessage {

View File

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

View File

@@ -31,6 +31,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
setSoundEnabled, setSoundEnabled,
diffEnabled, diffEnabled,
setDiffEnabled, setDiffEnabled,
debugDiffEnabled,
setDebugDiffEnabled,
openRouterModels, openRouterModels,
setAllowedCommands, setAllowedCommands,
allowedCommands, allowedCommands,
@@ -46,7 +48,10 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
setApiErrorMessage(apiValidationResult) setApiErrorMessage(apiValidationResult)
setModelIdErrorMessage(modelIdValidationResult) setModelIdErrorMessage(modelIdValidationResult)
if (!apiValidationResult && !modelIdValidationResult) { if (!apiValidationResult && !modelIdValidationResult) {
vscode.postMessage({ type: "apiConfiguration", apiConfiguration }) vscode.postMessage({
type: "apiConfiguration",
apiConfiguration
})
vscode.postMessage({ type: "customInstructions", text: customInstructions }) vscode.postMessage({ type: "customInstructions", text: customInstructions })
vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly }) vscode.postMessage({ type: "alwaysAllowReadOnly", bool: alwaysAllowReadOnly })
vscode.postMessage({ type: "alwaysAllowWrite", bool: alwaysAllowWrite }) vscode.postMessage({ type: "alwaysAllowWrite", bool: alwaysAllowWrite })
@@ -56,6 +61,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] }) vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] })
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled }) vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled }) vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
vscode.postMessage({ type: "debugDiffEnabled", bool: debugDiffEnabled })
onDone() onDone()
} }
} }
@@ -324,6 +330,20 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
When enabled, Cline will play sound effects for notifications and events. When enabled, Cline will play sound effects for notifications and events.
</p> </p>
</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> </div>
{IS_DEV && ( {IS_DEV && (

View File

@@ -30,6 +30,7 @@ export interface ExtensionStateContextType extends ExtensionState {
setAllowedCommands: (value: string[]) => void setAllowedCommands: (value: string[]) => void
setSoundEnabled: (value: boolean) => void setSoundEnabled: (value: boolean) => void
setDiffEnabled: (value: boolean) => void setDiffEnabled: (value: boolean) => void
setDebugDiffEnabled: (value: boolean) => void
} }
const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined) const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
@@ -43,6 +44,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
allowedCommands: [], allowedCommands: [],
soundEnabled: false, soundEnabled: false,
diffEnabled: false, diffEnabled: false,
debugDiffEnabled: false,
}) })
const [didHydrateState, setDidHydrateState] = useState(false) const [didHydrateState, setDidHydrateState] = useState(false)
const [showWelcome, setShowWelcome] = useState(false) const [showWelcome, setShowWelcome] = useState(false)
@@ -129,7 +131,10 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
openRouterModels, openRouterModels,
mcpServers, mcpServers,
filePaths, filePaths,
setApiConfiguration: (value) => setState((prevState) => ({ ...prevState, apiConfiguration: value })), setApiConfiguration: (value) => setState((prevState) => ({
...prevState,
apiConfiguration: value
})),
setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })), setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })),
setAlwaysAllowReadOnly: (value) => setState((prevState) => ({ ...prevState, alwaysAllowReadOnly: value })), setAlwaysAllowReadOnly: (value) => setState((prevState) => ({ ...prevState, alwaysAllowReadOnly: value })),
setAlwaysAllowWrite: (value) => setState((prevState) => ({ ...prevState, alwaysAllowWrite: value })), setAlwaysAllowWrite: (value) => setState((prevState) => ({ ...prevState, alwaysAllowWrite: value })),
@@ -140,6 +145,10 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })), setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })),
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })), setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })), setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
setDebugDiffEnabled: (value) => setState((prevState) => ({
...prevState,
debugDiffEnabled: value
})),
} }
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider> return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>