fix: support multi-folder workspace for codebase indexing

- Update CodeIndexManager.getInstance() to use active workspace folder instead of always using first folder
- Add handleWorkspaceFolderChange() method to ClineProvider to re-initialize code index when workspace changes
- Integrate workspace change detection in WorkspaceTracker to trigger code index updates
- This ensures codebase index corresponds to the currently active workspace folder

Fixes #6197
This commit is contained in:
Roo Code 2025-07-25 03:34:54 +00:00
parent 02118c5e7f
commit 62c84b91e6
4 changed files with 70 additions and 13 deletions

View file

@ -1825,6 +1825,58 @@ export class ClineProvider
return this.mcpHub
}
/**
* Handle workspace folder change by re-initializing the CodeIndexManager
* This ensures the code index corresponds to the currently active workspace folder
*/
public async handleWorkspaceFolderChange() {
if (!this.codeIndexManager) {
return
}
try {
// Dispose of the old code index status subscription
if (this.codeIndexStatusSubscription) {
this.codeIndexStatusSubscription.dispose()
this.codeIndexStatusSubscription = undefined
}
// Get a new instance of CodeIndexManager for the current workspace
const newManager = CodeIndexManager.getInstance(this.context)
if (!newManager) {
this.log("No workspace folder available for code index")
return
}
// Re-initialize the manager
await newManager.initialize(this.contextProxy)
// Re-subscribe to status updates
this.codeIndexStatusSubscription = newManager.onProgressUpdate((update: IndexProgressUpdate) => {
this.postMessageToWebview({
type: "indexingStatusUpdate",
values: update,
})
})
if (this.webviewDisposables && this.codeIndexStatusSubscription) {
this.webviewDisposables.push(this.codeIndexStatusSubscription)
}
// Update the reference
;(this as any).codeIndexManager = newManager
// Send the current status to the webview
this.postMessageToWebview({
type: "indexingStatusUpdate",
values: newManager.getCurrentStatus(),
})
this.log(`Code index re-initialized for workspace: ${getWorkspacePath()}`)
} catch (error) {
this.log(`Failed to re-initialize code index: ${error}`)
}
}
/**
* Check if the current state is compliant with MDM policy
* @returns true if compliant, false if blocked

View file

@ -97,11 +97,16 @@ class WorkspaceTracker {
}
this.resetTimer = setTimeout(async () => {
if (this.prevWorkSpacePath !== this.cwd) {
await this.providerRef.deref()?.postMessageToWebview({
type: "workspaceUpdated",
filePaths: [],
openedTabs: this.getOpenedTabsInfo(),
})
const provider = this.providerRef.deref()
if (provider) {
await provider.postMessageToWebview({
type: "workspaceUpdated",
filePaths: [],
openedTabs: this.getOpenedTabsInfo(),
})
// Trigger code index re-initialization for the new workspace
await provider.handleWorkspaceFolderChange()
}
this.filePaths.clear()
this.prevWorkSpacePath = this.cwd
this.initializeFilePaths()

View file

@ -13,6 +13,9 @@ vi.mock("vscode", () => ({
},
],
},
window: {
activeTextEditor: undefined,
},
}))
// Mock only the essential dependencies

View file

@ -29,17 +29,14 @@ export class CodeIndexManager {
private _cacheManager: CacheManager | undefined
public static getInstance(context: vscode.ExtensionContext): CodeIndexManager | undefined {
// Use first workspace folder consistently
const workspaceFolders = vscode.workspace.workspaceFolders
if (!workspaceFolders || workspaceFolders.length === 0) {
// Get the workspace path based on the active editor or current context
const workspacePath = getWorkspacePath()
if (!workspacePath) {
return undefined
}
// Always use the first workspace folder for consistency across all indexing operations.
// This ensures that the same workspace context is used throughout the indexing pipeline,
// preventing path resolution errors in multi-workspace scenarios.
const workspacePath = workspaceFolders[0].uri.fsPath
// Use the workspace folder of the active editor to support multi-folder workspaces.
// This ensures that the codebase index corresponds to the folder the user is currently working in.
if (!CodeIndexManager.instances.has(workspacePath)) {
CodeIndexManager.instances.set(workspacePath, new CodeIndexManager(workspacePath, context))
}