export interface ProjectInfo { name: string; path: string; type: 'repo' | 'worktree'; branch: string; } export interface ProjectScanOptions { includeWorktrees?: boolean; /** Hard cap on directories visited during a single scan. Guards against a * misconfigured scan root (e.g. `~`) turning the synchronous walk into a * minutes-long event-loop stall. Defaults to DEFAULT_MAX_SCAN_DIRS. */ maxScanDirs?: number; /** Wall-clock budget (ms) for a single scan, checked between filesystem * calls. A dir-count cap alone doesn't bound a "repo storm" root where * each repo spawns a slow `git` subprocess; this stops the walk once the * budget is spent. Defaults to DEFAULT_MAX_SCAN_MS. Note: this cannot * interrupt a single syscall already blocked in the kernel (e.g. a * readdir that hangs on a protected/stale directory) — only the space * between calls. Narrowing the scan root remains the real fix. */ maxScanMs?: number; /** Invoked once, after the walk, if either budget (dirs or wall-clock) was * hit — meaning the returned list may be incomplete. Lets a caller surface a * "scan root too large / narrow it" hint to the user instead of silently * showing a partial list or a misleading "no repos found". Not called when * the scan completes within budget. `reason` says which cap tripped. */ onBudgetExceeded?: (info: { reason: 'dirs' | 'time'; dirsVisited: number; baseDir: string; }) => void; } /** Upper bound on directories a single `scanProjects` walk will visit before * bailing out. `scanProjects` is fully synchronous (readdirSync + a `git` * subprocess per repo), so an unbounded walk over a huge root such as the * home directory blocks the daemon's event loop — no repo card is ever sent * and the whole bot appears hung. 4000 dirs comfortably covers a normal * projects root while capping the worst case. */ export declare const DEFAULT_MAX_SCAN_DIRS = 4000; /** Wall-clock budget for one scan. A normal projects root scans in well under * a second; anything past a few seconds means the root is misconfigured * (pointed at `~` or similar). Bailing keeps the daemon responsive. */ export declare const DEFAULT_MAX_SCAN_MS = 4000; /** * Describe a single directory as a project: the main worktree basename + * current git ref, or null if the directory isn't a git repo/worktree. Using * the main worktree name preserves the picker label for an explicitly selected * linked worktree without recursively scanning the configured roots first. */ export declare function describeProjectDir(dir: string): { name: string; branch: string; } | null; /** * Scan a directory for git repositories and their worktrees. */ export declare function scanProjects(baseDir: string, maxDepth?: number, options?: ProjectScanOptions): ProjectInfo[]; /** * Scan multiple directories and deduplicate by path. */ export declare function scanMultipleProjects(baseDirs: string[], maxDepth?: number, options?: ProjectScanOptions): ProjectInfo[]; //# sourceMappingURL=project-scanner.d.ts.map