import { realpathSync } from "fs"; import path from "path"; const WINDOWS_ABSOLUTE_RE = /^[a-zA-Z]:[\\/]/; function isWindowsAbsolutePath(filePath: string): boolean { return WINDOWS_ABSOLUTE_RE.test(filePath) || filePath.startsWith("\\\\") || filePath.startsWith("//"); } export function isPathWithinRoots(target: string, roots: Set): boolean { for (const root of roots) { const useWindowsRules = isWindowsAbsolutePath(target) || isWindowsAbsolutePath(root); const resolver = useWindowsRules ? path.win32 : path; const sep = useWindowsRules ? "\\" : path.sep; const normalized = resolver.resolve(target); const normalizedRoot = resolver.resolve(root); const comparable = useWindowsRules ? normalized.toLowerCase() : normalized; const comparableRoot = useWindowsRules ? normalizedRoot.toLowerCase() : normalizedRoot; const rootWithSep = comparableRoot.endsWith(sep) ? comparableRoot : comparableRoot + sep; if (comparable === comparableRoot || comparable.startsWith(rootWithSep)) return true; } return false; } export function isExistingPathWithinRoots(target: string, roots: Set): boolean { let realTarget: string; try { realTarget = realpathSync(target); } catch { return false; } const realRoots = new Set(); for (const root of roots) { try { realRoots.add(realpathSync(root)); } catch { // Ignore stale roots derived from removed sessions or worktrees. } } return isPathWithinRoots(realTarget, realRoots); }