Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ logs
.qodo/
.vercel
.roo/mcp.json

# Qdrant
qdrant_storage/
20 changes: 15 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 70 additions & 27 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<void>) | undefined

// This method is called when your extension is activated.
// Your extension is activated the very first time the command is executed.
Expand Down Expand Up @@ -94,27 +99,66 @@ 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) {
outputChannel.appendLine(
`[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) {
Expand All @@ -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(
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:^",
Expand All @@ -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",
Expand Down
2 changes: 0 additions & 2 deletions webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1787,8 +1787,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro

const areButtonsVisible = showScrollToBottom || primaryButtonText || secondaryButtonText || isStreaming

console.log("ChatView - render()")

return (
<div
data-testid="chat-view"
Expand Down
Loading