diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index 4c4d53d..afbae37 100644
--- a/src/core/Cline.ts
+++ b/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\n${responseText}\n`
@@ -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\n${userFeedback.text}\n`,
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` +
- `\n${addLineNumbers(finalContent || '')}\n\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` +
+ `\n${addLineNumbers(finalContent || '')}\n\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` +
- `\n${addLineNumbers(finalContent || '')}\n\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` +
+ `\n${addLineNumbers(finalContent || '')}\n\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
diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts
index b70d814..579a12e 100644
--- a/src/core/webview/ClineProvider.ts
+++ b/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.
-
+ 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.
+
- '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('allowedCommands') || []
diff --git a/src/core/webview/__tests__/ClineProvider.test.ts b/src/core/webview/__tests__/ClineProvider.test.ts
index c3470fe..0a7ee9a 100644
--- a/src/core/webview/__tests__/ClineProvider.test.ts
+++ b/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()
})
diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts
index f9e5c61..6b877a0 100644
--- a/src/shared/ExtensionMessage.ts
+++ b/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
diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts
index e5c9b64..0ca7cb3 100644
--- a/src/shared/WebviewMessage.ts
+++ b/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
diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx
index b6a922d..131364b 100644
--- a/webview-ui/src/context/ExtensionStateContext.tsx
+++ b/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)