瀏覽代碼

Revert some whitespace changes

Matt Rubens 11 月之前
父節點
當前提交
c9de9cda66

+ 75 - 68
src/core/Cline.ts

@@ -205,10 +205,10 @@ export class Cline {
 			const taskMessage = this.clineMessages[0] // first message is always the task say
 			const lastRelevantMessage =
 				this.clineMessages[
-				findLastIndex(
-					this.clineMessages,
-					(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"),
-				)
+					findLastIndex(
+						this.clineMessages,
+						(m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"),
+					)
 				]
 			await this.providerRef.deref()?.updateTaskHistory({
 				id: this.taskId,
@@ -390,7 +390,8 @@ export class Cline {
 	async sayAndCreateMissingParamError(toolName: ToolUseName, paramName: string, relPath?: string) {
 		await this.say(
 			"error",
-			`Cline tried to use ${toolName}${relPath ? ` for '${relPath.toPosix()}'` : ""
+			`Cline tried to use ${toolName}${
+				relPath ? ` for '${relPath.toPosix()}'` : ""
 			} without value for required parameter '${paramName}'. Retrying...`,
 		)
 		return formatResponse.toolError(formatResponse.missingToolParameterError(paramName))
@@ -448,7 +449,7 @@ export class Cline {
 		// need to make sure that the api conversation history can be resumed by the api, even if it goes out of sync with cline messages
 
 		let existingApiConversationHistory: Anthropic.Messages.MessageParam[] =
-			await this.getSavedApiConversationHistory()
+		await this.getSavedApiConversationHistory()
 
 		// Now present the cline messages to the user and ask if they want to resume
 
@@ -559,8 +560,8 @@ export class Cline {
 					: [{ type: "text", text: lastMessage.content }]
 				if (previousAssistantMessage && previousAssistantMessage.role === "assistant") {
 					const assistantContent = Array.isArray(previousAssistantMessage.content)
-						? previousAssistantMessage.content
-						: [{ type: "text", text: previousAssistantMessage.content }]
+							? previousAssistantMessage.content
+							: [{ type: "text", text: previousAssistantMessage.content }]
 
 					const toolUseBlocks = assistantContent.filter(
 						(block) => block.type === "tool_use",
@@ -625,9 +626,10 @@ export class Cline {
 		newUserContent.push({
 			type: "text",
 			text:
-				`[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.${wasRecent
-					? "\n\nIMPORTANT: If the last tool use was a write_to_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents."
-					: ""
+				`[TASK RESUMPTION] This task was interrupted ${agoText}. It may or may not be complete, so please reassess the task context. Be aware that the project state may have changed since then. The current working directory is now '${cwd.toPosix()}'. If the task has not been completed, retry the last step before interruption and proceed with completing the task.\n\nNote: If you previously attempted a tool use that the user did not provide a result for, you should assume the tool use was not successful and assess whether you should retry. If the last tool was a browser_action, the browser has been closed and you must launch a new browser if needed.${
+					wasRecent
+						? "\n\nIMPORTANT: If the last tool use was a write_to_file that was interrupted, the file was reverted back to its original state before the interrupted edit, and you do NOT need to re-read the file as you already have its up-to-date contents."
+						: ""
 				}` +
 				(responseText
 					? `\n\nNew instructions for task continuation:\n<user_message>\n${responseText}\n</user_message>`
@@ -741,7 +743,8 @@ export class Cline {
 			return [
 				true,
 				formatResponse.toolResult(
-					`Command is still running in the user's terminal.${result.length > 0 ? `\nHere's the output so far:\n${result}` : ""
+					`Command is still running in the user's terminal.${
+						result.length > 0 ? `\nHere's the output so far:\n${result}` : ""
 					}\n\nThe user provided the following feedback:\n<feedback>\n${userFeedback.text}\n</feedback>`,
 					userFeedback.images,
 				),
@@ -753,7 +756,8 @@ export class Cline {
 		} else {
 			return [
 				false,
-				`Command is still running in the user's terminal.${result.length > 0 ? `\nHere's the output so far:\n${result}` : ""
+				`Command is still running in the user's terminal.${
+					result.length > 0 ? `\nHere's the output so far:\n${result}` : ""
 				}\n\nYou will be updated on the terminal status and new output in the future.`,
 			]
 		}
@@ -931,8 +935,9 @@ export class Cline {
 						case "apply_diff":
 							return `[${block.name} for '${block.params.path}']`
 						case "search_files":
-							return `[${block.name} for '${block.params.regex}'${block.params.file_pattern ? ` in '${block.params.file_pattern}'` : ""
-								}]`
+							return `[${block.name} for '${block.params.regex}'${
+								block.params.file_pattern ? ` in '${block.params.file_pattern}'` : ""
+							}]`
 						case "list_files":
 							return `[${block.name} for '${block.params.path}']`
 						case "list_code_definition_names":
@@ -1118,7 +1123,7 @@ export class Cline {
 							if (block.partial) {
 								// update gui message
 								const partialMessage = JSON.stringify(sharedMessageProps)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								// update editor
 								if (!this.diffViewProvider.isEditing) {
 									// open the editor and prepare to stream content in
@@ -1154,7 +1159,7 @@ export class Cline {
 								if (!this.diffViewProvider.isEditing) {
 									// show gui message before showing edit animation
 									const partialMessage = JSON.stringify(sharedMessageProps)
-									await this.ask("tool", partialMessage, true).catch(() => { }) // sending true for partial even though it's not a partial, this shows the edit row before the content is streamed into the editor
+									await this.ask("tool", partialMessage, true).catch(() => {}) // sending true for partial even though it's not a partial, this shows the edit row before the content is streamed into the editor
 									await this.diffViewProvider.open(relPath)
 								}
 								await this.diffViewProvider.update(everyLineHasLineNumbers(newContent) ? stripLineNumbers(newContent) : newContent, true)
@@ -1192,10 +1197,10 @@ export class Cline {
 									content: fileExists ? undefined : newContent,
 									diff: fileExists
 										? formatResponse.createPrettyPatch(
-											relPath,
-											this.diffViewProvider.originalContent,
-											newContent,
-										)
+												relPath,
+												this.diffViewProvider.originalContent,
+												newContent,
+											)
 										: undefined,
 								} satisfies ClineSayTool)
 								const didApprove = await askApproval("tool", completeMessage)
@@ -1217,13 +1222,13 @@ export class Cline {
 									)
 									pushToolResult(
 										`The user made the following updates to your content:\n\n${userEdits}\n\n` +
-										`The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file, including line numbers:\n\n` +
-										`<final_file_content path="${relPath.toPosix()}">\n${addLineNumbers(finalContent || '')}\n</final_file_content>\n\n` +
-										`Please note:\n` +
-										`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
-										`2. Proceed with the task using this updated file content as the new baseline.\n` +
-										`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
-										`${newProblemsMessage}`,
+											`The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file, including line numbers:\n\n` +
+											`<final_file_content path="${relPath.toPosix()}">\n${addLineNumbers(finalContent || '')}\n</final_file_content>\n\n` +
+											`Please note:\n` +
+											`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
+											`2. Proceed with the task using this updated file content as the new baseline.\n` +
+											`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
+											`${newProblemsMessage}`,
 									)
 								} else {
 									pushToolResult(
@@ -1252,7 +1257,7 @@ export class Cline {
 							if (block.partial) {
 								// update gui message
 								const partialMessage = JSON.stringify(sharedMessageProps)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!relPath) {
@@ -1281,9 +1286,9 @@ export class Cline {
 
 								// Apply the diff to the original content
 								const diffResult = this.diffStrategy?.applyDiff(
-									originalContent,
-									diffContent,
-									parseInt(block.params.start_line ?? ''),
+									originalContent, 
+									diffContent, 
+									parseInt(block.params.start_line ?? ''), 
 									parseInt(block.params.end_line ?? '')
 								) ?? {
 									success: false,
@@ -1335,13 +1340,13 @@ export class Cline {
 									)
 									pushToolResult(
 										`The user made the following updates to your content:\n\n${userEdits}\n\n` +
-										`The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file, including line numbers:\n\n` +
-										`<final_file_content path="${relPath.toPosix()}">\n${addLineNumbers(finalContent || '')}\n</final_file_content>\n\n` +
-										`Please note:\n` +
-										`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
-										`2. Proceed with the task using this updated file content as the new baseline.\n` +
-										`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
-										`${newProblemsMessage}`,
+											`The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file, including line numbers:\n\n` +
+											`<final_file_content path="${relPath.toPosix()}">\n${addLineNumbers(finalContent || '')}\n</final_file_content>\n\n` +
+											`Please note:\n` +
+											`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
+											`2. Proceed with the task using this updated file content as the new baseline.\n` +
+											`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
+											`${newProblemsMessage}`,
 									)
 								} else {
 									pushToolResult(`Changes successfully applied to ${relPath.toPosix()}:\n\n${newProblemsMessage}`)
@@ -1367,7 +1372,7 @@ export class Cline {
 									...sharedMessageProps,
 									content: undefined,
 								} satisfies ClineSayTool)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!relPath) {
@@ -1409,7 +1414,7 @@ export class Cline {
 									...sharedMessageProps,
 									content: "",
 								} satisfies ClineSayTool)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!relDirPath) {
@@ -1449,7 +1454,7 @@ export class Cline {
 									...sharedMessageProps,
 									content: "",
 								} satisfies ClineSayTool)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!relDirPath) {
@@ -1494,7 +1499,7 @@ export class Cline {
 									...sharedMessageProps,
 									content: "",
 								} satisfies ClineSayTool)
-								await this.ask("tool", partialMessage, block.partial).catch(() => { })
+								await this.ask("tool", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!relDirPath) {
@@ -1549,7 +1554,7 @@ export class Cline {
 										"browser_action_launch",
 										removeClosingTag("url", url),
 										block.partial
-									).catch(() => { })
+									).catch(() => {})
 								} else {
 									await this.say(
 										"browser_action",
@@ -1649,7 +1654,8 @@ export class Cline {
 										await this.say("browser_action_result", JSON.stringify(browserActionResult))
 										pushToolResult(
 											formatResponse.toolResult(
-												`The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${browserActionResult.logs || "(No new logs)"
+												`The browser action has been executed. The console logs and screenshot have been captured for your analysis.\n\nConsole logs:\n${
+													browserActionResult.logs || "(No new logs)"
 												}\n\n(REMEMBER: if you need to proceed to using non-\`browser_action\` tools or launch a new browser, you MUST first close this browser. For example, if after analyzing the logs and screenshot you need to edit a file, you must first close the browser before you can use the write_to_file tool.)`,
 												browserActionResult.screenshot ? [browserActionResult.screenshot] : [],
 											),
@@ -1676,7 +1682,7 @@ export class Cline {
 						try {
 							if (block.partial) {
 								await this.ask("command", removeClosingTag("command", command), block.partial).catch(
-									() => { }
+									() => {}
 								)
 								break
 							} else {
@@ -1717,7 +1723,7 @@ export class Cline {
 									toolName: removeClosingTag("tool_name", tool_name),
 									arguments: removeClosingTag("arguments", mcp_arguments),
 								} satisfies ClineAskUseMcpServer)
-								await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => { })
+								await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!server_name) {
@@ -1778,19 +1784,19 @@ export class Cline {
 								// TODO: add progress indicator and ability to parse images and non-text responses
 								const toolResultPretty =
 									(toolResult?.isError ? "Error:\n" : "") +
-									toolResult?.content
-										.map((item) => {
-											if (item.type === "text") {
-												return item.text
-											}
-											if (item.type === "resource") {
-												const { blob, ...rest } = item.resource
-												return JSON.stringify(rest, null, 2)
-											}
-											return ""
-										})
-										.filter(Boolean)
-										.join("\n\n") || "(No response)"
+										toolResult?.content
+											.map((item) => {
+												if (item.type === "text") {
+													return item.text
+												}
+												if (item.type === "resource") {
+													const { blob, ...rest } = item.resource
+													return JSON.stringify(rest, null, 2)
+												}
+												return ""
+											})
+											.filter(Boolean)
+											.join("\n\n") || "(No response)"
 								await this.say("mcp_server_response", toolResultPretty)
 								pushToolResult(formatResponse.toolResult(toolResultPretty))
 								break
@@ -1810,7 +1816,7 @@ export class Cline {
 									serverName: removeClosingTag("server_name", server_name),
 									uri: removeClosingTag("uri", uri),
 								} satisfies ClineAskUseMcpServer)
-								await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => { })
+								await this.ask("use_mcp_server", partialMessage, block.partial).catch(() => {})
 								break
 							} else {
 								if (!server_name) {
@@ -1866,7 +1872,7 @@ export class Cline {
 						try {
 							if (block.partial) {
 								await this.ask("followup", removeClosingTag("question", question), block.partial).catch(
-									() => { },
+									() => {},
 								)
 								break
 							} else {
@@ -1925,7 +1931,7 @@ export class Cline {
 											"command",
 											removeClosingTag("command", command),
 											block.partial,
-										).catch(() => { })
+										).catch(() => {})
 									} else {
 										// last message is completion_result
 										// we have command string, which means we have the result as well, so finish it (doesnt have to exist yet)
@@ -1939,7 +1945,7 @@ export class Cline {
 											"command",
 											removeClosingTag("command", command),
 											block.partial,
-										).catch(() => { })
+										).catch(() => {})
 									}
 								} else {
 									// no command, still outputting partial result
@@ -2165,9 +2171,10 @@ export class Cline {
 							type: "text",
 							text:
 								assistantMessage +
-								`\n\n[${cancelReason === "streaming_failed"
-									? "Response interrupted by API Error"
-									: "Response interrupted by user"
+								`\n\n[${
+									cancelReason === "streaming_failed"
+										? "Response interrupted by API Error"
+										: "Response interrupted by user"
 								}]`,
 						},
 					],
@@ -2421,7 +2428,7 @@ export class Cline {
 			await pWaitFor(() => busyTerminals.every((t) => !this.terminalManager.isProcessHot(t.id)), {
 				interval: 100,
 				timeout: 15_000,
-			}).catch(() => { })
+			}).catch(() => {})
 		}
 
 		// we want to get diagnostics AFTER terminal cools down for a few reasons: terminal could be scaffolding a project, dev servers (compilers like webpack) will first re-compile and then send diagnostics, etc

+ 11 - 11
src/core/webview/ClineProvider.ts

@@ -235,7 +235,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			diffEnabled,
 			fuzzyMatchThreshold
 		} = await this.getState()
-
+		
 		this.cline = new Cline(
 			this,
 			apiConfiguration,
@@ -255,7 +255,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			diffEnabled,
 			fuzzyMatchThreshold
 		} = await this.getState()
-
+		
 		this.cline = new Cline(
 			this,
 			apiConfiguration,
@@ -321,15 +321,15 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 
 		// Use a nonce to only allow a specific script to be run.
 		/*
-		content security policy of your webview to only allow scripts that have a specific nonce
-		create a content security policy meta tag so that only loading scripts with a nonce is allowed
-		As your extension grows you will likely want to add custom styles, fonts, and/or images to your webview. If you do, you will need to update the content security policy meta tag to explicity allow for these resources. E.g.
-				<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
+        content security policy of your webview to only allow scripts that have a specific nonce
+        create a content security policy meta tag so that only loading scripts with a nonce is allowed
+        As your extension grows you will likely want to add custom styles, fonts, and/or images to your webview. If you do, you will need to update the content security policy meta tag to explicity allow for these resources. E.g.
+                <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; font-src ${webview.cspSource}; img-src ${webview.cspSource} https:; script-src 'nonce-${nonce}';">
 		- 'unsafe-inline' is required for styles due to vscode-webview-toolkit's dynamic style injection
 		- since we pass base64 images to the webview, we need to specify img-src ${webview.cspSource} data:;
 
-		in meta tag we add nonce attribute: A cryptographic nonce (only used once) to allow scripts. The server must generate a unique nonce value each time it transmits a policy. It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial.
-		*/
+        in meta tag we add nonce attribute: A cryptographic nonce (only used once) to allow scripts. The server must generate a unique nonce value each time it transmits a policy. It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial.
+        */
 		const nonce = getNonce()
 
 		// Tip: Install the es6-string-html VS Code extension to enable code highlighting below
@@ -557,7 +557,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 						this.postMessageToWebview({ type: "lmStudioModels", lmStudioModels })
 						break
 					case "refreshGlamaModels":
-						await this.refreshGlamaModels()
+							await this.refreshGlamaModels()
 						break
 					case "refreshOpenRouterModels":
 						await this.refreshOpenRouterModels()
@@ -566,7 +566,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 						if (message?.values?.baseUrl && message?.values?.apiKey) {
 							const openAiModels = await this.getOpenAiModels(message?.values?.baseUrl, message?.values?.apiKey)
 							this.postMessageToWebview({ type: "openAiModels", openAiModels })
-						}
+						}	
 						break
 					case "openImage":
 						openImage(message.text!)
@@ -1257,7 +1257,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
 			alwaysApproveResubmit,
 			requestDelaySeconds,
 		} = await this.getState()
-
+		
 		const allowedCommands = vscode.workspace
 			.getConfiguration('roo-cline')
 			.get<string[]>('allowedCommands') || []

+ 17 - 18
src/core/webview/__tests__/ClineProvider.test.ts

@@ -146,8 +146,8 @@ jest.mock('../../../integrations/misc/extract-text', () => ({
 
 // Spy on console.error and console.log to suppress expected messages
 beforeAll(() => {
-    jest.spyOn(console, 'error').mockImplementation(() => { })
-    jest.spyOn(console, 'log').mockImplementation(() => { })
+    jest.spyOn(console, 'error').mockImplementation(() => {})
+    jest.spyOn(console, 'log').mockImplementation(() => {})
 })
 
 afterAll(() => {
@@ -230,7 +230,7 @@ describe('ClineProvider', () => {
 
     test('resolveWebviewView sets up webview correctly', () => {
         provider.resolveWebviewView(mockWebviewView)
-
+        
         expect(mockWebviewView.webview.options).toEqual({
             enableScripts: true,
             localResourceRoots: [mockContext.extensionUri]
@@ -240,7 +240,7 @@ describe('ClineProvider', () => {
 
     test('postMessageToWebview sends message to webview', async () => {
         provider.resolveWebviewView(mockWebviewView)
-
+        
         const mockState: ExtensionState = {
             version: '1.0.0',
             preferredLanguage: 'English',
@@ -263,16 +263,15 @@ describe('ClineProvider', () => {
             browserViewportSize: "900x600",
             fuzzyMatchThreshold: 1.0,
             mcpEnabled: true,
-            alwaysApproveResubmit: false,
-            requestDelaySeconds: 5,
+            requestDelaySeconds: 5
         }
-
-        const message: ExtensionMessage = {
-            type: 'state',
+        
+        const message: ExtensionMessage = { 
+            type: 'state', 
             state: mockState
         }
         await provider.postMessageToWebview(message)
-
+        
         expect(mockPostMessage).toHaveBeenCalledWith(message)
     })
 
@@ -303,7 +302,7 @@ describe('ClineProvider', () => {
 
     test('getState returns correct initial state', async () => {
         const state = await provider.getState()
-
+        
         expect(state).toHaveProperty('apiConfiguration')
         expect(state.apiConfiguration).toHaveProperty('apiProvider')
         expect(state).toHaveProperty('customInstructions')
@@ -320,7 +319,7 @@ describe('ClineProvider', () => {
     test('preferredLanguage defaults to VSCode language when not set', async () => {
         // Mock VSCode language as Spanish
         (vscode.env as any).language = 'es-ES';
-
+        
         const state = await provider.getState();
         expect(state.preferredLanguage).toBe('Spanish');
     })
@@ -328,7 +327,7 @@ describe('ClineProvider', () => {
     test('preferredLanguage defaults to English for unsupported VSCode language', async () => {
         // Mock VSCode language as an unsupported language
         (vscode.env as any).language = 'unsupported-LANG';
-
+        
         const state = await provider.getState();
         expect(state.preferredLanguage).toBe('English');
     })
@@ -336,9 +335,9 @@ describe('ClineProvider', () => {
     test('diffEnabled defaults to true when not set', async () => {
         // Mock globalState.get to return undefined for diffEnabled
         (mockContext.globalState.get as jest.Mock).mockReturnValue(undefined)
-
+        
         const state = await provider.getState()
-
+        
         expect(state.diffEnabled).toBe(true)
     })
 
@@ -350,7 +349,7 @@ describe('ClineProvider', () => {
             }
             return null
         })
-
+        
         const state = await provider.getState()
         expect(state.writeDelayMs).toBe(1000)
     })
@@ -358,9 +357,9 @@ describe('ClineProvider', () => {
     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()
     })

+ 28 - 28
src/shared/ExtensionMessage.ts

@@ -8,28 +8,28 @@ import { GitCommit } from "../utils/git"
 // webview will hold state
 export interface ExtensionMessage {
 	type:
-	| "action"
-	| "state"
-	| "selectedImages"
-	| "ollamaModels"
-	| "lmStudioModels"
-	| "theme"
-	| "workspaceUpdated"
-	| "invoke"
-	| "partialMessage"
-	| "glamaModels"
-	| "openRouterModels"
-	| "openAiModels"
-	| "mcpServers"
-	| "enhancedPrompt"
-	| "commitSearchResults"
+		| "action"
+		| "state"
+		| "selectedImages"
+		| "ollamaModels"
+		| "lmStudioModels"
+		| "theme"
+		| "workspaceUpdated"
+		| "invoke"
+		| "partialMessage"
+		| "glamaModels"
+		| "openRouterModels"
+		| "openAiModels"
+		| "mcpServers"
+		| "enhancedPrompt"
+		| "commitSearchResults"
 	text?: string
 	action?:
-	| "chatButtonClicked"
-	| "mcpButtonClicked"
-	| "settingsButtonClicked"
-	| "historyButtonClicked"
-	| "didBecomeVisible"
+		| "chatButtonClicked"
+		| "mcpButtonClicked"
+		| "settingsButtonClicked"
+		| "historyButtonClicked"
+		| "didBecomeVisible"
 	invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick"
 	state?: ExtensionState
 	images?: string[]
@@ -117,14 +117,14 @@ export type ClineSay =
 
 export interface ClineSayTool {
 	tool:
-	| "editedExistingFile"
-	| "appliedDiff"
-	| "newFileCreated"
-	| "readFile"
-	| "listFilesTopLevel"
-	| "listFilesRecursive"
-	| "listCodeDefinitionNames"
-	| "searchFiles"
+		| "editedExistingFile"
+		| "appliedDiff"
+		| "newFileCreated"
+		| "readFile"
+		| "listFilesTopLevel"
+		| "listFilesRecursive"
+		| "listCodeDefinitionNames"
+		| "searchFiles"
 	path?: string
 	diff?: string
 	content?: string

+ 51 - 51
src/shared/WebviewMessage.ts

@@ -1,59 +1,59 @@
-import { ApiConfiguration } from "./api"
+import { ApiConfiguration, ApiProvider } from "./api"
 
 export type AudioType = "notification" | "celebration" | "progress_loop"
 
 export interface WebviewMessage {
 	type:
-	| "apiConfiguration"
-	| "customInstructions"
-	| "allowedCommands"
-	| "alwaysAllowReadOnly"
-	| "alwaysAllowWrite"
-	| "alwaysAllowExecute"
-	| "webviewDidLaunch"
-	| "newTask"
-	| "askResponse"
-	| "clearTask"
-	| "didShowAnnouncement"
-	| "selectImages"
-	| "exportCurrentTask"
-	| "showTaskWithId"
-	| "deleteTaskWithId"
-	| "exportTaskWithId"
-	| "resetState"
-	| "requestOllamaModels"
-	| "requestLmStudioModels"
-	| "openImage"
-	| "openFile"
-	| "openMention"
-	| "cancelTask"
-	| "refreshGlamaModels"
-	| "refreshOpenRouterModels"
-	| "refreshOpenAiModels"
-	| "alwaysAllowBrowser"
-	| "alwaysAllowMcp"
-	| "playSound"
-	| "soundEnabled"
-	| "soundVolume"
-	| "diffEnabled"
-	| "browserViewportSize"
-	| "screenshotQuality"
-	| "openMcpSettings"
-	| "restartMcpServer"
-	| "toggleToolAlwaysAllow"
-	| "toggleMcpServer"
-	| "fuzzyMatchThreshold"
-	| "preferredLanguage"
-	| "writeDelayMs"
-	| "enhancePrompt"
-	| "enhancedPrompt"
-	| "draggedImages"
-	| "deleteMessage"
-	| "terminalOutputLineLimit"
-	| "mcpEnabled"
-	| "searchCommits"
-	| "alwaysApproveResubmit"
-	| "requestDelaySeconds"
+		| "apiConfiguration"
+		| "customInstructions"
+		| "allowedCommands"
+		| "alwaysAllowReadOnly"
+		| "alwaysAllowWrite"
+		| "alwaysAllowExecute"
+		| "webviewDidLaunch"
+		| "newTask"
+		| "askResponse"
+		| "clearTask"
+		| "didShowAnnouncement"
+		| "selectImages"
+		| "exportCurrentTask"
+		| "showTaskWithId"
+		| "deleteTaskWithId"
+		| "exportTaskWithId"
+		| "resetState"
+		| "requestOllamaModels"
+		| "requestLmStudioModels"
+		| "openImage"
+		| "openFile"
+		| "openMention"
+		| "cancelTask"
+		| "refreshGlamaModels"
+		| "refreshOpenRouterModels"
+		| "refreshOpenAiModels"
+		| "alwaysAllowBrowser"
+		| "alwaysAllowMcp"
+		| "playSound"
+		| "soundEnabled"
+		| "soundVolume"
+		| "diffEnabled"
+		| "browserViewportSize"
+		| "screenshotQuality"
+		| "openMcpSettings"
+		| "restartMcpServer"
+		| "toggleToolAlwaysAllow"
+		| "toggleMcpServer"
+		| "fuzzyMatchThreshold"
+		| "preferredLanguage"
+		| "writeDelayMs"
+		| "enhancePrompt"
+		| "enhancedPrompt"
+		| "draggedImages"
+		| "deleteMessage"
+		| "terminalOutputLineLimit"
+		| "mcpEnabled"
+		| "searchCommits"
+		| "alwaysApproveResubmit"
+		| "requestDelaySeconds"
 	text?: string
 	disabled?: boolean
 	askResponse?: ClineAskResponse

+ 12 - 12
webview-ui/src/context/ExtensionStateContext.tsx

@@ -96,18 +96,18 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 				const config = message.state?.apiConfiguration
 				const hasKey = config
 					? [
-						config.apiKey,
-						config.glamaApiKey,
-						config.openRouterApiKey,
-						config.awsRegion,
-						config.vertexProjectId,
-						config.openAiApiKey,
-						config.ollamaModelId,
-						config.lmStudioModelId,
-						config.geminiApiKey,
-						config.openAiNativeApiKey,
-						config.deepSeekApiKey,
-					].some((key) => key !== undefined)
+							config.apiKey,
+							config.glamaApiKey,
+							config.openRouterApiKey,
+							config.awsRegion,
+							config.vertexProjectId,
+							config.openAiApiKey,
+							config.ollamaModelId,
+							config.lmStudioModelId,
+							config.geminiApiKey,
+							config.openAiNativeApiKey,
+							config.deepSeekApiKey,
+						].some((key) => key !== undefined)
 					: false
 				setShowWelcome(!hasKey)
 				setDidHydrateState(true)