mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-07 02:58:15 +00:00
fix: identify mcp and slash command config path in multiple folder workspace (#6904)
This commit is contained in:
parent
0510c03684
commit
1e403a7c92
9 changed files with 50 additions and 38 deletions
|
|
@ -95,7 +95,7 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
|
|||
TelemetryService.instance.captureTitleButtonClicked("plus")
|
||||
|
||||
await visibleProvider.removeClineFromStack()
|
||||
await visibleProvider.postStateToWebview()
|
||||
await visibleProvider.refreshWorkspace()
|
||||
await visibleProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
|
||||
// Send focusInput action immediately after chatButtonClicked
|
||||
// This ensures the focus happens after the view has switched
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { isBinaryFile } from "isbinaryfile"
|
|||
import { mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "../../shared/context-mentions"
|
||||
|
||||
import { getCommitInfo, getWorkingState } from "../../utils/git"
|
||||
import { getWorkspacePath } from "../../utils/path"
|
||||
|
||||
import { openFile } from "../../integrations/misc/open-file"
|
||||
import { extractTextFromFile } from "../../integrations/misc/extract-text"
|
||||
|
|
@ -49,16 +48,11 @@ function getUrlErrorMessage(error: unknown): string {
|
|||
return t("common:errors.url_fetch_failed", { error: errorMessage })
|
||||
}
|
||||
|
||||
export async function openMention(mention?: string): Promise<void> {
|
||||
export async function openMention(cwd: string, mention?: string): Promise<void> {
|
||||
if (!mention) {
|
||||
return
|
||||
}
|
||||
|
||||
const cwd = getWorkspacePath()
|
||||
if (!cwd) {
|
||||
return
|
||||
}
|
||||
|
||||
if (mention.startsWith("/")) {
|
||||
// Slice off the leading slash and unescape any spaces in the path
|
||||
const relPath = unescapeSpaces(mention.slice(1))
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ export interface TaskOptions extends CreateTaskOptions {
|
|||
taskNumber?: number
|
||||
onCreated?: (task: Task) => void
|
||||
initialTodos?: TodoItem[]
|
||||
workspacePath?: string
|
||||
}
|
||||
|
||||
export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
||||
|
|
@ -313,6 +314,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
taskNumber = -1,
|
||||
onCreated,
|
||||
initialTodos,
|
||||
workspacePath,
|
||||
}: TaskOptions) {
|
||||
super()
|
||||
|
||||
|
|
@ -333,7 +335,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
// Normal use-case is usually retry similar history task with new workspace.
|
||||
this.workspacePath = parentTask
|
||||
? parentTask.workspacePath
|
||||
: getWorkspacePath(path.join(os.homedir(), "Desktop"))
|
||||
: (workspacePath ?? getWorkspacePath(path.join(os.homedir(), "Desktop")))
|
||||
|
||||
this.instanceId = crypto.randomUUID().slice(0, 8)
|
||||
this.taskNumber = -1
|
||||
|
|
|
|||
|
|
@ -126,13 +126,14 @@ export class ClineProvider
|
|||
private view?: vscode.WebviewView | vscode.WebviewPanel
|
||||
private clineStack: Task[] = []
|
||||
private codeIndexStatusSubscription?: vscode.Disposable
|
||||
private currentWorkspaceManager?: CodeIndexManager
|
||||
private codeIndexManager?: CodeIndexManager
|
||||
private _workspaceTracker?: WorkspaceTracker // workSpaceTracker read-only for access outside this class
|
||||
protected mcpHub?: McpHub // Change from private to protected
|
||||
private marketplaceManager: MarketplaceManager
|
||||
private mdmService?: MdmService
|
||||
private taskCreationCallback: (task: Task) => void
|
||||
private taskEventListeners: WeakMap<Task, Array<() => void>> = new WeakMap()
|
||||
private currentWorkspacePath: string | undefined
|
||||
|
||||
private recentTasksCache?: string[]
|
||||
private pendingOperations: Map<string, PendingEditOperation> = new Map()
|
||||
|
|
@ -152,6 +153,7 @@ export class ClineProvider
|
|||
mdmService?: MdmService,
|
||||
) {
|
||||
super()
|
||||
this.currentWorkspacePath = getWorkspacePath()
|
||||
|
||||
ClineProvider.activeInstances.add(this)
|
||||
|
||||
|
|
@ -792,7 +794,7 @@ export class ClineProvider
|
|||
this.log("Clearing webview resources for sidebar view")
|
||||
this.clearWebviewResources()
|
||||
// Reset current workspace manager reference when view is disposed
|
||||
this.currentWorkspaceManager = undefined
|
||||
this.codeIndexManager = undefined
|
||||
}
|
||||
},
|
||||
null,
|
||||
|
|
@ -880,6 +882,7 @@ export class ClineProvider
|
|||
rootTask: historyItem.rootTask,
|
||||
parentTask: historyItem.parentTask,
|
||||
taskNumber: historyItem.number,
|
||||
workspacePath: historyItem.workspace,
|
||||
onCreated: this.taskCreationCallback,
|
||||
enableBridge: BridgeOrchestrator.isEnabled(cloudUserInfo, remoteControlEnabled),
|
||||
})
|
||||
|
|
@ -1562,6 +1565,11 @@ export class ClineProvider
|
|||
await this.postStateToWebview()
|
||||
}
|
||||
|
||||
async refreshWorkspace() {
|
||||
this.currentWorkspacePath = getWorkspacePath()
|
||||
await this.postStateToWebview()
|
||||
}
|
||||
|
||||
async postStateToWebview() {
|
||||
const state = await this.getStateToPostToWebview()
|
||||
this.postMessageToWebview({ type: "state", state })
|
||||
|
|
@ -2287,7 +2295,7 @@ export class ClineProvider
|
|||
const currentManager = this.getCurrentWorkspaceCodeIndexManager()
|
||||
|
||||
// If the manager hasn't changed, no need to update subscription
|
||||
if (currentManager === this.currentWorkspaceManager) {
|
||||
if (currentManager === this.codeIndexManager) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -2298,7 +2306,7 @@ export class ClineProvider
|
|||
}
|
||||
|
||||
// Update the current workspace manager reference
|
||||
this.currentWorkspaceManager = currentManager
|
||||
this.codeIndexManager = currentManager
|
||||
|
||||
// Subscribe to the new manager's progress updates if it exists
|
||||
if (currentManager) {
|
||||
|
|
@ -2659,7 +2667,7 @@ export class ClineProvider
|
|||
}
|
||||
|
||||
public get cwd() {
|
||||
return getWorkspacePath()
|
||||
return this.currentWorkspacePath || getWorkspacePath()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ export const webviewMessageHandler = async (
|
|||
const updateGlobalState = async <K extends keyof GlobalState>(key: K, value: GlobalState[K]) =>
|
||||
await provider.contextProxy.setValue(key, value)
|
||||
|
||||
const getCurrentCwd = () => {
|
||||
return provider.getCurrentTask()?.cwd || provider.cwd
|
||||
}
|
||||
/**
|
||||
* Shared utility to find message indices based on timestamp
|
||||
*/
|
||||
|
|
@ -912,10 +915,14 @@ export const webviewMessageHandler = async (
|
|||
saveImage(message.dataUri!)
|
||||
break
|
||||
case "openFile":
|
||||
openFile(message.text!, message.values as { create?: boolean; content?: string; line?: number })
|
||||
let filePath: string = message.text!
|
||||
if (!path.isAbsolute(filePath)) {
|
||||
filePath = path.join(getCurrentCwd(), filePath)
|
||||
}
|
||||
openFile(filePath, message.values as { create?: boolean; content?: string; line?: number })
|
||||
break
|
||||
case "openMention":
|
||||
openMention(message.text)
|
||||
openMention(getCurrentCwd(), message.text)
|
||||
break
|
||||
case "openExternal":
|
||||
if (message.url) {
|
||||
|
|
@ -1010,8 +1017,8 @@ export const webviewMessageHandler = async (
|
|||
return
|
||||
}
|
||||
|
||||
const workspaceFolder = vscode.workspace.workspaceFolders[0]
|
||||
const rooDir = path.join(workspaceFolder.uri.fsPath, ".roo")
|
||||
const workspaceFolder = getCurrentCwd()
|
||||
const rooDir = path.join(workspaceFolder, ".roo")
|
||||
const mcpPath = path.join(rooDir, "mcp.json")
|
||||
|
||||
try {
|
||||
|
|
@ -1660,7 +1667,7 @@ export const webviewMessageHandler = async (
|
|||
}
|
||||
break
|
||||
case "searchCommits": {
|
||||
const cwd = provider.cwd
|
||||
const cwd = getCurrentCwd()
|
||||
if (cwd) {
|
||||
try {
|
||||
const commits = await searchCommits(message.query || "", cwd)
|
||||
|
|
@ -1678,7 +1685,7 @@ export const webviewMessageHandler = async (
|
|||
break
|
||||
}
|
||||
case "searchFiles": {
|
||||
const workspacePath = getWorkspacePath()
|
||||
const workspacePath = getCurrentCwd()
|
||||
|
||||
if (!workspacePath) {
|
||||
// Handle case where workspace path is not available
|
||||
|
|
@ -2662,7 +2669,7 @@ export const webviewMessageHandler = async (
|
|||
case "requestCommands": {
|
||||
try {
|
||||
const { getCommands } = await import("../../services/command/commands")
|
||||
const commands = await getCommands(provider.cwd || "")
|
||||
const commands = await getCommands(getCurrentCwd())
|
||||
|
||||
// Convert to the format expected by the frontend
|
||||
const commandList = commands.map((command) => ({
|
||||
|
|
@ -2691,7 +2698,7 @@ export const webviewMessageHandler = async (
|
|||
try {
|
||||
if (message.text) {
|
||||
const { getCommand } = await import("../../services/command/commands")
|
||||
const command = await getCommand(provider.cwd || "", message.text)
|
||||
const command = await getCommand(getCurrentCwd(), message.text)
|
||||
|
||||
if (command && command.filePath) {
|
||||
openFile(command.filePath)
|
||||
|
|
@ -2711,7 +2718,7 @@ export const webviewMessageHandler = async (
|
|||
try {
|
||||
if (message.text && message.values?.source) {
|
||||
const { getCommand } = await import("../../services/command/commands")
|
||||
const command = await getCommand(provider.cwd || "", message.text)
|
||||
const command = await getCommand(getCurrentCwd(), message.text)
|
||||
|
||||
if (command && command.filePath) {
|
||||
// Delete the command file
|
||||
|
|
@ -2743,8 +2750,12 @@ export const webviewMessageHandler = async (
|
|||
const globalConfigDir = path.join(os.homedir(), ".roo")
|
||||
commandsDir = path.join(globalConfigDir, "commands")
|
||||
} else {
|
||||
if (!vscode.workspace.workspaceFolders?.length) {
|
||||
vscode.window.showErrorMessage(t("common:errors.no_workspace"))
|
||||
return
|
||||
}
|
||||
// Project commands
|
||||
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath
|
||||
const workspaceRoot = getCurrentCwd()
|
||||
if (!workspaceRoot) {
|
||||
vscode.window.showErrorMessage(t("common:errors.no_workspace_for_project_command"))
|
||||
break
|
||||
|
|
@ -2824,7 +2835,7 @@ export const webviewMessageHandler = async (
|
|||
|
||||
// Refresh commands list
|
||||
const { getCommands } = await import("../../services/command/commands")
|
||||
const commands = await getCommands(provider.cwd || "")
|
||||
const commands = await getCommands(getCurrentCwd() || "")
|
||||
const commandList = commands.map((command) => ({
|
||||
name: command.name,
|
||||
source: command.source,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class WorkspaceTracker {
|
|||
private resetTimer: NodeJS.Timeout | null = null
|
||||
|
||||
get cwd() {
|
||||
return getWorkspacePath()
|
||||
return this.providerRef?.deref()?.cwd ?? getWorkspacePath()
|
||||
}
|
||||
constructor(provider: ClineProvider) {
|
||||
this.providerRef = new WeakRef(provider)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import * as vscode from "vscode"
|
||||
import { getWorkspacePath } from "../../utils/path"
|
||||
import { ContextProxy } from "../../core/config/ContextProxy"
|
||||
import { VectorStoreSearchResult } from "./interfaces"
|
||||
import { IndexingState } from "./interfaces/manager"
|
||||
|
|
@ -133,7 +132,7 @@ export class CodeIndexManager {
|
|||
}
|
||||
|
||||
// 3. Check if workspace is available
|
||||
const workspacePath = getWorkspacePath()
|
||||
const workspacePath = this.workspacePath
|
||||
if (!workspacePath) {
|
||||
this._stateManager.setSystemState("Standby", "No workspace folder open")
|
||||
return { requiresRestart }
|
||||
|
|
@ -306,7 +305,7 @@ export class CodeIndexManager {
|
|||
)
|
||||
|
||||
const ignoreInstance = ignore()
|
||||
const workspacePath = getWorkspacePath()
|
||||
const workspacePath = this.workspacePath
|
||||
|
||||
if (!workspacePath) {
|
||||
this._stateManager.setSystemState("Standby", "")
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export class QdrantVectorStore implements IVectorStore {
|
|||
private client: QdrantClient
|
||||
private readonly collectionName: string
|
||||
private readonly qdrantUrl: string = "http://localhost:6333"
|
||||
private readonly workspacePath: string
|
||||
|
||||
/**
|
||||
* Creates a new Qdrant vector store
|
||||
|
|
@ -29,6 +30,7 @@ export class QdrantVectorStore implements IVectorStore {
|
|||
|
||||
// Store the resolved URL for our property
|
||||
this.qdrantUrl = parsedUrl
|
||||
this.workspacePath = workspacePath
|
||||
|
||||
try {
|
||||
const urlObj = new URL(parsedUrl)
|
||||
|
|
@ -457,7 +459,7 @@ export class QdrantVectorStore implements IVectorStore {
|
|||
return
|
||||
}
|
||||
|
||||
const workspaceRoot = getWorkspacePath()
|
||||
const workspaceRoot = this.workspacePath
|
||||
|
||||
// Build filters using pathSegments to match the indexed fields
|
||||
const filters = filePaths.map((filePath) => {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import {
|
|||
McpToolCallResponse,
|
||||
} from "../../shared/mcp"
|
||||
import { fileExistsAtPath } from "../../utils/fs"
|
||||
import { arePathsEqual } from "../../utils/path"
|
||||
import { arePathsEqual, getWorkspacePath } from "../../utils/path"
|
||||
import { injectVariables } from "../../utils/config"
|
||||
|
||||
// Discriminated union for connection states
|
||||
|
|
@ -349,7 +349,7 @@ export class McpHub {
|
|||
return
|
||||
}
|
||||
|
||||
const workspaceFolder = vscode.workspace.workspaceFolders[0]
|
||||
const workspaceFolder = this.providerRef.deref()?.cwd ?? getWorkspacePath()
|
||||
const projectMcpPattern = new vscode.RelativePattern(workspaceFolder, ".roo/mcp.json")
|
||||
|
||||
// Create a file system watcher for the project MCP file pattern
|
||||
|
|
@ -551,12 +551,8 @@ export class McpHub {
|
|||
|
||||
// Get project-level MCP configuration path
|
||||
private async getProjectMcpPath(): Promise<string | null> {
|
||||
if (!vscode.workspace.workspaceFolders?.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
const workspaceFolder = vscode.workspace.workspaceFolders[0]
|
||||
const projectMcpDir = path.join(workspaceFolder.uri.fsPath, ".roo")
|
||||
const workspacePath = this.providerRef.deref()?.cwd ?? getWorkspacePath()
|
||||
const projectMcpDir = path.join(workspacePath, ".roo")
|
||||
const projectMcpPath = path.join(projectMcpDir, "mcp.json")
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue