fix(core,cli): enable recursive directory access for (#17094)

This commit is contained in:
Gal Zahavi
2026-01-21 09:58:23 -08:00
committed by GitHub
parent acbef4cd31
commit 45d554ae2f
17 changed files with 410 additions and 135 deletions

View File

@@ -11,6 +11,11 @@ import { debugLogger } from './debugLogger.js';
export type Unsubscribe = () => void;
export interface AddDirectoriesResult {
added: string[];
failed: Array<{ path: string; error: Error }>;
}
/**
* WorkspaceContext manages multiple workspace directories and validates paths
* against them. This allows the CLI to operate on files from multiple directories
@@ -31,9 +36,7 @@ export class WorkspaceContext {
additionalDirectories: string[] = [],
) {
this.addDirectory(targetDir);
for (const additionalDirectory of additionalDirectories) {
this.addDirectory(additionalDirectory);
}
this.addDirectories(additionalDirectories);
this.initialDirectories = new Set(this.directories);
}
@@ -67,22 +70,49 @@ export class WorkspaceContext {
* 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)
* @throws Error if the directory cannot be added
*/
addDirectory(directory: string): void {
try {
const resolved = this.resolveAndValidateDir(directory);
if (this.directories.has(resolved)) {
return;
}
this.directories.add(resolved);
this.notifyDirectoriesChanged();
} catch (err) {
debugLogger.warn(
`[WARN] Skipping unreadable directory: ${directory} (${err instanceof Error ? err.message : String(err)})`,
);
const result = this.addDirectories([directory]);
if (result.failed.length > 0) {
throw result.failed[0].error;
}
}
/**
* Adds multiple directories to the workspace.
* Emits a single change event if any directories are added.
* @param directories The directory paths to add
* @returns Object containing successfully added directories and failures
*/
addDirectories(directories: string[]): AddDirectoriesResult {
const result: AddDirectoriesResult = { added: [], failed: [] };
let changed = false;
for (const directory of directories) {
try {
const resolved = this.resolveAndValidateDir(directory);
if (!this.directories.has(resolved)) {
this.directories.add(resolved);
changed = true;
}
result.added.push(directory);
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
debugLogger.warn(
`[WARN] Skipping unreadable directory: ${directory} (${error.message})`,
);
result.failed.push({ path: directory, error });
}
}
if (changed) {
this.notifyDirectoriesChanged();
}
return result;
}
private resolveAndValidateDir(directory: string): string {
const absolutePath = path.resolve(this.targetDir, directory);