{"version":3,"file":"repo-scan.d.ts","sourceRoot":"","sources":["../../../src/core/embsearch/repo-scan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0DH,MAAM,WAAW,YAAY;IAC5B,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACnB;AAUD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAsB3E","sourcesContent":["/**\n * Repository scan for semantic indexing: enumerates indexable source files\n * using the same ignore-aware walk the native find/grep fallbacks use, and\n * totals their bytes so the caller can apply the size threshold.\n */\n\nimport { statSync } from \"fs\";\nimport path from \"path\";\nimport { collectEntries } from \"../tools/native-search.js\";\n\n/** Files larger than this are never indexed (vendored bundles, lockfiles, data dumps). */\nconst MAX_FILE_BYTES = 1024 * 1024;\n\n/** Files that are part of the ignore mechanism, not source. */\nconst SKIP_NAMES = new Set([\".gitignore\", \".gitattributes\", \".gitkeep\"]);\n\n/** Extensions that are never worth embedding. */\nconst SKIP_EXTENSIONS = new Set([\n\t\".png\",\n\t\".jpg\",\n\t\".jpeg\",\n\t\".gif\",\n\t\".webp\",\n\t\".ico\",\n\t\".bmp\",\n\t\".svg\",\n\t\".pdf\",\n\t\".zip\",\n\t\".gz\",\n\t\".tar\",\n\t\".bz2\",\n\t\".xz\",\n\t\".7z\",\n\t\".jar\",\n\t\".war\",\n\t\".class\",\n\t\".exe\",\n\t\".dll\",\n\t\".so\",\n\t\".dylib\",\n\t\".bin\",\n\t\".dat\",\n\t\".onnx\",\n\t\".pt\",\n\t\".safetensors\",\n\t\".woff\",\n\t\".woff2\",\n\t\".ttf\",\n\t\".otf\",\n\t\".eot\",\n\t\".mp3\",\n\t\".mp4\",\n\t\".wav\",\n\t\".avi\",\n\t\".mov\",\n\t\".webm\",\n\t\".lock\",\n\t\".min.js\",\n\t\".min.css\",\n\t\".map\",\n]);\n\nexport interface RepoScanFile {\n\t/** Absolute path. */\n\tabs: string;\n\t/** POSIX path relative to the scan root. */\n\trel: string;\n\t/** File size in bytes. */\n\tsize: number;\n\t/** mtime in ms. */\n\tmtimeMs: number;\n}\n\nexport interface RepoScanResult {\n\tfiles: RepoScanFile[];\n\ttotalBytes: number;\n}\n\nfunction hasSkippedExtension(rel: string): boolean {\n\tconst lower = rel.toLowerCase();\n\tfor (const ext of SKIP_EXTENSIONS) {\n\t\tif (lower.endsWith(ext)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Enumerate indexable files under `root`: respects hierarchical `.gitignore`,\n * always skips `.git`/`node_modules`, drops binary-ish extensions and files\n * over 1MB. Returns files plus their byte total for threshold checks.\n */\nexport function scanRepo(root: string, signal?: AbortSignal): RepoScanResult {\n\tconst entries = collectEntries(root, {\n\t\tsignal,\n\t\talwaysSkipDirs: new Set([\".git\", \"node_modules\"]),\n\t});\n\tconst files: RepoScanFile[] = [];\n\tlet totalBytes = 0;\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"f\") continue;\n\t\tif (SKIP_NAMES.has(path.basename(entry.rel))) continue;\n\t\tif (hasSkippedExtension(entry.rel)) continue;\n\t\tlet stat: ReturnType<typeof statSync>;\n\t\ttry {\n\t\t\tstat = statSync(entry.abs);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (stat.size === 0 || stat.size > MAX_FILE_BYTES) continue;\n\t\tfiles.push({ abs: entry.abs, rel: entry.rel, size: stat.size, mtimeMs: stat.mtimeMs });\n\t\ttotalBytes += stat.size;\n\t}\n\treturn { files, totalBytes };\n}\n"]}