/** * Options for directory crawling */ export interface CrawlOptions { /** Base directory to start crawl */ baseDir: string; /** Include patterns (glob) - default: ['**\/*'] */ include?: string[]; /** Exclude patterns (glob) - default: ['**\/node_modules/**', '**\/.git/**'] */ exclude?: string[]; /** Follow symbolic links (default: false) */ followSymlinks?: boolean; /** Return absolute paths in results (default: true) */ absolute?: boolean; /** Only return files (not directories) - default: true */ filesOnly?: boolean; /** * Respect .gitignore files (default: true). * * When true (and the baseDir is inside a git repository) the crawl is * answered by `git ls-files`, which is orders of magnitude cheaper than * walking the tree. Setting this to false forces a full recursive walk of * every non-excluded directory — including build caches, nested worktrees * and generated output — so only pass it when you genuinely need files git * has been told to ignore. To pick up files git simply does not track yet, * use {@link CrawlOptions.includeUntracked} instead and keep the fast path. */ respectGitignore?: boolean; /** * Include untracked (but not ignored) files (default: false). * * Only meaningful alongside `respectGitignore: true`, where it widens the * `git ls-files` query from tracked files to tracked + untracked-not-ignored. * This is the right knob for "the author is editing something they have not * committed yet"; `respectGitignore: false` is not, and costs the whole walk. */ includeUntracked?: boolean; } /** * Directories no VAT crawl should ever walk into. THE canonical list — any lane * that needs its own additions should spread this rather than restate it. * * There were three of these and they disagreed: this one omitted worktrees * entirely, the discovery scanner had both worktree paths but not `dist`, and * the repo-structure gate used bare basenames. A worktree is a FULL COPY of the * repository, so omitting it does not just cost time — it makes a crawl report * the same file two or three times under different paths, and this repo keeps its * worktrees at `.claude/worktrees/`, inside a dot-directory that `dot: true` * (see {@link PICOMATCH_OPTIONS}) deliberately makes reachable. * * `.turbo` is here rather than in {@link BUILD_OUTPUT_GLOBS}, and the placement * is the decision. The line between the two lists is not "who produced it" — * `coverage/` is tool output too — it is *does any lane exist precisely to look * at it*. Something does walk `dist/`; nothing walks `.turbo`, which holds * `turbo-.log` telemetry plus, when `cacheDir` points inside it, * hash-keyed cache entries that are COPIES of package build output. That is the * `.worktrees` failure two lines up, not the `dist` one: a crawl that descends * into it reports the same file twice under two paths. Filing it as build * output would have it exactly backwards, since a lane spreading only this list * is by definition a lane that wants to see built output — and so is precisely * the lane that must not walk a cache of copies. (Turborepo is a common enough * monorepo layout that this is not hypothetical: every package in THIS repo has * a `.turbo/`.) * * Note these patterns only bite when `respectGitignore` is false; the fast * `git ls-files` path never sees ignored directories in the first place. For * `.turbo` that is the only path it could bite on — it is gitignored by every * turborepo setup — which is the same position `coverage/` and `.test-output/` * are in. */ export declare const NEVER_CRAWL_GLOBS: readonly ["**/node_modules/**", "**/.git/**", "**/coverage/**", "**/.test-output/**", "**/.worktrees/**", "**/.claude/worktrees/**", "**/.turbo/**"]; /** * Build output — excluded by DEFAULT, but deliberately NOT part of * {@link NEVER_CRAWL_GLOBS}. * * The distinction is real, and collapsing it is a bug: everything in * `NEVER_CRAWL_GLOBS` is "never user content, no lane wants it", while `dist/` is * content VAT itself produced and some lanes exist precisely to look at. Skill * discovery CLASSIFIES what it finds as source or build output, so it must walk * `dist/`; a crawl for authored markdown must not. Two different questions, so * two lists — a lane spreads whichever ones apply. */ export declare const BUILD_OUTPUT_GLOBS: readonly ["**/dist/**"]; /** * Crawl a directory tree and return matching files (async) * * Uses picomatch for glob pattern matching (same as Vitest) * Cross-platform compatible * * @param options - Crawl options * @returns Promise resolving to array of matching file paths * * @example * const files = await crawlDirectory({ * baseDir: '/project', * include: ['**\/*.md'], * exclude: ['**\/node_modules/**'], * }); */ export declare function crawlDirectory(options: CrawlOptions): Promise; /** * Crawl a directory tree and return matching files (synchronous) * * Uses picomatch for glob pattern matching (same as Vitest) * Cross-platform compatible * * @param options - Crawl options * @returns Array of matching file paths * * @example * const files = crawlDirectorySync({ * baseDir: '/project', * include: ['**\/*.md'], * exclude: ['**\/node_modules/**'], * }); */ export declare function crawlDirectorySync(options: CrawlOptions): string[]; //# sourceMappingURL=file-crawler.d.ts.map