kly 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,6 +21,14 @@ kly scans your codebase, extracts structural information via tree-sitter AST, an
21
21
  npm install -g kly
22
22
  ```
23
23
 
24
+ ## Agent Skill
25
+
26
+ Install the kly skill to let your AI agent use kly automatically:
27
+
28
+ ```bash
29
+ npx skills add xinyao27/kly
30
+ ```
31
+
24
32
  ## Quick Start
25
33
 
26
34
  ```bash
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as openDatabase, E as saveState, F as isGitRepo, J as loadConfig, K as initKlyDir, M as getFileHistory, S as loadState, a as searchFilesWithRerank, c as buildDependencyGraph, d as renderGraphAscii, f as renderGraphSvg, i as searchFiles, l as generateMermaid, q as isInitialized, s as buildIndex, t as enrichErrorStack, w as removeBranchDb, x as listBranchDbs } from "./enrich-BHaZ2daX.mjs";
2
+ import { C as openDatabase, E as saveState, F as isGitRepo, J as isInitialized, M as getFileHistory, S as loadState, Y as loadConfig, a as searchFilesWithRerank, c as buildDependencyGraph, d as renderGraphAscii, f as renderGraphSvg, i as searchFiles, l as generateMermaid, q as initKlyDir, s as buildIndex, t as enrichErrorStack, w as removeBranchDb, x as listBranchDbs } from "./enrich-CjNdkQfO.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { execSync } from "node:child_process";
@@ -85,6 +85,21 @@ function getStatePath(root) {
85
85
  function isInitialized(root) {
86
86
  return fs.existsSync(getKlyDir(root));
87
87
  }
88
+ const GITIGNORE_ENTRY = ".kly";
89
+ /** Append `.kly` to root `.gitignore` when inside a git repo; idempotent. */
90
+ function ensureGitignore(root) {
91
+ const gitDir = path.join(root, ".git");
92
+ if (!fs.existsSync(gitDir)) return;
93
+ const gitignorePath = path.join(root, ".gitignore");
94
+ if (!fs.existsSync(gitignorePath)) {
95
+ fs.writeFileSync(gitignorePath, `${GITIGNORE_ENTRY}\n`, "utf-8");
96
+ return;
97
+ }
98
+ const content = fs.readFileSync(gitignorePath, "utf-8");
99
+ if (content.split(/\r?\n/).some((line) => line.trim() === GITIGNORE_ENTRY)) return;
100
+ const suffix = content.endsWith("\n") || content === "" ? `${GITIGNORE_ENTRY}\n` : `\n${GITIGNORE_ENTRY}\n`;
101
+ fs.appendFileSync(gitignorePath, suffix, "utf-8");
102
+ }
88
103
  function initKlyDir(root, config) {
89
104
  const klyDir = getKlyDir(root);
90
105
  if (!fs.existsSync(klyDir)) fs.mkdirSync(klyDir, { recursive: true });
@@ -92,6 +107,7 @@ function initKlyDir(root, config) {
92
107
  if (!fs.existsSync(dbDir)) fs.mkdirSync(dbDir, { recursive: true });
93
108
  const configToWrite = config || DEFAULT_CONFIG;
94
109
  fs.writeFileSync(getConfigPath(root), stringify(configToWrite), "utf-8");
110
+ ensureGitignore(root);
95
111
  }
96
112
  function loadConfig(root) {
97
113
  const configPath = getConfigPath(root);
@@ -2995,6 +3011,6 @@ function enrichErrorStack(db, root, frames) {
2995
3011
  };
2996
3012
  }
2997
3013
  //#endregion
2998
- export { getCurrentBranch as A, getConfigPath as B, openDatabase as C, setBranchState as D, saveState as E, isGitRepo as F, hashConfig as G, getDbPath as H, hasChanged as I, loadConfig as J, initKlyDir as K, hashFile as L, getFileHistory as M, getMergeBase as N, branchToDbName as O, isAncestor as P, scanFiles as R, loadState as S, resolveDbName as T, getKlyDir as U, getDbDir as V, getStatePath as W, copyDatabase as _, searchFilesWithRerank as a, getFileFromDb as b, buildDependencyGraph as c, renderGraphAscii as d, renderGraphSvg as f, filterGitDiff as g, ParserManager as h, searchFiles as i, getCurrentCommit as j, getChangedFiles as k, generateMermaid as l, LLMService as m, filterByLanguage as n, rerankResults as o, resolveImport as p, isInitialized as q, filterByPath as r, buildIndex as s, enrichErrorStack as t, isRelativeImport as u, getAllFilesFromDb as v, removeBranchDb as w, listBranchDbs as x, getBranchState as y, IndexDatabase as z };
3014
+ export { getCurrentBranch as A, ensureGitignore as B, openDatabase as C, setBranchState as D, saveState as E, isGitRepo as F, getStatePath as G, getDbDir as H, hasChanged as I, isInitialized as J, hashConfig as K, hashFile as L, getFileHistory as M, getMergeBase as N, branchToDbName as O, isAncestor as P, scanFiles as R, loadState as S, resolveDbName as T, getDbPath as U, getConfigPath as V, getKlyDir as W, loadConfig as Y, copyDatabase as _, searchFilesWithRerank as a, getFileFromDb as b, buildDependencyGraph as c, renderGraphAscii as d, renderGraphSvg as f, filterGitDiff as g, ParserManager as h, searchFiles as i, getCurrentCommit as j, getChangedFiles as k, generateMermaid as l, LLMService as m, filterByLanguage as n, rerankResults as o, resolveImport as p, initKlyDir as q, filterByPath as r, buildIndex as s, enrichErrorStack as t, isRelativeImport as u, getAllFilesFromDb as v, removeBranchDb as w, listBranchDbs as x, getBranchState as y, IndexDatabase as z };
2999
3015
 
3000
- //# sourceMappingURL=enrich-BHaZ2daX.mjs.map
3016
+ //# sourceMappingURL=enrich-CjNdkQfO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrich-CjNdkQfO.mjs","names":["stringifyYaml","parseYaml","parseYaml","stringifyYaml","path","path","path","SYMBOL_NODE_TYPES","extractName"],"sources":["../src/config.ts","../src/database.ts","../src/scanner.ts","../src/hasher.ts","../src/git.ts","../src/store.ts","../node_modules/picomatch/lib/constants.js","../node_modules/picomatch/lib/utils.js","../node_modules/picomatch/lib/scan.js","../node_modules/picomatch/lib/parse.js","../node_modules/picomatch/lib/picomatch.js","../node_modules/picomatch/index.js","../src/diff-filter.ts","../src/parser/base.ts","../src/parser/swift.ts","../src/parser/typescript.ts","../src/parser/index.ts","../src/llm/batcher.ts","../src/llm/prompts.ts","../src/llm/index.ts","../src/graph.ts","../src/indexer.ts","../src/llm/reranker.ts","../src/query.ts","../src/enrich.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport type { KlyConfig } from \"./types\";\n\nconst KLY_DIR = \".kly\";\nconst CONFIG_FILE = \"config.yaml\";\nconst DB_DIR = \"db\";\nconst STATE_FILE = \"state.yaml\";\n\nconst DEFAULT_CONFIG: KlyConfig = {\n llm: {\n provider: \"openrouter\",\n model: \"anthropic/claude-haiku-4.5\",\n apiKey: \"\",\n },\n include: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\", \"**/*.swift\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.git/**\",\n \"**/.kly/**\",\n \"**/vendor/**\",\n \"**/*.d.ts\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/__tests__/**\",\n ],\n};\n\nexport function getKlyDir(root: string): string {\n return path.join(root, KLY_DIR);\n}\n\nexport function getConfigPath(root: string): string {\n return path.join(getKlyDir(root), CONFIG_FILE);\n}\n\nexport function getDbDir(root: string): string {\n return path.join(getKlyDir(root), DB_DIR);\n}\n\nexport function getDbPath(root: string, dbName: string): string {\n return path.join(getDbDir(root), `${dbName}.db`);\n}\n\nexport function getStatePath(root: string): string {\n return path.join(getKlyDir(root), STATE_FILE);\n}\n\nexport function isInitialized(root: string): boolean {\n return fs.existsSync(getKlyDir(root));\n}\n\nconst GITIGNORE_ENTRY = \".kly\";\n\n/** Append `.kly` to root `.gitignore` when inside a git repo; idempotent. */\nexport function ensureGitignore(root: string): void {\n const gitDir = path.join(root, \".git\");\n if (!fs.existsSync(gitDir)) {\n return;\n }\n\n const gitignorePath = path.join(root, \".gitignore\");\n\n if (!fs.existsSync(gitignorePath)) {\n fs.writeFileSync(gitignorePath, `${GITIGNORE_ENTRY}\\n`, \"utf-8\");\n return;\n }\n\n const content = fs.readFileSync(gitignorePath, \"utf-8\");\n const hasEntry = content.split(/\\r?\\n/).some((line) => line.trim() === GITIGNORE_ENTRY);\n if (hasEntry) {\n return;\n }\n\n const endsWithNewline = content.endsWith(\"\\n\") || content === \"\";\n const suffix = endsWithNewline ? `${GITIGNORE_ENTRY}\\n` : `\\n${GITIGNORE_ENTRY}\\n`;\n fs.appendFileSync(gitignorePath, suffix, \"utf-8\");\n}\n\nexport function initKlyDir(root: string, config?: KlyConfig): void {\n const klyDir = getKlyDir(root);\n if (!fs.existsSync(klyDir)) {\n fs.mkdirSync(klyDir, { recursive: true });\n }\n\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const configToWrite = config || DEFAULT_CONFIG;\n fs.writeFileSync(getConfigPath(root), stringifyYaml(configToWrite), \"utf-8\");\n\n ensureGitignore(root);\n}\n\nexport function loadConfig(root: string): KlyConfig {\n const configPath = getConfigPath(root);\n if (!fs.existsSync(configPath)) {\n return DEFAULT_CONFIG;\n }\n\n const raw = fs.readFileSync(configPath, \"utf-8\");\n const parsed = parseYaml(raw) as Partial<KlyConfig>;\n\n return {\n ...DEFAULT_CONFIG,\n ...parsed,\n llm: { ...DEFAULT_CONFIG.llm, ...parsed.llm },\n };\n}\n\nexport function hashConfig(config: KlyConfig): string {\n const significant = JSON.stringify({\n include: config.include,\n exclude: config.exclude,\n });\n return createHash(\"sha256\").update(significant).digest(\"hex\");\n}\n","import Database from \"better-sqlite3\";\n\nimport type { FileIndex, SymbolInfo } from \"./types\";\n\nexport interface SearchResult {\n file: FileIndex;\n score: number;\n}\n\nexport class IndexDatabase {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.init();\n }\n\n private init(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS files (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n language TEXT NOT NULL,\n imports TEXT NOT NULL DEFAULT '[]',\n exports TEXT NOT NULL DEFAULT '[]',\n symbols TEXT NOT NULL DEFAULT '[]',\n summary TEXT NOT NULL DEFAULT '',\n hash TEXT NOT NULL,\n indexed_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS dependencies (\n from_path TEXT NOT NULL,\n to_path TEXT NOT NULL,\n PRIMARY KEY (from_path, to_path)\n );\n\n CREATE INDEX IF NOT EXISTS idx_deps_to ON dependencies(to_path);\n `);\n\n // Create FTS5 virtual table if not exists\n // Use a try-catch because FTS5 tables can't use IF NOT EXISTS\n try {\n this.db.exec(`\n CREATE VIRTUAL TABLE files_fts USING fts5(\n path, name, description, summary, symbols_text,\n content=files,\n content_rowid=rowid\n );\n `);\n } catch {\n // Table already exists, that's fine\n }\n\n // Create triggers to keep FTS in sync\n this.db.exec(`\n CREATE TRIGGER IF NOT EXISTS files_ai AFTER INSERT ON files BEGIN\n INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (new.rowid, new.path, new.name, new.description, new.summary, '');\n END;\n\n CREATE TRIGGER IF NOT EXISTS files_ad AFTER DELETE ON files BEGIN\n INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', old.rowid, old.path, old.name, old.description, old.summary, '');\n END;\n\n CREATE TRIGGER IF NOT EXISTS files_au AFTER UPDATE ON files BEGIN\n INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', old.rowid, old.path, old.name, old.description, old.summary, '');\n INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (new.rowid, new.path, new.name, new.description, new.summary, '');\n END;\n `);\n }\n\n getFile(filePath: string): FileIndex | undefined {\n const row = this.db.prepare(\"SELECT * FROM files WHERE path = ?\").get(filePath) as\n | RawFileRow\n | undefined;\n return row ? rowToFileIndex(row) : undefined;\n }\n\n upsertFile(fileIndex: FileIndex): void {\n const stmt = this.db.prepare(`\n INSERT INTO files (path, name, description, language, imports, exports, symbols, summary, hash, indexed_at)\n VALUES (@path, @name, @description, @language, @imports, @exports, @symbols, @summary, @hash, @indexed_at)\n ON CONFLICT(path) DO UPDATE SET\n name = @name,\n description = @description,\n language = @language,\n imports = @imports,\n exports = @exports,\n symbols = @symbols,\n summary = @summary,\n hash = @hash,\n indexed_at = @indexed_at\n `);\n stmt.run(fileIndexToRow(fileIndex));\n\n // Update FTS symbols_text\n this.updateFtsSymbolsText(fileIndex);\n }\n\n upsertFiles(fileIndexes: FileIndex[]): void {\n const stmt = this.db.prepare(`\n INSERT INTO files (path, name, description, language, imports, exports, symbols, summary, hash, indexed_at)\n VALUES (@path, @name, @description, @language, @imports, @exports, @symbols, @summary, @hash, @indexed_at)\n ON CONFLICT(path) DO UPDATE SET\n name = @name,\n description = @description,\n language = @language,\n imports = @imports,\n exports = @exports,\n symbols = @symbols,\n summary = @summary,\n hash = @hash,\n indexed_at = @indexed_at\n `);\n\n const transaction = this.db.transaction((files: FileIndex[]) => {\n for (const file of files) {\n stmt.run(fileIndexToRow(file));\n this.updateFtsSymbolsText(file);\n }\n });\n transaction(fileIndexes);\n }\n\n removeFile(filePath: string): void {\n this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(filePath);\n }\n\n removeFiles(paths: string[]): void {\n const stmt = this.db.prepare(\"DELETE FROM files WHERE path = ?\");\n const transaction = this.db.transaction((pathList: string[]) => {\n for (const p of pathList) {\n stmt.run(p);\n }\n });\n transaction(paths);\n }\n\n searchFiles(query: string, limit = 20): SearchResult[] {\n // Use FTS5 match query\n const ftsQuery = query\n .split(/\\s+/)\n .filter(Boolean)\n .map((term) => `\"${term.replace(/\"/g, '\"\"')}\"`)\n .join(\" OR \");\n\n if (!ftsQuery) return [];\n\n const rows = this.db\n .prepare(\n `\n SELECT f.*, bm25(files_fts) as rank\n FROM files_fts fts\n JOIN files f ON f.rowid = fts.rowid\n WHERE files_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `,\n )\n .all(ftsQuery, limit) as (RawFileRow & { rank: number })[];\n\n return rows.map((row) => ({\n file: rowToFileIndex(row),\n score: -row.rank, // bm25 returns negative values, lower = better match\n }));\n }\n\n getAllFiles(): FileIndex[] {\n const rows = this.db.prepare(\"SELECT * FROM files ORDER BY path\").all() as RawFileRow[];\n return rows.map(rowToFileIndex);\n }\n\n getFileCount(): number {\n const row = this.db.prepare(\"SELECT COUNT(*) as count FROM files\").get() as { count: number };\n return row.count;\n }\n\n getLanguageStats(): Record<string, number> {\n const rows = this.db\n .prepare(\"SELECT language, COUNT(*) as count FROM files GROUP BY language\")\n .all() as { language: string; count: number }[];\n\n const stats: Record<string, number> = {};\n for (const row of rows) {\n stats[row.language] = row.count;\n }\n return stats;\n }\n\n getMetadata(key: string): string | undefined {\n const row = this.db.prepare(\"SELECT value FROM metadata WHERE key = ?\").get(key) as\n | { value: string }\n | undefined;\n return row?.value;\n }\n\n setMetadata(key: string, value: string): void {\n this.db\n .prepare(\n `INSERT INTO metadata (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = ?`,\n )\n .run(key, value, value);\n }\n\n upsertDependencies(fromPath: string, toPaths: string[]): void {\n this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\").run(fromPath);\n const stmt = this.db.prepare(\n \"INSERT OR IGNORE INTO dependencies (from_path, to_path) VALUES (?, ?)\",\n );\n for (const to of toPaths) {\n stmt.run(fromPath, to);\n }\n }\n\n upsertBatchDependencies(entries: Array<{ fromPath: string; toPaths: string[] }>): void {\n const del = this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\");\n const ins = this.db.prepare(\n \"INSERT OR IGNORE INTO dependencies (from_path, to_path) VALUES (?, ?)\",\n );\n const transaction = this.db.transaction(\n (items: Array<{ fromPath: string; toPaths: string[] }>) => {\n for (const { fromPath, toPaths } of items) {\n del.run(fromPath);\n for (const to of toPaths) {\n ins.run(fromPath, to);\n }\n }\n },\n );\n transaction(entries);\n }\n\n removeDependencies(fromPath: string): void {\n this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\").run(fromPath);\n }\n\n removeDependenciesBatch(fromPaths: string[]): void {\n const stmt = this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\");\n const transaction = this.db.transaction((paths: string[]) => {\n for (const p of paths) {\n stmt.run(p);\n }\n });\n transaction(fromPaths);\n }\n\n getDependencies(filePath: string): string[] {\n const rows = this.db\n .prepare(\"SELECT to_path FROM dependencies WHERE from_path = ? ORDER BY to_path\")\n .all(filePath) as { to_path: string }[];\n return rows.map((r) => r.to_path);\n }\n\n getDependents(filePath: string): string[] {\n const rows = this.db\n .prepare(\"SELECT from_path FROM dependencies WHERE to_path = ? ORDER BY from_path\")\n .all(filePath) as { from_path: string }[];\n return rows.map((r) => r.from_path);\n }\n\n removeAllDependencies(): void {\n this.db.exec(\"DELETE FROM dependencies\");\n }\n\n close(): void {\n this.db.close();\n }\n\n private updateFtsSymbolsText(fileIndex: FileIndex): void {\n const symbolsText = fileIndex.symbols.map((s) => `${s.name} ${s.description}`).join(\" \");\n // Row is guaranteed to exist — this is always called after upsert\n const row = this.db.prepare(\"SELECT rowid FROM files WHERE path = ?\").get(fileIndex.path) as {\n rowid: number;\n };\n // Delete old FTS entry and insert new one with symbols_text\n this.db\n .prepare(\n `INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', ?, ?, ?, ?, ?, '')`,\n )\n .run(row.rowid, fileIndex.path, fileIndex.name, fileIndex.description, fileIndex.summary);\n this.db\n .prepare(\n `INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (?, ?, ?, ?, ?, ?)`,\n )\n .run(\n row.rowid,\n fileIndex.path,\n fileIndex.name,\n fileIndex.description,\n fileIndex.summary,\n symbolsText,\n );\n }\n}\n\ninterface RawFileRow {\n path: string;\n name: string;\n description: string;\n language: string;\n imports: string;\n exports: string;\n symbols: string;\n summary: string;\n hash: string;\n indexed_at: number;\n}\n\nfunction rowToFileIndex(row: RawFileRow): FileIndex {\n return {\n path: row.path,\n name: row.name,\n description: row.description,\n language: row.language as FileIndex[\"language\"],\n imports: JSON.parse(row.imports) as string[],\n exports: JSON.parse(row.exports) as string[],\n symbols: JSON.parse(row.symbols) as SymbolInfo[],\n summary: row.summary,\n hash: row.hash,\n indexedAt: row.indexed_at,\n };\n}\n\nfunction fileIndexToRow(fileIndex: FileIndex): Record<string, string | number> {\n return {\n path: fileIndex.path,\n name: fileIndex.name,\n description: fileIndex.description,\n language: fileIndex.language,\n imports: JSON.stringify(fileIndex.imports),\n exports: JSON.stringify(fileIndex.exports),\n symbols: JSON.stringify(fileIndex.symbols),\n summary: fileIndex.summary,\n hash: fileIndex.hash,\n indexed_at: fileIndex.indexedAt,\n };\n}\n","import { globby } from \"globby\";\n\nimport type { KlyConfig } from \"./types\";\n\nexport async function scanFiles(root: string, config: KlyConfig): Promise<string[]> {\n const files = await globby(config.include, {\n cwd: root,\n ignore: config.exclude,\n gitignore: true,\n absolute: false,\n });\n\n return files.sort();\n}\n","import { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport function hashFile(root: string, filePath: string): string {\n const fullPath = path.join(root, filePath);\n const content = fs.readFileSync(fullPath, \"utf-8\");\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nexport function hasChanged(oldHash: string, newHash: string): boolean {\n return oldHash !== newHash;\n}\n","import { execSync } from \"node:child_process\";\n\nimport type { GitCommit, GitDiff } from \"./types\";\n\nfunction exec(root: string, cmd: string): string {\n return execSync(cmd, { cwd: root, encoding: \"utf-8\", stdio: [\"pipe\", \"pipe\", \"pipe\"] }).trim();\n}\n\nexport function isGitRepo(root: string): boolean {\n try {\n exec(root, \"git rev-parse --is-inside-work-tree\");\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getCurrentBranch(root: string): string | null {\n try {\n return exec(root, \"git symbolic-ref --short HEAD\");\n } catch {\n // Detached HEAD\n return null;\n }\n}\n\nexport function getCurrentCommit(root: string): string {\n return exec(root, \"git rev-parse HEAD\");\n}\n\nexport function getChangedFiles(root: string, from: string, to?: string): GitDiff {\n const target = to || \"HEAD\";\n const output = exec(root, `git diff --name-status ${from} ${target}`);\n\n const diff: GitDiff = { added: [], modified: [], deleted: [], renamed: [] };\n\n if (!output) return diff;\n\n for (const line of output.split(\"\\n\")) {\n const parts = line.split(\"\\t\");\n const status = parts[0];\n const filePath = parts[1];\n\n switch (status[0]) {\n case \"A\":\n diff.added.push(filePath);\n break;\n case \"M\":\n diff.modified.push(filePath);\n break;\n case \"D\":\n diff.deleted.push(filePath);\n break;\n case \"R\":\n diff.renamed.push({ from: filePath, to: parts[2] });\n break;\n }\n }\n\n return diff;\n}\n\nexport function isAncestor(root: string, ancestor: string, descendant: string): boolean {\n try {\n execSync(`git merge-base --is-ancestor ${ancestor} ${descendant}`, {\n cwd: root,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getMergeBase(root: string, a: string, b: string): string | null {\n try {\n return exec(root, `git merge-base ${a} ${b}`);\n } catch {\n return null;\n }\n}\n\nexport function getFileHistory(root: string, filePath: string, limit = 5): GitCommit[] {\n let output: string;\n try {\n output = exec(\n root,\n `git log --follow -n ${limit} --format=\"%H|%an|%ae|%at|%s\" -- \"${filePath}\"`,\n );\n } catch {\n return [];\n }\n if (!output) return [];\n return output\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const [hash, author, email, date, ...msgParts] = line.split(\"|\");\n return {\n hash,\n author,\n email,\n date: parseInt(date, 10),\n message: msgParts.join(\"|\"),\n };\n });\n}\n\nexport function branchToDbName(branch: string | null, commitHash?: string): string {\n if (branch === null) {\n const shortHash = commitHash ? commitHash.slice(0, 8) : \"unknown\";\n return `_detached--${shortHash}`;\n }\n return branch.replace(/\\//g, \"--\");\n}\n","import fs from \"node:fs\";\n\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport { getDbDir, getDbPath, getStatePath } from \"./config\";\nimport { IndexDatabase } from \"./database\";\nimport { branchToDbName, getCurrentBranch, getCurrentCommit, isGitRepo } from \"./git\";\nimport type { BranchState, FileIndex, GitState } from \"./types\";\n\nconst STATE_VERSION = 2;\n\n// --- Database management ---\n\nexport function openDatabase(root: string, dbName?: string): IndexDatabase {\n const name = dbName || resolveDbName(root);\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n return new IndexDatabase(getDbPath(root, name));\n}\n\nexport function resolveDbName(root: string): string {\n if (!isGitRepo(root)) {\n return \"default\";\n }\n const branch = getCurrentBranch(root);\n const commit = branch === null ? getCurrentCommit(root) : undefined;\n return branchToDbName(branch, commit);\n}\n\nexport function copyDatabase(root: string, fromName: string, toName: string): void {\n const fromPath = getDbPath(root, fromName);\n const toPath = getDbPath(root, toName);\n if (fs.existsSync(fromPath)) {\n fs.copyFileSync(fromPath, toPath);\n }\n}\n\n// --- State management ---\n\nexport function loadState(root: string): GitState {\n const statePath = getStatePath(root);\n if (!fs.existsSync(statePath)) {\n return { version: STATE_VERSION, configHash: \"\", branches: {} };\n }\n const raw = fs.readFileSync(statePath, \"utf-8\");\n return parseYaml(raw) as GitState;\n}\n\nexport function saveState(root: string, state: GitState): void {\n const statePath = getStatePath(root);\n fs.writeFileSync(statePath, stringifyYaml(state), \"utf-8\");\n}\n\nexport function getBranchState(state: GitState, dbName: string): BranchState | undefined {\n return state.branches[dbName];\n}\n\nexport function setBranchState(state: GitState, dbName: string, branchState: BranchState): void {\n state.branches[dbName] = branchState;\n}\n\n// --- Convenience wrappers (for commands that just need quick access) ---\n\nexport function getFileFromDb(root: string, filePath: string): FileIndex | undefined {\n const db = openDatabase(root);\n try {\n return db.getFile(filePath);\n } finally {\n db.close();\n }\n}\n\nexport function getAllFilesFromDb(root: string): FileIndex[] {\n const db = openDatabase(root);\n try {\n return db.getAllFiles();\n } finally {\n db.close();\n }\n}\n\n// --- Branch db cleanup ---\n\nexport function listBranchDbs(root: string): string[] {\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) return [];\n return fs\n .readdirSync(dbDir)\n .filter((f) => f.endsWith(\".db\"))\n .map((f) => f.replace(/\\.db$/, \"\"));\n}\n\nexport function removeBranchDb(root: string, dbName: string): void {\n const dbPath = getDbPath(root, dbName);\n if (fs.existsSync(dbPath)) {\n fs.unlinkSync(dbPath);\n }\n // Also remove WAL and SHM files\n for (const ext of [\"-wal\", \"-shm\"]) {\n const auxPath = dbPath + ext;\n if (fs.existsSync(auxPath)) {\n fs.unlinkSync(auxPath);\n }\n }\n}\n","'use strict';\n\nconst path = require('path');\nconst WIN_SLASH = '\\\\\\\\/';\nconst WIN_NO_SLASH = `[^${WIN_SLASH}]`;\n\n/**\n * Posix glob regex\n */\n\nconst DOT_LITERAL = '\\\\.';\nconst PLUS_LITERAL = '\\\\+';\nconst QMARK_LITERAL = '\\\\?';\nconst SLASH_LITERAL = '\\\\/';\nconst ONE_CHAR = '(?=.)';\nconst QMARK = '[^/]';\nconst END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;\nconst START_ANCHOR = `(?:^|${SLASH_LITERAL})`;\nconst DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;\nconst NO_DOT = `(?!${DOT_LITERAL})`;\nconst NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;\nconst NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;\nconst NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;\nconst QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;\nconst STAR = `${QMARK}*?`;\n\nconst POSIX_CHARS = {\n DOT_LITERAL,\n PLUS_LITERAL,\n QMARK_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n QMARK,\n END_ANCHOR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOTS,\n NO_DOT_SLASH,\n NO_DOTS_SLASH,\n QMARK_NO_DOT,\n STAR,\n START_ANCHOR\n};\n\n/**\n * Windows glob regex\n */\n\nconst WINDOWS_CHARS = {\n ...POSIX_CHARS,\n\n SLASH_LITERAL: `[${WIN_SLASH}]`,\n QMARK: WIN_NO_SLASH,\n STAR: `${WIN_NO_SLASH}*?`,\n DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,\n NO_DOT: `(?!${DOT_LITERAL})`,\n NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,\n NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,\n NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,\n QMARK_NO_DOT: `[^.${WIN_SLASH}]`,\n START_ANCHOR: `(?:^|[${WIN_SLASH}])`,\n END_ANCHOR: `(?:[${WIN_SLASH}]|$)`\n};\n\n/**\n * POSIX Bracket Regex\n */\n\nconst POSIX_REGEX_SOURCE = {\n alnum: 'a-zA-Z0-9',\n alpha: 'a-zA-Z',\n ascii: '\\\\x00-\\\\x7F',\n blank: ' \\\\t',\n cntrl: '\\\\x00-\\\\x1F\\\\x7F',\n digit: '0-9',\n graph: '\\\\x21-\\\\x7E',\n lower: 'a-z',\n print: '\\\\x20-\\\\x7E ',\n punct: '\\\\-!\"#$%&\\'()\\\\*+,./:;<=>?@[\\\\]^_`{|}~',\n space: ' \\\\t\\\\r\\\\n\\\\v\\\\f',\n upper: 'A-Z',\n word: 'A-Za-z0-9_',\n xdigit: 'A-Fa-f0-9'\n};\n\nmodule.exports = {\n MAX_LENGTH: 1024 * 64,\n POSIX_REGEX_SOURCE,\n\n // regular expressions\n REGEX_BACKSLASH: /\\\\(?![*+?^${}(|)[\\]])/g,\n REGEX_NON_SPECIAL_CHARS: /^[^@![\\].,$*+?^{}()|\\\\/]+/,\n REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\\]]/,\n REGEX_SPECIAL_CHARS_BACKREF: /(\\\\?)((\\W)(\\3*))/g,\n REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\\]])/g,\n REGEX_REMOVE_BACKSLASH: /(?:\\[.*?[^\\\\]\\]|\\\\(?=.))/g,\n\n // Replace globs with equivalent patterns to reduce parsing time.\n REPLACEMENTS: {\n '***': '*',\n '**/**': '**',\n '**/**/**': '**'\n },\n\n // Digits\n CHAR_0: 48, /* 0 */\n CHAR_9: 57, /* 9 */\n\n // Alphabet chars.\n CHAR_UPPERCASE_A: 65, /* A */\n CHAR_LOWERCASE_A: 97, /* a */\n CHAR_UPPERCASE_Z: 90, /* Z */\n CHAR_LOWERCASE_Z: 122, /* z */\n\n CHAR_LEFT_PARENTHESES: 40, /* ( */\n CHAR_RIGHT_PARENTHESES: 41, /* ) */\n\n CHAR_ASTERISK: 42, /* * */\n\n // Non-alphabetic chars.\n CHAR_AMPERSAND: 38, /* & */\n CHAR_AT: 64, /* @ */\n CHAR_BACKWARD_SLASH: 92, /* \\ */\n CHAR_CARRIAGE_RETURN: 13, /* \\r */\n CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */\n CHAR_COLON: 58, /* : */\n CHAR_COMMA: 44, /* , */\n CHAR_DOT: 46, /* . */\n CHAR_DOUBLE_QUOTE: 34, /* \" */\n CHAR_EQUAL: 61, /* = */\n CHAR_EXCLAMATION_MARK: 33, /* ! */\n CHAR_FORM_FEED: 12, /* \\f */\n CHAR_FORWARD_SLASH: 47, /* / */\n CHAR_GRAVE_ACCENT: 96, /* ` */\n CHAR_HASH: 35, /* # */\n CHAR_HYPHEN_MINUS: 45, /* - */\n CHAR_LEFT_ANGLE_BRACKET: 60, /* < */\n CHAR_LEFT_CURLY_BRACE: 123, /* { */\n CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */\n CHAR_LINE_FEED: 10, /* \\n */\n CHAR_NO_BREAK_SPACE: 160, /* \\u00A0 */\n CHAR_PERCENT: 37, /* % */\n CHAR_PLUS: 43, /* + */\n CHAR_QUESTION_MARK: 63, /* ? */\n CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */\n CHAR_RIGHT_CURLY_BRACE: 125, /* } */\n CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */\n CHAR_SEMICOLON: 59, /* ; */\n CHAR_SINGLE_QUOTE: 39, /* ' */\n CHAR_SPACE: 32, /* */\n CHAR_TAB: 9, /* \\t */\n CHAR_UNDERSCORE: 95, /* _ */\n CHAR_VERTICAL_LINE: 124, /* | */\n CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \\uFEFF */\n\n SEP: path.sep,\n\n /**\n * Create EXTGLOB_CHARS\n */\n\n extglobChars(chars) {\n return {\n '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },\n '?': { type: 'qmark', open: '(?:', close: ')?' },\n '+': { type: 'plus', open: '(?:', close: ')+' },\n '*': { type: 'star', open: '(?:', close: ')*' },\n '@': { type: 'at', open: '(?:', close: ')' }\n };\n },\n\n /**\n * Create GLOB_CHARS\n */\n\n globChars(win32) {\n return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;\n }\n};\n","'use strict';\n\nconst path = require('path');\nconst win32 = process.platform === 'win32';\nconst {\n REGEX_BACKSLASH,\n REGEX_REMOVE_BACKSLASH,\n REGEX_SPECIAL_CHARS,\n REGEX_SPECIAL_CHARS_GLOBAL\n} = require('./constants');\n\nexports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);\nexports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);\nexports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);\nexports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\\\$1');\nexports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');\n\nexports.removeBackslashes = str => {\n return str.replace(REGEX_REMOVE_BACKSLASH, match => {\n return match === '\\\\' ? '' : match;\n });\n};\n\nexports.supportsLookbehinds = () => {\n const segs = process.version.slice(1).split('.').map(Number);\n if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {\n return true;\n }\n return false;\n};\n\nexports.isWindows = options => {\n if (options && typeof options.windows === 'boolean') {\n return options.windows;\n }\n return win32 === true || path.sep === '\\\\';\n};\n\nexports.escapeLast = (input, char, lastIdx) => {\n const idx = input.lastIndexOf(char, lastIdx);\n if (idx === -1) return input;\n if (input[idx - 1] === '\\\\') return exports.escapeLast(input, char, idx - 1);\n return `${input.slice(0, idx)}\\\\${input.slice(idx)}`;\n};\n\nexports.removePrefix = (input, state = {}) => {\n let output = input;\n if (output.startsWith('./')) {\n output = output.slice(2);\n state.prefix = './';\n }\n return output;\n};\n\nexports.wrapOutput = (input, state = {}, options = {}) => {\n const prepend = options.contains ? '' : '^';\n const append = options.contains ? '' : '$';\n\n let output = `${prepend}(?:${input})${append}`;\n if (state.negated === true) {\n output = `(?:^(?!${output}).*$)`;\n }\n return output;\n};\n","'use strict';\n\nconst utils = require('./utils');\nconst {\n CHAR_ASTERISK, /* * */\n CHAR_AT, /* @ */\n CHAR_BACKWARD_SLASH, /* \\ */\n CHAR_COMMA, /* , */\n CHAR_DOT, /* . */\n CHAR_EXCLAMATION_MARK, /* ! */\n CHAR_FORWARD_SLASH, /* / */\n CHAR_LEFT_CURLY_BRACE, /* { */\n CHAR_LEFT_PARENTHESES, /* ( */\n CHAR_LEFT_SQUARE_BRACKET, /* [ */\n CHAR_PLUS, /* + */\n CHAR_QUESTION_MARK, /* ? */\n CHAR_RIGHT_CURLY_BRACE, /* } */\n CHAR_RIGHT_PARENTHESES, /* ) */\n CHAR_RIGHT_SQUARE_BRACKET /* ] */\n} = require('./constants');\n\nconst isPathSeparator = code => {\n return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;\n};\n\nconst depth = token => {\n if (token.isPrefix !== true) {\n token.depth = token.isGlobstar ? Infinity : 1;\n }\n};\n\n/**\n * Quickly scans a glob pattern and returns an object with a handful of\n * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),\n * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not\n * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).\n *\n * ```js\n * const pm = require('picomatch');\n * console.log(pm.scan('foo/bar/*.js'));\n * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }\n * ```\n * @param {String} `str`\n * @param {Object} `options`\n * @return {Object} Returns an object with tokens and regex source string.\n * @api public\n */\n\nconst scan = (input, options) => {\n const opts = options || {};\n\n const length = input.length - 1;\n const scanToEnd = opts.parts === true || opts.scanToEnd === true;\n const slashes = [];\n const tokens = [];\n const parts = [];\n\n let str = input;\n let index = -1;\n let start = 0;\n let lastIndex = 0;\n let isBrace = false;\n let isBracket = false;\n let isGlob = false;\n let isExtglob = false;\n let isGlobstar = false;\n let braceEscaped = false;\n let backslashes = false;\n let negated = false;\n let negatedExtglob = false;\n let finished = false;\n let braces = 0;\n let prev;\n let code;\n let token = { value: '', depth: 0, isGlob: false };\n\n const eos = () => index >= length;\n const peek = () => str.charCodeAt(index + 1);\n const advance = () => {\n prev = code;\n return str.charCodeAt(++index);\n };\n\n while (index < length) {\n code = advance();\n let next;\n\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n code = advance();\n\n if (code === CHAR_LEFT_CURLY_BRACE) {\n braceEscaped = true;\n }\n continue;\n }\n\n if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {\n braces++;\n\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n advance();\n continue;\n }\n\n if (code === CHAR_LEFT_CURLY_BRACE) {\n braces++;\n continue;\n }\n\n if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {\n isBrace = token.isBrace = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (braceEscaped !== true && code === CHAR_COMMA) {\n isBrace = token.isBrace = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (code === CHAR_RIGHT_CURLY_BRACE) {\n braces--;\n\n if (braces === 0) {\n braceEscaped = false;\n isBrace = token.isBrace = true;\n finished = true;\n break;\n }\n }\n }\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (code === CHAR_FORWARD_SLASH) {\n slashes.push(index);\n tokens.push(token);\n token = { value: '', depth: 0, isGlob: false };\n\n if (finished === true) continue;\n if (prev === CHAR_DOT && index === (start + 1)) {\n start += 2;\n continue;\n }\n\n lastIndex = index + 1;\n continue;\n }\n\n if (opts.noext !== true) {\n const isExtglobChar = code === CHAR_PLUS\n || code === CHAR_AT\n || code === CHAR_ASTERISK\n || code === CHAR_QUESTION_MARK\n || code === CHAR_EXCLAMATION_MARK;\n\n if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {\n isGlob = token.isGlob = true;\n isExtglob = token.isExtglob = true;\n finished = true;\n if (code === CHAR_EXCLAMATION_MARK && index === start) {\n negatedExtglob = true;\n }\n\n if (scanToEnd === true) {\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n code = advance();\n continue;\n }\n\n if (code === CHAR_RIGHT_PARENTHESES) {\n isGlob = token.isGlob = true;\n finished = true;\n break;\n }\n }\n continue;\n }\n break;\n }\n }\n\n if (code === CHAR_ASTERISK) {\n if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n break;\n }\n\n if (code === CHAR_QUESTION_MARK) {\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n break;\n }\n\n if (code === CHAR_LEFT_SQUARE_BRACKET) {\n while (eos() !== true && (next = advance())) {\n if (next === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n advance();\n continue;\n }\n\n if (next === CHAR_RIGHT_SQUARE_BRACKET) {\n isBracket = token.isBracket = true;\n isGlob = token.isGlob = true;\n finished = true;\n break;\n }\n }\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {\n negated = token.negated = true;\n start++;\n continue;\n }\n\n if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {\n isGlob = token.isGlob = true;\n\n if (scanToEnd === true) {\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_LEFT_PARENTHESES) {\n backslashes = token.backslashes = true;\n code = advance();\n continue;\n }\n\n if (code === CHAR_RIGHT_PARENTHESES) {\n finished = true;\n break;\n }\n }\n continue;\n }\n break;\n }\n\n if (isGlob === true) {\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n }\n\n if (opts.noext === true) {\n isExtglob = false;\n isGlob = false;\n }\n\n let base = str;\n let prefix = '';\n let glob = '';\n\n if (start > 0) {\n prefix = str.slice(0, start);\n str = str.slice(start);\n lastIndex -= start;\n }\n\n if (base && isGlob === true && lastIndex > 0) {\n base = str.slice(0, lastIndex);\n glob = str.slice(lastIndex);\n } else if (isGlob === true) {\n base = '';\n glob = str;\n } else {\n base = str;\n }\n\n if (base && base !== '' && base !== '/' && base !== str) {\n if (isPathSeparator(base.charCodeAt(base.length - 1))) {\n base = base.slice(0, -1);\n }\n }\n\n if (opts.unescape === true) {\n if (glob) glob = utils.removeBackslashes(glob);\n\n if (base && backslashes === true) {\n base = utils.removeBackslashes(base);\n }\n }\n\n const state = {\n prefix,\n input,\n start,\n base,\n glob,\n isBrace,\n isBracket,\n isGlob,\n isExtglob,\n isGlobstar,\n negated,\n negatedExtglob\n };\n\n if (opts.tokens === true) {\n state.maxDepth = 0;\n if (!isPathSeparator(code)) {\n tokens.push(token);\n }\n state.tokens = tokens;\n }\n\n if (opts.parts === true || opts.tokens === true) {\n let prevIndex;\n\n for (let idx = 0; idx < slashes.length; idx++) {\n const n = prevIndex ? prevIndex + 1 : start;\n const i = slashes[idx];\n const value = input.slice(n, i);\n if (opts.tokens) {\n if (idx === 0 && start !== 0) {\n tokens[idx].isPrefix = true;\n tokens[idx].value = prefix;\n } else {\n tokens[idx].value = value;\n }\n depth(tokens[idx]);\n state.maxDepth += tokens[idx].depth;\n }\n if (idx !== 0 || value !== '') {\n parts.push(value);\n }\n prevIndex = i;\n }\n\n if (prevIndex && prevIndex + 1 < input.length) {\n const value = input.slice(prevIndex + 1);\n parts.push(value);\n\n if (opts.tokens) {\n tokens[tokens.length - 1].value = value;\n depth(tokens[tokens.length - 1]);\n state.maxDepth += tokens[tokens.length - 1].depth;\n }\n }\n\n state.slashes = slashes;\n state.parts = parts;\n }\n\n return state;\n};\n\nmodule.exports = scan;\n","'use strict';\n\nconst constants = require('./constants');\nconst utils = require('./utils');\n\n/**\n * Constants\n */\n\nconst {\n MAX_LENGTH,\n POSIX_REGEX_SOURCE,\n REGEX_NON_SPECIAL_CHARS,\n REGEX_SPECIAL_CHARS_BACKREF,\n REPLACEMENTS\n} = constants;\n\n/**\n * Helpers\n */\n\nconst expandRange = (args, options) => {\n if (typeof options.expandRange === 'function') {\n return options.expandRange(...args, options);\n }\n\n args.sort();\n const value = `[${args.join('-')}]`;\n\n try {\n /* eslint-disable-next-line no-new */\n new RegExp(value);\n } catch (ex) {\n return args.map(v => utils.escapeRegex(v)).join('..');\n }\n\n return value;\n};\n\n/**\n * Create the message for a syntax error\n */\n\nconst syntaxError = (type, char) => {\n return `Missing ${type}: \"${char}\" - use \"\\\\\\\\${char}\" to match literal characters`;\n};\n\n/**\n * Parse the given input string.\n * @param {String} input\n * @param {Object} options\n * @return {Object}\n */\n\nconst parse = (input, options) => {\n if (typeof input !== 'string') {\n throw new TypeError('Expected a string');\n }\n\n input = REPLACEMENTS[input] || input;\n\n const opts = { ...options };\n const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;\n\n let len = input.length;\n if (len > max) {\n throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);\n }\n\n const bos = { type: 'bos', value: '', output: opts.prepend || '' };\n const tokens = [bos];\n\n const capture = opts.capture ? '' : '?:';\n const win32 = utils.isWindows(options);\n\n // create constants based on platform, for windows or posix\n const PLATFORM_CHARS = constants.globChars(win32);\n const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);\n\n const {\n DOT_LITERAL,\n PLUS_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOT_SLASH,\n NO_DOTS_SLASH,\n QMARK,\n QMARK_NO_DOT,\n STAR,\n START_ANCHOR\n } = PLATFORM_CHARS;\n\n const globstar = opts => {\n return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;\n };\n\n const nodot = opts.dot ? '' : NO_DOT;\n const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;\n let star = opts.bash === true ? globstar(opts) : STAR;\n\n if (opts.capture) {\n star = `(${star})`;\n }\n\n // minimatch options support\n if (typeof opts.noext === 'boolean') {\n opts.noextglob = opts.noext;\n }\n\n const state = {\n input,\n index: -1,\n start: 0,\n dot: opts.dot === true,\n consumed: '',\n output: '',\n prefix: '',\n backtrack: false,\n negated: false,\n brackets: 0,\n braces: 0,\n parens: 0,\n quotes: 0,\n globstar: false,\n tokens\n };\n\n input = utils.removePrefix(input, state);\n len = input.length;\n\n const extglobs = [];\n const braces = [];\n const stack = [];\n let prev = bos;\n let value;\n\n /**\n * Tokenizing helpers\n */\n\n const eos = () => state.index === len - 1;\n const peek = state.peek = (n = 1) => input[state.index + n];\n const advance = state.advance = () => input[++state.index] || '';\n const remaining = () => input.slice(state.index + 1);\n const consume = (value = '', num = 0) => {\n state.consumed += value;\n state.index += num;\n };\n\n const append = token => {\n state.output += token.output != null ? token.output : token.value;\n consume(token.value);\n };\n\n const negate = () => {\n let count = 1;\n\n while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {\n advance();\n state.start++;\n count++;\n }\n\n if (count % 2 === 0) {\n return false;\n }\n\n state.negated = true;\n state.start++;\n return true;\n };\n\n const increment = type => {\n state[type]++;\n stack.push(type);\n };\n\n const decrement = type => {\n state[type]--;\n stack.pop();\n };\n\n /**\n * Push tokens onto the tokens array. This helper speeds up\n * tokenizing by 1) helping us avoid backtracking as much as possible,\n * and 2) helping us avoid creating extra tokens when consecutive\n * characters are plain text. This improves performance and simplifies\n * lookbehinds.\n */\n\n const push = tok => {\n if (prev.type === 'globstar') {\n const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');\n const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));\n\n if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {\n state.output = state.output.slice(0, -prev.output.length);\n prev.type = 'star';\n prev.value = '*';\n prev.output = star;\n state.output += prev.output;\n }\n }\n\n if (extglobs.length && tok.type !== 'paren') {\n extglobs[extglobs.length - 1].inner += tok.value;\n }\n\n if (tok.value || tok.output) append(tok);\n if (prev && prev.type === 'text' && tok.type === 'text') {\n prev.value += tok.value;\n prev.output = (prev.output || '') + tok.value;\n return;\n }\n\n tok.prev = prev;\n tokens.push(tok);\n prev = tok;\n };\n\n const extglobOpen = (type, value) => {\n const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };\n\n token.prev = prev;\n token.parens = state.parens;\n token.output = state.output;\n const output = (opts.capture ? '(' : '') + token.open;\n\n increment('parens');\n push({ type, value, output: state.output ? '' : ONE_CHAR });\n push({ type: 'paren', extglob: true, value: advance(), output });\n extglobs.push(token);\n };\n\n const extglobClose = token => {\n let output = token.close + (opts.capture ? ')' : '');\n let rest;\n\n if (token.type === 'negate') {\n let extglobStar = star;\n\n if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {\n extglobStar = globstar(opts);\n }\n\n if (extglobStar !== star || eos() || /^\\)+$/.test(remaining())) {\n output = token.close = `)$))${extglobStar}`;\n }\n\n if (token.inner.includes('*') && (rest = remaining()) && /^\\.[^\\\\/.]+$/.test(rest)) {\n // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.\n // In this case, we need to parse the string and use it in the output of the original pattern.\n // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.\n //\n // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.\n const expression = parse(rest, { ...options, fastpaths: false }).output;\n\n output = token.close = `)${expression})${extglobStar})`;\n }\n\n if (token.prev.type === 'bos') {\n state.negatedExtglob = true;\n }\n }\n\n push({ type: 'paren', extglob: true, value, output });\n decrement('parens');\n };\n\n /**\n * Fast paths\n */\n\n if (opts.fastpaths !== false && !/(^[*!]|[/()[\\]{}\"])/.test(input)) {\n let backslashes = false;\n\n let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {\n if (first === '\\\\') {\n backslashes = true;\n return m;\n }\n\n if (first === '?') {\n if (esc) {\n return esc + first + (rest ? QMARK.repeat(rest.length) : '');\n }\n if (index === 0) {\n return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');\n }\n return QMARK.repeat(chars.length);\n }\n\n if (first === '.') {\n return DOT_LITERAL.repeat(chars.length);\n }\n\n if (first === '*') {\n if (esc) {\n return esc + first + (rest ? star : '');\n }\n return star;\n }\n return esc ? m : `\\\\${m}`;\n });\n\n if (backslashes === true) {\n if (opts.unescape === true) {\n output = output.replace(/\\\\/g, '');\n } else {\n output = output.replace(/\\\\+/g, m => {\n return m.length % 2 === 0 ? '\\\\\\\\' : (m ? '\\\\' : '');\n });\n }\n }\n\n if (output === input && opts.contains === true) {\n state.output = input;\n return state;\n }\n\n state.output = utils.wrapOutput(output, state, options);\n return state;\n }\n\n /**\n * Tokenize input until we reach end-of-string\n */\n\n while (!eos()) {\n value = advance();\n\n if (value === '\\u0000') {\n continue;\n }\n\n /**\n * Escaped characters\n */\n\n if (value === '\\\\') {\n const next = peek();\n\n if (next === '/' && opts.bash !== true) {\n continue;\n }\n\n if (next === '.' || next === ';') {\n continue;\n }\n\n if (!next) {\n value += '\\\\';\n push({ type: 'text', value });\n continue;\n }\n\n // collapse slashes to reduce potential for exploits\n const match = /^\\\\+/.exec(remaining());\n let slashes = 0;\n\n if (match && match[0].length > 2) {\n slashes = match[0].length;\n state.index += slashes;\n if (slashes % 2 !== 0) {\n value += '\\\\';\n }\n }\n\n if (opts.unescape === true) {\n value = advance();\n } else {\n value += advance();\n }\n\n if (state.brackets === 0) {\n push({ type: 'text', value });\n continue;\n }\n }\n\n /**\n * If we're inside a regex character class, continue\n * until we reach the closing bracket.\n */\n\n if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {\n if (opts.posix !== false && value === ':') {\n const inner = prev.value.slice(1);\n if (inner.includes('[')) {\n prev.posix = true;\n\n if (inner.includes(':')) {\n const idx = prev.value.lastIndexOf('[');\n const pre = prev.value.slice(0, idx);\n const rest = prev.value.slice(idx + 2);\n const posix = POSIX_REGEX_SOURCE[rest];\n if (posix) {\n prev.value = pre + posix;\n state.backtrack = true;\n advance();\n\n if (!bos.output && tokens.indexOf(prev) === 1) {\n bos.output = ONE_CHAR;\n }\n continue;\n }\n }\n }\n }\n\n if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {\n value = `\\\\${value}`;\n }\n\n if (value === ']' && (prev.value === '[' || prev.value === '[^')) {\n value = `\\\\${value}`;\n }\n\n if (opts.posix === true && value === '!' && prev.value === '[') {\n value = '^';\n }\n\n prev.value += value;\n append({ value });\n continue;\n }\n\n /**\n * If we're inside a quoted string, continue\n * until we reach the closing double quote.\n */\n\n if (state.quotes === 1 && value !== '\"') {\n value = utils.escapeRegex(value);\n prev.value += value;\n append({ value });\n continue;\n }\n\n /**\n * Double quotes\n */\n\n if (value === '\"') {\n state.quotes = state.quotes === 1 ? 0 : 1;\n if (opts.keepQuotes === true) {\n push({ type: 'text', value });\n }\n continue;\n }\n\n /**\n * Parentheses\n */\n\n if (value === '(') {\n increment('parens');\n push({ type: 'paren', value });\n continue;\n }\n\n if (value === ')') {\n if (state.parens === 0 && opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('opening', '('));\n }\n\n const extglob = extglobs[extglobs.length - 1];\n if (extglob && state.parens === extglob.parens + 1) {\n extglobClose(extglobs.pop());\n continue;\n }\n\n push({ type: 'paren', value, output: state.parens ? ')' : '\\\\)' });\n decrement('parens');\n continue;\n }\n\n /**\n * Square brackets\n */\n\n if (value === '[') {\n if (opts.nobracket === true || !remaining().includes(']')) {\n if (opts.nobracket !== true && opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('closing', ']'));\n }\n\n value = `\\\\${value}`;\n } else {\n increment('brackets');\n }\n\n push({ type: 'bracket', value });\n continue;\n }\n\n if (value === ']') {\n if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {\n push({ type: 'text', value, output: `\\\\${value}` });\n continue;\n }\n\n if (state.brackets === 0) {\n if (opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('opening', '['));\n }\n\n push({ type: 'text', value, output: `\\\\${value}` });\n continue;\n }\n\n decrement('brackets');\n\n const prevValue = prev.value.slice(1);\n if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {\n value = `/${value}`;\n }\n\n prev.value += value;\n append({ value });\n\n // when literal brackets are explicitly disabled\n // assume we should match with a regex character class\n if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {\n continue;\n }\n\n const escaped = utils.escapeRegex(prev.value);\n state.output = state.output.slice(0, -prev.value.length);\n\n // when literal brackets are explicitly enabled\n // assume we should escape the brackets to match literal characters\n if (opts.literalBrackets === true) {\n state.output += escaped;\n prev.value = escaped;\n continue;\n }\n\n // when the user specifies nothing, try to match both\n prev.value = `(${capture}${escaped}|${prev.value})`;\n state.output += prev.value;\n continue;\n }\n\n /**\n * Braces\n */\n\n if (value === '{' && opts.nobrace !== true) {\n increment('braces');\n\n const open = {\n type: 'brace',\n value,\n output: '(',\n outputIndex: state.output.length,\n tokensIndex: state.tokens.length\n };\n\n braces.push(open);\n push(open);\n continue;\n }\n\n if (value === '}') {\n const brace = braces[braces.length - 1];\n\n if (opts.nobrace === true || !brace) {\n push({ type: 'text', value, output: value });\n continue;\n }\n\n let output = ')';\n\n if (brace.dots === true) {\n const arr = tokens.slice();\n const range = [];\n\n for (let i = arr.length - 1; i >= 0; i--) {\n tokens.pop();\n if (arr[i].type === 'brace') {\n break;\n }\n if (arr[i].type !== 'dots') {\n range.unshift(arr[i].value);\n }\n }\n\n output = expandRange(range, opts);\n state.backtrack = true;\n }\n\n if (brace.comma !== true && brace.dots !== true) {\n const out = state.output.slice(0, brace.outputIndex);\n const toks = state.tokens.slice(brace.tokensIndex);\n brace.value = brace.output = '\\\\{';\n value = output = '\\\\}';\n state.output = out;\n for (const t of toks) {\n state.output += (t.output || t.value);\n }\n }\n\n push({ type: 'brace', value, output });\n decrement('braces');\n braces.pop();\n continue;\n }\n\n /**\n * Pipes\n */\n\n if (value === '|') {\n if (extglobs.length > 0) {\n extglobs[extglobs.length - 1].conditions++;\n }\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Commas\n */\n\n if (value === ',') {\n let output = value;\n\n const brace = braces[braces.length - 1];\n if (brace && stack[stack.length - 1] === 'braces') {\n brace.comma = true;\n output = '|';\n }\n\n push({ type: 'comma', value, output });\n continue;\n }\n\n /**\n * Slashes\n */\n\n if (value === '/') {\n // if the beginning of the glob is \"./\", advance the start\n // to the current index, and don't add the \"./\" characters\n // to the state. This greatly simplifies lookbehinds when\n // checking for BOS characters like \"!\" and \".\" (not \"./\")\n if (prev.type === 'dot' && state.index === state.start + 1) {\n state.start = state.index + 1;\n state.consumed = '';\n state.output = '';\n tokens.pop();\n prev = bos; // reset \"prev\" to the first token\n continue;\n }\n\n push({ type: 'slash', value, output: SLASH_LITERAL });\n continue;\n }\n\n /**\n * Dots\n */\n\n if (value === '.') {\n if (state.braces > 0 && prev.type === 'dot') {\n if (prev.value === '.') prev.output = DOT_LITERAL;\n const brace = braces[braces.length - 1];\n prev.type = 'dots';\n prev.output += value;\n prev.value += value;\n brace.dots = true;\n continue;\n }\n\n if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {\n push({ type: 'text', value, output: DOT_LITERAL });\n continue;\n }\n\n push({ type: 'dot', value, output: DOT_LITERAL });\n continue;\n }\n\n /**\n * Question marks\n */\n\n if (value === '?') {\n const isGroup = prev && prev.value === '(';\n if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n extglobOpen('qmark', value);\n continue;\n }\n\n if (prev && prev.type === 'paren') {\n const next = peek();\n let output = value;\n\n if (next === '<' && !utils.supportsLookbehinds()) {\n throw new Error('Node.js v10 or higher is required for regex lookbehinds');\n }\n\n if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\\w+>)/.test(remaining()))) {\n output = `\\\\${value}`;\n }\n\n push({ type: 'text', value, output });\n continue;\n }\n\n if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {\n push({ type: 'qmark', value, output: QMARK_NO_DOT });\n continue;\n }\n\n push({ type: 'qmark', value, output: QMARK });\n continue;\n }\n\n /**\n * Exclamation\n */\n\n if (value === '!') {\n if (opts.noextglob !== true && peek() === '(') {\n if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {\n extglobOpen('negate', value);\n continue;\n }\n }\n\n if (opts.nonegate !== true && state.index === 0) {\n negate();\n continue;\n }\n }\n\n /**\n * Plus\n */\n\n if (value === '+') {\n if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n extglobOpen('plus', value);\n continue;\n }\n\n if ((prev && prev.value === '(') || opts.regex === false) {\n push({ type: 'plus', value, output: PLUS_LITERAL });\n continue;\n }\n\n if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {\n push({ type: 'plus', value });\n continue;\n }\n\n push({ type: 'plus', value: PLUS_LITERAL });\n continue;\n }\n\n /**\n * Plain text\n */\n\n if (value === '@') {\n if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n push({ type: 'at', extglob: true, value, output: '' });\n continue;\n }\n\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Plain text\n */\n\n if (value !== '*') {\n if (value === '$' || value === '^') {\n value = `\\\\${value}`;\n }\n\n const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());\n if (match) {\n value += match[0];\n state.index += match[0].length;\n }\n\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Stars\n */\n\n if (prev && (prev.type === 'globstar' || prev.star === true)) {\n prev.type = 'star';\n prev.star = true;\n prev.value += value;\n prev.output = star;\n state.backtrack = true;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n let rest = remaining();\n if (opts.noextglob !== true && /^\\([^?]/.test(rest)) {\n extglobOpen('star', value);\n continue;\n }\n\n if (prev.type === 'star') {\n if (opts.noglobstar === true) {\n consume(value);\n continue;\n }\n\n const prior = prev.prev;\n const before = prior.prev;\n const isStart = prior.type === 'slash' || prior.type === 'bos';\n const afterStar = before && (before.type === 'star' || before.type === 'globstar');\n\n if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {\n push({ type: 'star', value, output: '' });\n continue;\n }\n\n const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');\n const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');\n if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {\n push({ type: 'star', value, output: '' });\n continue;\n }\n\n // strip consecutive `/**/`\n while (rest.slice(0, 3) === '/**') {\n const after = input[state.index + 4];\n if (after && after !== '/') {\n break;\n }\n rest = rest.slice(3);\n consume('/**', 3);\n }\n\n if (prior.type === 'bos' && eos()) {\n prev.type = 'globstar';\n prev.value += value;\n prev.output = globstar(opts);\n state.output = prev.output;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {\n state.output = state.output.slice(0, -(prior.output + prev.output).length);\n prior.output = `(?:${prior.output}`;\n\n prev.type = 'globstar';\n prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');\n prev.value += value;\n state.globstar = true;\n state.output += prior.output + prev.output;\n consume(value);\n continue;\n }\n\n if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {\n const end = rest[1] !== void 0 ? '|$' : '';\n\n state.output = state.output.slice(0, -(prior.output + prev.output).length);\n prior.output = `(?:${prior.output}`;\n\n prev.type = 'globstar';\n prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;\n prev.value += value;\n\n state.output += prior.output + prev.output;\n state.globstar = true;\n\n consume(value + advance());\n\n push({ type: 'slash', value: '/', output: '' });\n continue;\n }\n\n if (prior.type === 'bos' && rest[0] === '/') {\n prev.type = 'globstar';\n prev.value += value;\n prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;\n state.output = prev.output;\n state.globstar = true;\n consume(value + advance());\n push({ type: 'slash', value: '/', output: '' });\n continue;\n }\n\n // remove single star from output\n state.output = state.output.slice(0, -prev.output.length);\n\n // reset previous token to globstar\n prev.type = 'globstar';\n prev.output = globstar(opts);\n prev.value += value;\n\n // reset output with globstar\n state.output += prev.output;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n const token = { type: 'star', value, output: star };\n\n if (opts.bash === true) {\n token.output = '.*?';\n if (prev.type === 'bos' || prev.type === 'slash') {\n token.output = nodot + token.output;\n }\n push(token);\n continue;\n }\n\n if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {\n token.output = value;\n push(token);\n continue;\n }\n\n if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {\n if (prev.type === 'dot') {\n state.output += NO_DOT_SLASH;\n prev.output += NO_DOT_SLASH;\n\n } else if (opts.dot === true) {\n state.output += NO_DOTS_SLASH;\n prev.output += NO_DOTS_SLASH;\n\n } else {\n state.output += nodot;\n prev.output += nodot;\n }\n\n if (peek() !== '*') {\n state.output += ONE_CHAR;\n prev.output += ONE_CHAR;\n }\n }\n\n push(token);\n }\n\n while (state.brackets > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));\n state.output = utils.escapeLast(state.output, '[');\n decrement('brackets');\n }\n\n while (state.parens > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));\n state.output = utils.escapeLast(state.output, '(');\n decrement('parens');\n }\n\n while (state.braces > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));\n state.output = utils.escapeLast(state.output, '{');\n decrement('braces');\n }\n\n if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {\n push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });\n }\n\n // rebuild the output if we had to backtrack at any point\n if (state.backtrack === true) {\n state.output = '';\n\n for (const token of state.tokens) {\n state.output += token.output != null ? token.output : token.value;\n\n if (token.suffix) {\n state.output += token.suffix;\n }\n }\n }\n\n return state;\n};\n\n/**\n * Fast paths for creating regular expressions for common glob patterns.\n * This can significantly speed up processing and has very little downside\n * impact when none of the fast paths match.\n */\n\nparse.fastpaths = (input, options) => {\n const opts = { ...options };\n const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;\n const len = input.length;\n if (len > max) {\n throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);\n }\n\n input = REPLACEMENTS[input] || input;\n const win32 = utils.isWindows(options);\n\n // create constants based on platform, for windows or posix\n const {\n DOT_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOTS,\n NO_DOTS_SLASH,\n STAR,\n START_ANCHOR\n } = constants.globChars(win32);\n\n const nodot = opts.dot ? NO_DOTS : NO_DOT;\n const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;\n const capture = opts.capture ? '' : '?:';\n const state = { negated: false, prefix: '' };\n let star = opts.bash === true ? '.*?' : STAR;\n\n if (opts.capture) {\n star = `(${star})`;\n }\n\n const globstar = opts => {\n if (opts.noglobstar === true) return star;\n return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;\n };\n\n const create = str => {\n switch (str) {\n case '*':\n return `${nodot}${ONE_CHAR}${star}`;\n\n case '.*':\n return `${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '*.*':\n return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '*/*':\n return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;\n\n case '**':\n return nodot + globstar(opts);\n\n case '**/*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;\n\n case '**/*.*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '**/.*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n default: {\n const match = /^(.*?)\\.(\\w+)$/.exec(str);\n if (!match) return;\n\n const source = create(match[1]);\n if (!source) return;\n\n return source + DOT_LITERAL + match[2];\n }\n }\n };\n\n const output = utils.removePrefix(input, state);\n let source = create(output);\n\n if (source && opts.strictSlashes !== true) {\n source += `${SLASH_LITERAL}?`;\n }\n\n return source;\n};\n\nmodule.exports = parse;\n","'use strict';\n\nconst path = require('path');\nconst scan = require('./scan');\nconst parse = require('./parse');\nconst utils = require('./utils');\nconst constants = require('./constants');\nconst isObject = val => val && typeof val === 'object' && !Array.isArray(val);\n\n/**\n * Creates a matcher function from one or more glob patterns. The\n * returned function takes a string to match as its first argument,\n * and returns true if the string is a match. The returned matcher\n * function also takes a boolean as the second argument that, when true,\n * returns an object with additional information.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch(glob[, options]);\n *\n * const isMatch = picomatch('*.!(*a)');\n * console.log(isMatch('a.a')); //=> false\n * console.log(isMatch('a.b')); //=> true\n * ```\n * @name picomatch\n * @param {String|Array} `globs` One or more glob patterns.\n * @param {Object=} `options`\n * @return {Function=} Returns a matcher function.\n * @api public\n */\n\nconst picomatch = (glob, options, returnState = false) => {\n if (Array.isArray(glob)) {\n const fns = glob.map(input => picomatch(input, options, returnState));\n const arrayMatcher = str => {\n for (const isMatch of fns) {\n const state = isMatch(str);\n if (state) return state;\n }\n return false;\n };\n return arrayMatcher;\n }\n\n const isState = isObject(glob) && glob.tokens && glob.input;\n\n if (glob === '' || (typeof glob !== 'string' && !isState)) {\n throw new TypeError('Expected pattern to be a non-empty string');\n }\n\n const opts = options || {};\n const posix = utils.isWindows(options);\n const regex = isState\n ? picomatch.compileRe(glob, options)\n : picomatch.makeRe(glob, options, false, true);\n\n const state = regex.state;\n delete regex.state;\n\n let isIgnored = () => false;\n if (opts.ignore) {\n const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };\n isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);\n }\n\n const matcher = (input, returnObject = false) => {\n const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });\n const result = { glob, state, regex, posix, input, output, match, isMatch };\n\n if (typeof opts.onResult === 'function') {\n opts.onResult(result);\n }\n\n if (isMatch === false) {\n result.isMatch = false;\n return returnObject ? result : false;\n }\n\n if (isIgnored(input)) {\n if (typeof opts.onIgnore === 'function') {\n opts.onIgnore(result);\n }\n result.isMatch = false;\n return returnObject ? result : false;\n }\n\n if (typeof opts.onMatch === 'function') {\n opts.onMatch(result);\n }\n return returnObject ? result : true;\n };\n\n if (returnState) {\n matcher.state = state;\n }\n\n return matcher;\n};\n\n/**\n * Test `input` with the given `regex`. This is used by the main\n * `picomatch()` function to test the input string.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.test(input, regex[, options]);\n *\n * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\\/([^/]*?))$/));\n * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }\n * ```\n * @param {String} `input` String to test.\n * @param {RegExp} `regex`\n * @return {Object} Returns an object with matching info.\n * @api public\n */\n\npicomatch.test = (input, regex, options, { glob, posix } = {}) => {\n if (typeof input !== 'string') {\n throw new TypeError('Expected input to be a string');\n }\n\n if (input === '') {\n return { isMatch: false, output: '' };\n }\n\n const opts = options || {};\n const format = opts.format || (posix ? utils.toPosixSlashes : null);\n let match = input === glob;\n let output = (match && format) ? format(input) : input;\n\n if (match === false) {\n output = format ? format(input) : input;\n match = output === glob;\n }\n\n if (match === false || opts.capture === true) {\n if (opts.matchBase === true || opts.basename === true) {\n match = picomatch.matchBase(input, regex, options, posix);\n } else {\n match = regex.exec(output);\n }\n }\n\n return { isMatch: Boolean(match), match, output };\n};\n\n/**\n * Match the basename of a filepath.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.matchBase(input, glob[, options]);\n * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true\n * ```\n * @param {String} `input` String to test.\n * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).\n * @return {Boolean}\n * @api public\n */\n\npicomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {\n const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);\n return regex.test(path.basename(input));\n};\n\n/**\n * Returns true if **any** of the given glob `patterns` match the specified `string`.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.isMatch(string, patterns[, options]);\n *\n * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true\n * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false\n * ```\n * @param {String|Array} str The string to test.\n * @param {String|Array} patterns One or more glob patterns to use for matching.\n * @param {Object} [options] See available [options](#options).\n * @return {Boolean} Returns true if any patterns match `str`\n * @api public\n */\n\npicomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);\n\n/**\n * Parse a glob pattern to create the source string for a regular\n * expression.\n *\n * ```js\n * const picomatch = require('picomatch');\n * const result = picomatch.parse(pattern[, options]);\n * ```\n * @param {String} `pattern`\n * @param {Object} `options`\n * @return {Object} Returns an object with useful properties and output to be used as a regex source string.\n * @api public\n */\n\npicomatch.parse = (pattern, options) => {\n if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));\n return parse(pattern, { ...options, fastpaths: false });\n};\n\n/**\n * Scan a glob pattern to separate the pattern into segments.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.scan(input[, options]);\n *\n * const result = picomatch.scan('!./foo/*.js');\n * console.log(result);\n * { prefix: '!./',\n * input: '!./foo/*.js',\n * start: 3,\n * base: 'foo',\n * glob: '*.js',\n * isBrace: false,\n * isBracket: false,\n * isGlob: true,\n * isExtglob: false,\n * isGlobstar: false,\n * negated: true }\n * ```\n * @param {String} `input` Glob pattern to scan.\n * @param {Object} `options`\n * @return {Object} Returns an object with\n * @api public\n */\n\npicomatch.scan = (input, options) => scan(input, options);\n\n/**\n * Compile a regular expression from the `state` object returned by the\n * [parse()](#parse) method.\n *\n * @param {Object} `state`\n * @param {Object} `options`\n * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.\n * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.\n * @return {RegExp}\n * @api public\n */\n\npicomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {\n if (returnOutput === true) {\n return state.output;\n }\n\n const opts = options || {};\n const prepend = opts.contains ? '' : '^';\n const append = opts.contains ? '' : '$';\n\n let source = `${prepend}(?:${state.output})${append}`;\n if (state && state.negated === true) {\n source = `^(?!${source}).*$`;\n }\n\n const regex = picomatch.toRegex(source, options);\n if (returnState === true) {\n regex.state = state;\n }\n\n return regex;\n};\n\n/**\n * Create a regular expression from a parsed glob pattern.\n *\n * ```js\n * const picomatch = require('picomatch');\n * const state = picomatch.parse('*.js');\n * // picomatch.compileRe(state[, options]);\n *\n * console.log(picomatch.compileRe(state));\n * //=> /^(?:(?!\\.)(?=.)[^/]*?\\.js)$/\n * ```\n * @param {String} `state` The object returned from the `.parse` method.\n * @param {Object} `options`\n * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.\n * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.\n * @return {RegExp} Returns a regex created from the given pattern.\n * @api public\n */\n\npicomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {\n if (!input || typeof input !== 'string') {\n throw new TypeError('Expected a non-empty string');\n }\n\n let parsed = { negated: false, fastpaths: true };\n\n if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {\n parsed.output = parse.fastpaths(input, options);\n }\n\n if (!parsed.output) {\n parsed = parse(input, options);\n }\n\n return picomatch.compileRe(parsed, options, returnOutput, returnState);\n};\n\n/**\n * Create a regular expression from the given regex source string.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.toRegex(source[, options]);\n *\n * const { output } = picomatch.parse('*.js');\n * console.log(picomatch.toRegex(output));\n * //=> /^(?:(?!\\.)(?=.)[^/]*?\\.js)$/\n * ```\n * @param {String} `source` Regular expression source string.\n * @param {Object} `options`\n * @return {RegExp}\n * @api public\n */\n\npicomatch.toRegex = (source, options) => {\n try {\n const opts = options || {};\n return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));\n } catch (err) {\n if (options && options.debug === true) throw err;\n return /$^/;\n }\n};\n\n/**\n * Picomatch constants.\n * @return {Object}\n */\n\npicomatch.constants = constants;\n\n/**\n * Expose \"picomatch\"\n */\n\nmodule.exports = picomatch;\n","'use strict';\n\nmodule.exports = require('./lib/picomatch');\n","import picomatch from \"picomatch\";\n\nimport type { GitDiff, KlyConfig } from \"./types\";\n\nexport interface FilteredDiff {\n toIndex: string[];\n toDelete: string[];\n renamed: Array<{ from: string; to: string }>;\n}\n\nexport function filterGitDiff(diff: GitDiff, config: KlyConfig): FilteredDiff {\n const isIncluded = picomatch(config.include);\n const isExcluded = picomatch(config.exclude);\n\n const matches = (filePath: string): boolean => isIncluded(filePath) && !isExcluded(filePath);\n\n const toIndex: string[] = [];\n const toDelete: string[] = [];\n const renamed: Array<{ from: string; to: string }> = [];\n\n for (const filePath of [...diff.added, ...diff.modified]) {\n if (matches(filePath)) {\n toIndex.push(filePath);\n }\n }\n\n for (const filePath of diff.deleted) {\n if (matches(filePath)) {\n toDelete.push(filePath);\n }\n }\n\n for (const r of diff.renamed) {\n const fromMatches = matches(r.from);\n const toMatches = matches(r.to);\n\n if (toMatches) {\n renamed.push(r);\n }\n if (fromMatches && !toMatches) {\n toDelete.push(r.from);\n }\n }\n\n return { toIndex, toDelete, renamed };\n}\n","import type { ParseResult } from \"../types\";\n\nexport abstract class BaseParser {\n abstract readonly extensions: string[];\n\n abstract parse(content: string, filePath: string): ParseResult;\n\n supports(filePath: string): boolean {\n return this.extensions.some((ext) => filePath.endsWith(ext));\n }\n}\n","import Parser from \"tree-sitter\";\nimport Swift from \"tree-sitter-swift\";\n\nimport type { ParseResult, SymbolInfo, SymbolKind } from \"../types\";\nimport { BaseParser } from \"./base\";\n\nconst swiftParser = new Parser();\nswiftParser.setLanguage(Swift);\n\nconst SYMBOL_NODE_TYPES: Record<string, SymbolKind> = {\n class_declaration: \"class\",\n protocol_declaration: \"protocol\",\n function_declaration: \"function\",\n};\n\n// tree-sitter-swift parses struct/enum/class all as class_declaration.\n// Detect actual kind from the first keyword child.\nconst KEYWORD_TO_KIND: Record<string, SymbolKind> = {\n struct: \"struct\",\n enum: \"enum\",\n class: \"class\",\n};\n\nfunction extractName(node: Parser.SyntaxNode): string | null {\n /* v8 ignore next */\n return node.childForFieldName(\"name\")?.text ?? null;\n}\n\nexport class SwiftParser extends BaseParser {\n readonly extensions = [\".swift\"];\n\n parse(content: string, _filePath: string): ParseResult {\n const tree = swiftParser.parse(content);\n const rootNode = tree.rootNode;\n\n const imports: string[] = [];\n const exports: string[] = [];\n const symbols: SymbolInfo[] = [];\n\n function walk(node: Parser.SyntaxNode): void {\n // Imports\n if (node.type === \"import_declaration\") {\n // Get the module name from import statement\n const children = node.children.filter((c: Parser.SyntaxNode) => c.type !== \"import\");\n /* v8 ignore next */\n if (children.length > 0) {\n imports.push(children.map((c: Parser.SyntaxNode) => c.text).join(\".\"));\n }\n }\n\n // Symbols\n let kind = SYMBOL_NODE_TYPES[node.type];\n if (node.type === \"class_declaration\") {\n // Detect struct/enum/class from keyword child\n const keyword = node.children.find((c: Parser.SyntaxNode) => c.type in KEYWORD_TO_KIND);\n /* v8 ignore next */\n kind = keyword ? KEYWORD_TO_KIND[keyword.type] : \"class\";\n }\n if (kind) {\n const name = extractName(node);\n /* v8 ignore next */\n if (name) {\n symbols.push({ name, kind, description: \"\" });\n // In Swift, all top-level declarations are effectively exported\n exports.push(name);\n }\n }\n\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(rootNode);\n\n return { imports, exports, symbols };\n }\n}\n","import Parser from \"tree-sitter\";\nimport TypeScript from \"tree-sitter-typescript\";\n\nimport type { ParseResult, SymbolInfo, SymbolKind } from \"../types\";\nimport { BaseParser } from \"./base\";\n\nconst tsParser = new Parser();\ntsParser.setLanguage(TypeScript.typescript);\n\nconst tsxParser = new Parser();\ntsxParser.setLanguage(TypeScript.tsx);\n\nconst IMPORT_TYPES = new Set([\"import_statement\"]);\nconst EXPORT_NODE_TYPES = new Set([\"export_statement\"]);\n\nconst SYMBOL_NODE_TYPES: Record<string, SymbolKind> = {\n class_declaration: \"class\",\n function_declaration: \"function\",\n method_definition: \"method\",\n interface_declaration: \"interface\",\n type_alias_declaration: \"type\",\n enum_declaration: \"enum\",\n lexical_declaration: \"variable\",\n variable_declaration: \"variable\",\n};\n\nfunction extractName(node: Parser.SyntaxNode): string | null {\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) return nameNode.text;\n\n // For variable declarations, look for the first declarator\n for (const child of node.children) {\n if (child.type === \"variable_declarator\") {\n const n = child.childForFieldName(\"name\");\n /* v8 ignore next */\n if (n) return n.text;\n }\n }\n\n /* v8 ignore next */\n return null;\n}\n\nfunction extractImports(rootNode: Parser.SyntaxNode): string[] {\n const imports: string[] = [];\n\n for (const child of rootNode.children) {\n if (IMPORT_TYPES.has(child.type)) {\n const source = child.childForFieldName(\"source\");\n /* v8 ignore next */\n if (source) {\n imports.push(source.text.replace(/['\"]/g, \"\"));\n }\n }\n }\n\n return imports;\n}\n\nfunction extractExports(rootNode: Parser.SyntaxNode): string[] {\n const exports: string[] = [];\n\n for (const child of rootNode.children) {\n if (EXPORT_NODE_TYPES.has(child.type)) {\n // export { ... }\n const exportClause = child.children.find(\n (c: Parser.SyntaxNode) => c.type === \"export_clause\",\n );\n if (exportClause) {\n for (const specifier of exportClause.children) {\n if (specifier.type === \"export_specifier\") {\n const name = specifier.childForFieldName(\"name\");\n /* v8 ignore next */\n if (name) exports.push(name.text);\n }\n }\n continue;\n }\n\n // export declaration (class, function, etc.)\n const declaration = child.childForFieldName(\"declaration\");\n if (declaration) {\n const name = extractName(declaration);\n /* v8 ignore next */\n if (name) exports.push(name);\n }\n }\n }\n\n return exports;\n}\n\nfunction extractSymbols(rootNode: Parser.SyntaxNode): SymbolInfo[] {\n const symbols: SymbolInfo[] = [];\n\n function walk(node: Parser.SyntaxNode): void {\n // Check if this is an exported declaration wrapper\n if (EXPORT_NODE_TYPES.has(node.type)) {\n const declaration = node.childForFieldName(\"declaration\");\n if (declaration) {\n processSymbolNode(declaration);\n }\n return;\n }\n\n processSymbolNode(node);\n\n for (const child of node.children) {\n // Only go one level deep for top-level symbols, skip into class bodies for methods\n if (child.type === \"class_body\") {\n for (const member of child.children) {\n processSymbolNode(member);\n }\n }\n }\n }\n\n function processSymbolNode(node: Parser.SyntaxNode): void {\n const kind = SYMBOL_NODE_TYPES[node.type];\n if (!kind) return;\n\n const name = extractName(node);\n /* v8 ignore next */\n if (!name) return;\n\n symbols.push({\n name,\n kind,\n description: \"\",\n });\n }\n\n for (const child of rootNode.children) {\n walk(child);\n }\n\n return symbols;\n}\n\nexport class TypeScriptParser extends BaseParser {\n readonly extensions = [\".ts\", \".tsx\", \".js\", \".jsx\"];\n\n parse(content: string, filePath: string): ParseResult {\n const isTsx = filePath.endsWith(\".tsx\") || filePath.endsWith(\".jsx\");\n const parser = isTsx ? tsxParser : tsParser;\n const tree = parser.parse(content);\n const rootNode = tree.rootNode;\n\n return {\n imports: extractImports(rootNode),\n exports: extractExports(rootNode),\n symbols: extractSymbols(rootNode),\n };\n }\n}\n","import type { Language, ParseResult } from \"../types\";\nimport { BaseParser } from \"./base\";\nimport { SwiftParser } from \"./swift\";\nimport { TypeScriptParser } from \"./typescript\";\n\nconst EXTENSION_TO_LANGUAGE: Record<string, Language> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".swift\": \"swift\",\n};\n\nexport class ParserManager {\n private parsers: BaseParser[];\n\n constructor() {\n this.parsers = [new TypeScriptParser(), new SwiftParser()];\n }\n\n getParser(filePath: string): BaseParser | undefined {\n return this.parsers.find((p) => p.supports(filePath));\n }\n\n parse(content: string, filePath: string): ParseResult | null {\n const parser = this.getParser(filePath);\n if (!parser) return null;\n return parser.parse(content, filePath);\n }\n\n getLanguage(filePath: string): Language | undefined {\n const ext = filePath.slice(filePath.lastIndexOf(\".\"));\n return EXTENSION_TO_LANGUAGE[ext];\n }\n}\n\nexport { BaseParser } from \"./base\";\nexport { SwiftParser } from \"./swift\";\nexport { TypeScriptParser } from \"./typescript\";\n","import pLimit from \"p-limit\";\n\nexport interface BatchTask<T> {\n execute: () => Promise<T>;\n}\n\nexport class Batcher<T> {\n private limit: ReturnType<typeof pLimit>;\n\n constructor(concurrency: number = 5) {\n this.limit = pLimit(concurrency);\n }\n\n async run(tasks: BatchTask<T>[]): Promise<T[]> {\n return Promise.all(tasks.map((task) => this.limit(() => task.execute())));\n }\n}\n","export const INDEXING_SYSTEM_PROMPT = `You are a code indexing assistant. Your job is to analyze source code files and generate structured metadata.\n\nFor each file, you must return a JSON object with exactly these fields:\n- \"name\": A short, descriptive name for the file (e.g., \"User Authentication Service\")\n- \"description\": A one-line description of what this file does\n- \"summary\": A 2-3 sentence summary of the file's purpose and key functionality\n- \"symbols\": An array of symbol descriptions, each with \"name\" and \"description\"\n\nRules:\n- Be concise and precise\n- Focus on what the code DOES, not how it's structured\n- Symbol descriptions should explain the purpose, not restate the signature\n- Return ONLY valid JSON, no markdown or explanation`;\n\nexport const RERANK_SYSTEM_PROMPT = `You are a search result reranking assistant. Given a user query and a list of candidate files, reorder them by relevance.\n\nReturn ONLY a JSON array of file paths, ordered from most relevant to least relevant.\nDo not include any explanation, markdown, or extra text — just the JSON array.`;\n\nexport function buildRerankPrompt(\n query: string,\n candidates: Array<{ path: string; name: string; description: string; summary: string }>,\n): string {\n const fileList = candidates\n .map(\n (c, i) =>\n `${i + 1}. ${c.path}\\n Name: ${c.name}\\n Description: ${c.description}\\n Summary: ${c.summary}`,\n )\n .join(\"\\n\\n\");\n\n return `User query: \"${query}\"\n\nCandidate files:\n${fileList}\n\nReorder these files by relevance to the query. Return a JSON array of file paths, most relevant first.`;\n}\n\nexport function buildIndexingPrompt(\n filePath: string,\n content: string,\n symbols: { name: string; kind: string }[],\n): string {\n const symbolList = symbols.map((s) => `- ${s.kind}: ${s.name}`).join(\"\\n\");\n\n return `Analyze this source file and generate indexing metadata.\n\nFile: ${filePath}\nDetected symbols:\n${symbolList}\n\nSource code:\n\\`\\`\\`\n${content}\n\\`\\`\\`\n\nReturn a JSON object with: name, description, summary, and symbols (array with name + description for each detected symbol).`;\n}\n","import { complete, getModel } from \"@mariozechner/pi-ai\";\nimport type { Api, Model, Provider, TextContent } from \"@mariozechner/pi-ai\";\n\nimport type { KlyConfig, SymbolInfo } from \"../types\";\nimport { Batcher } from \"./batcher\";\nimport { buildIndexingPrompt, INDEXING_SYSTEM_PROMPT } from \"./prompts\";\n\ninterface LLMIndexResult {\n name: string;\n description: string;\n summary: string;\n symbols: { name: string; description: string }[];\n}\n\n/**\n * Resolve a model by provider and model ID from user config.\n * pi-ai's getModel is generic over compile-time known providers/models,\n * but user config is dynamic. This wrapper bridges the gap.\n */\nfunction resolveModel(provider: Provider, modelId: string): Model<Api> {\n const model = (getModel as (p: Provider, m: string) => Model<Api> | undefined)(provider, modelId);\n if (!model) {\n throw new Error(\n `Unknown model \"${modelId}\" for provider \"${provider}\". Check your .kly/config.yaml.`,\n );\n }\n return model;\n}\n\nexport class LLMService {\n private model: Model<Api>;\n private batcher: Batcher<LLMIndexResult>;\n\n constructor(config: KlyConfig) {\n const envKey = this.getEnvKeyName(config.llm.provider);\n if (config.llm.apiKey && !process.env[envKey]) {\n process.env[envKey] = config.llm.apiKey;\n }\n\n this.model = resolveModel(config.llm.provider, config.llm.model);\n this.batcher = new Batcher(5);\n }\n\n private getEnvKeyName(provider: string): string {\n const map: Record<string, string> = {\n openrouter: \"OPENROUTER_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n google: \"GOOGLE_API_KEY\",\n mistral: \"MISTRAL_API_KEY\",\n groq: \"GROQ_API_KEY\",\n xai: \"XAI_API_KEY\",\n };\n return map[provider] || `${provider.toUpperCase()}_API_KEY`;\n }\n\n async indexFile(\n filePath: string,\n content: string,\n symbols: SymbolInfo[],\n ): Promise<LLMIndexResult> {\n const prompt = buildIndexingPrompt(\n filePath,\n content,\n symbols.map((s) => ({ name: s.name, kind: s.kind })),\n );\n\n const response = await complete(this.model, {\n systemPrompt: INDEXING_SYSTEM_PROMPT,\n messages: [\n {\n role: \"user\",\n content: prompt,\n timestamp: Date.now(),\n },\n ],\n });\n\n const text = response.content\n .filter((block): block is TextContent => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\n return this.parseResponse(text);\n }\n\n async indexFiles(\n files: { path: string; content: string; symbols: SymbolInfo[] }[],\n ): Promise<Map<string, LLMIndexResult>> {\n const results = new Map<string, LLMIndexResult>();\n\n const tasks = files.map((file) => ({\n execute: async () => {\n const result = await this.indexFile(file.path, file.content, file.symbols);\n results.set(file.path, result);\n return result;\n },\n }));\n\n await this.batcher.run(tasks);\n return results;\n }\n\n private parseResponse(text: string): LLMIndexResult {\n const jsonMatch = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n const jsonStr = jsonMatch ? jsonMatch[1].trim() : text.trim();\n\n const parsed = JSON.parse(jsonStr) as LLMIndexResult;\n\n return {\n name: parsed.name || \"\",\n description: parsed.description || \"\",\n summary: parsed.summary || \"\",\n symbols: Array.isArray(parsed.symbols)\n ? parsed.symbols.map((s) => ({\n name: s.name || \"\",\n description: s.description || \"\",\n }))\n : [],\n };\n }\n}\n","import path from \"node:path\";\n\nimport { renderMermaidASCII, renderMermaidSVG } from \"beautiful-mermaid\";\n\nimport type { IndexDatabase } from \"./database\";\nimport type { FileIndex, Language } from \"./types\";\n\nexport type GraphFormat = \"json\" | \"mermaid\" | \"ascii\" | \"svg\";\n\nexport interface GraphNode {\n path: string;\n name: string;\n language: Language;\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, GraphNode>;\n edges: GraphEdge[];\n}\n\nconst RESOLVE_EXTENSIONS = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \"/index.ts\",\n \"/index.tsx\",\n \"/index.js\",\n \"/index.jsx\",\n];\n\nexport function isRelativeImport(importPath: string): boolean {\n return importPath.startsWith(\".\") || importPath.startsWith(\"/\");\n}\n\n/**\n * Resolve a relative import path to a file path that exists in the index.\n */\nexport function resolveImport(\n fromFile: string,\n importPath: string,\n indexedPaths: Set<string>,\n): string | undefined {\n if (!isRelativeImport(importPath)) return undefined;\n\n const dir = path.dirname(fromFile);\n const resolved = path.normalize(path.join(dir, importPath));\n\n // Direct match (already has extension)\n if (indexedPaths.has(resolved)) return resolved;\n\n // Try extension completion\n for (const ext of RESOLVE_EXTENSIONS) {\n const candidate = resolved + ext;\n if (indexedPaths.has(candidate)) return candidate;\n }\n\n return undefined;\n}\n\n/**\n * Build a dependency graph from indexed files.\n */\nexport function buildDependencyGraph(\n db: IndexDatabase,\n options: { focus?: string; depth?: number } = {},\n): DependencyGraph {\n const { focus, depth = 2 } = options;\n const allFiles = db.getAllFiles();\n const indexedPaths = new Set(allFiles.map((f) => f.path));\n const fileMap = new Map<string, FileIndex>();\n for (const file of allFiles) {\n fileMap.set(file.path, file);\n }\n\n // Build full adjacency list\n const adjacency = new Map<string, string[]>();\n for (const file of allFiles) {\n const deps: string[] = [];\n for (const imp of file.imports) {\n const resolved = resolveImport(file.path, imp, indexedPaths);\n if (resolved) deps.push(resolved);\n }\n adjacency.set(file.path, deps);\n }\n\n // Determine which nodes to include\n let includedPaths: Set<string>;\n\n if (focus) {\n // BFS from focus node up to depth\n includedPaths = new Set<string>();\n const queue: Array<{ path: string; currentDepth: number }> = [{ path: focus, currentDepth: 0 }];\n includedPaths.add(focus);\n\n while (queue.length > 0) {\n const { path: current, currentDepth } = queue.shift()!;\n if (currentDepth >= depth) continue;\n\n // Forward edges (dependencies of current)\n const deps = adjacency.get(current) || [];\n for (const dep of deps) {\n if (!includedPaths.has(dep)) {\n includedPaths.add(dep);\n queue.push({ path: dep, currentDepth: currentDepth + 1 });\n }\n }\n\n // Reverse edges (files that depend on current)\n for (const [source, targets] of adjacency) {\n if (targets.includes(current) && !includedPaths.has(source)) {\n includedPaths.add(source);\n queue.push({ path: source, currentDepth: currentDepth + 1 });\n }\n }\n }\n } else {\n includedPaths = indexedPaths;\n }\n\n // Build graph\n const nodes = new Map<string, GraphNode>();\n const edges: GraphEdge[] = [];\n\n for (const filePath of includedPaths) {\n const file = fileMap.get(filePath);\n if (!file) continue;\n nodes.set(filePath, {\n path: file.path,\n name: file.name,\n language: file.language,\n });\n }\n\n for (const filePath of includedPaths) {\n const deps = adjacency.get(filePath) || [];\n for (const dep of deps) {\n if (includedPaths.has(dep)) {\n edges.push({ from: filePath, to: dep });\n }\n }\n }\n\n return { nodes, edges };\n}\n\n/**\n * Generate Mermaid syntax from a dependency graph.\n */\nexport function generateMermaid(graph: DependencyGraph): string {\n const lines: string[] = [\"graph LR\"];\n\n // Create stable node IDs\n const nodeIds = new Map<string, string>();\n let idCounter = 0;\n for (const filePath of graph.nodes.keys()) {\n nodeIds.set(filePath, `N${idCounter++}`);\n }\n\n // Node declarations\n for (const [filePath, node] of graph.nodes) {\n const id = nodeIds.get(filePath)!;\n const label = node.path.replace(/\"/g, \"'\");\n lines.push(` ${id}[\"${label}\"]`);\n }\n\n // Edge declarations\n for (const edge of graph.edges) {\n const fromId = nodeIds.get(edge.from);\n const toId = nodeIds.get(edge.to);\n if (fromId && toId) {\n lines.push(` ${fromId} --> ${toId}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a Mermaid diagram string to ASCII/Unicode art.\n */\nexport function renderGraphAscii(mermaid: string): string {\n return renderMermaidASCII(mermaid, { colorMode: \"none\" });\n}\n\n/**\n * Render a Mermaid diagram string to SVG.\n */\nexport function renderGraphSvg(mermaid: string): string {\n return renderMermaidSVG(mermaid, { transparent: true });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { hashConfig, loadConfig } from \"./config\";\nimport type { IndexDatabase } from \"./database\";\nimport { filterGitDiff } from \"./diff-filter\";\nimport {\n getCurrentBranch,\n getCurrentCommit,\n getChangedFiles,\n isAncestor,\n getMergeBase,\n isGitRepo,\n branchToDbName,\n} from \"./git\";\nimport { resolveImport } from \"./graph\";\nimport { hashFile, hasChanged } from \"./hasher\";\nimport { LLMService } from \"./llm/index\";\nimport { ParserManager } from \"./parser/index\";\nimport { scanFiles } from \"./scanner\";\nimport {\n openDatabase,\n loadState,\n saveState,\n getBranchState,\n setBranchState,\n copyDatabase,\n} from \"./store\";\nimport type { BranchState, FileIndex } from \"./types\";\n\nexport interface IndexProgress {\n total: number;\n completed: number;\n current: string;\n skipped: number;\n}\n\nexport type ProgressCallback = (progress: IndexProgress) => void;\n\nexport interface IndexOptions {\n incremental?: boolean;\n full?: boolean;\n quiet?: boolean;\n onProgress?: ProgressCallback;\n}\n\nexport interface BuildResult {\n totalFiles: number;\n newFiles: number;\n updatedFiles: number;\n deletedFiles: number;\n unchangedFiles: number;\n branch: string;\n commit: string;\n durationMs: number;\n}\n\nfunction emptyBuildResult(root: string): BuildResult {\n const gitRepo = isGitRepo(root);\n return {\n totalFiles: 0,\n newFiles: 0,\n updatedFiles: 0,\n deletedFiles: 0,\n unchangedFiles: 0,\n branch: gitRepo ? getCurrentBranch(root) || \"detached\" : \"default\",\n commit: gitRepo ? getCurrentCommit(root) : \"\",\n durationMs: 0,\n };\n}\n\nexport async function buildIndex(root: string, options: IndexOptions = {}): Promise<BuildResult> {\n const start = Date.now();\n const config = loadConfig(root);\n const parserManager = new ParserManager();\n const llmService = new LLMService(config);\n\n const gitRepo = isGitRepo(root);\n\n let result: BuildResult;\n if (gitRepo && !options.full) {\n result = await buildGitAware(root, config, parserManager, llmService, options);\n } else {\n result = await buildClassic(root, config, parserManager, llmService, options);\n }\n\n result.durationMs = Date.now() - start;\n return result;\n}\n\nasync function buildGitAware(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n): Promise<BuildResult> {\n const branch = getCurrentBranch(root);\n const commit = getCurrentCommit(root);\n const dbName = branchToDbName(branch, commit);\n\n const state = loadState(root);\n const currentConfigHash = hashConfig(config);\n\n let result: BuildResult;\n\n // Config changed — force full rebuild\n if (state.configHash && state.configHash !== currentConfigHash) {\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n state.configHash = currentConfigHash;\n setBranchState(state, dbName, { lastCommit: commit, lastBuilt: Date.now() });\n saveState(root, state);\n return result;\n }\n\n const branchState = getBranchState(state, dbName);\n\n if (branchState?.lastCommit) {\n if (isAncestor(root, branchState.lastCommit, commit)) {\n // Normal incremental: diff from last indexed commit\n result = await buildFromGitDiff(\n root,\n config,\n parserManager,\n llmService,\n options,\n dbName,\n branchState.lastCommit,\n commit,\n );\n } else {\n // Rebase/force push: fall back to hash-based incremental\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n } else {\n // New branch: try to fork from parent\n const forkedFromDb = tryForkFromParent(root, dbName, state);\n if (forkedFromDb) {\n // Track the fork origin so we can preserve it across rebuilds\n setBranchState(state, dbName, { lastCommit: \"\", lastBuilt: 0, forkedFrom: forkedFromDb });\n // parentState is guaranteed to exist — tryForkFromParent checks state.branches[candidate]\n const parentState = getBranchState(state, forkedFromDb)!;\n const mergeBase = getMergeBase(root, parentState.lastCommit, commit);\n if (mergeBase) {\n result = await buildFromGitDiff(\n root,\n config,\n parserManager,\n llmService,\n options,\n dbName,\n mergeBase,\n commit,\n );\n } else {\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n } else {\n // Full build\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n }\n\n state.configHash = currentConfigHash;\n const newBranchState: BranchState = {\n lastCommit: commit,\n lastBuilt: Date.now(),\n };\n // Preserve forkedFrom if it was previously set\n const currentBranchState = getBranchState(state, dbName);\n if (currentBranchState?.forkedFrom) {\n newBranchState.forkedFrom = currentBranchState.forkedFrom;\n }\n setBranchState(state, dbName, newBranchState);\n saveState(root, state);\n return result;\n}\n\nfunction tryForkFromParent(\n root: string,\n dbName: string,\n state: { branches: Record<string, { lastCommit: string }> },\n): string | null {\n // Try to find \"main\" or \"master\" as parent\n for (const candidate of [\"main\", \"master\"]) {\n if (state.branches[candidate] && candidate !== dbName) {\n copyDatabase(root, candidate, dbName);\n return candidate;\n }\n }\n return null;\n}\n\nasync function buildFromGitDiff(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n dbName: string,\n fromCommit: string,\n toCommit: string,\n): Promise<BuildResult> {\n const gitDiff = getChangedFiles(root, fromCommit, toCommit);\n const filtered = filterGitDiff(gitDiff, config);\n\n // Handle renamed files: add the new path to index list, delete old path\n const toIndex = [...filtered.toIndex];\n const toDelete = [...filtered.toDelete];\n\n for (const r of filtered.renamed) {\n toIndex.push(r.to);\n toDelete.push(r.from);\n }\n\n const db = openDatabase(root, dbName);\n const result = emptyBuildResult(root);\n\n try {\n if (toDelete.length > 0) {\n db.removeFiles(toDelete);\n db.removeDependenciesBatch(toDelete);\n result.deletedFiles = toDelete.length;\n }\n\n if (toIndex.length === 0) {\n options.onProgress?.({\n total: 0,\n completed: 0,\n current: \"\",\n skipped: 0,\n });\n result.totalFiles = db.getFileCount();\n result.unchangedFiles = result.totalFiles;\n return result;\n }\n\n const indexResult = await indexFiles(root, toIndex, db, parserManager, llmService, options);\n result.newFiles = indexResult.newFiles;\n result.updatedFiles = indexResult.updatedFiles;\n result.totalFiles = db.getFileCount();\n result.unchangedFiles = result.totalFiles - result.newFiles - result.updatedFiles;\n return result;\n } finally {\n db.close();\n }\n}\n\nasync function buildClassic(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n dbName?: string,\n): Promise<BuildResult> {\n const name =\n dbName ||\n (isGitRepo(root) ? branchToDbName(getCurrentBranch(root), getCurrentCommit(root)) : \"default\");\n const db = openDatabase(root, name);\n const result = emptyBuildResult(root);\n\n try {\n const files = await scanFiles(root, config);\n const progress: IndexProgress = {\n total: files.length,\n completed: 0,\n current: \"\",\n skipped: 0,\n };\n\n // Collect files that need indexing, track which already exist\n const toIndex: string[] = [];\n const existingPaths = new Set<string>();\n\n for (const filePath of files) {\n const hash = hashFile(root, filePath);\n const existing = db.getFile(filePath);\n\n if (existing) {\n existingPaths.add(filePath);\n }\n\n if (existing && !hasChanged(existing.hash, hash) && !options.full) {\n progress.skipped++;\n progress.completed++;\n result.unchangedFiles++;\n options.onProgress?.(progress);\n continue;\n }\n\n toIndex.push(filePath);\n }\n\n if (toIndex.length > 0) {\n await indexFiles(root, toIndex, db, parserManager, llmService, options, progress);\n // Determine new vs updated based on whether they existed before\n for (const filePath of toIndex) {\n if (existingPaths.has(filePath)) {\n result.updatedFiles++;\n } else {\n result.newFiles++;\n }\n }\n }\n\n // Remove files that no longer exist on disk\n const fileSet = new Set(files);\n const allIndexed = db.getAllFiles();\n const toRemove = allIndexed.filter((f) => !fileSet.has(f.path)).map((f) => f.path);\n if (toRemove.length > 0) {\n db.removeFiles(toRemove);\n db.removeDependenciesBatch(toRemove);\n result.deletedFiles = toRemove.length;\n }\n\n result.totalFiles = db.getFileCount();\n return result;\n } finally {\n db.close();\n }\n}\n\ninterface IndexFilesResult {\n indexed: number;\n newFiles: number;\n updatedFiles: number;\n}\n\nasync function indexFiles(\n root: string,\n filePaths: string[],\n db: IndexDatabase,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n progress?: IndexProgress,\n): Promise<IndexFilesResult> {\n const prog = progress || {\n total: filePaths.length,\n completed: 0,\n current: \"\",\n skipped: 0,\n };\n\n if (!progress) {\n prog.total = filePaths.length;\n }\n\n // Read and parse files\n const parsedFiles = filePaths.map((filePath) => {\n const fullPath = path.join(root, filePath);\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const hash = hashFile(root, filePath);\n const language = parserManager.getLanguage(filePath);\n const parseResult = parserManager.parse(content, filePath);\n\n return {\n path: filePath,\n content,\n hash,\n language: language || (\"typescript\" as const),\n imports: parseResult?.imports || [],\n exports: parseResult?.exports || [],\n symbols: parseResult?.symbols || [],\n };\n });\n\n // LLM index in batches\n const llmResults = await llmService.indexFiles(\n parsedFiles.map((f) => ({\n path: f.path,\n content: f.content,\n symbols: f.symbols,\n })),\n );\n\n // Merge and upsert\n const fileIndexes: FileIndex[] = parsedFiles.map((file) => {\n const llmResult = llmResults.get(file.path);\n\n const fileIndex: FileIndex = {\n path: file.path,\n name: llmResult?.name || path.basename(file.path),\n description: llmResult?.description || \"\",\n language: file.language,\n imports: file.imports,\n exports: file.exports,\n symbols: file.symbols.map((s) => {\n const llmSymbol = llmResult?.symbols.find((ls) => ls.name === s.name);\n return {\n ...s,\n description: llmSymbol?.description || s.description,\n };\n }),\n summary: llmResult?.summary || \"\",\n hash: file.hash,\n indexedAt: Date.now(),\n };\n\n prog.completed++;\n prog.current = file.path;\n options.onProgress?.(prog);\n\n return fileIndex;\n });\n\n db.upsertFiles(fileIndexes);\n\n // Build and write dependencies\n const allFiles = db.getAllFiles();\n const indexedPaths = new Set(allFiles.map((f) => f.path));\n const depEntries: Array<{ fromPath: string; toPaths: string[] }> = [];\n\n for (const file of parsedFiles) {\n const resolved: string[] = [];\n for (const imp of file.imports) {\n const target = resolveImport(file.path, imp, indexedPaths);\n if (target) resolved.push(target);\n }\n depEntries.push({ fromPath: file.path, toPaths: resolved });\n }\n\n if (depEntries.length > 0) {\n db.upsertBatchDependencies(depEntries);\n }\n\n return {\n indexed: fileIndexes.length,\n newFiles: 0, // caller determines new vs updated\n updatedFiles: 0,\n };\n}\n","import { complete } from \"@mariozechner/pi-ai\";\nimport type { Api, Model, TextContent } from \"@mariozechner/pi-ai\";\n\nimport type { SearchResult } from \"../database\";\nimport { buildRerankPrompt, RERANK_SYSTEM_PROMPT } from \"./prompts\";\n\n/**\n * Rerank search results using LLM.\n * Takes FTS5 candidates and returns them reordered by semantic relevance.\n */\nexport async function rerankResults(\n model: Model<Api>,\n query: string,\n candidates: SearchResult[],\n topK = 10,\n): Promise<SearchResult[]> {\n if (candidates.length === 0) return [];\n if (candidates.length <= 1) return candidates.slice(0, topK);\n\n const prompt = buildRerankPrompt(\n query,\n candidates.map((c) => ({\n path: c.file.path,\n name: c.file.name,\n description: c.file.description,\n summary: c.file.summary,\n })),\n );\n\n const response = await complete(model, {\n systemPrompt: RERANK_SYSTEM_PROMPT,\n messages: [\n {\n role: \"user\",\n content: prompt,\n timestamp: Date.now(),\n },\n ],\n });\n\n const text = response.content\n .filter((block): block is TextContent => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\n const rankedPaths = parseRerankResponse(text);\n\n // Build a path→result lookup\n const resultMap = new Map<string, SearchResult>();\n for (const candidate of candidates) {\n resultMap.set(candidate.file.path, candidate);\n }\n\n // Reorder by LLM ranking, then append any missing candidates at the end\n const reranked: SearchResult[] = [];\n const seen = new Set<string>();\n\n for (const filePath of rankedPaths) {\n const result = resultMap.get(filePath);\n if (result && !seen.has(filePath)) {\n reranked.push(result);\n seen.add(filePath);\n }\n }\n\n // Append candidates not mentioned by LLM (preserving original order)\n for (const candidate of candidates) {\n if (!seen.has(candidate.file.path)) {\n reranked.push(candidate);\n seen.add(candidate.file.path);\n }\n }\n\n return reranked.slice(0, topK);\n}\n\n/**\n * Parse the LLM rerank response into an array of file paths.\n */\nexport function parseRerankResponse(text: string): string[] {\n // Try to extract JSON array from response\n const jsonMatch = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n const jsonStr = jsonMatch ? jsonMatch[1].trim() : text.trim();\n\n try {\n const parsed = JSON.parse(jsonStr) as unknown;\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\n return parsed;\n }\n } catch {\n // If JSON parse fails, try line-by-line extraction\n }\n\n // Fallback: extract file paths line by line\n return jsonStr\n .split(\"\\n\")\n .map((line) =>\n line\n .replace(/^[\\d.)\\-\\s\"]+/, \"\")\n .replace(/[\",\\s]+$/, \"\")\n .trim(),\n )\n .filter((line) => line.length > 0 && (line.includes(\"/\") || line.includes(\".\")));\n}\n","import type { Api, Model } from \"@mariozechner/pi-ai\";\n\nimport type { IndexDatabase, SearchResult } from \"./database\";\nimport { rerankResults } from \"./llm/reranker\";\nimport type { FileIndex } from \"./types\";\n\nexport type { SearchResult } from \"./database\";\n\nexport function searchFiles(db: IndexDatabase, query: string, limit = 20): SearchResult[] {\n return db.searchFiles(query, limit);\n}\n\nexport async function searchFilesWithRerank(\n db: IndexDatabase,\n model: Model<Api>,\n query: string,\n topK = 10,\n): Promise<SearchResult[]> {\n // Fetch more candidates for reranking\n const candidates = db.searchFiles(query, 50);\n if (candidates.length === 0) return [];\n\n return rerankResults(model, query, candidates, topK);\n}\n\nexport function filterByLanguage(db: IndexDatabase, language: string): FileIndex[] {\n return db.getAllFiles().filter((f) => f.language === language);\n}\n\nexport function filterByPath(db: IndexDatabase, pathPattern: string): FileIndex[] {\n return db.getAllFiles().filter((f) => f.path.includes(pathPattern));\n}\n","import type { IndexDatabase } from \"./database\";\nimport { getFileHistory } from \"./git\";\nimport type { EnrichedErrorStack, EnrichedFrame, ErrorFrame } from \"./types\";\n\n/**\n * Enrich error stack frames with file descriptions, dependencies, and git history.\n *\n * For each frame, looks up the file in the kly index and augments it with:\n * - File description, summary, symbols, language (from index)\n * - importedBy / importsFrom (from dependencies table)\n * - Recent git commits (from git log)\n *\n * Frames whose files are not in the index are included with empty/default values.\n */\nexport function enrichErrorStack(\n db: IndexDatabase,\n root: string,\n frames: ErrorFrame[],\n): EnrichedErrorStack {\n const allImportedBy = new Set<string>();\n const enrichedFrames: EnrichedFrame[] = [];\n\n for (const frame of frames) {\n const fileIndex = db.getFile(frame.file);\n const importedBy = db.getDependents(frame.file);\n const importsFrom = db.getDependencies(frame.file);\n const commits = getFileHistory(root, frame.file, 5);\n\n for (const dep of importedBy) {\n allImportedBy.add(dep);\n }\n\n enrichedFrames.push({\n file: frame.file,\n line: frame.line,\n column: frame.column,\n function: frame.function,\n fileDescription: fileIndex?.description ?? \"\",\n fileSummary: fileIndex?.summary ?? \"\",\n symbols: fileIndex?.symbols ?? [],\n language: fileIndex?.language ?? \"typescript\",\n importedBy,\n importsFrom,\n lastModified: commits[0] ?? null,\n recentCommits: commits,\n });\n }\n\n return {\n frames: enrichedFrames,\n affectedFiles: allImportedBy.size,\n };\n}\n"],"x_google_ignoreList":[6,7,8,9,10,11],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -92,6 +92,8 @@ declare function getDbDir(root: string): string;
92
92
  declare function getDbPath(root: string, dbName: string): string;
93
93
  declare function getStatePath(root: string): string;
94
94
  declare function isInitialized(root: string): boolean;
95
+ /** Append `.kly` to root `.gitignore` when inside a git repo; idempotent. */
96
+ declare function ensureGitignore(root: string): void;
95
97
  declare function initKlyDir(root: string, config?: KlyConfig): void;
96
98
  declare function loadConfig(root: string): KlyConfig;
97
99
  declare function hashConfig(config: KlyConfig): string;
@@ -303,5 +305,5 @@ declare function renderGraphSvg(mermaid: string): string;
303
305
  */
304
306
  declare function enrichErrorStack(db: IndexDatabase, root: string, frames: ErrorFrame[]): EnrichedErrorStack;
305
307
  //#endregion
306
- export { type BranchState, type BuildResult, type DependencyGraph, type EnrichedErrorStack, type EnrichedFrame, type ErrorFrame, type FileIndex, type FilteredDiff, type GitCommit, type GitDiff, type GitState, type GraphEdge, type GraphFormat, type GraphNode, IndexDatabase, type IndexOptions, type IndexProgress, type KlyConfig, LLMService, type Language, type ParseResult, ParserManager, type ProgressCallback, type SearchResult, type SymbolInfo, type SymbolKind, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
308
+ export { type BranchState, type BuildResult, type DependencyGraph, type EnrichedErrorStack, type EnrichedFrame, type ErrorFrame, type FileIndex, type FilteredDiff, type GitCommit, type GitDiff, type GitState, type GraphEdge, type GraphFormat, type GraphNode, IndexDatabase, type IndexOptions, type IndexProgress, type KlyConfig, LLMService, type Language, type ParseResult, ParserManager, type ProgressCallback, type SearchResult, type SymbolInfo, type SymbolKind, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, ensureGitignore, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
307
309
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { A as getCurrentBranch, B as getConfigPath, C as openDatabase, D as setBranchState, E as saveState, F as isGitRepo, G as hashConfig, H as getDbPath, I as hasChanged, J as loadConfig, K as initKlyDir, L as hashFile, M as getFileHistory, N as getMergeBase, O as branchToDbName, P as isAncestor, R as scanFiles, S as loadState, T as resolveDbName, U as getKlyDir, V as getDbDir, W as getStatePath, _ as copyDatabase, a as searchFilesWithRerank, b as getFileFromDb, c as buildDependencyGraph, d as renderGraphAscii, f as renderGraphSvg, g as filterGitDiff, h as ParserManager, i as searchFiles, j as getCurrentCommit, k as getChangedFiles, l as generateMermaid, m as LLMService, n as filterByLanguage, o as rerankResults, p as resolveImport, q as isInitialized, r as filterByPath, s as buildIndex, t as enrichErrorStack, u as isRelativeImport, v as getAllFilesFromDb, w as removeBranchDb, x as listBranchDbs, y as getBranchState, z as IndexDatabase } from "./enrich-BHaZ2daX.mjs";
2
- export { IndexDatabase, LLMService, ParserManager, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
1
+ import { A as getCurrentBranch, B as ensureGitignore, C as openDatabase, D as setBranchState, E as saveState, F as isGitRepo, G as getStatePath, H as getDbDir, I as hasChanged, J as isInitialized, K as hashConfig, L as hashFile, M as getFileHistory, N as getMergeBase, O as branchToDbName, P as isAncestor, R as scanFiles, S as loadState, T as resolveDbName, U as getDbPath, V as getConfigPath, W as getKlyDir, Y as loadConfig, _ as copyDatabase, a as searchFilesWithRerank, b as getFileFromDb, c as buildDependencyGraph, d as renderGraphAscii, f as renderGraphSvg, g as filterGitDiff, h as ParserManager, i as searchFiles, j as getCurrentCommit, k as getChangedFiles, l as generateMermaid, m as LLMService, n as filterByLanguage, o as rerankResults, p as resolveImport, q as initKlyDir, r as filterByPath, s as buildIndex, t as enrichErrorStack, u as isRelativeImport, v as getAllFilesFromDb, w as removeBranchDb, x as listBranchDbs, y as getBranchState, z as IndexDatabase } from "./enrich-CjNdkQfO.mjs";
2
+ export { IndexDatabase, LLMService, ParserManager, branchToDbName, buildDependencyGraph, buildIndex, copyDatabase, enrichErrorStack, ensureGitignore, filterByLanguage, filterByPath, filterGitDiff, generateMermaid, getAllFilesFromDb, getBranchState, getChangedFiles, getConfigPath, getCurrentBranch, getCurrentCommit, getDbDir, getDbPath, getFileFromDb, getFileHistory, getKlyDir, getMergeBase, getStatePath, hasChanged, hashConfig, hashFile, initKlyDir, isAncestor, isGitRepo, isInitialized, isRelativeImport, listBranchDbs, loadConfig, loadState, openDatabase, removeBranchDb, renderGraphAscii, renderGraphSvg, rerankResults, resolveDbName, resolveImport, saveState, scanFiles, searchFiles, searchFilesWithRerank, setBranchState };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kly",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Code repository file-level indexing tool for AI agents",
5
5
  "homepage": "https://github.com/xinyao27/kly#readme",
6
6
  "bugs": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "scripts": {
35
35
  "dev": "vp pack --watch",
36
- "build": "vp pack",
36
+ "build": "npm run postinstall && vp pack",
37
37
  "check": "vp check --fix",
38
38
  "lint": "vp lint --fix",
39
39
  "fmt": "vp fmt",
@@ -1 +0,0 @@
1
- {"version":3,"file":"enrich-BHaZ2daX.mjs","names":["stringifyYaml","parseYaml","parseYaml","stringifyYaml","path","path","path","SYMBOL_NODE_TYPES","extractName"],"sources":["../src/config.ts","../src/database.ts","../src/scanner.ts","../src/hasher.ts","../src/git.ts","../src/store.ts","../node_modules/picomatch/lib/constants.js","../node_modules/picomatch/lib/utils.js","../node_modules/picomatch/lib/scan.js","../node_modules/picomatch/lib/parse.js","../node_modules/picomatch/lib/picomatch.js","../node_modules/picomatch/index.js","../src/diff-filter.ts","../src/parser/base.ts","../src/parser/swift.ts","../src/parser/typescript.ts","../src/parser/index.ts","../src/llm/batcher.ts","../src/llm/prompts.ts","../src/llm/index.ts","../src/graph.ts","../src/indexer.ts","../src/llm/reranker.ts","../src/query.ts","../src/enrich.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport type { KlyConfig } from \"./types\";\n\nconst KLY_DIR = \".kly\";\nconst CONFIG_FILE = \"config.yaml\";\nconst DB_DIR = \"db\";\nconst STATE_FILE = \"state.yaml\";\n\nconst DEFAULT_CONFIG: KlyConfig = {\n llm: {\n provider: \"openrouter\",\n model: \"anthropic/claude-haiku-4.5\",\n apiKey: \"\",\n },\n include: [\"**/*.ts\", \"**/*.tsx\", \"**/*.js\", \"**/*.jsx\", \"**/*.swift\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.git/**\",\n \"**/.kly/**\",\n \"**/vendor/**\",\n \"**/*.d.ts\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n \"**/__tests__/**\",\n ],\n};\n\nexport function getKlyDir(root: string): string {\n return path.join(root, KLY_DIR);\n}\n\nexport function getConfigPath(root: string): string {\n return path.join(getKlyDir(root), CONFIG_FILE);\n}\n\nexport function getDbDir(root: string): string {\n return path.join(getKlyDir(root), DB_DIR);\n}\n\nexport function getDbPath(root: string, dbName: string): string {\n return path.join(getDbDir(root), `${dbName}.db`);\n}\n\nexport function getStatePath(root: string): string {\n return path.join(getKlyDir(root), STATE_FILE);\n}\n\nexport function isInitialized(root: string): boolean {\n return fs.existsSync(getKlyDir(root));\n}\n\nexport function initKlyDir(root: string, config?: KlyConfig): void {\n const klyDir = getKlyDir(root);\n if (!fs.existsSync(klyDir)) {\n fs.mkdirSync(klyDir, { recursive: true });\n }\n\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n\n const configToWrite = config || DEFAULT_CONFIG;\n fs.writeFileSync(getConfigPath(root), stringifyYaml(configToWrite), \"utf-8\");\n}\n\nexport function loadConfig(root: string): KlyConfig {\n const configPath = getConfigPath(root);\n if (!fs.existsSync(configPath)) {\n return DEFAULT_CONFIG;\n }\n\n const raw = fs.readFileSync(configPath, \"utf-8\");\n const parsed = parseYaml(raw) as Partial<KlyConfig>;\n\n return {\n ...DEFAULT_CONFIG,\n ...parsed,\n llm: { ...DEFAULT_CONFIG.llm, ...parsed.llm },\n };\n}\n\nexport function hashConfig(config: KlyConfig): string {\n const significant = JSON.stringify({\n include: config.include,\n exclude: config.exclude,\n });\n return createHash(\"sha256\").update(significant).digest(\"hex\");\n}\n","import Database from \"better-sqlite3\";\n\nimport type { FileIndex, SymbolInfo } from \"./types\";\n\nexport interface SearchResult {\n file: FileIndex;\n score: number;\n}\n\nexport class IndexDatabase {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.init();\n }\n\n private init(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS files (\n path TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n language TEXT NOT NULL,\n imports TEXT NOT NULL DEFAULT '[]',\n exports TEXT NOT NULL DEFAULT '[]',\n symbols TEXT NOT NULL DEFAULT '[]',\n summary TEXT NOT NULL DEFAULT '',\n hash TEXT NOT NULL,\n indexed_at INTEGER NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS dependencies (\n from_path TEXT NOT NULL,\n to_path TEXT NOT NULL,\n PRIMARY KEY (from_path, to_path)\n );\n\n CREATE INDEX IF NOT EXISTS idx_deps_to ON dependencies(to_path);\n `);\n\n // Create FTS5 virtual table if not exists\n // Use a try-catch because FTS5 tables can't use IF NOT EXISTS\n try {\n this.db.exec(`\n CREATE VIRTUAL TABLE files_fts USING fts5(\n path, name, description, summary, symbols_text,\n content=files,\n content_rowid=rowid\n );\n `);\n } catch {\n // Table already exists, that's fine\n }\n\n // Create triggers to keep FTS in sync\n this.db.exec(`\n CREATE TRIGGER IF NOT EXISTS files_ai AFTER INSERT ON files BEGIN\n INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (new.rowid, new.path, new.name, new.description, new.summary, '');\n END;\n\n CREATE TRIGGER IF NOT EXISTS files_ad AFTER DELETE ON files BEGIN\n INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', old.rowid, old.path, old.name, old.description, old.summary, '');\n END;\n\n CREATE TRIGGER IF NOT EXISTS files_au AFTER UPDATE ON files BEGIN\n INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', old.rowid, old.path, old.name, old.description, old.summary, '');\n INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (new.rowid, new.path, new.name, new.description, new.summary, '');\n END;\n `);\n }\n\n getFile(filePath: string): FileIndex | undefined {\n const row = this.db.prepare(\"SELECT * FROM files WHERE path = ?\").get(filePath) as\n | RawFileRow\n | undefined;\n return row ? rowToFileIndex(row) : undefined;\n }\n\n upsertFile(fileIndex: FileIndex): void {\n const stmt = this.db.prepare(`\n INSERT INTO files (path, name, description, language, imports, exports, symbols, summary, hash, indexed_at)\n VALUES (@path, @name, @description, @language, @imports, @exports, @symbols, @summary, @hash, @indexed_at)\n ON CONFLICT(path) DO UPDATE SET\n name = @name,\n description = @description,\n language = @language,\n imports = @imports,\n exports = @exports,\n symbols = @symbols,\n summary = @summary,\n hash = @hash,\n indexed_at = @indexed_at\n `);\n stmt.run(fileIndexToRow(fileIndex));\n\n // Update FTS symbols_text\n this.updateFtsSymbolsText(fileIndex);\n }\n\n upsertFiles(fileIndexes: FileIndex[]): void {\n const stmt = this.db.prepare(`\n INSERT INTO files (path, name, description, language, imports, exports, symbols, summary, hash, indexed_at)\n VALUES (@path, @name, @description, @language, @imports, @exports, @symbols, @summary, @hash, @indexed_at)\n ON CONFLICT(path) DO UPDATE SET\n name = @name,\n description = @description,\n language = @language,\n imports = @imports,\n exports = @exports,\n symbols = @symbols,\n summary = @summary,\n hash = @hash,\n indexed_at = @indexed_at\n `);\n\n const transaction = this.db.transaction((files: FileIndex[]) => {\n for (const file of files) {\n stmt.run(fileIndexToRow(file));\n this.updateFtsSymbolsText(file);\n }\n });\n transaction(fileIndexes);\n }\n\n removeFile(filePath: string): void {\n this.db.prepare(\"DELETE FROM files WHERE path = ?\").run(filePath);\n }\n\n removeFiles(paths: string[]): void {\n const stmt = this.db.prepare(\"DELETE FROM files WHERE path = ?\");\n const transaction = this.db.transaction((pathList: string[]) => {\n for (const p of pathList) {\n stmt.run(p);\n }\n });\n transaction(paths);\n }\n\n searchFiles(query: string, limit = 20): SearchResult[] {\n // Use FTS5 match query\n const ftsQuery = query\n .split(/\\s+/)\n .filter(Boolean)\n .map((term) => `\"${term.replace(/\"/g, '\"\"')}\"`)\n .join(\" OR \");\n\n if (!ftsQuery) return [];\n\n const rows = this.db\n .prepare(\n `\n SELECT f.*, bm25(files_fts) as rank\n FROM files_fts fts\n JOIN files f ON f.rowid = fts.rowid\n WHERE files_fts MATCH ?\n ORDER BY rank\n LIMIT ?\n `,\n )\n .all(ftsQuery, limit) as (RawFileRow & { rank: number })[];\n\n return rows.map((row) => ({\n file: rowToFileIndex(row),\n score: -row.rank, // bm25 returns negative values, lower = better match\n }));\n }\n\n getAllFiles(): FileIndex[] {\n const rows = this.db.prepare(\"SELECT * FROM files ORDER BY path\").all() as RawFileRow[];\n return rows.map(rowToFileIndex);\n }\n\n getFileCount(): number {\n const row = this.db.prepare(\"SELECT COUNT(*) as count FROM files\").get() as { count: number };\n return row.count;\n }\n\n getLanguageStats(): Record<string, number> {\n const rows = this.db\n .prepare(\"SELECT language, COUNT(*) as count FROM files GROUP BY language\")\n .all() as { language: string; count: number }[];\n\n const stats: Record<string, number> = {};\n for (const row of rows) {\n stats[row.language] = row.count;\n }\n return stats;\n }\n\n getMetadata(key: string): string | undefined {\n const row = this.db.prepare(\"SELECT value FROM metadata WHERE key = ?\").get(key) as\n | { value: string }\n | undefined;\n return row?.value;\n }\n\n setMetadata(key: string, value: string): void {\n this.db\n .prepare(\n `INSERT INTO metadata (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = ?`,\n )\n .run(key, value, value);\n }\n\n upsertDependencies(fromPath: string, toPaths: string[]): void {\n this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\").run(fromPath);\n const stmt = this.db.prepare(\n \"INSERT OR IGNORE INTO dependencies (from_path, to_path) VALUES (?, ?)\",\n );\n for (const to of toPaths) {\n stmt.run(fromPath, to);\n }\n }\n\n upsertBatchDependencies(entries: Array<{ fromPath: string; toPaths: string[] }>): void {\n const del = this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\");\n const ins = this.db.prepare(\n \"INSERT OR IGNORE INTO dependencies (from_path, to_path) VALUES (?, ?)\",\n );\n const transaction = this.db.transaction(\n (items: Array<{ fromPath: string; toPaths: string[] }>) => {\n for (const { fromPath, toPaths } of items) {\n del.run(fromPath);\n for (const to of toPaths) {\n ins.run(fromPath, to);\n }\n }\n },\n );\n transaction(entries);\n }\n\n removeDependencies(fromPath: string): void {\n this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\").run(fromPath);\n }\n\n removeDependenciesBatch(fromPaths: string[]): void {\n const stmt = this.db.prepare(\"DELETE FROM dependencies WHERE from_path = ?\");\n const transaction = this.db.transaction((paths: string[]) => {\n for (const p of paths) {\n stmt.run(p);\n }\n });\n transaction(fromPaths);\n }\n\n getDependencies(filePath: string): string[] {\n const rows = this.db\n .prepare(\"SELECT to_path FROM dependencies WHERE from_path = ? ORDER BY to_path\")\n .all(filePath) as { to_path: string }[];\n return rows.map((r) => r.to_path);\n }\n\n getDependents(filePath: string): string[] {\n const rows = this.db\n .prepare(\"SELECT from_path FROM dependencies WHERE to_path = ? ORDER BY from_path\")\n .all(filePath) as { from_path: string }[];\n return rows.map((r) => r.from_path);\n }\n\n removeAllDependencies(): void {\n this.db.exec(\"DELETE FROM dependencies\");\n }\n\n close(): void {\n this.db.close();\n }\n\n private updateFtsSymbolsText(fileIndex: FileIndex): void {\n const symbolsText = fileIndex.symbols.map((s) => `${s.name} ${s.description}`).join(\" \");\n // Row is guaranteed to exist — this is always called after upsert\n const row = this.db.prepare(\"SELECT rowid FROM files WHERE path = ?\").get(fileIndex.path) as {\n rowid: number;\n };\n // Delete old FTS entry and insert new one with symbols_text\n this.db\n .prepare(\n `INSERT INTO files_fts(files_fts, rowid, path, name, description, summary, symbols_text)\n VALUES ('delete', ?, ?, ?, ?, ?, '')`,\n )\n .run(row.rowid, fileIndex.path, fileIndex.name, fileIndex.description, fileIndex.summary);\n this.db\n .prepare(\n `INSERT INTO files_fts(rowid, path, name, description, summary, symbols_text)\n VALUES (?, ?, ?, ?, ?, ?)`,\n )\n .run(\n row.rowid,\n fileIndex.path,\n fileIndex.name,\n fileIndex.description,\n fileIndex.summary,\n symbolsText,\n );\n }\n}\n\ninterface RawFileRow {\n path: string;\n name: string;\n description: string;\n language: string;\n imports: string;\n exports: string;\n symbols: string;\n summary: string;\n hash: string;\n indexed_at: number;\n}\n\nfunction rowToFileIndex(row: RawFileRow): FileIndex {\n return {\n path: row.path,\n name: row.name,\n description: row.description,\n language: row.language as FileIndex[\"language\"],\n imports: JSON.parse(row.imports) as string[],\n exports: JSON.parse(row.exports) as string[],\n symbols: JSON.parse(row.symbols) as SymbolInfo[],\n summary: row.summary,\n hash: row.hash,\n indexedAt: row.indexed_at,\n };\n}\n\nfunction fileIndexToRow(fileIndex: FileIndex): Record<string, string | number> {\n return {\n path: fileIndex.path,\n name: fileIndex.name,\n description: fileIndex.description,\n language: fileIndex.language,\n imports: JSON.stringify(fileIndex.imports),\n exports: JSON.stringify(fileIndex.exports),\n symbols: JSON.stringify(fileIndex.symbols),\n summary: fileIndex.summary,\n hash: fileIndex.hash,\n indexed_at: fileIndex.indexedAt,\n };\n}\n","import { globby } from \"globby\";\n\nimport type { KlyConfig } from \"./types\";\n\nexport async function scanFiles(root: string, config: KlyConfig): Promise<string[]> {\n const files = await globby(config.include, {\n cwd: root,\n ignore: config.exclude,\n gitignore: true,\n absolute: false,\n });\n\n return files.sort();\n}\n","import { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport function hashFile(root: string, filePath: string): string {\n const fullPath = path.join(root, filePath);\n const content = fs.readFileSync(fullPath, \"utf-8\");\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nexport function hasChanged(oldHash: string, newHash: string): boolean {\n return oldHash !== newHash;\n}\n","import { execSync } from \"node:child_process\";\n\nimport type { GitCommit, GitDiff } from \"./types\";\n\nfunction exec(root: string, cmd: string): string {\n return execSync(cmd, { cwd: root, encoding: \"utf-8\", stdio: [\"pipe\", \"pipe\", \"pipe\"] }).trim();\n}\n\nexport function isGitRepo(root: string): boolean {\n try {\n exec(root, \"git rev-parse --is-inside-work-tree\");\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getCurrentBranch(root: string): string | null {\n try {\n return exec(root, \"git symbolic-ref --short HEAD\");\n } catch {\n // Detached HEAD\n return null;\n }\n}\n\nexport function getCurrentCommit(root: string): string {\n return exec(root, \"git rev-parse HEAD\");\n}\n\nexport function getChangedFiles(root: string, from: string, to?: string): GitDiff {\n const target = to || \"HEAD\";\n const output = exec(root, `git diff --name-status ${from} ${target}`);\n\n const diff: GitDiff = { added: [], modified: [], deleted: [], renamed: [] };\n\n if (!output) return diff;\n\n for (const line of output.split(\"\\n\")) {\n const parts = line.split(\"\\t\");\n const status = parts[0];\n const filePath = parts[1];\n\n switch (status[0]) {\n case \"A\":\n diff.added.push(filePath);\n break;\n case \"M\":\n diff.modified.push(filePath);\n break;\n case \"D\":\n diff.deleted.push(filePath);\n break;\n case \"R\":\n diff.renamed.push({ from: filePath, to: parts[2] });\n break;\n }\n }\n\n return diff;\n}\n\nexport function isAncestor(root: string, ancestor: string, descendant: string): boolean {\n try {\n execSync(`git merge-base --is-ancestor ${ancestor} ${descendant}`, {\n cwd: root,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getMergeBase(root: string, a: string, b: string): string | null {\n try {\n return exec(root, `git merge-base ${a} ${b}`);\n } catch {\n return null;\n }\n}\n\nexport function getFileHistory(root: string, filePath: string, limit = 5): GitCommit[] {\n let output: string;\n try {\n output = exec(\n root,\n `git log --follow -n ${limit} --format=\"%H|%an|%ae|%at|%s\" -- \"${filePath}\"`,\n );\n } catch {\n return [];\n }\n if (!output) return [];\n return output\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const [hash, author, email, date, ...msgParts] = line.split(\"|\");\n return {\n hash,\n author,\n email,\n date: parseInt(date, 10),\n message: msgParts.join(\"|\"),\n };\n });\n}\n\nexport function branchToDbName(branch: string | null, commitHash?: string): string {\n if (branch === null) {\n const shortHash = commitHash ? commitHash.slice(0, 8) : \"unknown\";\n return `_detached--${shortHash}`;\n }\n return branch.replace(/\\//g, \"--\");\n}\n","import fs from \"node:fs\";\n\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport { getDbDir, getDbPath, getStatePath } from \"./config\";\nimport { IndexDatabase } from \"./database\";\nimport { branchToDbName, getCurrentBranch, getCurrentCommit, isGitRepo } from \"./git\";\nimport type { BranchState, FileIndex, GitState } from \"./types\";\n\nconst STATE_VERSION = 2;\n\n// --- Database management ---\n\nexport function openDatabase(root: string, dbName?: string): IndexDatabase {\n const name = dbName || resolveDbName(root);\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true });\n }\n return new IndexDatabase(getDbPath(root, name));\n}\n\nexport function resolveDbName(root: string): string {\n if (!isGitRepo(root)) {\n return \"default\";\n }\n const branch = getCurrentBranch(root);\n const commit = branch === null ? getCurrentCommit(root) : undefined;\n return branchToDbName(branch, commit);\n}\n\nexport function copyDatabase(root: string, fromName: string, toName: string): void {\n const fromPath = getDbPath(root, fromName);\n const toPath = getDbPath(root, toName);\n if (fs.existsSync(fromPath)) {\n fs.copyFileSync(fromPath, toPath);\n }\n}\n\n// --- State management ---\n\nexport function loadState(root: string): GitState {\n const statePath = getStatePath(root);\n if (!fs.existsSync(statePath)) {\n return { version: STATE_VERSION, configHash: \"\", branches: {} };\n }\n const raw = fs.readFileSync(statePath, \"utf-8\");\n return parseYaml(raw) as GitState;\n}\n\nexport function saveState(root: string, state: GitState): void {\n const statePath = getStatePath(root);\n fs.writeFileSync(statePath, stringifyYaml(state), \"utf-8\");\n}\n\nexport function getBranchState(state: GitState, dbName: string): BranchState | undefined {\n return state.branches[dbName];\n}\n\nexport function setBranchState(state: GitState, dbName: string, branchState: BranchState): void {\n state.branches[dbName] = branchState;\n}\n\n// --- Convenience wrappers (for commands that just need quick access) ---\n\nexport function getFileFromDb(root: string, filePath: string): FileIndex | undefined {\n const db = openDatabase(root);\n try {\n return db.getFile(filePath);\n } finally {\n db.close();\n }\n}\n\nexport function getAllFilesFromDb(root: string): FileIndex[] {\n const db = openDatabase(root);\n try {\n return db.getAllFiles();\n } finally {\n db.close();\n }\n}\n\n// --- Branch db cleanup ---\n\nexport function listBranchDbs(root: string): string[] {\n const dbDir = getDbDir(root);\n if (!fs.existsSync(dbDir)) return [];\n return fs\n .readdirSync(dbDir)\n .filter((f) => f.endsWith(\".db\"))\n .map((f) => f.replace(/\\.db$/, \"\"));\n}\n\nexport function removeBranchDb(root: string, dbName: string): void {\n const dbPath = getDbPath(root, dbName);\n if (fs.existsSync(dbPath)) {\n fs.unlinkSync(dbPath);\n }\n // Also remove WAL and SHM files\n for (const ext of [\"-wal\", \"-shm\"]) {\n const auxPath = dbPath + ext;\n if (fs.existsSync(auxPath)) {\n fs.unlinkSync(auxPath);\n }\n }\n}\n","'use strict';\n\nconst path = require('path');\nconst WIN_SLASH = '\\\\\\\\/';\nconst WIN_NO_SLASH = `[^${WIN_SLASH}]`;\n\n/**\n * Posix glob regex\n */\n\nconst DOT_LITERAL = '\\\\.';\nconst PLUS_LITERAL = '\\\\+';\nconst QMARK_LITERAL = '\\\\?';\nconst SLASH_LITERAL = '\\\\/';\nconst ONE_CHAR = '(?=.)';\nconst QMARK = '[^/]';\nconst END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;\nconst START_ANCHOR = `(?:^|${SLASH_LITERAL})`;\nconst DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;\nconst NO_DOT = `(?!${DOT_LITERAL})`;\nconst NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;\nconst NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;\nconst NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;\nconst QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;\nconst STAR = `${QMARK}*?`;\n\nconst POSIX_CHARS = {\n DOT_LITERAL,\n PLUS_LITERAL,\n QMARK_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n QMARK,\n END_ANCHOR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOTS,\n NO_DOT_SLASH,\n NO_DOTS_SLASH,\n QMARK_NO_DOT,\n STAR,\n START_ANCHOR\n};\n\n/**\n * Windows glob regex\n */\n\nconst WINDOWS_CHARS = {\n ...POSIX_CHARS,\n\n SLASH_LITERAL: `[${WIN_SLASH}]`,\n QMARK: WIN_NO_SLASH,\n STAR: `${WIN_NO_SLASH}*?`,\n DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,\n NO_DOT: `(?!${DOT_LITERAL})`,\n NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,\n NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,\n NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,\n QMARK_NO_DOT: `[^.${WIN_SLASH}]`,\n START_ANCHOR: `(?:^|[${WIN_SLASH}])`,\n END_ANCHOR: `(?:[${WIN_SLASH}]|$)`\n};\n\n/**\n * POSIX Bracket Regex\n */\n\nconst POSIX_REGEX_SOURCE = {\n alnum: 'a-zA-Z0-9',\n alpha: 'a-zA-Z',\n ascii: '\\\\x00-\\\\x7F',\n blank: ' \\\\t',\n cntrl: '\\\\x00-\\\\x1F\\\\x7F',\n digit: '0-9',\n graph: '\\\\x21-\\\\x7E',\n lower: 'a-z',\n print: '\\\\x20-\\\\x7E ',\n punct: '\\\\-!\"#$%&\\'()\\\\*+,./:;<=>?@[\\\\]^_`{|}~',\n space: ' \\\\t\\\\r\\\\n\\\\v\\\\f',\n upper: 'A-Z',\n word: 'A-Za-z0-9_',\n xdigit: 'A-Fa-f0-9'\n};\n\nmodule.exports = {\n MAX_LENGTH: 1024 * 64,\n POSIX_REGEX_SOURCE,\n\n // regular expressions\n REGEX_BACKSLASH: /\\\\(?![*+?^${}(|)[\\]])/g,\n REGEX_NON_SPECIAL_CHARS: /^[^@![\\].,$*+?^{}()|\\\\/]+/,\n REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\\]]/,\n REGEX_SPECIAL_CHARS_BACKREF: /(\\\\?)((\\W)(\\3*))/g,\n REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\\]])/g,\n REGEX_REMOVE_BACKSLASH: /(?:\\[.*?[^\\\\]\\]|\\\\(?=.))/g,\n\n // Replace globs with equivalent patterns to reduce parsing time.\n REPLACEMENTS: {\n '***': '*',\n '**/**': '**',\n '**/**/**': '**'\n },\n\n // Digits\n CHAR_0: 48, /* 0 */\n CHAR_9: 57, /* 9 */\n\n // Alphabet chars.\n CHAR_UPPERCASE_A: 65, /* A */\n CHAR_LOWERCASE_A: 97, /* a */\n CHAR_UPPERCASE_Z: 90, /* Z */\n CHAR_LOWERCASE_Z: 122, /* z */\n\n CHAR_LEFT_PARENTHESES: 40, /* ( */\n CHAR_RIGHT_PARENTHESES: 41, /* ) */\n\n CHAR_ASTERISK: 42, /* * */\n\n // Non-alphabetic chars.\n CHAR_AMPERSAND: 38, /* & */\n CHAR_AT: 64, /* @ */\n CHAR_BACKWARD_SLASH: 92, /* \\ */\n CHAR_CARRIAGE_RETURN: 13, /* \\r */\n CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */\n CHAR_COLON: 58, /* : */\n CHAR_COMMA: 44, /* , */\n CHAR_DOT: 46, /* . */\n CHAR_DOUBLE_QUOTE: 34, /* \" */\n CHAR_EQUAL: 61, /* = */\n CHAR_EXCLAMATION_MARK: 33, /* ! */\n CHAR_FORM_FEED: 12, /* \\f */\n CHAR_FORWARD_SLASH: 47, /* / */\n CHAR_GRAVE_ACCENT: 96, /* ` */\n CHAR_HASH: 35, /* # */\n CHAR_HYPHEN_MINUS: 45, /* - */\n CHAR_LEFT_ANGLE_BRACKET: 60, /* < */\n CHAR_LEFT_CURLY_BRACE: 123, /* { */\n CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */\n CHAR_LINE_FEED: 10, /* \\n */\n CHAR_NO_BREAK_SPACE: 160, /* \\u00A0 */\n CHAR_PERCENT: 37, /* % */\n CHAR_PLUS: 43, /* + */\n CHAR_QUESTION_MARK: 63, /* ? */\n CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */\n CHAR_RIGHT_CURLY_BRACE: 125, /* } */\n CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */\n CHAR_SEMICOLON: 59, /* ; */\n CHAR_SINGLE_QUOTE: 39, /* ' */\n CHAR_SPACE: 32, /* */\n CHAR_TAB: 9, /* \\t */\n CHAR_UNDERSCORE: 95, /* _ */\n CHAR_VERTICAL_LINE: 124, /* | */\n CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \\uFEFF */\n\n SEP: path.sep,\n\n /**\n * Create EXTGLOB_CHARS\n */\n\n extglobChars(chars) {\n return {\n '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },\n '?': { type: 'qmark', open: '(?:', close: ')?' },\n '+': { type: 'plus', open: '(?:', close: ')+' },\n '*': { type: 'star', open: '(?:', close: ')*' },\n '@': { type: 'at', open: '(?:', close: ')' }\n };\n },\n\n /**\n * Create GLOB_CHARS\n */\n\n globChars(win32) {\n return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;\n }\n};\n","'use strict';\n\nconst path = require('path');\nconst win32 = process.platform === 'win32';\nconst {\n REGEX_BACKSLASH,\n REGEX_REMOVE_BACKSLASH,\n REGEX_SPECIAL_CHARS,\n REGEX_SPECIAL_CHARS_GLOBAL\n} = require('./constants');\n\nexports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);\nexports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);\nexports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);\nexports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\\\$1');\nexports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');\n\nexports.removeBackslashes = str => {\n return str.replace(REGEX_REMOVE_BACKSLASH, match => {\n return match === '\\\\' ? '' : match;\n });\n};\n\nexports.supportsLookbehinds = () => {\n const segs = process.version.slice(1).split('.').map(Number);\n if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {\n return true;\n }\n return false;\n};\n\nexports.isWindows = options => {\n if (options && typeof options.windows === 'boolean') {\n return options.windows;\n }\n return win32 === true || path.sep === '\\\\';\n};\n\nexports.escapeLast = (input, char, lastIdx) => {\n const idx = input.lastIndexOf(char, lastIdx);\n if (idx === -1) return input;\n if (input[idx - 1] === '\\\\') return exports.escapeLast(input, char, idx - 1);\n return `${input.slice(0, idx)}\\\\${input.slice(idx)}`;\n};\n\nexports.removePrefix = (input, state = {}) => {\n let output = input;\n if (output.startsWith('./')) {\n output = output.slice(2);\n state.prefix = './';\n }\n return output;\n};\n\nexports.wrapOutput = (input, state = {}, options = {}) => {\n const prepend = options.contains ? '' : '^';\n const append = options.contains ? '' : '$';\n\n let output = `${prepend}(?:${input})${append}`;\n if (state.negated === true) {\n output = `(?:^(?!${output}).*$)`;\n }\n return output;\n};\n","'use strict';\n\nconst utils = require('./utils');\nconst {\n CHAR_ASTERISK, /* * */\n CHAR_AT, /* @ */\n CHAR_BACKWARD_SLASH, /* \\ */\n CHAR_COMMA, /* , */\n CHAR_DOT, /* . */\n CHAR_EXCLAMATION_MARK, /* ! */\n CHAR_FORWARD_SLASH, /* / */\n CHAR_LEFT_CURLY_BRACE, /* { */\n CHAR_LEFT_PARENTHESES, /* ( */\n CHAR_LEFT_SQUARE_BRACKET, /* [ */\n CHAR_PLUS, /* + */\n CHAR_QUESTION_MARK, /* ? */\n CHAR_RIGHT_CURLY_BRACE, /* } */\n CHAR_RIGHT_PARENTHESES, /* ) */\n CHAR_RIGHT_SQUARE_BRACKET /* ] */\n} = require('./constants');\n\nconst isPathSeparator = code => {\n return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;\n};\n\nconst depth = token => {\n if (token.isPrefix !== true) {\n token.depth = token.isGlobstar ? Infinity : 1;\n }\n};\n\n/**\n * Quickly scans a glob pattern and returns an object with a handful of\n * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),\n * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not\n * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).\n *\n * ```js\n * const pm = require('picomatch');\n * console.log(pm.scan('foo/bar/*.js'));\n * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }\n * ```\n * @param {String} `str`\n * @param {Object} `options`\n * @return {Object} Returns an object with tokens and regex source string.\n * @api public\n */\n\nconst scan = (input, options) => {\n const opts = options || {};\n\n const length = input.length - 1;\n const scanToEnd = opts.parts === true || opts.scanToEnd === true;\n const slashes = [];\n const tokens = [];\n const parts = [];\n\n let str = input;\n let index = -1;\n let start = 0;\n let lastIndex = 0;\n let isBrace = false;\n let isBracket = false;\n let isGlob = false;\n let isExtglob = false;\n let isGlobstar = false;\n let braceEscaped = false;\n let backslashes = false;\n let negated = false;\n let negatedExtglob = false;\n let finished = false;\n let braces = 0;\n let prev;\n let code;\n let token = { value: '', depth: 0, isGlob: false };\n\n const eos = () => index >= length;\n const peek = () => str.charCodeAt(index + 1);\n const advance = () => {\n prev = code;\n return str.charCodeAt(++index);\n };\n\n while (index < length) {\n code = advance();\n let next;\n\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n code = advance();\n\n if (code === CHAR_LEFT_CURLY_BRACE) {\n braceEscaped = true;\n }\n continue;\n }\n\n if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {\n braces++;\n\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n advance();\n continue;\n }\n\n if (code === CHAR_LEFT_CURLY_BRACE) {\n braces++;\n continue;\n }\n\n if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {\n isBrace = token.isBrace = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (braceEscaped !== true && code === CHAR_COMMA) {\n isBrace = token.isBrace = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (code === CHAR_RIGHT_CURLY_BRACE) {\n braces--;\n\n if (braces === 0) {\n braceEscaped = false;\n isBrace = token.isBrace = true;\n finished = true;\n break;\n }\n }\n }\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (code === CHAR_FORWARD_SLASH) {\n slashes.push(index);\n tokens.push(token);\n token = { value: '', depth: 0, isGlob: false };\n\n if (finished === true) continue;\n if (prev === CHAR_DOT && index === (start + 1)) {\n start += 2;\n continue;\n }\n\n lastIndex = index + 1;\n continue;\n }\n\n if (opts.noext !== true) {\n const isExtglobChar = code === CHAR_PLUS\n || code === CHAR_AT\n || code === CHAR_ASTERISK\n || code === CHAR_QUESTION_MARK\n || code === CHAR_EXCLAMATION_MARK;\n\n if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {\n isGlob = token.isGlob = true;\n isExtglob = token.isExtglob = true;\n finished = true;\n if (code === CHAR_EXCLAMATION_MARK && index === start) {\n negatedExtglob = true;\n }\n\n if (scanToEnd === true) {\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n code = advance();\n continue;\n }\n\n if (code === CHAR_RIGHT_PARENTHESES) {\n isGlob = token.isGlob = true;\n finished = true;\n break;\n }\n }\n continue;\n }\n break;\n }\n }\n\n if (code === CHAR_ASTERISK) {\n if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n break;\n }\n\n if (code === CHAR_QUESTION_MARK) {\n isGlob = token.isGlob = true;\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n break;\n }\n\n if (code === CHAR_LEFT_SQUARE_BRACKET) {\n while (eos() !== true && (next = advance())) {\n if (next === CHAR_BACKWARD_SLASH) {\n backslashes = token.backslashes = true;\n advance();\n continue;\n }\n\n if (next === CHAR_RIGHT_SQUARE_BRACKET) {\n isBracket = token.isBracket = true;\n isGlob = token.isGlob = true;\n finished = true;\n break;\n }\n }\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n\n if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {\n negated = token.negated = true;\n start++;\n continue;\n }\n\n if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {\n isGlob = token.isGlob = true;\n\n if (scanToEnd === true) {\n while (eos() !== true && (code = advance())) {\n if (code === CHAR_LEFT_PARENTHESES) {\n backslashes = token.backslashes = true;\n code = advance();\n continue;\n }\n\n if (code === CHAR_RIGHT_PARENTHESES) {\n finished = true;\n break;\n }\n }\n continue;\n }\n break;\n }\n\n if (isGlob === true) {\n finished = true;\n\n if (scanToEnd === true) {\n continue;\n }\n\n break;\n }\n }\n\n if (opts.noext === true) {\n isExtglob = false;\n isGlob = false;\n }\n\n let base = str;\n let prefix = '';\n let glob = '';\n\n if (start > 0) {\n prefix = str.slice(0, start);\n str = str.slice(start);\n lastIndex -= start;\n }\n\n if (base && isGlob === true && lastIndex > 0) {\n base = str.slice(0, lastIndex);\n glob = str.slice(lastIndex);\n } else if (isGlob === true) {\n base = '';\n glob = str;\n } else {\n base = str;\n }\n\n if (base && base !== '' && base !== '/' && base !== str) {\n if (isPathSeparator(base.charCodeAt(base.length - 1))) {\n base = base.slice(0, -1);\n }\n }\n\n if (opts.unescape === true) {\n if (glob) glob = utils.removeBackslashes(glob);\n\n if (base && backslashes === true) {\n base = utils.removeBackslashes(base);\n }\n }\n\n const state = {\n prefix,\n input,\n start,\n base,\n glob,\n isBrace,\n isBracket,\n isGlob,\n isExtglob,\n isGlobstar,\n negated,\n negatedExtglob\n };\n\n if (opts.tokens === true) {\n state.maxDepth = 0;\n if (!isPathSeparator(code)) {\n tokens.push(token);\n }\n state.tokens = tokens;\n }\n\n if (opts.parts === true || opts.tokens === true) {\n let prevIndex;\n\n for (let idx = 0; idx < slashes.length; idx++) {\n const n = prevIndex ? prevIndex + 1 : start;\n const i = slashes[idx];\n const value = input.slice(n, i);\n if (opts.tokens) {\n if (idx === 0 && start !== 0) {\n tokens[idx].isPrefix = true;\n tokens[idx].value = prefix;\n } else {\n tokens[idx].value = value;\n }\n depth(tokens[idx]);\n state.maxDepth += tokens[idx].depth;\n }\n if (idx !== 0 || value !== '') {\n parts.push(value);\n }\n prevIndex = i;\n }\n\n if (prevIndex && prevIndex + 1 < input.length) {\n const value = input.slice(prevIndex + 1);\n parts.push(value);\n\n if (opts.tokens) {\n tokens[tokens.length - 1].value = value;\n depth(tokens[tokens.length - 1]);\n state.maxDepth += tokens[tokens.length - 1].depth;\n }\n }\n\n state.slashes = slashes;\n state.parts = parts;\n }\n\n return state;\n};\n\nmodule.exports = scan;\n","'use strict';\n\nconst constants = require('./constants');\nconst utils = require('./utils');\n\n/**\n * Constants\n */\n\nconst {\n MAX_LENGTH,\n POSIX_REGEX_SOURCE,\n REGEX_NON_SPECIAL_CHARS,\n REGEX_SPECIAL_CHARS_BACKREF,\n REPLACEMENTS\n} = constants;\n\n/**\n * Helpers\n */\n\nconst expandRange = (args, options) => {\n if (typeof options.expandRange === 'function') {\n return options.expandRange(...args, options);\n }\n\n args.sort();\n const value = `[${args.join('-')}]`;\n\n try {\n /* eslint-disable-next-line no-new */\n new RegExp(value);\n } catch (ex) {\n return args.map(v => utils.escapeRegex(v)).join('..');\n }\n\n return value;\n};\n\n/**\n * Create the message for a syntax error\n */\n\nconst syntaxError = (type, char) => {\n return `Missing ${type}: \"${char}\" - use \"\\\\\\\\${char}\" to match literal characters`;\n};\n\n/**\n * Parse the given input string.\n * @param {String} input\n * @param {Object} options\n * @return {Object}\n */\n\nconst parse = (input, options) => {\n if (typeof input !== 'string') {\n throw new TypeError('Expected a string');\n }\n\n input = REPLACEMENTS[input] || input;\n\n const opts = { ...options };\n const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;\n\n let len = input.length;\n if (len > max) {\n throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);\n }\n\n const bos = { type: 'bos', value: '', output: opts.prepend || '' };\n const tokens = [bos];\n\n const capture = opts.capture ? '' : '?:';\n const win32 = utils.isWindows(options);\n\n // create constants based on platform, for windows or posix\n const PLATFORM_CHARS = constants.globChars(win32);\n const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);\n\n const {\n DOT_LITERAL,\n PLUS_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOT_SLASH,\n NO_DOTS_SLASH,\n QMARK,\n QMARK_NO_DOT,\n STAR,\n START_ANCHOR\n } = PLATFORM_CHARS;\n\n const globstar = opts => {\n return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;\n };\n\n const nodot = opts.dot ? '' : NO_DOT;\n const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;\n let star = opts.bash === true ? globstar(opts) : STAR;\n\n if (opts.capture) {\n star = `(${star})`;\n }\n\n // minimatch options support\n if (typeof opts.noext === 'boolean') {\n opts.noextglob = opts.noext;\n }\n\n const state = {\n input,\n index: -1,\n start: 0,\n dot: opts.dot === true,\n consumed: '',\n output: '',\n prefix: '',\n backtrack: false,\n negated: false,\n brackets: 0,\n braces: 0,\n parens: 0,\n quotes: 0,\n globstar: false,\n tokens\n };\n\n input = utils.removePrefix(input, state);\n len = input.length;\n\n const extglobs = [];\n const braces = [];\n const stack = [];\n let prev = bos;\n let value;\n\n /**\n * Tokenizing helpers\n */\n\n const eos = () => state.index === len - 1;\n const peek = state.peek = (n = 1) => input[state.index + n];\n const advance = state.advance = () => input[++state.index] || '';\n const remaining = () => input.slice(state.index + 1);\n const consume = (value = '', num = 0) => {\n state.consumed += value;\n state.index += num;\n };\n\n const append = token => {\n state.output += token.output != null ? token.output : token.value;\n consume(token.value);\n };\n\n const negate = () => {\n let count = 1;\n\n while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {\n advance();\n state.start++;\n count++;\n }\n\n if (count % 2 === 0) {\n return false;\n }\n\n state.negated = true;\n state.start++;\n return true;\n };\n\n const increment = type => {\n state[type]++;\n stack.push(type);\n };\n\n const decrement = type => {\n state[type]--;\n stack.pop();\n };\n\n /**\n * Push tokens onto the tokens array. This helper speeds up\n * tokenizing by 1) helping us avoid backtracking as much as possible,\n * and 2) helping us avoid creating extra tokens when consecutive\n * characters are plain text. This improves performance and simplifies\n * lookbehinds.\n */\n\n const push = tok => {\n if (prev.type === 'globstar') {\n const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');\n const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));\n\n if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {\n state.output = state.output.slice(0, -prev.output.length);\n prev.type = 'star';\n prev.value = '*';\n prev.output = star;\n state.output += prev.output;\n }\n }\n\n if (extglobs.length && tok.type !== 'paren') {\n extglobs[extglobs.length - 1].inner += tok.value;\n }\n\n if (tok.value || tok.output) append(tok);\n if (prev && prev.type === 'text' && tok.type === 'text') {\n prev.value += tok.value;\n prev.output = (prev.output || '') + tok.value;\n return;\n }\n\n tok.prev = prev;\n tokens.push(tok);\n prev = tok;\n };\n\n const extglobOpen = (type, value) => {\n const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };\n\n token.prev = prev;\n token.parens = state.parens;\n token.output = state.output;\n const output = (opts.capture ? '(' : '') + token.open;\n\n increment('parens');\n push({ type, value, output: state.output ? '' : ONE_CHAR });\n push({ type: 'paren', extglob: true, value: advance(), output });\n extglobs.push(token);\n };\n\n const extglobClose = token => {\n let output = token.close + (opts.capture ? ')' : '');\n let rest;\n\n if (token.type === 'negate') {\n let extglobStar = star;\n\n if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {\n extglobStar = globstar(opts);\n }\n\n if (extglobStar !== star || eos() || /^\\)+$/.test(remaining())) {\n output = token.close = `)$))${extglobStar}`;\n }\n\n if (token.inner.includes('*') && (rest = remaining()) && /^\\.[^\\\\/.]+$/.test(rest)) {\n // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.\n // In this case, we need to parse the string and use it in the output of the original pattern.\n // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.\n //\n // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.\n const expression = parse(rest, { ...options, fastpaths: false }).output;\n\n output = token.close = `)${expression})${extglobStar})`;\n }\n\n if (token.prev.type === 'bos') {\n state.negatedExtglob = true;\n }\n }\n\n push({ type: 'paren', extglob: true, value, output });\n decrement('parens');\n };\n\n /**\n * Fast paths\n */\n\n if (opts.fastpaths !== false && !/(^[*!]|[/()[\\]{}\"])/.test(input)) {\n let backslashes = false;\n\n let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {\n if (first === '\\\\') {\n backslashes = true;\n return m;\n }\n\n if (first === '?') {\n if (esc) {\n return esc + first + (rest ? QMARK.repeat(rest.length) : '');\n }\n if (index === 0) {\n return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');\n }\n return QMARK.repeat(chars.length);\n }\n\n if (first === '.') {\n return DOT_LITERAL.repeat(chars.length);\n }\n\n if (first === '*') {\n if (esc) {\n return esc + first + (rest ? star : '');\n }\n return star;\n }\n return esc ? m : `\\\\${m}`;\n });\n\n if (backslashes === true) {\n if (opts.unescape === true) {\n output = output.replace(/\\\\/g, '');\n } else {\n output = output.replace(/\\\\+/g, m => {\n return m.length % 2 === 0 ? '\\\\\\\\' : (m ? '\\\\' : '');\n });\n }\n }\n\n if (output === input && opts.contains === true) {\n state.output = input;\n return state;\n }\n\n state.output = utils.wrapOutput(output, state, options);\n return state;\n }\n\n /**\n * Tokenize input until we reach end-of-string\n */\n\n while (!eos()) {\n value = advance();\n\n if (value === '\\u0000') {\n continue;\n }\n\n /**\n * Escaped characters\n */\n\n if (value === '\\\\') {\n const next = peek();\n\n if (next === '/' && opts.bash !== true) {\n continue;\n }\n\n if (next === '.' || next === ';') {\n continue;\n }\n\n if (!next) {\n value += '\\\\';\n push({ type: 'text', value });\n continue;\n }\n\n // collapse slashes to reduce potential for exploits\n const match = /^\\\\+/.exec(remaining());\n let slashes = 0;\n\n if (match && match[0].length > 2) {\n slashes = match[0].length;\n state.index += slashes;\n if (slashes % 2 !== 0) {\n value += '\\\\';\n }\n }\n\n if (opts.unescape === true) {\n value = advance();\n } else {\n value += advance();\n }\n\n if (state.brackets === 0) {\n push({ type: 'text', value });\n continue;\n }\n }\n\n /**\n * If we're inside a regex character class, continue\n * until we reach the closing bracket.\n */\n\n if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {\n if (opts.posix !== false && value === ':') {\n const inner = prev.value.slice(1);\n if (inner.includes('[')) {\n prev.posix = true;\n\n if (inner.includes(':')) {\n const idx = prev.value.lastIndexOf('[');\n const pre = prev.value.slice(0, idx);\n const rest = prev.value.slice(idx + 2);\n const posix = POSIX_REGEX_SOURCE[rest];\n if (posix) {\n prev.value = pre + posix;\n state.backtrack = true;\n advance();\n\n if (!bos.output && tokens.indexOf(prev) === 1) {\n bos.output = ONE_CHAR;\n }\n continue;\n }\n }\n }\n }\n\n if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {\n value = `\\\\${value}`;\n }\n\n if (value === ']' && (prev.value === '[' || prev.value === '[^')) {\n value = `\\\\${value}`;\n }\n\n if (opts.posix === true && value === '!' && prev.value === '[') {\n value = '^';\n }\n\n prev.value += value;\n append({ value });\n continue;\n }\n\n /**\n * If we're inside a quoted string, continue\n * until we reach the closing double quote.\n */\n\n if (state.quotes === 1 && value !== '\"') {\n value = utils.escapeRegex(value);\n prev.value += value;\n append({ value });\n continue;\n }\n\n /**\n * Double quotes\n */\n\n if (value === '\"') {\n state.quotes = state.quotes === 1 ? 0 : 1;\n if (opts.keepQuotes === true) {\n push({ type: 'text', value });\n }\n continue;\n }\n\n /**\n * Parentheses\n */\n\n if (value === '(') {\n increment('parens');\n push({ type: 'paren', value });\n continue;\n }\n\n if (value === ')') {\n if (state.parens === 0 && opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('opening', '('));\n }\n\n const extglob = extglobs[extglobs.length - 1];\n if (extglob && state.parens === extglob.parens + 1) {\n extglobClose(extglobs.pop());\n continue;\n }\n\n push({ type: 'paren', value, output: state.parens ? ')' : '\\\\)' });\n decrement('parens');\n continue;\n }\n\n /**\n * Square brackets\n */\n\n if (value === '[') {\n if (opts.nobracket === true || !remaining().includes(']')) {\n if (opts.nobracket !== true && opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('closing', ']'));\n }\n\n value = `\\\\${value}`;\n } else {\n increment('brackets');\n }\n\n push({ type: 'bracket', value });\n continue;\n }\n\n if (value === ']') {\n if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {\n push({ type: 'text', value, output: `\\\\${value}` });\n continue;\n }\n\n if (state.brackets === 0) {\n if (opts.strictBrackets === true) {\n throw new SyntaxError(syntaxError('opening', '['));\n }\n\n push({ type: 'text', value, output: `\\\\${value}` });\n continue;\n }\n\n decrement('brackets');\n\n const prevValue = prev.value.slice(1);\n if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {\n value = `/${value}`;\n }\n\n prev.value += value;\n append({ value });\n\n // when literal brackets are explicitly disabled\n // assume we should match with a regex character class\n if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {\n continue;\n }\n\n const escaped = utils.escapeRegex(prev.value);\n state.output = state.output.slice(0, -prev.value.length);\n\n // when literal brackets are explicitly enabled\n // assume we should escape the brackets to match literal characters\n if (opts.literalBrackets === true) {\n state.output += escaped;\n prev.value = escaped;\n continue;\n }\n\n // when the user specifies nothing, try to match both\n prev.value = `(${capture}${escaped}|${prev.value})`;\n state.output += prev.value;\n continue;\n }\n\n /**\n * Braces\n */\n\n if (value === '{' && opts.nobrace !== true) {\n increment('braces');\n\n const open = {\n type: 'brace',\n value,\n output: '(',\n outputIndex: state.output.length,\n tokensIndex: state.tokens.length\n };\n\n braces.push(open);\n push(open);\n continue;\n }\n\n if (value === '}') {\n const brace = braces[braces.length - 1];\n\n if (opts.nobrace === true || !brace) {\n push({ type: 'text', value, output: value });\n continue;\n }\n\n let output = ')';\n\n if (brace.dots === true) {\n const arr = tokens.slice();\n const range = [];\n\n for (let i = arr.length - 1; i >= 0; i--) {\n tokens.pop();\n if (arr[i].type === 'brace') {\n break;\n }\n if (arr[i].type !== 'dots') {\n range.unshift(arr[i].value);\n }\n }\n\n output = expandRange(range, opts);\n state.backtrack = true;\n }\n\n if (brace.comma !== true && brace.dots !== true) {\n const out = state.output.slice(0, brace.outputIndex);\n const toks = state.tokens.slice(brace.tokensIndex);\n brace.value = brace.output = '\\\\{';\n value = output = '\\\\}';\n state.output = out;\n for (const t of toks) {\n state.output += (t.output || t.value);\n }\n }\n\n push({ type: 'brace', value, output });\n decrement('braces');\n braces.pop();\n continue;\n }\n\n /**\n * Pipes\n */\n\n if (value === '|') {\n if (extglobs.length > 0) {\n extglobs[extglobs.length - 1].conditions++;\n }\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Commas\n */\n\n if (value === ',') {\n let output = value;\n\n const brace = braces[braces.length - 1];\n if (brace && stack[stack.length - 1] === 'braces') {\n brace.comma = true;\n output = '|';\n }\n\n push({ type: 'comma', value, output });\n continue;\n }\n\n /**\n * Slashes\n */\n\n if (value === '/') {\n // if the beginning of the glob is \"./\", advance the start\n // to the current index, and don't add the \"./\" characters\n // to the state. This greatly simplifies lookbehinds when\n // checking for BOS characters like \"!\" and \".\" (not \"./\")\n if (prev.type === 'dot' && state.index === state.start + 1) {\n state.start = state.index + 1;\n state.consumed = '';\n state.output = '';\n tokens.pop();\n prev = bos; // reset \"prev\" to the first token\n continue;\n }\n\n push({ type: 'slash', value, output: SLASH_LITERAL });\n continue;\n }\n\n /**\n * Dots\n */\n\n if (value === '.') {\n if (state.braces > 0 && prev.type === 'dot') {\n if (prev.value === '.') prev.output = DOT_LITERAL;\n const brace = braces[braces.length - 1];\n prev.type = 'dots';\n prev.output += value;\n prev.value += value;\n brace.dots = true;\n continue;\n }\n\n if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {\n push({ type: 'text', value, output: DOT_LITERAL });\n continue;\n }\n\n push({ type: 'dot', value, output: DOT_LITERAL });\n continue;\n }\n\n /**\n * Question marks\n */\n\n if (value === '?') {\n const isGroup = prev && prev.value === '(';\n if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n extglobOpen('qmark', value);\n continue;\n }\n\n if (prev && prev.type === 'paren') {\n const next = peek();\n let output = value;\n\n if (next === '<' && !utils.supportsLookbehinds()) {\n throw new Error('Node.js v10 or higher is required for regex lookbehinds');\n }\n\n if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\\w+>)/.test(remaining()))) {\n output = `\\\\${value}`;\n }\n\n push({ type: 'text', value, output });\n continue;\n }\n\n if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {\n push({ type: 'qmark', value, output: QMARK_NO_DOT });\n continue;\n }\n\n push({ type: 'qmark', value, output: QMARK });\n continue;\n }\n\n /**\n * Exclamation\n */\n\n if (value === '!') {\n if (opts.noextglob !== true && peek() === '(') {\n if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {\n extglobOpen('negate', value);\n continue;\n }\n }\n\n if (opts.nonegate !== true && state.index === 0) {\n negate();\n continue;\n }\n }\n\n /**\n * Plus\n */\n\n if (value === '+') {\n if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n extglobOpen('plus', value);\n continue;\n }\n\n if ((prev && prev.value === '(') || opts.regex === false) {\n push({ type: 'plus', value, output: PLUS_LITERAL });\n continue;\n }\n\n if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {\n push({ type: 'plus', value });\n continue;\n }\n\n push({ type: 'plus', value: PLUS_LITERAL });\n continue;\n }\n\n /**\n * Plain text\n */\n\n if (value === '@') {\n if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {\n push({ type: 'at', extglob: true, value, output: '' });\n continue;\n }\n\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Plain text\n */\n\n if (value !== '*') {\n if (value === '$' || value === '^') {\n value = `\\\\${value}`;\n }\n\n const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());\n if (match) {\n value += match[0];\n state.index += match[0].length;\n }\n\n push({ type: 'text', value });\n continue;\n }\n\n /**\n * Stars\n */\n\n if (prev && (prev.type === 'globstar' || prev.star === true)) {\n prev.type = 'star';\n prev.star = true;\n prev.value += value;\n prev.output = star;\n state.backtrack = true;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n let rest = remaining();\n if (opts.noextglob !== true && /^\\([^?]/.test(rest)) {\n extglobOpen('star', value);\n continue;\n }\n\n if (prev.type === 'star') {\n if (opts.noglobstar === true) {\n consume(value);\n continue;\n }\n\n const prior = prev.prev;\n const before = prior.prev;\n const isStart = prior.type === 'slash' || prior.type === 'bos';\n const afterStar = before && (before.type === 'star' || before.type === 'globstar');\n\n if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {\n push({ type: 'star', value, output: '' });\n continue;\n }\n\n const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');\n const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');\n if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {\n push({ type: 'star', value, output: '' });\n continue;\n }\n\n // strip consecutive `/**/`\n while (rest.slice(0, 3) === '/**') {\n const after = input[state.index + 4];\n if (after && after !== '/') {\n break;\n }\n rest = rest.slice(3);\n consume('/**', 3);\n }\n\n if (prior.type === 'bos' && eos()) {\n prev.type = 'globstar';\n prev.value += value;\n prev.output = globstar(opts);\n state.output = prev.output;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {\n state.output = state.output.slice(0, -(prior.output + prev.output).length);\n prior.output = `(?:${prior.output}`;\n\n prev.type = 'globstar';\n prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');\n prev.value += value;\n state.globstar = true;\n state.output += prior.output + prev.output;\n consume(value);\n continue;\n }\n\n if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {\n const end = rest[1] !== void 0 ? '|$' : '';\n\n state.output = state.output.slice(0, -(prior.output + prev.output).length);\n prior.output = `(?:${prior.output}`;\n\n prev.type = 'globstar';\n prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;\n prev.value += value;\n\n state.output += prior.output + prev.output;\n state.globstar = true;\n\n consume(value + advance());\n\n push({ type: 'slash', value: '/', output: '' });\n continue;\n }\n\n if (prior.type === 'bos' && rest[0] === '/') {\n prev.type = 'globstar';\n prev.value += value;\n prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;\n state.output = prev.output;\n state.globstar = true;\n consume(value + advance());\n push({ type: 'slash', value: '/', output: '' });\n continue;\n }\n\n // remove single star from output\n state.output = state.output.slice(0, -prev.output.length);\n\n // reset previous token to globstar\n prev.type = 'globstar';\n prev.output = globstar(opts);\n prev.value += value;\n\n // reset output with globstar\n state.output += prev.output;\n state.globstar = true;\n consume(value);\n continue;\n }\n\n const token = { type: 'star', value, output: star };\n\n if (opts.bash === true) {\n token.output = '.*?';\n if (prev.type === 'bos' || prev.type === 'slash') {\n token.output = nodot + token.output;\n }\n push(token);\n continue;\n }\n\n if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {\n token.output = value;\n push(token);\n continue;\n }\n\n if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {\n if (prev.type === 'dot') {\n state.output += NO_DOT_SLASH;\n prev.output += NO_DOT_SLASH;\n\n } else if (opts.dot === true) {\n state.output += NO_DOTS_SLASH;\n prev.output += NO_DOTS_SLASH;\n\n } else {\n state.output += nodot;\n prev.output += nodot;\n }\n\n if (peek() !== '*') {\n state.output += ONE_CHAR;\n prev.output += ONE_CHAR;\n }\n }\n\n push(token);\n }\n\n while (state.brackets > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));\n state.output = utils.escapeLast(state.output, '[');\n decrement('brackets');\n }\n\n while (state.parens > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));\n state.output = utils.escapeLast(state.output, '(');\n decrement('parens');\n }\n\n while (state.braces > 0) {\n if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));\n state.output = utils.escapeLast(state.output, '{');\n decrement('braces');\n }\n\n if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {\n push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });\n }\n\n // rebuild the output if we had to backtrack at any point\n if (state.backtrack === true) {\n state.output = '';\n\n for (const token of state.tokens) {\n state.output += token.output != null ? token.output : token.value;\n\n if (token.suffix) {\n state.output += token.suffix;\n }\n }\n }\n\n return state;\n};\n\n/**\n * Fast paths for creating regular expressions for common glob patterns.\n * This can significantly speed up processing and has very little downside\n * impact when none of the fast paths match.\n */\n\nparse.fastpaths = (input, options) => {\n const opts = { ...options };\n const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;\n const len = input.length;\n if (len > max) {\n throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);\n }\n\n input = REPLACEMENTS[input] || input;\n const win32 = utils.isWindows(options);\n\n // create constants based on platform, for windows or posix\n const {\n DOT_LITERAL,\n SLASH_LITERAL,\n ONE_CHAR,\n DOTS_SLASH,\n NO_DOT,\n NO_DOTS,\n NO_DOTS_SLASH,\n STAR,\n START_ANCHOR\n } = constants.globChars(win32);\n\n const nodot = opts.dot ? NO_DOTS : NO_DOT;\n const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;\n const capture = opts.capture ? '' : '?:';\n const state = { negated: false, prefix: '' };\n let star = opts.bash === true ? '.*?' : STAR;\n\n if (opts.capture) {\n star = `(${star})`;\n }\n\n const globstar = opts => {\n if (opts.noglobstar === true) return star;\n return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;\n };\n\n const create = str => {\n switch (str) {\n case '*':\n return `${nodot}${ONE_CHAR}${star}`;\n\n case '.*':\n return `${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '*.*':\n return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '*/*':\n return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;\n\n case '**':\n return nodot + globstar(opts);\n\n case '**/*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;\n\n case '**/*.*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n case '**/.*':\n return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;\n\n default: {\n const match = /^(.*?)\\.(\\w+)$/.exec(str);\n if (!match) return;\n\n const source = create(match[1]);\n if (!source) return;\n\n return source + DOT_LITERAL + match[2];\n }\n }\n };\n\n const output = utils.removePrefix(input, state);\n let source = create(output);\n\n if (source && opts.strictSlashes !== true) {\n source += `${SLASH_LITERAL}?`;\n }\n\n return source;\n};\n\nmodule.exports = parse;\n","'use strict';\n\nconst path = require('path');\nconst scan = require('./scan');\nconst parse = require('./parse');\nconst utils = require('./utils');\nconst constants = require('./constants');\nconst isObject = val => val && typeof val === 'object' && !Array.isArray(val);\n\n/**\n * Creates a matcher function from one or more glob patterns. The\n * returned function takes a string to match as its first argument,\n * and returns true if the string is a match. The returned matcher\n * function also takes a boolean as the second argument that, when true,\n * returns an object with additional information.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch(glob[, options]);\n *\n * const isMatch = picomatch('*.!(*a)');\n * console.log(isMatch('a.a')); //=> false\n * console.log(isMatch('a.b')); //=> true\n * ```\n * @name picomatch\n * @param {String|Array} `globs` One or more glob patterns.\n * @param {Object=} `options`\n * @return {Function=} Returns a matcher function.\n * @api public\n */\n\nconst picomatch = (glob, options, returnState = false) => {\n if (Array.isArray(glob)) {\n const fns = glob.map(input => picomatch(input, options, returnState));\n const arrayMatcher = str => {\n for (const isMatch of fns) {\n const state = isMatch(str);\n if (state) return state;\n }\n return false;\n };\n return arrayMatcher;\n }\n\n const isState = isObject(glob) && glob.tokens && glob.input;\n\n if (glob === '' || (typeof glob !== 'string' && !isState)) {\n throw new TypeError('Expected pattern to be a non-empty string');\n }\n\n const opts = options || {};\n const posix = utils.isWindows(options);\n const regex = isState\n ? picomatch.compileRe(glob, options)\n : picomatch.makeRe(glob, options, false, true);\n\n const state = regex.state;\n delete regex.state;\n\n let isIgnored = () => false;\n if (opts.ignore) {\n const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };\n isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);\n }\n\n const matcher = (input, returnObject = false) => {\n const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });\n const result = { glob, state, regex, posix, input, output, match, isMatch };\n\n if (typeof opts.onResult === 'function') {\n opts.onResult(result);\n }\n\n if (isMatch === false) {\n result.isMatch = false;\n return returnObject ? result : false;\n }\n\n if (isIgnored(input)) {\n if (typeof opts.onIgnore === 'function') {\n opts.onIgnore(result);\n }\n result.isMatch = false;\n return returnObject ? result : false;\n }\n\n if (typeof opts.onMatch === 'function') {\n opts.onMatch(result);\n }\n return returnObject ? result : true;\n };\n\n if (returnState) {\n matcher.state = state;\n }\n\n return matcher;\n};\n\n/**\n * Test `input` with the given `regex`. This is used by the main\n * `picomatch()` function to test the input string.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.test(input, regex[, options]);\n *\n * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\\/([^/]*?))$/));\n * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }\n * ```\n * @param {String} `input` String to test.\n * @param {RegExp} `regex`\n * @return {Object} Returns an object with matching info.\n * @api public\n */\n\npicomatch.test = (input, regex, options, { glob, posix } = {}) => {\n if (typeof input !== 'string') {\n throw new TypeError('Expected input to be a string');\n }\n\n if (input === '') {\n return { isMatch: false, output: '' };\n }\n\n const opts = options || {};\n const format = opts.format || (posix ? utils.toPosixSlashes : null);\n let match = input === glob;\n let output = (match && format) ? format(input) : input;\n\n if (match === false) {\n output = format ? format(input) : input;\n match = output === glob;\n }\n\n if (match === false || opts.capture === true) {\n if (opts.matchBase === true || opts.basename === true) {\n match = picomatch.matchBase(input, regex, options, posix);\n } else {\n match = regex.exec(output);\n }\n }\n\n return { isMatch: Boolean(match), match, output };\n};\n\n/**\n * Match the basename of a filepath.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.matchBase(input, glob[, options]);\n * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true\n * ```\n * @param {String} `input` String to test.\n * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).\n * @return {Boolean}\n * @api public\n */\n\npicomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {\n const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);\n return regex.test(path.basename(input));\n};\n\n/**\n * Returns true if **any** of the given glob `patterns` match the specified `string`.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.isMatch(string, patterns[, options]);\n *\n * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true\n * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false\n * ```\n * @param {String|Array} str The string to test.\n * @param {String|Array} patterns One or more glob patterns to use for matching.\n * @param {Object} [options] See available [options](#options).\n * @return {Boolean} Returns true if any patterns match `str`\n * @api public\n */\n\npicomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);\n\n/**\n * Parse a glob pattern to create the source string for a regular\n * expression.\n *\n * ```js\n * const picomatch = require('picomatch');\n * const result = picomatch.parse(pattern[, options]);\n * ```\n * @param {String} `pattern`\n * @param {Object} `options`\n * @return {Object} Returns an object with useful properties and output to be used as a regex source string.\n * @api public\n */\n\npicomatch.parse = (pattern, options) => {\n if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));\n return parse(pattern, { ...options, fastpaths: false });\n};\n\n/**\n * Scan a glob pattern to separate the pattern into segments.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.scan(input[, options]);\n *\n * const result = picomatch.scan('!./foo/*.js');\n * console.log(result);\n * { prefix: '!./',\n * input: '!./foo/*.js',\n * start: 3,\n * base: 'foo',\n * glob: '*.js',\n * isBrace: false,\n * isBracket: false,\n * isGlob: true,\n * isExtglob: false,\n * isGlobstar: false,\n * negated: true }\n * ```\n * @param {String} `input` Glob pattern to scan.\n * @param {Object} `options`\n * @return {Object} Returns an object with\n * @api public\n */\n\npicomatch.scan = (input, options) => scan(input, options);\n\n/**\n * Compile a regular expression from the `state` object returned by the\n * [parse()](#parse) method.\n *\n * @param {Object} `state`\n * @param {Object} `options`\n * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.\n * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.\n * @return {RegExp}\n * @api public\n */\n\npicomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {\n if (returnOutput === true) {\n return state.output;\n }\n\n const opts = options || {};\n const prepend = opts.contains ? '' : '^';\n const append = opts.contains ? '' : '$';\n\n let source = `${prepend}(?:${state.output})${append}`;\n if (state && state.negated === true) {\n source = `^(?!${source}).*$`;\n }\n\n const regex = picomatch.toRegex(source, options);\n if (returnState === true) {\n regex.state = state;\n }\n\n return regex;\n};\n\n/**\n * Create a regular expression from a parsed glob pattern.\n *\n * ```js\n * const picomatch = require('picomatch');\n * const state = picomatch.parse('*.js');\n * // picomatch.compileRe(state[, options]);\n *\n * console.log(picomatch.compileRe(state));\n * //=> /^(?:(?!\\.)(?=.)[^/]*?\\.js)$/\n * ```\n * @param {String} `state` The object returned from the `.parse` method.\n * @param {Object} `options`\n * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.\n * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.\n * @return {RegExp} Returns a regex created from the given pattern.\n * @api public\n */\n\npicomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {\n if (!input || typeof input !== 'string') {\n throw new TypeError('Expected a non-empty string');\n }\n\n let parsed = { negated: false, fastpaths: true };\n\n if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {\n parsed.output = parse.fastpaths(input, options);\n }\n\n if (!parsed.output) {\n parsed = parse(input, options);\n }\n\n return picomatch.compileRe(parsed, options, returnOutput, returnState);\n};\n\n/**\n * Create a regular expression from the given regex source string.\n *\n * ```js\n * const picomatch = require('picomatch');\n * // picomatch.toRegex(source[, options]);\n *\n * const { output } = picomatch.parse('*.js');\n * console.log(picomatch.toRegex(output));\n * //=> /^(?:(?!\\.)(?=.)[^/]*?\\.js)$/\n * ```\n * @param {String} `source` Regular expression source string.\n * @param {Object} `options`\n * @return {RegExp}\n * @api public\n */\n\npicomatch.toRegex = (source, options) => {\n try {\n const opts = options || {};\n return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));\n } catch (err) {\n if (options && options.debug === true) throw err;\n return /$^/;\n }\n};\n\n/**\n * Picomatch constants.\n * @return {Object}\n */\n\npicomatch.constants = constants;\n\n/**\n * Expose \"picomatch\"\n */\n\nmodule.exports = picomatch;\n","'use strict';\n\nmodule.exports = require('./lib/picomatch');\n","import picomatch from \"picomatch\";\n\nimport type { GitDiff, KlyConfig } from \"./types\";\n\nexport interface FilteredDiff {\n toIndex: string[];\n toDelete: string[];\n renamed: Array<{ from: string; to: string }>;\n}\n\nexport function filterGitDiff(diff: GitDiff, config: KlyConfig): FilteredDiff {\n const isIncluded = picomatch(config.include);\n const isExcluded = picomatch(config.exclude);\n\n const matches = (filePath: string): boolean => isIncluded(filePath) && !isExcluded(filePath);\n\n const toIndex: string[] = [];\n const toDelete: string[] = [];\n const renamed: Array<{ from: string; to: string }> = [];\n\n for (const filePath of [...diff.added, ...diff.modified]) {\n if (matches(filePath)) {\n toIndex.push(filePath);\n }\n }\n\n for (const filePath of diff.deleted) {\n if (matches(filePath)) {\n toDelete.push(filePath);\n }\n }\n\n for (const r of diff.renamed) {\n const fromMatches = matches(r.from);\n const toMatches = matches(r.to);\n\n if (toMatches) {\n renamed.push(r);\n }\n if (fromMatches && !toMatches) {\n toDelete.push(r.from);\n }\n }\n\n return { toIndex, toDelete, renamed };\n}\n","import type { ParseResult } from \"../types\";\n\nexport abstract class BaseParser {\n abstract readonly extensions: string[];\n\n abstract parse(content: string, filePath: string): ParseResult;\n\n supports(filePath: string): boolean {\n return this.extensions.some((ext) => filePath.endsWith(ext));\n }\n}\n","import Parser from \"tree-sitter\";\nimport Swift from \"tree-sitter-swift\";\n\nimport type { ParseResult, SymbolInfo, SymbolKind } from \"../types\";\nimport { BaseParser } from \"./base\";\n\nconst swiftParser = new Parser();\nswiftParser.setLanguage(Swift);\n\nconst SYMBOL_NODE_TYPES: Record<string, SymbolKind> = {\n class_declaration: \"class\",\n protocol_declaration: \"protocol\",\n function_declaration: \"function\",\n};\n\n// tree-sitter-swift parses struct/enum/class all as class_declaration.\n// Detect actual kind from the first keyword child.\nconst KEYWORD_TO_KIND: Record<string, SymbolKind> = {\n struct: \"struct\",\n enum: \"enum\",\n class: \"class\",\n};\n\nfunction extractName(node: Parser.SyntaxNode): string | null {\n /* v8 ignore next */\n return node.childForFieldName(\"name\")?.text ?? null;\n}\n\nexport class SwiftParser extends BaseParser {\n readonly extensions = [\".swift\"];\n\n parse(content: string, _filePath: string): ParseResult {\n const tree = swiftParser.parse(content);\n const rootNode = tree.rootNode;\n\n const imports: string[] = [];\n const exports: string[] = [];\n const symbols: SymbolInfo[] = [];\n\n function walk(node: Parser.SyntaxNode): void {\n // Imports\n if (node.type === \"import_declaration\") {\n // Get the module name from import statement\n const children = node.children.filter((c: Parser.SyntaxNode) => c.type !== \"import\");\n /* v8 ignore next */\n if (children.length > 0) {\n imports.push(children.map((c: Parser.SyntaxNode) => c.text).join(\".\"));\n }\n }\n\n // Symbols\n let kind = SYMBOL_NODE_TYPES[node.type];\n if (node.type === \"class_declaration\") {\n // Detect struct/enum/class from keyword child\n const keyword = node.children.find((c: Parser.SyntaxNode) => c.type in KEYWORD_TO_KIND);\n /* v8 ignore next */\n kind = keyword ? KEYWORD_TO_KIND[keyword.type] : \"class\";\n }\n if (kind) {\n const name = extractName(node);\n /* v8 ignore next */\n if (name) {\n symbols.push({ name, kind, description: \"\" });\n // In Swift, all top-level declarations are effectively exported\n exports.push(name);\n }\n }\n\n for (const child of node.children) {\n walk(child);\n }\n }\n\n walk(rootNode);\n\n return { imports, exports, symbols };\n }\n}\n","import Parser from \"tree-sitter\";\nimport TypeScript from \"tree-sitter-typescript\";\n\nimport type { ParseResult, SymbolInfo, SymbolKind } from \"../types\";\nimport { BaseParser } from \"./base\";\n\nconst tsParser = new Parser();\ntsParser.setLanguage(TypeScript.typescript);\n\nconst tsxParser = new Parser();\ntsxParser.setLanguage(TypeScript.tsx);\n\nconst IMPORT_TYPES = new Set([\"import_statement\"]);\nconst EXPORT_NODE_TYPES = new Set([\"export_statement\"]);\n\nconst SYMBOL_NODE_TYPES: Record<string, SymbolKind> = {\n class_declaration: \"class\",\n function_declaration: \"function\",\n method_definition: \"method\",\n interface_declaration: \"interface\",\n type_alias_declaration: \"type\",\n enum_declaration: \"enum\",\n lexical_declaration: \"variable\",\n variable_declaration: \"variable\",\n};\n\nfunction extractName(node: Parser.SyntaxNode): string | null {\n const nameNode = node.childForFieldName(\"name\");\n if (nameNode) return nameNode.text;\n\n // For variable declarations, look for the first declarator\n for (const child of node.children) {\n if (child.type === \"variable_declarator\") {\n const n = child.childForFieldName(\"name\");\n /* v8 ignore next */\n if (n) return n.text;\n }\n }\n\n /* v8 ignore next */\n return null;\n}\n\nfunction extractImports(rootNode: Parser.SyntaxNode): string[] {\n const imports: string[] = [];\n\n for (const child of rootNode.children) {\n if (IMPORT_TYPES.has(child.type)) {\n const source = child.childForFieldName(\"source\");\n /* v8 ignore next */\n if (source) {\n imports.push(source.text.replace(/['\"]/g, \"\"));\n }\n }\n }\n\n return imports;\n}\n\nfunction extractExports(rootNode: Parser.SyntaxNode): string[] {\n const exports: string[] = [];\n\n for (const child of rootNode.children) {\n if (EXPORT_NODE_TYPES.has(child.type)) {\n // export { ... }\n const exportClause = child.children.find(\n (c: Parser.SyntaxNode) => c.type === \"export_clause\",\n );\n if (exportClause) {\n for (const specifier of exportClause.children) {\n if (specifier.type === \"export_specifier\") {\n const name = specifier.childForFieldName(\"name\");\n /* v8 ignore next */\n if (name) exports.push(name.text);\n }\n }\n continue;\n }\n\n // export declaration (class, function, etc.)\n const declaration = child.childForFieldName(\"declaration\");\n if (declaration) {\n const name = extractName(declaration);\n /* v8 ignore next */\n if (name) exports.push(name);\n }\n }\n }\n\n return exports;\n}\n\nfunction extractSymbols(rootNode: Parser.SyntaxNode): SymbolInfo[] {\n const symbols: SymbolInfo[] = [];\n\n function walk(node: Parser.SyntaxNode): void {\n // Check if this is an exported declaration wrapper\n if (EXPORT_NODE_TYPES.has(node.type)) {\n const declaration = node.childForFieldName(\"declaration\");\n if (declaration) {\n processSymbolNode(declaration);\n }\n return;\n }\n\n processSymbolNode(node);\n\n for (const child of node.children) {\n // Only go one level deep for top-level symbols, skip into class bodies for methods\n if (child.type === \"class_body\") {\n for (const member of child.children) {\n processSymbolNode(member);\n }\n }\n }\n }\n\n function processSymbolNode(node: Parser.SyntaxNode): void {\n const kind = SYMBOL_NODE_TYPES[node.type];\n if (!kind) return;\n\n const name = extractName(node);\n /* v8 ignore next */\n if (!name) return;\n\n symbols.push({\n name,\n kind,\n description: \"\",\n });\n }\n\n for (const child of rootNode.children) {\n walk(child);\n }\n\n return symbols;\n}\n\nexport class TypeScriptParser extends BaseParser {\n readonly extensions = [\".ts\", \".tsx\", \".js\", \".jsx\"];\n\n parse(content: string, filePath: string): ParseResult {\n const isTsx = filePath.endsWith(\".tsx\") || filePath.endsWith(\".jsx\");\n const parser = isTsx ? tsxParser : tsParser;\n const tree = parser.parse(content);\n const rootNode = tree.rootNode;\n\n return {\n imports: extractImports(rootNode),\n exports: extractExports(rootNode),\n symbols: extractSymbols(rootNode),\n };\n }\n}\n","import type { Language, ParseResult } from \"../types\";\nimport { BaseParser } from \"./base\";\nimport { SwiftParser } from \"./swift\";\nimport { TypeScriptParser } from \"./typescript\";\n\nconst EXTENSION_TO_LANGUAGE: Record<string, Language> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".swift\": \"swift\",\n};\n\nexport class ParserManager {\n private parsers: BaseParser[];\n\n constructor() {\n this.parsers = [new TypeScriptParser(), new SwiftParser()];\n }\n\n getParser(filePath: string): BaseParser | undefined {\n return this.parsers.find((p) => p.supports(filePath));\n }\n\n parse(content: string, filePath: string): ParseResult | null {\n const parser = this.getParser(filePath);\n if (!parser) return null;\n return parser.parse(content, filePath);\n }\n\n getLanguage(filePath: string): Language | undefined {\n const ext = filePath.slice(filePath.lastIndexOf(\".\"));\n return EXTENSION_TO_LANGUAGE[ext];\n }\n}\n\nexport { BaseParser } from \"./base\";\nexport { SwiftParser } from \"./swift\";\nexport { TypeScriptParser } from \"./typescript\";\n","import pLimit from \"p-limit\";\n\nexport interface BatchTask<T> {\n execute: () => Promise<T>;\n}\n\nexport class Batcher<T> {\n private limit: ReturnType<typeof pLimit>;\n\n constructor(concurrency: number = 5) {\n this.limit = pLimit(concurrency);\n }\n\n async run(tasks: BatchTask<T>[]): Promise<T[]> {\n return Promise.all(tasks.map((task) => this.limit(() => task.execute())));\n }\n}\n","export const INDEXING_SYSTEM_PROMPT = `You are a code indexing assistant. Your job is to analyze source code files and generate structured metadata.\n\nFor each file, you must return a JSON object with exactly these fields:\n- \"name\": A short, descriptive name for the file (e.g., \"User Authentication Service\")\n- \"description\": A one-line description of what this file does\n- \"summary\": A 2-3 sentence summary of the file's purpose and key functionality\n- \"symbols\": An array of symbol descriptions, each with \"name\" and \"description\"\n\nRules:\n- Be concise and precise\n- Focus on what the code DOES, not how it's structured\n- Symbol descriptions should explain the purpose, not restate the signature\n- Return ONLY valid JSON, no markdown or explanation`;\n\nexport const RERANK_SYSTEM_PROMPT = `You are a search result reranking assistant. Given a user query and a list of candidate files, reorder them by relevance.\n\nReturn ONLY a JSON array of file paths, ordered from most relevant to least relevant.\nDo not include any explanation, markdown, or extra text — just the JSON array.`;\n\nexport function buildRerankPrompt(\n query: string,\n candidates: Array<{ path: string; name: string; description: string; summary: string }>,\n): string {\n const fileList = candidates\n .map(\n (c, i) =>\n `${i + 1}. ${c.path}\\n Name: ${c.name}\\n Description: ${c.description}\\n Summary: ${c.summary}`,\n )\n .join(\"\\n\\n\");\n\n return `User query: \"${query}\"\n\nCandidate files:\n${fileList}\n\nReorder these files by relevance to the query. Return a JSON array of file paths, most relevant first.`;\n}\n\nexport function buildIndexingPrompt(\n filePath: string,\n content: string,\n symbols: { name: string; kind: string }[],\n): string {\n const symbolList = symbols.map((s) => `- ${s.kind}: ${s.name}`).join(\"\\n\");\n\n return `Analyze this source file and generate indexing metadata.\n\nFile: ${filePath}\nDetected symbols:\n${symbolList}\n\nSource code:\n\\`\\`\\`\n${content}\n\\`\\`\\`\n\nReturn a JSON object with: name, description, summary, and symbols (array with name + description for each detected symbol).`;\n}\n","import { complete, getModel } from \"@mariozechner/pi-ai\";\nimport type { Api, Model, Provider, TextContent } from \"@mariozechner/pi-ai\";\n\nimport type { KlyConfig, SymbolInfo } from \"../types\";\nimport { Batcher } from \"./batcher\";\nimport { buildIndexingPrompt, INDEXING_SYSTEM_PROMPT } from \"./prompts\";\n\ninterface LLMIndexResult {\n name: string;\n description: string;\n summary: string;\n symbols: { name: string; description: string }[];\n}\n\n/**\n * Resolve a model by provider and model ID from user config.\n * pi-ai's getModel is generic over compile-time known providers/models,\n * but user config is dynamic. This wrapper bridges the gap.\n */\nfunction resolveModel(provider: Provider, modelId: string): Model<Api> {\n const model = (getModel as (p: Provider, m: string) => Model<Api> | undefined)(provider, modelId);\n if (!model) {\n throw new Error(\n `Unknown model \"${modelId}\" for provider \"${provider}\". Check your .kly/config.yaml.`,\n );\n }\n return model;\n}\n\nexport class LLMService {\n private model: Model<Api>;\n private batcher: Batcher<LLMIndexResult>;\n\n constructor(config: KlyConfig) {\n const envKey = this.getEnvKeyName(config.llm.provider);\n if (config.llm.apiKey && !process.env[envKey]) {\n process.env[envKey] = config.llm.apiKey;\n }\n\n this.model = resolveModel(config.llm.provider, config.llm.model);\n this.batcher = new Batcher(5);\n }\n\n private getEnvKeyName(provider: string): string {\n const map: Record<string, string> = {\n openrouter: \"OPENROUTER_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openai: \"OPENAI_API_KEY\",\n google: \"GOOGLE_API_KEY\",\n mistral: \"MISTRAL_API_KEY\",\n groq: \"GROQ_API_KEY\",\n xai: \"XAI_API_KEY\",\n };\n return map[provider] || `${provider.toUpperCase()}_API_KEY`;\n }\n\n async indexFile(\n filePath: string,\n content: string,\n symbols: SymbolInfo[],\n ): Promise<LLMIndexResult> {\n const prompt = buildIndexingPrompt(\n filePath,\n content,\n symbols.map((s) => ({ name: s.name, kind: s.kind })),\n );\n\n const response = await complete(this.model, {\n systemPrompt: INDEXING_SYSTEM_PROMPT,\n messages: [\n {\n role: \"user\",\n content: prompt,\n timestamp: Date.now(),\n },\n ],\n });\n\n const text = response.content\n .filter((block): block is TextContent => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\n return this.parseResponse(text);\n }\n\n async indexFiles(\n files: { path: string; content: string; symbols: SymbolInfo[] }[],\n ): Promise<Map<string, LLMIndexResult>> {\n const results = new Map<string, LLMIndexResult>();\n\n const tasks = files.map((file) => ({\n execute: async () => {\n const result = await this.indexFile(file.path, file.content, file.symbols);\n results.set(file.path, result);\n return result;\n },\n }));\n\n await this.batcher.run(tasks);\n return results;\n }\n\n private parseResponse(text: string): LLMIndexResult {\n const jsonMatch = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n const jsonStr = jsonMatch ? jsonMatch[1].trim() : text.trim();\n\n const parsed = JSON.parse(jsonStr) as LLMIndexResult;\n\n return {\n name: parsed.name || \"\",\n description: parsed.description || \"\",\n summary: parsed.summary || \"\",\n symbols: Array.isArray(parsed.symbols)\n ? parsed.symbols.map((s) => ({\n name: s.name || \"\",\n description: s.description || \"\",\n }))\n : [],\n };\n }\n}\n","import path from \"node:path\";\n\nimport { renderMermaidASCII, renderMermaidSVG } from \"beautiful-mermaid\";\n\nimport type { IndexDatabase } from \"./database\";\nimport type { FileIndex, Language } from \"./types\";\n\nexport type GraphFormat = \"json\" | \"mermaid\" | \"ascii\" | \"svg\";\n\nexport interface GraphNode {\n path: string;\n name: string;\n language: Language;\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, GraphNode>;\n edges: GraphEdge[];\n}\n\nconst RESOLVE_EXTENSIONS = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \"/index.ts\",\n \"/index.tsx\",\n \"/index.js\",\n \"/index.jsx\",\n];\n\nexport function isRelativeImport(importPath: string): boolean {\n return importPath.startsWith(\".\") || importPath.startsWith(\"/\");\n}\n\n/**\n * Resolve a relative import path to a file path that exists in the index.\n */\nexport function resolveImport(\n fromFile: string,\n importPath: string,\n indexedPaths: Set<string>,\n): string | undefined {\n if (!isRelativeImport(importPath)) return undefined;\n\n const dir = path.dirname(fromFile);\n const resolved = path.normalize(path.join(dir, importPath));\n\n // Direct match (already has extension)\n if (indexedPaths.has(resolved)) return resolved;\n\n // Try extension completion\n for (const ext of RESOLVE_EXTENSIONS) {\n const candidate = resolved + ext;\n if (indexedPaths.has(candidate)) return candidate;\n }\n\n return undefined;\n}\n\n/**\n * Build a dependency graph from indexed files.\n */\nexport function buildDependencyGraph(\n db: IndexDatabase,\n options: { focus?: string; depth?: number } = {},\n): DependencyGraph {\n const { focus, depth = 2 } = options;\n const allFiles = db.getAllFiles();\n const indexedPaths = new Set(allFiles.map((f) => f.path));\n const fileMap = new Map<string, FileIndex>();\n for (const file of allFiles) {\n fileMap.set(file.path, file);\n }\n\n // Build full adjacency list\n const adjacency = new Map<string, string[]>();\n for (const file of allFiles) {\n const deps: string[] = [];\n for (const imp of file.imports) {\n const resolved = resolveImport(file.path, imp, indexedPaths);\n if (resolved) deps.push(resolved);\n }\n adjacency.set(file.path, deps);\n }\n\n // Determine which nodes to include\n let includedPaths: Set<string>;\n\n if (focus) {\n // BFS from focus node up to depth\n includedPaths = new Set<string>();\n const queue: Array<{ path: string; currentDepth: number }> = [{ path: focus, currentDepth: 0 }];\n includedPaths.add(focus);\n\n while (queue.length > 0) {\n const { path: current, currentDepth } = queue.shift()!;\n if (currentDepth >= depth) continue;\n\n // Forward edges (dependencies of current)\n const deps = adjacency.get(current) || [];\n for (const dep of deps) {\n if (!includedPaths.has(dep)) {\n includedPaths.add(dep);\n queue.push({ path: dep, currentDepth: currentDepth + 1 });\n }\n }\n\n // Reverse edges (files that depend on current)\n for (const [source, targets] of adjacency) {\n if (targets.includes(current) && !includedPaths.has(source)) {\n includedPaths.add(source);\n queue.push({ path: source, currentDepth: currentDepth + 1 });\n }\n }\n }\n } else {\n includedPaths = indexedPaths;\n }\n\n // Build graph\n const nodes = new Map<string, GraphNode>();\n const edges: GraphEdge[] = [];\n\n for (const filePath of includedPaths) {\n const file = fileMap.get(filePath);\n if (!file) continue;\n nodes.set(filePath, {\n path: file.path,\n name: file.name,\n language: file.language,\n });\n }\n\n for (const filePath of includedPaths) {\n const deps = adjacency.get(filePath) || [];\n for (const dep of deps) {\n if (includedPaths.has(dep)) {\n edges.push({ from: filePath, to: dep });\n }\n }\n }\n\n return { nodes, edges };\n}\n\n/**\n * Generate Mermaid syntax from a dependency graph.\n */\nexport function generateMermaid(graph: DependencyGraph): string {\n const lines: string[] = [\"graph LR\"];\n\n // Create stable node IDs\n const nodeIds = new Map<string, string>();\n let idCounter = 0;\n for (const filePath of graph.nodes.keys()) {\n nodeIds.set(filePath, `N${idCounter++}`);\n }\n\n // Node declarations\n for (const [filePath, node] of graph.nodes) {\n const id = nodeIds.get(filePath)!;\n const label = node.path.replace(/\"/g, \"'\");\n lines.push(` ${id}[\"${label}\"]`);\n }\n\n // Edge declarations\n for (const edge of graph.edges) {\n const fromId = nodeIds.get(edge.from);\n const toId = nodeIds.get(edge.to);\n if (fromId && toId) {\n lines.push(` ${fromId} --> ${toId}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Render a Mermaid diagram string to ASCII/Unicode art.\n */\nexport function renderGraphAscii(mermaid: string): string {\n return renderMermaidASCII(mermaid, { colorMode: \"none\" });\n}\n\n/**\n * Render a Mermaid diagram string to SVG.\n */\nexport function renderGraphSvg(mermaid: string): string {\n return renderMermaidSVG(mermaid, { transparent: true });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { hashConfig, loadConfig } from \"./config\";\nimport type { IndexDatabase } from \"./database\";\nimport { filterGitDiff } from \"./diff-filter\";\nimport {\n getCurrentBranch,\n getCurrentCommit,\n getChangedFiles,\n isAncestor,\n getMergeBase,\n isGitRepo,\n branchToDbName,\n} from \"./git\";\nimport { resolveImport } from \"./graph\";\nimport { hashFile, hasChanged } from \"./hasher\";\nimport { LLMService } from \"./llm/index\";\nimport { ParserManager } from \"./parser/index\";\nimport { scanFiles } from \"./scanner\";\nimport {\n openDatabase,\n loadState,\n saveState,\n getBranchState,\n setBranchState,\n copyDatabase,\n} from \"./store\";\nimport type { BranchState, FileIndex } from \"./types\";\n\nexport interface IndexProgress {\n total: number;\n completed: number;\n current: string;\n skipped: number;\n}\n\nexport type ProgressCallback = (progress: IndexProgress) => void;\n\nexport interface IndexOptions {\n incremental?: boolean;\n full?: boolean;\n quiet?: boolean;\n onProgress?: ProgressCallback;\n}\n\nexport interface BuildResult {\n totalFiles: number;\n newFiles: number;\n updatedFiles: number;\n deletedFiles: number;\n unchangedFiles: number;\n branch: string;\n commit: string;\n durationMs: number;\n}\n\nfunction emptyBuildResult(root: string): BuildResult {\n const gitRepo = isGitRepo(root);\n return {\n totalFiles: 0,\n newFiles: 0,\n updatedFiles: 0,\n deletedFiles: 0,\n unchangedFiles: 0,\n branch: gitRepo ? getCurrentBranch(root) || \"detached\" : \"default\",\n commit: gitRepo ? getCurrentCommit(root) : \"\",\n durationMs: 0,\n };\n}\n\nexport async function buildIndex(root: string, options: IndexOptions = {}): Promise<BuildResult> {\n const start = Date.now();\n const config = loadConfig(root);\n const parserManager = new ParserManager();\n const llmService = new LLMService(config);\n\n const gitRepo = isGitRepo(root);\n\n let result: BuildResult;\n if (gitRepo && !options.full) {\n result = await buildGitAware(root, config, parserManager, llmService, options);\n } else {\n result = await buildClassic(root, config, parserManager, llmService, options);\n }\n\n result.durationMs = Date.now() - start;\n return result;\n}\n\nasync function buildGitAware(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n): Promise<BuildResult> {\n const branch = getCurrentBranch(root);\n const commit = getCurrentCommit(root);\n const dbName = branchToDbName(branch, commit);\n\n const state = loadState(root);\n const currentConfigHash = hashConfig(config);\n\n let result: BuildResult;\n\n // Config changed — force full rebuild\n if (state.configHash && state.configHash !== currentConfigHash) {\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n state.configHash = currentConfigHash;\n setBranchState(state, dbName, { lastCommit: commit, lastBuilt: Date.now() });\n saveState(root, state);\n return result;\n }\n\n const branchState = getBranchState(state, dbName);\n\n if (branchState?.lastCommit) {\n if (isAncestor(root, branchState.lastCommit, commit)) {\n // Normal incremental: diff from last indexed commit\n result = await buildFromGitDiff(\n root,\n config,\n parserManager,\n llmService,\n options,\n dbName,\n branchState.lastCommit,\n commit,\n );\n } else {\n // Rebase/force push: fall back to hash-based incremental\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n } else {\n // New branch: try to fork from parent\n const forkedFromDb = tryForkFromParent(root, dbName, state);\n if (forkedFromDb) {\n // Track the fork origin so we can preserve it across rebuilds\n setBranchState(state, dbName, { lastCommit: \"\", lastBuilt: 0, forkedFrom: forkedFromDb });\n // parentState is guaranteed to exist — tryForkFromParent checks state.branches[candidate]\n const parentState = getBranchState(state, forkedFromDb)!;\n const mergeBase = getMergeBase(root, parentState.lastCommit, commit);\n if (mergeBase) {\n result = await buildFromGitDiff(\n root,\n config,\n parserManager,\n llmService,\n options,\n dbName,\n mergeBase,\n commit,\n );\n } else {\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n } else {\n // Full build\n result = await buildClassic(root, config, parserManager, llmService, options, dbName);\n }\n }\n\n state.configHash = currentConfigHash;\n const newBranchState: BranchState = {\n lastCommit: commit,\n lastBuilt: Date.now(),\n };\n // Preserve forkedFrom if it was previously set\n const currentBranchState = getBranchState(state, dbName);\n if (currentBranchState?.forkedFrom) {\n newBranchState.forkedFrom = currentBranchState.forkedFrom;\n }\n setBranchState(state, dbName, newBranchState);\n saveState(root, state);\n return result;\n}\n\nfunction tryForkFromParent(\n root: string,\n dbName: string,\n state: { branches: Record<string, { lastCommit: string }> },\n): string | null {\n // Try to find \"main\" or \"master\" as parent\n for (const candidate of [\"main\", \"master\"]) {\n if (state.branches[candidate] && candidate !== dbName) {\n copyDatabase(root, candidate, dbName);\n return candidate;\n }\n }\n return null;\n}\n\nasync function buildFromGitDiff(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n dbName: string,\n fromCommit: string,\n toCommit: string,\n): Promise<BuildResult> {\n const gitDiff = getChangedFiles(root, fromCommit, toCommit);\n const filtered = filterGitDiff(gitDiff, config);\n\n // Handle renamed files: add the new path to index list, delete old path\n const toIndex = [...filtered.toIndex];\n const toDelete = [...filtered.toDelete];\n\n for (const r of filtered.renamed) {\n toIndex.push(r.to);\n toDelete.push(r.from);\n }\n\n const db = openDatabase(root, dbName);\n const result = emptyBuildResult(root);\n\n try {\n if (toDelete.length > 0) {\n db.removeFiles(toDelete);\n db.removeDependenciesBatch(toDelete);\n result.deletedFiles = toDelete.length;\n }\n\n if (toIndex.length === 0) {\n options.onProgress?.({\n total: 0,\n completed: 0,\n current: \"\",\n skipped: 0,\n });\n result.totalFiles = db.getFileCount();\n result.unchangedFiles = result.totalFiles;\n return result;\n }\n\n const indexResult = await indexFiles(root, toIndex, db, parserManager, llmService, options);\n result.newFiles = indexResult.newFiles;\n result.updatedFiles = indexResult.updatedFiles;\n result.totalFiles = db.getFileCount();\n result.unchangedFiles = result.totalFiles - result.newFiles - result.updatedFiles;\n return result;\n } finally {\n db.close();\n }\n}\n\nasync function buildClassic(\n root: string,\n config: ReturnType<typeof loadConfig>,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n dbName?: string,\n): Promise<BuildResult> {\n const name =\n dbName ||\n (isGitRepo(root) ? branchToDbName(getCurrentBranch(root), getCurrentCommit(root)) : \"default\");\n const db = openDatabase(root, name);\n const result = emptyBuildResult(root);\n\n try {\n const files = await scanFiles(root, config);\n const progress: IndexProgress = {\n total: files.length,\n completed: 0,\n current: \"\",\n skipped: 0,\n };\n\n // Collect files that need indexing, track which already exist\n const toIndex: string[] = [];\n const existingPaths = new Set<string>();\n\n for (const filePath of files) {\n const hash = hashFile(root, filePath);\n const existing = db.getFile(filePath);\n\n if (existing) {\n existingPaths.add(filePath);\n }\n\n if (existing && !hasChanged(existing.hash, hash) && !options.full) {\n progress.skipped++;\n progress.completed++;\n result.unchangedFiles++;\n options.onProgress?.(progress);\n continue;\n }\n\n toIndex.push(filePath);\n }\n\n if (toIndex.length > 0) {\n await indexFiles(root, toIndex, db, parserManager, llmService, options, progress);\n // Determine new vs updated based on whether they existed before\n for (const filePath of toIndex) {\n if (existingPaths.has(filePath)) {\n result.updatedFiles++;\n } else {\n result.newFiles++;\n }\n }\n }\n\n // Remove files that no longer exist on disk\n const fileSet = new Set(files);\n const allIndexed = db.getAllFiles();\n const toRemove = allIndexed.filter((f) => !fileSet.has(f.path)).map((f) => f.path);\n if (toRemove.length > 0) {\n db.removeFiles(toRemove);\n db.removeDependenciesBatch(toRemove);\n result.deletedFiles = toRemove.length;\n }\n\n result.totalFiles = db.getFileCount();\n return result;\n } finally {\n db.close();\n }\n}\n\ninterface IndexFilesResult {\n indexed: number;\n newFiles: number;\n updatedFiles: number;\n}\n\nasync function indexFiles(\n root: string,\n filePaths: string[],\n db: IndexDatabase,\n parserManager: ParserManager,\n llmService: LLMService,\n options: IndexOptions,\n progress?: IndexProgress,\n): Promise<IndexFilesResult> {\n const prog = progress || {\n total: filePaths.length,\n completed: 0,\n current: \"\",\n skipped: 0,\n };\n\n if (!progress) {\n prog.total = filePaths.length;\n }\n\n // Read and parse files\n const parsedFiles = filePaths.map((filePath) => {\n const fullPath = path.join(root, filePath);\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const hash = hashFile(root, filePath);\n const language = parserManager.getLanguage(filePath);\n const parseResult = parserManager.parse(content, filePath);\n\n return {\n path: filePath,\n content,\n hash,\n language: language || (\"typescript\" as const),\n imports: parseResult?.imports || [],\n exports: parseResult?.exports || [],\n symbols: parseResult?.symbols || [],\n };\n });\n\n // LLM index in batches\n const llmResults = await llmService.indexFiles(\n parsedFiles.map((f) => ({\n path: f.path,\n content: f.content,\n symbols: f.symbols,\n })),\n );\n\n // Merge and upsert\n const fileIndexes: FileIndex[] = parsedFiles.map((file) => {\n const llmResult = llmResults.get(file.path);\n\n const fileIndex: FileIndex = {\n path: file.path,\n name: llmResult?.name || path.basename(file.path),\n description: llmResult?.description || \"\",\n language: file.language,\n imports: file.imports,\n exports: file.exports,\n symbols: file.symbols.map((s) => {\n const llmSymbol = llmResult?.symbols.find((ls) => ls.name === s.name);\n return {\n ...s,\n description: llmSymbol?.description || s.description,\n };\n }),\n summary: llmResult?.summary || \"\",\n hash: file.hash,\n indexedAt: Date.now(),\n };\n\n prog.completed++;\n prog.current = file.path;\n options.onProgress?.(prog);\n\n return fileIndex;\n });\n\n db.upsertFiles(fileIndexes);\n\n // Build and write dependencies\n const allFiles = db.getAllFiles();\n const indexedPaths = new Set(allFiles.map((f) => f.path));\n const depEntries: Array<{ fromPath: string; toPaths: string[] }> = [];\n\n for (const file of parsedFiles) {\n const resolved: string[] = [];\n for (const imp of file.imports) {\n const target = resolveImport(file.path, imp, indexedPaths);\n if (target) resolved.push(target);\n }\n depEntries.push({ fromPath: file.path, toPaths: resolved });\n }\n\n if (depEntries.length > 0) {\n db.upsertBatchDependencies(depEntries);\n }\n\n return {\n indexed: fileIndexes.length,\n newFiles: 0, // caller determines new vs updated\n updatedFiles: 0,\n };\n}\n","import { complete } from \"@mariozechner/pi-ai\";\nimport type { Api, Model, TextContent } from \"@mariozechner/pi-ai\";\n\nimport type { SearchResult } from \"../database\";\nimport { buildRerankPrompt, RERANK_SYSTEM_PROMPT } from \"./prompts\";\n\n/**\n * Rerank search results using LLM.\n * Takes FTS5 candidates and returns them reordered by semantic relevance.\n */\nexport async function rerankResults(\n model: Model<Api>,\n query: string,\n candidates: SearchResult[],\n topK = 10,\n): Promise<SearchResult[]> {\n if (candidates.length === 0) return [];\n if (candidates.length <= 1) return candidates.slice(0, topK);\n\n const prompt = buildRerankPrompt(\n query,\n candidates.map((c) => ({\n path: c.file.path,\n name: c.file.name,\n description: c.file.description,\n summary: c.file.summary,\n })),\n );\n\n const response = await complete(model, {\n systemPrompt: RERANK_SYSTEM_PROMPT,\n messages: [\n {\n role: \"user\",\n content: prompt,\n timestamp: Date.now(),\n },\n ],\n });\n\n const text = response.content\n .filter((block): block is TextContent => block.type === \"text\")\n .map((block) => block.text)\n .join(\"\");\n\n const rankedPaths = parseRerankResponse(text);\n\n // Build a path→result lookup\n const resultMap = new Map<string, SearchResult>();\n for (const candidate of candidates) {\n resultMap.set(candidate.file.path, candidate);\n }\n\n // Reorder by LLM ranking, then append any missing candidates at the end\n const reranked: SearchResult[] = [];\n const seen = new Set<string>();\n\n for (const filePath of rankedPaths) {\n const result = resultMap.get(filePath);\n if (result && !seen.has(filePath)) {\n reranked.push(result);\n seen.add(filePath);\n }\n }\n\n // Append candidates not mentioned by LLM (preserving original order)\n for (const candidate of candidates) {\n if (!seen.has(candidate.file.path)) {\n reranked.push(candidate);\n seen.add(candidate.file.path);\n }\n }\n\n return reranked.slice(0, topK);\n}\n\n/**\n * Parse the LLM rerank response into an array of file paths.\n */\nexport function parseRerankResponse(text: string): string[] {\n // Try to extract JSON array from response\n const jsonMatch = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n const jsonStr = jsonMatch ? jsonMatch[1].trim() : text.trim();\n\n try {\n const parsed = JSON.parse(jsonStr) as unknown;\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\n return parsed;\n }\n } catch {\n // If JSON parse fails, try line-by-line extraction\n }\n\n // Fallback: extract file paths line by line\n return jsonStr\n .split(\"\\n\")\n .map((line) =>\n line\n .replace(/^[\\d.)\\-\\s\"]+/, \"\")\n .replace(/[\",\\s]+$/, \"\")\n .trim(),\n )\n .filter((line) => line.length > 0 && (line.includes(\"/\") || line.includes(\".\")));\n}\n","import type { Api, Model } from \"@mariozechner/pi-ai\";\n\nimport type { IndexDatabase, SearchResult } from \"./database\";\nimport { rerankResults } from \"./llm/reranker\";\nimport type { FileIndex } from \"./types\";\n\nexport type { SearchResult } from \"./database\";\n\nexport function searchFiles(db: IndexDatabase, query: string, limit = 20): SearchResult[] {\n return db.searchFiles(query, limit);\n}\n\nexport async function searchFilesWithRerank(\n db: IndexDatabase,\n model: Model<Api>,\n query: string,\n topK = 10,\n): Promise<SearchResult[]> {\n // Fetch more candidates for reranking\n const candidates = db.searchFiles(query, 50);\n if (candidates.length === 0) return [];\n\n return rerankResults(model, query, candidates, topK);\n}\n\nexport function filterByLanguage(db: IndexDatabase, language: string): FileIndex[] {\n return db.getAllFiles().filter((f) => f.language === language);\n}\n\nexport function filterByPath(db: IndexDatabase, pathPattern: string): FileIndex[] {\n return db.getAllFiles().filter((f) => f.path.includes(pathPattern));\n}\n","import type { IndexDatabase } from \"./database\";\nimport { getFileHistory } from \"./git\";\nimport type { EnrichedErrorStack, EnrichedFrame, ErrorFrame } from \"./types\";\n\n/**\n * Enrich error stack frames with file descriptions, dependencies, and git history.\n *\n * For each frame, looks up the file in the kly index and augments it with:\n * - File description, summary, symbols, language (from index)\n * - importedBy / importsFrom (from dependencies table)\n * - Recent git commits (from git log)\n *\n * Frames whose files are not in the index are included with empty/default values.\n */\nexport function enrichErrorStack(\n db: IndexDatabase,\n root: string,\n frames: ErrorFrame[],\n): EnrichedErrorStack {\n const allImportedBy = new Set<string>();\n const enrichedFrames: EnrichedFrame[] = [];\n\n for (const frame of frames) {\n const fileIndex = db.getFile(frame.file);\n const importedBy = db.getDependents(frame.file);\n const importsFrom = db.getDependencies(frame.file);\n const commits = getFileHistory(root, frame.file, 5);\n\n for (const dep of importedBy) {\n allImportedBy.add(dep);\n }\n\n enrichedFrames.push({\n file: frame.file,\n line: frame.line,\n column: frame.column,\n function: frame.function,\n fileDescription: fileIndex?.description ?? \"\",\n fileSummary: fileIndex?.summary ?? \"\",\n symbols: fileIndex?.symbols ?? [],\n language: fileIndex?.language ?? \"typescript\",\n importedBy,\n importsFrom,\n lastModified: commits[0] ?? null,\n recentCommits: commits,\n });\n }\n\n return {\n frames: enrichedFrames,\n affectedFiles: allImportedBy.size,\n };\n}\n"],"x_google_ignoreList":[6,7,8,9,10,11],"mappings":"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"}