diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 47e31d7e2d..94474c80c9 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -142,7 +142,7 @@ function runDelegationTransition( locks.set(parentTaskId, tail) - tail.finally(() => { + void tail.finally(() => { if (locks.get(parentTaskId) === tail) { locks.delete(parentTaskId) } @@ -234,7 +234,7 @@ export class ClineProvider ClineProvider.activeInstances.add(this) this.mdmService = mdmService - this.updateGlobalState("codebaseIndexModels", EMBEDDING_MODEL_PROFILES) + void this.updateGlobalState("codebaseIndexModels", EMBEDDING_MODEL_PROFILES) // Initialize the per-task file-based history store. // The globalState write-through is debounced separately (not on every mutation) @@ -687,7 +687,7 @@ export class ClineProvider this.mcpHub = undefined await this.skillsManager?.dispose() this.skillsManager = undefined - this.marketplaceManager?.cleanup() + await this.marketplaceManager?.cleanup() this.customModesManager?.dispose() this.taskHistoryStore.dispose() this.flushGlobalStateWriteThrough() @@ -822,9 +822,27 @@ export class ClineProvider setPanel(webviewView, "sidebar") } + // Set up webview options with proper resource roots + const resourceRoots = [this.contextProxy.extensionUri] + + // Add workspace folders to allow access to workspace files + if (vscode.workspace.workspaceFolders) { + resourceRoots.push(...vscode.workspace.workspaceFolders.map((folder) => folder.uri)) + } + + webviewView.webview.options = { + enableScripts: true, + localResourceRoots: resourceRoots, + } + + webviewView.webview.html = + this.contextProxy.extensionMode === vscode.ExtensionMode.Development + ? await this.getHMRHtmlContent(webviewView.webview) + : await this.getHtmlContent(webviewView.webview) + // Initialize out-of-scope variables that need to receive persistent // global state values. - this.getState().then( + await this.getState().then( ({ terminalShellIntegrationTimeout = Terminal.defaultShellIntegrationTimeout, terminalShellIntegrationDisabled = false, @@ -852,24 +870,6 @@ export class ClineProvider }, ) - // Set up webview options with proper resource roots - const resourceRoots = [this.contextProxy.extensionUri] - - // Add workspace folders to allow access to workspace files - if (vscode.workspace.workspaceFolders) { - resourceRoots.push(...vscode.workspace.workspaceFolders.map((folder) => folder.uri)) - } - - webviewView.webview.options = { - enableScripts: true, - localResourceRoots: resourceRoots, - } - - webviewView.webview.html = - this.contextProxy.extensionMode === vscode.ExtensionMode.Development - ? await this.getHMRHtmlContent(webviewView.webview) - : await this.getHtmlContent(webviewView.webview) - // Sets up an event listener to listen for messages passed from the webview view context // and executes code based on the message that is received. this.setWebviewMessageListener(webviewView.webview) @@ -892,7 +892,7 @@ export class ClineProvider // for this visibility listener panel. const viewStateDisposable = webviewView.onDidChangeViewState(() => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + void this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) } else { this.logWebviewHiddenDiagnostics() } @@ -903,7 +903,7 @@ export class ClineProvider // sidebar const visibilityDisposable = webviewView.onDidChangeVisibility(() => { if (this.view?.visible) { - this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) + void this.postMessageToWebview({ type: "action", action: "didBecomeVisible" }) } else { this.logWebviewHiddenDiagnostics() } @@ -2107,7 +2107,7 @@ export class ClineProvider const state = await this.getStateToPostToWebview() this.clineMessagesSeq++ state.clineMessagesSeq = this.clineMessagesSeq - this.postMessageToWebview({ type: "state", state }) + await this.postMessageToWebview({ type: "state", state }) } /** @@ -2123,7 +2123,7 @@ export class ClineProvider this.clineMessagesSeq++ state.clineMessagesSeq = this.clineMessagesSeq const { taskHistory: _omit, ...rest } = state - this.postMessageToWebview({ type: "state", state: rest }) + await this.postMessageToWebview({ type: "state", state: rest }) } /** @@ -2140,7 +2140,7 @@ export class ClineProvider async postStateToWebviewWithoutClineMessages(): Promise { const state = await this.getStateToPostToWebview() const { clineMessages: _omitMessages, taskHistory: _omitHistory, ...rest } = state - this.postMessageToWebview({ type: "state", state: rest }) + await this.postMessageToWebview({ type: "state", state: rest }) } /** @@ -2160,7 +2160,7 @@ export class ClineProvider ]) // Send marketplace data separately - this.postMessageToWebview({ + await this.postMessageToWebview({ type: "marketplaceData", organizationMcps: marketplaceResult.organizationMcps || [], marketplaceItems: marketplaceResult.marketplaceItems || [], @@ -2171,7 +2171,7 @@ export class ClineProvider console.error("Failed to fetch marketplace data:", error) // Send empty data on error to prevent UI from hanging - this.postMessageToWebview({ + await this.postMessageToWebview({ type: "marketplaceData", organizationMcps: [], marketplaceItems: [], @@ -2954,7 +2954,7 @@ export class ClineProvider if (currentManager === this.getCurrentWorkspaceCodeIndexManager()) { // Get the full status from the manager to ensure we have all fields correctly formatted const fullStatus = currentManager.getCurrentStatus() - this.postMessageToWebview({ + void this.postMessageToWebview({ type: "indexingStatusUpdate", values: fullStatus, }) @@ -2966,7 +2966,7 @@ export class ClineProvider } // Send initial status for the current workspace - this.postMessageToWebview({ + void this.postMessageToWebview({ type: "indexingStatusUpdate", values: currentManager.getCurrentStatus(), }) diff --git a/src/core/webview/__tests__/ClineProvider.spec.ts b/src/core/webview/__tests__/ClineProvider.spec.ts index b1e5df93f9..7734dfd45f 100644 --- a/src/core/webview/__tests__/ClineProvider.spec.ts +++ b/src/core/webview/__tests__/ClineProvider.spec.ts @@ -1149,7 +1149,7 @@ describe("ClineProvider", () => { setModeConfig: vi.fn(), } as any - provider.setValue("currentApiConfigName", "current-config") + await provider.setValue("currentApiConfigName", "current-config") // Switch to architect mode await messageHandler({ type: "mode", text: "architect" }) @@ -1247,7 +1247,7 @@ describe("ClineProvider", () => { }, } - provider.setValue("customModePrompts", existingPrompts) + await provider.setValue("customModePrompts", existingPrompts) // Test updating a prompt await messageHandler({ diff --git a/src/core/webview/checkpointRestoreHandler.ts b/src/core/webview/checkpointRestoreHandler.ts index a3f62f74f3..5a517cdcc0 100644 --- a/src/core/webview/checkpointRestoreHandler.ts +++ b/src/core/webview/checkpointRestoreHandler.ts @@ -31,7 +31,7 @@ export async function handleCheckpointRestoreOperation(config: CheckpointRestore // This prevents "Current ask promise was ignored" errors // For edit operations, we don't abort because the checkpoint restore will handle it if (operation === "delete" && currentCline && !currentCline.abort) { - currentCline.abortTask() + await currentCline.abortTask() // Wait a bit for the abort to complete await pWaitFor(() => currentCline.abort === true, { timeout: 1000, diff --git a/src/core/webview/rulesMessageHandler.ts b/src/core/webview/rulesMessageHandler.ts index 343adf8738..68fcc5f7b2 100644 --- a/src/core/webview/rulesMessageHandler.ts +++ b/src/core/webview/rulesMessageHandler.ts @@ -38,7 +38,7 @@ export async function handleCreateRule( try { const input = parseCreateRuleInput(message) const createdPath = await createRule(cwd, input) - openFile(createdPath) + await openFile(createdPath) } catch (error) { const errorMessage = getErrorMessage(error) provider.log(`Error creating rule: ${errorMessage}`) @@ -89,7 +89,7 @@ export async function handleOpenRuleFile(provider: ClineProvider, cwd: string, m throw new Error("Rule file not found") } - openFile(filePath) + await openFile(filePath) } catch (error) { const errorMessage = getErrorMessage(error) provider.log(`Error opening rule file: ${errorMessage}`) @@ -109,7 +109,7 @@ export async function handleOpenRulesDirectory( kind: values.kind, modeSlug: values.modeSlug, } as CreateRuleInput) - openFile(directoryPath) + await openFile(directoryPath) } catch (error) { const errorMessage = getErrorMessage(error) provider.log(`Error opening rules directory: ${errorMessage}`) diff --git a/src/core/webview/skillsMessageHandler.ts b/src/core/webview/skillsMessageHandler.ts index 496ff70c24..2eab270734 100644 --- a/src/core/webview/skillsMessageHandler.ts +++ b/src/core/webview/skillsMessageHandler.ts @@ -55,7 +55,7 @@ export async function handleCreateSkill( const createdPath = await skillsManager.createSkill(skillName, source, skillDescription, modeSlugs) // Open the created file in the editor - openFile(createdPath) + await openFile(createdPath) // Send updated skills list const skills = skillsManager.getSkillsMetadata() @@ -199,7 +199,7 @@ export async function handleOpenSkillFile(provider: ClineProvider, message: Webv throw new Error(t("skills:errors.skill_not_found", { name: skillName })) } - openFile(skill.path) + await openFile(skill.path) } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error) provider.log(`Error opening skill file: ${errorMessage}`) diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index c3918e24a5..4e0f2912f7 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -562,17 +562,19 @@ export const webviewMessageHandler = async ( const customModes = await provider.customModesManager.getCustomModes() await updateGlobalState("customModes", customModes) - provider.postStateToWebview() - provider.workspaceTracker?.initializeFilePaths() // Don't await. + await provider.postStateToWebview() + void provider.workspaceTracker?.initializeFilePaths() // Don't await. - getTheme().then((theme) => provider.postMessageToWebview({ type: "theme", text: JSON.stringify(theme) })) + await getTheme().then((theme) => + provider.postMessageToWebview({ type: "theme", text: JSON.stringify(theme) }), + ) // If MCP Hub is already initialized, update the webview with // current server list. const mcpHub = provider.getMcpHub() if (mcpHub) { - provider.postMessageToWebview({ type: "mcpServers", mcpServers: mcpHub.getAllServers() }) + await provider.postMessageToWebview({ type: "mcpServers", mcpServers: mcpHub.getAllServers() }) } provider.providerSettingsManager @@ -629,7 +631,7 @@ export const webviewMessageHandler = async ( ) // Enable telemetry by default (when unset) or when explicitly enabled - provider.getStateToPostToWebview().then((state) => { + await provider.getStateToPostToWebview().then((state) => { const { telemetrySetting } = state const isOptedIn = telemetrySetting !== "disabled" TelemetryService.instance.updateTelemetryState(isOptedIn) @@ -785,7 +787,7 @@ export const webviewMessageHandler = async ( case "terminalOperation": if (message.terminalOperation) { - provider.getCurrentTask()?.handleTerminalOperation(message.terminalOperation) + await provider.getCurrentTask()?.handleTerminalOperation(message.terminalOperation) } break case "clearTask": @@ -811,7 +813,7 @@ export const webviewMessageHandler = async ( case "exportCurrentTask": const currentTaskId = provider.getCurrentTask()?.taskId if (currentTaskId) { - provider.exportTaskWithId(currentTaskId) + await provider.exportTaskWithId(currentTaskId) } break case "shareCurrentTask": @@ -825,13 +827,13 @@ export const webviewMessageHandler = async ( vscode.window.showErrorMessage(t("common:errors.share_not_enabled")) break case "showTaskWithId": - provider.showTaskWithId(message.text!) + await provider.showTaskWithId(message.text!) break case "condenseTaskContextRequest": - provider.condenseTaskContext(message.text!) + await provider.condenseTaskContext(message.text!) break case "deleteTaskWithId": - provider.deleteTaskWithId(message.text!) + await provider.deleteTaskWithId(message.text!) break case "deleteMultipleTasksWithIds": { const ids = message.ids @@ -878,7 +880,7 @@ export const webviewMessageHandler = async ( break } case "exportTaskWithId": - provider.exportTaskWithId(message.text!) + await provider.exportTaskWithId(message.text!) break case "getTaskWithAggregatedCosts": { try { @@ -1202,7 +1204,7 @@ export const webviewMessageHandler = async ( routerModels[routerName] = {} // Ensure it's an empty object in the main routerModels message. - provider.postMessageToWebview({ + void provider.postMessageToWebview({ type: "singleRouterModelFetchResponse", success: false, error: errorMessage, @@ -1211,7 +1213,7 @@ export const webviewMessageHandler = async ( } }) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "routerModels", routerModels, values: providerFilter ? { provider: requestedProvider } : undefined, @@ -1233,7 +1235,7 @@ export const webviewMessageHandler = async ( const ollamaModels = await getModels(ollamaOptions) if (Object.keys(ollamaModels).length > 0) { - provider.postMessageToWebview({ type: "ollamaModels", ollamaModels: ollamaModels }) + await provider.postMessageToWebview({ type: "ollamaModels", ollamaModels: ollamaModels }) } } catch (error) { // Silently fail - user hasn't configured Ollama yet @@ -1261,7 +1263,7 @@ export const webviewMessageHandler = async ( } if (Object.keys(lmStudioModels).length > 0) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "lmStudioModels", lmStudioModels: lmStudioModels, }) @@ -1273,7 +1275,7 @@ export const webviewMessageHandler = async ( break } case "requestRooModels": { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "singleRouterModelFetchResponse", success: false, error: getRouterRemovalMessage(), @@ -1289,24 +1291,24 @@ export const webviewMessageHandler = async ( message?.values?.openAiHeaders, ) - provider.postMessageToWebview({ type: "openAiModels", openAiModels }) + await provider.postMessageToWebview({ type: "openAiModels", openAiModels }) } break case "requestVsCodeLmModels": const vsCodeLmModels = await getVsCodeLmModels() // TODO: Cache like we do for OpenRouter, etc? - provider.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels }) + await provider.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels }) break case "openImage": - openImage(message.text!, { values: message.values }) + await openImage(message.text!, { values: message.values }) break case "saveImage": if (message.dataUri) { const matches = message.dataUri.match(/^data:image\/([a-zA-Z]+);base64,(.+)$/) if (!matches) { // Let saveImage handle invalid URI error - saveImage(message.dataUri, vscode.Uri.file("")) + await saveImage(message.dataUri, vscode.Uri.file("")) break } const format = matches[1] @@ -1334,12 +1336,12 @@ export const webviewMessageHandler = async ( if (!path.isAbsolute(filePath)) { filePath = path.join(getCurrentCwd(), filePath) } - openFile(filePath, message.values as { create?: boolean; content?: string; line?: number }) + await openFile(filePath, message.values as { create?: boolean; content?: string; line?: number }) break case "readFileContent": { const relPath = message.text || "" if (!relPath) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content: null, error: "No path provided" }, }) @@ -1348,7 +1350,7 @@ export const webviewMessageHandler = async ( try { const cwd = getCurrentCwd() if (!cwd) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content: null, error: "No workspace path available" }, }) @@ -1357,17 +1359,17 @@ export const webviewMessageHandler = async ( const absPath = path.resolve(cwd, relPath) // Workspace-boundary validation: prevent path traversal attacks if (isPathOutsideWorkspace(absPath)) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content: null, error: "Path is outside workspace" }, }) break } const content = await fs.readFile(absPath, "utf-8") - provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content } }) + await provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content } }) } catch (err) { const errorMsg = err instanceof Error ? err.message : String(err) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "fileContent", fileContent: { path: relPath, content: null, error: errorMsg }, }) @@ -1375,7 +1377,7 @@ export const webviewMessageHandler = async ( break } case "openMention": - openMention(getCurrentCwd(), message.text) + await openMention(getCurrentCwd(), message.text) break case "openExternal": if (message.url) { @@ -1505,7 +1507,7 @@ export const webviewMessageHandler = async ( const customModesFilePath = await provider.customModesManager.getCustomModesFilePath() if (customModesFilePath) { - openFile(customModesFilePath) + await openFile(customModesFilePath) } break @@ -1532,7 +1534,7 @@ export const webviewMessageHandler = async ( const mcpSettingsFilePath = await provider.getMcpHub()?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { - openFile(mcpSettingsFilePath) + await openFile(mcpSettingsFilePath) } break @@ -1669,7 +1671,7 @@ export const webviewMessageHandler = async ( break case "playTts": if (message.text) { - playTts(message.text, { + void playTts(message.text, { onStart: () => provider.postMessageToWebview({ type: "ttsStart", text: message.text }), onStop: () => provider.postMessageToWebview({ type: "ttsStop", text: message.text }), }) @@ -1752,7 +1754,7 @@ export const webviewMessageHandler = async ( customModePrompts: updatedPrompts, hasOpenedModeSelector: currentState.hasOpenedModeSelector ?? false, } - provider.postMessageToWebview({ type: "state", state: stateWithPrompts }) + await provider.postMessageToWebview({ type: "state", state: stateWithPrompts }) if (TelemetryService.hasInstance()) { // Determine which setting was changed by comparing objects @@ -2157,7 +2159,7 @@ export const webviewMessageHandler = async ( try { const listApiConfig = await provider.providerSettingsManager.listConfig() await updateGlobalState("listApiConfigMeta", listApiConfig) - provider.postMessageToWebview({ type: "listApiConfig", listApiConfig }) + await provider.postMessageToWebview({ type: "listApiConfig", listApiConfig }) } catch (error) { provider.log( `Error get list api configuration: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, @@ -2333,7 +2335,7 @@ export const webviewMessageHandler = async ( await fs.writeFile(saveUri.fsPath, result.yaml, "utf-8") // Send success message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "exportModeResult", success: true, slug: message.slug, @@ -2343,7 +2345,7 @@ export const webviewMessageHandler = async ( vscode.window.showInformationMessage(t("common:info.mode_exported", { mode: message.slug })) } else { // User cancelled the save dialog - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "exportModeResult", success: false, error: "Export cancelled", @@ -2352,7 +2354,7 @@ export const webviewMessageHandler = async ( } } else { // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "exportModeResult", success: false, error: result.error, @@ -2364,7 +2366,7 @@ export const webviewMessageHandler = async ( provider.log(`Failed to export mode ${message.slug}: ${errorMessage}`) // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "exportModeResult", success: false, error: errorMessage, @@ -2423,7 +2425,7 @@ export const webviewMessageHandler = async ( await provider.postStateToWebview() // Send success message to webview, include the imported slug so UI can switch - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "importModeResult", success: true, slug: result.slug, @@ -2433,7 +2435,7 @@ export const webviewMessageHandler = async ( vscode.window.showInformationMessage(t("common:info.mode_imported")) } else { // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "importModeResult", success: false, error: result.error, @@ -2444,7 +2446,7 @@ export const webviewMessageHandler = async ( } } else { // User cancelled the file dialog - reset the importing state - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "importModeResult", success: false, error: "cancelled", @@ -2455,7 +2457,7 @@ export const webviewMessageHandler = async ( provider.log(`Failed to import mode: ${errorMessage}`) // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "importModeResult", success: false, error: errorMessage, @@ -2469,7 +2471,7 @@ export const webviewMessageHandler = async ( if (message.slug) { const hasContent = await provider.customModesManager.checkRulesDirectoryHasContent(message.slug) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "checkRulesDirectoryResult", slug: message.slug, hasContent: hasContent, @@ -2547,14 +2549,14 @@ export const webviewMessageHandler = async ( case "rooCloudSignOut": { if (!isCloudServiceAvailable()) { await provider.postStateToWebview() - provider.postMessageToWebview({ type: "authenticatedUser", userInfo: undefined }) + await provider.postMessageToWebview({ type: "authenticatedUser", userInfo: undefined }) break } try { await CloudService.instance.logout() await provider.postStateToWebview() - provider.postMessageToWebview({ type: "authenticatedUser", userInfo: undefined }) + await provider.postMessageToWebview({ type: "authenticatedUser", userInfo: undefined }) } catch (error) { provider.log(`AuthService#logout failed: ${error}`) vscode.window.showErrorMessage("Sign out failed.") @@ -2918,7 +2920,7 @@ export const webviewMessageHandler = async ( const manager = provider.getCurrentWorkspaceCodeIndexManager() if (!manager) { // No workspace open - send error status - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: { systemStatus: "Error", @@ -2943,7 +2945,7 @@ export const webviewMessageHandler = async ( workspacePath: undefined, } - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: status, }) @@ -2963,7 +2965,7 @@ export const webviewMessageHandler = async ( )) const hasOpenRouterApiKey = !!(await provider.context.secrets.get("codebaseIndexOpenRouterApiKey")) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "codeIndexSecretStatus", values: { hasOpenAiKey, @@ -2981,7 +2983,7 @@ export const webviewMessageHandler = async ( try { const manager = provider.getCurrentWorkspaceCodeIndexManager() if (!manager) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: { systemStatus: "Error", @@ -3003,12 +3005,12 @@ export const webviewMessageHandler = async ( const currentState = manager.state if (currentState === "Standby" || currentState === "Error") { - manager.startIndexing() + void manager.startIndexing() if (!manager.isInitialized) { await manager.initialize(provider.contextProxy) if (manager.state === "Standby" || manager.state === "Error") { - manager.startIndexing() + void manager.startIndexing() } } } @@ -3026,7 +3028,7 @@ export const webviewMessageHandler = async ( return } manager.stopIndexing() - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: manager.getCurrentStatus(), }) @@ -3046,11 +3048,11 @@ export const webviewMessageHandler = async ( await manager.setWorkspaceEnabled(enabled) if (enabled && manager.isFeatureEnabled && manager.isFeatureConfigured) { await manager.initialize(provider.contextProxy) - manager.startIndexing() + void manager.startIndexing() } else if (!enabled) { manager.stopIndexing() } - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: manager.getCurrentStatus(), }) @@ -3080,10 +3082,10 @@ export const webviewMessageHandler = async ( m.stopIndexing() } else if (!wasEnabled && isNowEnabled && m.isFeatureEnabled && m.isFeatureConfigured) { await m.initialize(provider.contextProxy) - m.startIndexing() + void m.startIndexing() } } - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexingStatusUpdate", values: manager.getCurrentStatus(), }) @@ -3099,7 +3101,7 @@ export const webviewMessageHandler = async ( const manager = provider.getCurrentWorkspaceCodeIndexManager() if (!manager) { provider.log("Cannot clear index data: No workspace folder open") - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexCleared", values: { success: false, @@ -3109,10 +3111,10 @@ export const webviewMessageHandler = async ( return } await manager.clearIndexData() - provider.postMessageToWebview({ type: "indexCleared", values: { success: true } }) + await provider.postMessageToWebview({ type: "indexCleared", values: { success: true } }) } catch (error) { provider.log(`Error clearing index data: ${error instanceof Error ? error.message : String(error)}`) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "indexCleared", values: { success: false, @@ -3161,7 +3163,7 @@ export const webviewMessageHandler = async ( console.log(`Marketplace item installed and config file opened: ${configFilePath}`) // Send success message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "marketplaceInstallResult", success: true, slug: message.mpItem.id, @@ -3169,7 +3171,7 @@ export const webviewMessageHandler = async ( } catch (error) { console.error(`Error installing marketplace item: ${error}`) // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "marketplaceInstallResult", success: false, error: error instanceof Error ? error.message : String(error), @@ -3187,7 +3189,7 @@ export const webviewMessageHandler = async ( await provider.postStateToWebview() // Send success message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "marketplaceRemoveResult", success: true, slug: message.mpItem.id, @@ -3201,7 +3203,7 @@ export const webviewMessageHandler = async ( ) // Send error message to webview - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "marketplaceRemoveResult", success: false, error: error instanceof Error ? error.message : String(error), @@ -3218,7 +3220,7 @@ export const webviewMessageHandler = async ( vscode.window.showErrorMessage(errorMessage) if (message.mpItem?.id) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "marketplaceRemoveResult", success: false, error: errorMessage, @@ -3334,7 +3336,7 @@ export const webviewMessageHandler = async ( const command = await getCommand(getCurrentCwd(), message.text) if (command && command.filePath) { - openFile(command.filePath) + await openFile(command.filePath) } else { vscode.window.showErrorMessage(t("common:errors.command_not_found", { name: message.text })) } @@ -3464,7 +3466,7 @@ export const webviewMessageHandler = async ( provider.log(`Created new command file: ${filePath}`) // Open the new file in the editor - openFile(filePath) + await openFile(filePath) // Refresh commands list const { getCommands } = await import("../../services/command/commands") @@ -3588,7 +3590,7 @@ export const webviewMessageHandler = async ( const accessToken = await openAiCodexOAuthManager.getAccessToken() if (!accessToken) { - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "openAiCodexRateLimits", error: "Not authenticated with OpenAI Codex", }) @@ -3599,14 +3601,14 @@ export const webviewMessageHandler = async ( const { fetchOpenAiCodexRateLimitInfo } = await import("../../integrations/openai-codex/rate-limits") const rateLimits = await fetchOpenAiCodexRateLimitInfo(accessToken, { accountId }) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "openAiCodexRateLimits", values: rateLimits, }) } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error) provider.log(`Error fetching OpenAI Codex rate limits: ${errorMessage}`) - provider.postMessageToWebview({ + await provider.postMessageToWebview({ type: "openAiCodexRateLimits", error: errorMessage, }) @@ -3732,7 +3734,7 @@ export const webviewMessageHandler = async ( createNewBranch: message.worktreeCreateNewBranch, }, (progress) => { - provider.postMessageToWebview({ + void provider.postMessageToWebview({ type: "worktreeCopyProgress", copyProgressBytesCopied: progress.bytesCopied, copyProgressItemName: progress.itemName, diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index 5c866ef941..0f29c7bd51 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -33,7 +33,7 @@ export default [ { // Ratchet: enforce no-floating-promises directory by directory. Each // directory is added here once its floating promises are resolved. - files: ["activate/**/*.ts", "core/task/**/*.ts"], + files: ["activate/**/*.ts", "core/task/**/*.ts", "core/webview/**/*.ts"], languageOptions: { parserOptions: { project: true,