diff --git a/.gitignore b/.gitignore index 65c201c3c25..e044fc32a7b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ logs .qodo/ .vercel .roo/mcp.json + +# Qdrant +qdrant_storage/ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 905845e552e..191d8100443 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -584,8 +584,8 @@ importers: specifier: ^1.14.0 version: 1.14.0(typescript@5.8.3) '@roo-code/cloud': - specifier: ^0.22.0 - version: 0.22.0 + specifier: ^0.24.0 + version: 0.24.0 '@roo-code/ipc': specifier: workspace:^ version: link:../packages/ipc @@ -661,6 +661,9 @@ importers: isbinaryfile: specifier: ^5.0.2 version: 5.0.4 + jwt-decode: + specifier: ^4.0.0 + version: 4.0.0 lodash.debounce: specifier: ^4.0.8 version: 4.0.8 @@ -3343,8 +3346,8 @@ packages: cpu: [x64] os: [win32] - '@roo-code/cloud@0.22.0': - resolution: {integrity: sha512-s1d4wcDYeDzcwr+YypMWDlNKL4f2osOZ3NoIlD36LCfFeMs+hnluZPS1oXX3WHtmPDC76vSzPMfwW2Ef41hEoA==} + '@roo-code/cloud@0.24.0': + resolution: {integrity: sha512-0aG1rWFQ18jCC1ZuDlBYoB+di640p7uK1pv2zNRwOJIClWRtkP84GARYPotRgtCGfiyuI4sQ0jQRdi8Hh1ClRQ==} '@roo-code/types@1.61.0': resolution: {integrity: sha512-YJdFc6aYfaZ8EN08KbWaKLehRr1dcN3G3CzDjpppb08iehSEUZMycax/ryP5/G4vl34HTdtzyHNMboDen5ElUg==} @@ -7001,6 +7004,10 @@ packages: jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + katex@0.16.22: resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} hasBin: true @@ -12725,10 +12732,11 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.40.2': optional: true - '@roo-code/cloud@0.22.0': + '@roo-code/cloud@0.24.0': dependencies: '@roo-code/types': 1.61.0 ioredis: 5.6.1 + jwt-decode: 4.0.0 p-wait-for: 5.0.2 socket.io-client: 4.8.1 zod: 3.25.76 @@ -17002,6 +17010,8 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 + jwt-decode@4.0.0: {} + katex@0.16.22: dependencies: commander: 8.3.0 diff --git a/src/extension.ts b/src/extension.ts index 6cb6ea4b073..bd0863bd35f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,7 +12,7 @@ try { console.warn("Failed to load environment variables:", e) } -import { CloudService, ExtensionBridgeService } from "@roo-code/cloud" +import { CloudService, ExtensionBridgeService, type CloudUserInfo } from "@roo-code/cloud" import { TelemetryService, PostHogTelemetryClient } from "@roo-code/telemetry" import "./utils/path" // Necessary to have access to String.prototype.toPosix. @@ -51,6 +51,11 @@ import { initializeI18n } from "./i18n" let outputChannel: vscode.OutputChannel let extensionContext: vscode.ExtensionContext +let cloudService: CloudService | undefined + +let authStateChangedHandler: (() => void) | undefined +let settingsUpdatedHandler: (() => void) | undefined +let userInfoHandler: ((data: { userInfo: CloudUserInfo }) => Promise) | undefined // This method is called when your extension is activated. // Your extension is activated the very first time the command is executed. @@ -94,13 +99,16 @@ export async function activate(context: vscode.ExtensionContext) { const contextProxy = await ContextProxy.getInstance(context) - // Initialize code index managers for all workspace folders + // Initialize code index managers for all workspace folders. const codeIndexManagers: CodeIndexManager[] = [] + if (vscode.workspace.workspaceFolders) { for (const folder of vscode.workspace.workspaceFolders) { const manager = CodeIndexManager.getInstance(context, folder.uri.fsPath) + if (manager) { codeIndexManagers.push(manager) + try { await manager.initialize(contextProxy) } catch (error) { @@ -108,13 +116,49 @@ export async function activate(context: vscode.ExtensionContext) { `[CodeIndexManager] Error during background CodeIndexManager configuration/indexing for ${folder.uri.fsPath}: ${error.message || error}`, ) } + context.subscriptions.push(manager) } } } + // Initialize the provider *before* the Roo Code Cloud service. + const provider = new ClineProvider(context, outputChannel, "sidebar", contextProxy, mdmService) + // Initialize Roo Code Cloud service. - const cloudService = await CloudService.createInstance(context, cloudLogger) + const postStateListener = () => ClineProvider.getVisibleInstance()?.postStateToWebview() + authStateChangedHandler = postStateListener + settingsUpdatedHandler = postStateListener + + userInfoHandler = async ({ userInfo }: { userInfo: CloudUserInfo }) => { + postStateListener() + + if (!CloudService.instance.cloudAPI) { + cloudLogger("[CloudService] CloudAPI is not initialized") + return + } + + try { + const config = await CloudService.instance.cloudAPI.bridgeConfig() + + ExtensionBridgeService.handleRemoteControlState( + userInfo, + contextProxy.getValue("remoteControlEnabled"), + { ...config, provider, sessionId: vscode.env.sessionId }, + (message: string) => outputChannel.appendLine(message), + ) + } catch (error) { + cloudLogger( + `[CloudService] Failed to fetch bridgeConfig: ${error instanceof Error ? error.message : String(error)}`, + ) + } + } + + cloudService = await CloudService.createInstance(context, cloudLogger, { + "auth-state-changed": authStateChangedHandler, + "settings-updated": settingsUpdatedHandler, + "user-info": userInfoHandler, + }) try { if (cloudService.telemetryClient) { @@ -126,33 +170,10 @@ export async function activate(context: vscode.ExtensionContext) { ) } - const postStateListener = () => ClineProvider.getVisibleInstance()?.postStateToWebview() - - cloudService.on("auth-state-changed", postStateListener) - cloudService.on("settings-updated", postStateListener) - - cloudService.on("user-info", async ({ userInfo }) => { - postStateListener() - - const bridgeConfig = await cloudService.cloudAPI?.bridgeConfig().catch(() => undefined) - - if (!bridgeConfig) { - outputChannel.appendLine("[CloudService] Failed to get bridge config") - return - } - - ExtensionBridgeService.handleRemoteControlState( - userInfo, - contextProxy.getValue("remoteControlEnabled"), - { ...bridgeConfig, provider, sessionId: vscode.env.sessionId }, - (message: string) => outputChannel.appendLine(message), - ) - }) - // Add to subscriptions for proper cleanup on deactivate. context.subscriptions.push(cloudService) - const provider = new ClineProvider(context, outputChannel, "sidebar", contextProxy, mdmService) + // Finish initializing the provider. TelemetryService.instance.setProvider(provider) context.subscriptions.push( @@ -280,6 +301,28 @@ export async function activate(context: vscode.ExtensionContext) { export async function deactivate() { outputChannel.appendLine(`${Package.name} extension deactivated`) + if (cloudService && CloudService.hasInstance()) { + try { + if (authStateChangedHandler) { + CloudService.instance.off("auth-state-changed", authStateChangedHandler) + } + + if (settingsUpdatedHandler) { + CloudService.instance.off("settings-updated", settingsUpdatedHandler) + } + + if (userInfoHandler) { + CloudService.instance.off("user-info", userInfoHandler as any) + } + + outputChannel.appendLine("CloudService event handlers cleaned up") + } catch (error) { + outputChannel.appendLine( + `Failed to clean up CloudService event handlers: ${error instanceof Error ? error.message : String(error)}`, + ) + } + } + const bridgeService = ExtensionBridgeService.getInstance() if (bridgeService) { diff --git a/src/package.json b/src/package.json index 1f515496845..64e097aed0e 100644 --- a/src/package.json +++ b/src/package.json @@ -429,7 +429,7 @@ "@mistralai/mistralai": "^1.9.18", "@modelcontextprotocol/sdk": "^1.9.0", "@qdrant/js-client-rest": "^1.14.0", - "@roo-code/cloud": "^0.22.0", + "@roo-code/cloud": "^0.24.0", "@roo-code/ipc": "workspace:^", "@roo-code/telemetry": "workspace:^", "@roo-code/types": "workspace:^", @@ -455,6 +455,7 @@ "i18next": "^25.0.0", "ignore": "^7.0.3", "isbinaryfile": "^5.0.2", + "jwt-decode": "^4.0.0", "lodash.debounce": "^4.0.8", "mammoth": "^1.9.1", "monaco-vscode-textmate-theme-converter": "^0.1.7", diff --git a/webview-ui/src/components/chat/ChatView.tsx b/webview-ui/src/components/chat/ChatView.tsx index 8a93b8becc7..7cca453580b 100644 --- a/webview-ui/src/components/chat/ChatView.tsx +++ b/webview-ui/src/components/chat/ChatView.tsx @@ -1787,8 +1787,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction