mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
Add MCP Root change notifications (#6502)
This commit is contained in:
@@ -8,6 +8,8 @@ import { isNodeError } from '../utils/errors.js';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
export type Unsubscribe = () => void;
|
||||
|
||||
/**
|
||||
* WorkspaceContext manages multiple workspace directories and validates paths
|
||||
* against them. This allows the CLI to operate on files from multiple directories
|
||||
@@ -16,6 +18,7 @@ import * as path from 'path';
|
||||
export class WorkspaceContext {
|
||||
private directories = new Set<string>();
|
||||
private initialDirectories: Set<string>;
|
||||
private onDirectoriesChangedListeners = new Set<() => void>();
|
||||
|
||||
/**
|
||||
* Creates a new WorkspaceContext with the given initial directory and optional additional directories.
|
||||
@@ -31,13 +34,42 @@ export class WorkspaceContext {
|
||||
this.initialDirectories = new Set(this.directories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a listener that is called when the workspace directories change.
|
||||
* @param listener The listener to call.
|
||||
* @returns A function to unsubscribe the listener.
|
||||
*/
|
||||
onDirectoriesChanged(listener: () => void): Unsubscribe {
|
||||
this.onDirectoriesChangedListeners.add(listener);
|
||||
return () => {
|
||||
this.onDirectoriesChangedListeners.delete(listener);
|
||||
};
|
||||
}
|
||||
|
||||
private notifyDirectoriesChanged() {
|
||||
// Iterate over a copy of the set in case a listener unsubscribes itself or others.
|
||||
for (const listener of [...this.onDirectoriesChangedListeners]) {
|
||||
try {
|
||||
listener();
|
||||
} catch (e) {
|
||||
// Don't let one listener break others.
|
||||
console.error('Error in WorkspaceContext listener:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directory to the workspace.
|
||||
* @param directory The directory path to add (can be relative or absolute)
|
||||
* @param basePath Optional base path for resolving relative paths (defaults to cwd)
|
||||
*/
|
||||
addDirectory(directory: string, basePath: string = process.cwd()): void {
|
||||
this.directories.add(this.resolveAndValidateDir(directory, basePath));
|
||||
const resolved = this.resolveAndValidateDir(directory, basePath);
|
||||
if (this.directories.has(resolved)) {
|
||||
return;
|
||||
}
|
||||
this.directories.add(resolved);
|
||||
this.notifyDirectoriesChanged();
|
||||
}
|
||||
|
||||
private resolveAndValidateDir(
|
||||
@@ -72,9 +104,17 @@ export class WorkspaceContext {
|
||||
}
|
||||
|
||||
setDirectories(directories: readonly string[]): void {
|
||||
this.directories.clear();
|
||||
const newDirectories = new Set<string>();
|
||||
for (const dir of directories) {
|
||||
this.addDirectory(dir);
|
||||
newDirectories.add(this.resolveAndValidateDir(dir));
|
||||
}
|
||||
|
||||
if (
|
||||
newDirectories.size !== this.directories.size ||
|
||||
![...newDirectories].every((d) => this.directories.has(d))
|
||||
) {
|
||||
this.directories = newDirectories;
|
||||
this.notifyDirectoriesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user