{"file":"README.md","kind":"sample","line":[5,9],"text":"codeix # start MCP server, watch for changes\ncodeix build # parse source files, write .codeindex\ncodeix serve --no-watch # serve without file watching\n","parent":"codeix"}
{"file":"README.md","kind":"sample","line":[40,46],"text":".codeindex/\n index.json # manifest: version, name, languages\n files.jsonl # one line per source file (path, lang, hash, line count)\n symbols.jsonl # one line per symbol (functions, classes, imports, with signatures)\n texts.jsonl # one line per comment, docstring, string literal\n","parent":"codeix/The `.codeindex` format"}
{"file":"README.md","kind":"sample","line":[51,56],"text":"{\"file\":\"src/main.py\",\"name\":\"os\",\"kind\":\"import\",\"line\":[1,1]}\n{\"file\":\"src/main.py\",\"name\":\"Config\",\"kind\":\"class\",\"line\":[22,45]}\n{\"file\":\"src/main.py\",\"name\":\"Config.__init__\",\"kind\":\"method\",\"line\":[23,30],\"parent\":\"Config\",\"sig\":\"def __init__(self, path: str, debug: bool = False)\"}\n{\"file\":\"src/main.py\",\"name\":\"main\",\"kind\":\"function\",\"line\":[48,60],\"sig\":\"def main(args: list[str]) -> int\"}\n","parent":"codeix/The `.codeindex` format"}
{"file":"README.md","kind":"sample","line":[123,140],"text":"# npm / npx — run without installing\nnpx codeix\n\n# pip / uvx — run without installing\nuvx codeix\n\n# Rust\ncargo install codeix\n\n# Homebrew\nbrew install codeix\n\n# Or build from source\ngit clone https://github.com/montanetech/codeix.git\ncd codeix\ncargo build --release\n","parent":"codeix/Install"}
{"file":"README.md","kind":"sample","line":[146,159],"text":"# Build the index for the current project\ncodeix build\n\n# Build from a specific directory (discovers all git repos below)\ncodeix build ~/projects\n\n# Start MCP server (default command, watches for changes)\ncodeix\n\n# Or explicitly\ncodeix serve\ncodeix serve --no-watch\n","parent":"codeix/Usage"}
{"file":"README.md","kind":"sample","line":[165,173],"text":"{\n \"mcpServers\": {\n \"codeix\": {\n \"command\": \"codeix\"\n }\n }\n}\n","parent":"codeix/Usage/MCP client configuration"}
{"file":"docs/architecture.md","kind":"sample","line":[42,48],"text":".codeindex/\n index.json # manifest: version, name, metadata\n files.jsonl # one line per source file\n symbols.jsonl # one line per symbol, sorted by file then line\n texts.jsonl # one line per comment/string/docstring\n","parent":"Codeindex — Architecture Decisions/ADR-002: Index structure — 4 files"}
{"file":"docs/architecture.md","kind":"sample","line":[51,58],"text":"{\n \"version\": \"1.0\",\n \"name\": \"my-project\",\n \"root\": \".\",\n \"languages\": [\"python\", \"typescript\"]\n}\n","parent":"Codeindex — Architecture Decisions/ADR-002: Index structure — 4 files/`index.json` — manifest"}
{"file":"docs/architecture.md","kind":"sample","line":[63,66],"text":"{\"path\":\"src/main.py\",\"lang\":\"python\",\"hash\":\"a1b2c3\",\"lines\":142}\n{\"path\":\"src/utils/helpers.py\",\"lang\":\"python\",\"hash\":\"d4e5f6\",\"lines\":87}\n","parent":"Codeindex — Architecture Decisions/ADR-002: Index structure — 4 files/`files.jsonl` — file registry"}
{"file":"docs/architecture.md","kind":"sample","line":[71,77],"text":"{\"file\":\"src/main.py\",\"name\":\"os\",\"kind\":\"import\",\"line\":[1,1]}\n{\"file\":\"src/main.py\",\"name\":\"utils.parse\",\"kind\":\"import\",\"line\":[2,2],\"alias\":\"parse\"}\n{\"file\":\"src/main.py\",\"name\":\"Config\",\"kind\":\"class\",\"line\":[22,45]}\n{\"file\":\"src/main.py\",\"name\":\"Config.__init__\",\"kind\":\"method\",\"line\":[23,30],\"parent\":\"Config\",\"sig\":\"def __init__(self, path: str, debug: bool = False)\"}\n{\"file\":\"src/main.py\",\"name\":\"main\",\"kind\":\"function\",\"line\":[48,60],\"sig\":\"def main(args: list[str]) -> int\"}\n","parent":"Codeindex — Architecture Decisions/ADR-002: Index structure — 4 files/`symbols.jsonl` — symbol index (definitions + imports)"}
{"file":"docs/architecture.md","kind":"sample","line":[86,90],"text":"{\"file\":\"src/main.py\",\"kind\":\"docstring\",\"line\":[15,18],\"text\":\"Validates user credentials against the database.\",\"parent\":\"authenticate\"}\n{\"file\":\"src/main.py\",\"kind\":\"comment\",\"line\":[45,45],\"text\":\"TODO: add rate limiting\"}\n{\"file\":\"src/main.py\",\"kind\":\"string\",\"line\":[22,22],\"text\":\"Invalid credentials for user: %s\"}\n","parent":"Codeindex — Architecture Decisions/ADR-002: Index structure — 4 files/`texts.jsonl` — comments, docstrings, string literals"}
{"file":"docs/architecture.md","kind":"sample","line":[129,134],"text":"server reads package.json → workspaces: [\"packages/*\"]\n → finds packages/core/.codeindex/\n → finds packages/ui/.codeindex/\n → mounts both automatically\n","parent":"Codeindex — Architecture Decisions/ADR-003: Index is self-contained, no dependency declarations"}
{"file":"docs/architecture.md","kind":"sample","line":[137,141],"text":"server reads pyproject.toml → dependencies\n → checks .venv/lib/.../requests/.codeindex/\n → if present, loads it\n","parent":"Codeindex — Architecture Decisions/ADR-003: Index is self-contained, no dependency declarations"}
{"file":"docs/architecture.md","kind":"sample","line":[261,269],"text":"$ codeindex serve --watch # start once, forget about it\n\n# ... edit code ...\n# .codeindex/ updates automatically\n\n$ git add -A # .codeindex/ is just another changed file\n$ git commit -m \"feat: ...\"\n","parent":"Codeindex — Architecture Decisions/ADR-007: Index stays on disk via watch mode — committed like a lockfile"}
{"file":"docs/architecture.md","kind":"sample","line":[432,436],"text":"~/myproject/ # has .git/\n src/\n .codeindex/ ← built here\n","parent":"Codeindex — Architecture Decisions/ADR-011: Project discovery — `.git/` boundaries"}
{"file":"docs/architecture.md","kind":"sample","line":[439,444],"text":"~/projects/ # no .git/\n frontend/ # has .git/ → frontend/.codeindex/\n backend/ # has .git/ → backend/.codeindex/\n shared-lib/ # has .git/ → shared-lib/.codeindex/\n","parent":"Codeindex — Architecture Decisions/ADR-011: Project discovery — `.git/` boundaries"}
{"file":"docs/architecture.md","kind":"sample","line":[447,451],"text":"~/monorepo/ # has .git/ → monorepo/.codeindex/\n vendor/libfoo/ # has .git → vendor/libfoo/.codeindex/\n vendor/libbar/ # has .git → vendor/libbar/.codeindex/\n","parent":"Codeindex — Architecture Decisions/ADR-011: Project discovery — `.git/` boundaries"}
{"file":"docs/architecture.md","kind":"sample","line":[470,477],"text":"Mount::walk(root)\n ├── WalkDir with follow_links(false) — no symlink loops\n ├── GitignoreBuilder — builds .gitignore rules incrementally during walk\n ├── SKIP_ENTRIES — always excludes .git, .codeindex, .vscode, .idea, etc.\n ├── notify watcher — watches directories discovered during walk\n └── emits MountEvent to handler (FileAdded, FileRemoved, DirAdded, DirRemoved, ProjectAdded)\n","parent":"Codeindex — Architecture Decisions/ADR-011: Project discovery — `.git/` boundaries"}
{"file":"docs/architecture.md","kind":"sample","line":[532,541],"text":"{\n \"version\": \"1.0\",\n \"name\": \"my-nuxt-app\",\n \"mcp\": {\n \"nuxt-ui\": { \"command\": \"npx nuxi-mcp\" },\n \"supabase\": { \"url\": \"https://mcp.supabase.com\" }\n }\n }\n ","parent":"Codeindex — Architecture Decisions/Future Considerations/External API documentation — two-tier model"}
{"file":"npm/install.js","kind":"string","line":[2,2],"text":"use strict"}
{"file":"npm/install.js","kind":"comment","line":[4,5],"text":"Postinstall script: downloads the prebuilt codeix binary from GitHub Releases.\nZero dependencies — uses Node.js built-in modules only."}
{"file":"npm/install.js","kind":"string","line":[18,18],"text":"x86_64-unknown-linux-gnu"}
{"file":"npm/install.js","kind":"string","line":[19,19],"text":"x86_64-pc-windows-msvc"}
{"file":"npm/install.js","kind":"string","line":[23,23],"text":"${process.platform}-${process.arch}"}
{"file":"npm/install.js","kind":"string","line":[26,26],"text":"codeix: unsupported platform ${key}"}
{"file":"npm/install.js","kind":"string","line":[27,27],"text":"Supported: ${Object.keys(PLATFORM_MAP).join(\", \")}"}
{"file":"npm/install.js","kind":"string","line":[35,35],"text":"https://github.com/${REPO}/releases/download/v${VERSION}/codeix-${target}.${ext}"}
{"file":"npm/install.js","kind":"comment","line":[41,41],"text":"Follow redirects (GitHub releases redirect to S3)"}
{"file":"npm/install.js","kind":"string","line":[46,46],"text":"HTTP ${res.statusCode} for ${url}"}
{"file":"npm/install.js","kind":"comment","line":[57,57],"text":"Write to temp file then extract with tar (available on macOS/Linux)"}
{"file":"npm/install.js","kind":"string","line":[60,60],"text":"tar xzf \"${tmpFile}\" -C \"${destDir}\""}
{"file":"npm/install.js","kind":"comment","line":[65,65],"text":"Write to temp file then extract with PowerShell (Windows)"}
{"file":"npm/install.js","kind":"string","line":[69,69],"text":"powershell -Command \"Expand-Archive -Path '${tmpFile}' -DestinationPath '${destDir}' -Force\""}
{"file":"npm/install.js","kind":"comment","line":[80,80],"text":"Skip if binary already exists (e.g. CI caching)"}
{"file":"npm/install.js","kind":"string","line":[87,87],"text":"Downloading codeix v${VERSION} for ${target}..."}
{"file":"npm/install.js","kind":"string","line":[100,100],"text":"Installed codeix to ${binPath}"}
{"file":"npm/install.js","kind":"string","line":[104,104],"text":"codeix install failed: ${err.message}"}
{"file":"npm/install.js","kind":"string","line":[105,105],"text":"You can install manually from:"}
{"file":"npm/install.js","kind":"string","line":[106,106],"text":" https://github.com/${REPO}/releases/tag/v${VERSION}"}
{"file":"npm/install.js","kind":"comment","line":[107,108],"text":"Don't fail the install — the binary just won't be available\nThis avoids breaking `npm install` in CI environments that don't need the binary"}
{"file":"npm/run.js","kind":"string","line":[2,2],"text":"use strict"}
{"file":"npm/run.js","kind":"string","line":[16,16],"text":"codeix: binary not found at ${bin}"}
{"file":"npm/run.js","kind":"string","line":[17,17],"text":"Try reinstalling: npm install -g codeix"}
{"file":"python/codeix/__init__.py","kind":"docstring","line":[1,1],"text":"codeix — Portable, composable code index."}
{"file":"python/codeix/__init__.py","kind":"string","line":[1,1],"text":"codeix — Portable, composable code index."}
{"file":"python/codeix/__init__.py","kind":"comment","line":[15,15],"text":"x-release-please-version"}
{"file":"python/codeix/__init__.py","kind":"string","line":[21,21],"text":"x86_64-unknown-linux-gnu"}
{"file":"python/codeix/__init__.py","kind":"string","line":[22,22],"text":"x86_64-pc-windows-msvc"}
{"file":"python/codeix/__init__.py","kind":"docstring","line":[27,27],"text":"Platform-appropriate cache directory.","parent":"_cache_dir"}
{"file":"python/codeix/__init__.py","kind":"string","line":[41,41],"text":"codeix: unsupported platform {key}","parent":"_get_target"}
{"file":"python/codeix/__init__.py","kind":"string","line":[42,42],"text":"Supported: {list(PLATFORM_MAP.keys())}","parent":"_get_target"}
{"file":"python/codeix/__init__.py","kind":"string","line":[48,48],"text":"codeix-python/{__version__}","parent":"_download"}
{"file":"python/codeix/__init__.py","kind":"docstring","line":[54,54],"text":"Download the binary if not cached, return its path.","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"string","line":[58,58],"text":"codeix-{__version__}{ext}","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"string","line":[64,64],"text":"https://github.com/{REPO}/releases/download/v{__version__}/codeix-{target}.{archive_ext}","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"string","line":[66,66],"text":"Downloading codeix v{__version__} for {target}...","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"string","line":[87,87],"text":"codeix: failed to extract binary from archive","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"comment","line":[90,90],"text":"Make executable on Unix","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"string","line":[94,94],"text":"Cached codeix to {bin_path}","parent":"_ensure_binary"}
{"file":"python/codeix/__init__.py","kind":"docstring","line":[99,99],"text":"Entry point: download binary if needed, then exec with forwarded args.","parent":"main"}
{"file":"python/codeix/__init__.py","kind":"string","line":[103,103],"text":"codeix: failed to download binary: {e}","parent":"main"}
{"file":"python/codeix/__init__.py","kind":"string","line":[104,104],"text":"Install manually from: https://github.com/{REPO}/releases/tag/v{__version__}","parent":"main"}
{"file":"python/codeix/__main__.py","kind":"docstring","line":[1,1],"text":"Allow running as `python -m codeix`."}
{"file":"python/codeix/__main__.py","kind":"string","line":[1,1],"text":"Allow running as `python -m codeix`."}
{"file":"scripts/bench.py","kind":"comment","line":[1,1],"text":"!/usr/bin/env python3"}
{"file":"scripts/bench.py","kind":"docstring","line":[2,14],"text":"Codeix Benchmark Suite\n\nUsage:\n python scripts/bench.py index-speed [--verbose]\n python scripts/bench.py search-quality [--question ID]\n python scripts/bench.py search-value [--question ID]\n\nCommands:\n index-speed Quantitative indexing speed benchmark\n search-quality A/B: prod codeix vs dev codeix\n search-value A/B: codeix vs raw Claude (no MCP)"}
{"file":"scripts/bench.py","kind":"string","line":[2,14],"text":"\nCodeix Benchmark Suite\n\nUsage:\n python scripts/bench.py index-speed [--verbose]\n python scripts/bench.py search-quality [--question ID]\n python scripts/bench.py search-value [--question ID]\n\nCommands:\n index-speed Quantitative indexing speed benchmark\n search-quality A/B: prod codeix vs dev codeix\n search-value A/B: codeix vs raw Claude (no MCP)\n"}
{"file":"scripts/bench/__init__.py","kind":"docstring","line":[1,1],"text":"Codeix Benchmark Suite."}
{"file":"scripts/bench/__init__.py","kind":"string","line":[1,1],"text":"Codeix Benchmark Suite."}
{"file":"scripts/bench/__main__.py","kind":"docstring","line":[1,1],"text":"Entry point for python -m scripts.bench."}
{"file":"scripts/bench/__main__.py","kind":"string","line":[1,1],"text":"Entry point for python -m scripts.bench."}
{"file":"scripts/bench/__main__.py","kind":"docstring","line":[15,15],"text":"Export benchmark results in pytest-like JSON format.","parent":"export_results"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[17,17],"text":"No results to export","parent":"export_results"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[37,37],"text":"{config_name}:{q.get('id', 'unknown')}","parent":"export_results"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[59,59],"text":"Exported {len(results)} results to {output}","parent":"export_results"}
{"file":"scripts/bench/__main__.py","kind":"docstring","line":[63,63],"text":"Extract reason from judge response.","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"comment","line":[66,66],"text":"With --json-schema, output is in structured_output","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"comment","line":[70,70],"text":"Fallback: try result field (for legacy cached responses)","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"comment","line":[75,75],"text":"Try direct JSON parse","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"comment","line":[80,80],"text":"Extract from markdown JSON block","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[82,82],"text":"r'\"reason\"\\s*:\\s*\"([^\"]+)\"'","parent":"_extract_reason"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[90,90],"text":"Codeix Benchmark Suite","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[92,106],"text":"\nCommands:\n index-speed Quantitative indexing speed benchmark\n search-quality A/B: dev codeix vs prod codeix\n search-value A/B: codeix vs raw Claude (no MCP)\n clear-cache Clear response cache\n\nExamples:\n python -m scripts.bench index-speed\n python -m scripts.bench search-quality\n python -m scripts.bench search-value\n python -m scripts.bench search-value --question entry-point\n python -m scripts.bench search-quality --export results.json\n python -m scripts.bench clear-cache\n","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[108,108],"text":"Benchmark command","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[109,109],"text":"Show detailed output","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[110,110],"text":"Run specific question by ID","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[111,111],"text":"Export results to JSON file (pytest-like format)","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[128,128],"text":"Cleared response cache: {RESPONSE_CACHE_DIR}","parent":"main"}
{"file":"scripts/bench/__main__.py","kind":"string","line":[130,130],"text":"Response cache already empty","parent":"main"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[1,1],"text":"A/B benchmark framework using claude CLI."}
{"file":"scripts/bench/ab.py","kind":"string","line":[1,1],"text":"A/B benchmark framework using claude CLI."}
{"file":"scripts/bench/ab.py","kind":"comment","line":[28,28],"text":"Max parallel questions (each runs 2 Claude calls + 1 judge)"}
{"file":"scripts/bench/ab.py","kind":"string","line":[29,29],"text":"CODEIX_BENCH_PARALLEL"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[37,40],"text":"Build a claude command with codeix MCP tools.\n\n Standardized arg order ensures cache key consistency across benchmarks.","parent":"build_codeix_cmd"}
{"file":"scripts/bench/ab.py","kind":"string","line":[43,43],"text":"--no-session-persistence","parent":"build_codeix_cmd"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[55,55],"text":"Build a raw claude command (no tools).","parent":"build_claude_cmd"}
{"file":"scripts/bench/ab.py","kind":"string","line":[58,58],"text":"--no-session-persistence","parent":"build_claude_cmd"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[65,69],"text":"Build MCP config JSON for codeix.\n\n Uses \".\" as repo path since cwd is set to the project repo.\n This makes the command line consistent across runs (for caching).","parent":"build_mcp_config"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[81,81],"text":"Build standardized prompt for codeix questions.","parent":"build_prompt"}
{"file":"scripts/bench/ab.py","kind":"string","line":[82,82],"text":"Project: {project}\\n\\n{question}\\n\\nUse the codeindex MCP tools to answer.","parent":"build_prompt"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[87,87],"text":"Configuration for A/B benchmark.","parent":"ABConfig"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[92,93],"text":"Called once at start to setup binaries, returns (bin_a, bin_b)\nbin_a/bin_b are versioned names (e.g., \"codeix-abc123\", \"codeix-0.2.0\")","parent":"ABConfig"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[95,96],"text":"Returns (cmd_a, cwd_a, cmd_b, cwd_b) for a question\ncwd is set to the project repo so paths are relative","parent":"ABConfig"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[98,98],"text":"Optional per-question setup callbacks: setup_a(question, ctx) -> bool","parent":"ABConfig"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[101,101],"text":"Extra judge output fields","parent":"ABConfig"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[106,106],"text":"Extract winner from judge response.","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[109,109],"text":"With --json-schema, output is in structured_output","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[113,113],"text":"Fallback: try result field (for legacy cached responses)","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[118,118],"text":"Try direct JSON parse","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[123,123],"text":"Extract JSON from markdown (handles nested braces better)","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"string","line":[124,124],"text":"r'\\{[^{}]*\"winner\"\\s*:\\s*\"([^\"]+)\"[^{}]*\\}'","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[127,127],"text":"Fallback: look for \"winner\": \"X\" pattern anywhere","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"string","line":[128,128],"text":"r'\"winner\"\\s*:\\s*\"([^\"]+)\"'","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[131,131],"text":"Fallback: look for \"Winner: X\" or \"**Winner**: X\" in text","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"string","line":[132,132],"text":"r'\\*?\\*?[Ww]inner\\*?\\*?\\s*:\\s*\\*?\\*?([ABab]|[Tt]ie)\\*?\\*?'","parent":"parse_judge_winner"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[139,142],"text":"Run a subprocess command without TTY (prevents terminal issues with claude).\n\n If bin_dir is provided, it's prepended to PATH so versioned binaries can be found.","parent":"run_subprocess"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[145,145],"text":"Build environment with bin_dir in PATH","parent":"run_subprocess"}
{"file":"scripts/bench/ab.py","kind":"string","line":[148,148],"text":"{bin_dir}:{env.get('PATH', '')}","parent":"run_subprocess"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[153,153],"text":"No TTY - prevents terminal issues","parent":"run_subprocess"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[158,158],"text":"Detach from controlling terminal","parent":"run_subprocess"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[180,186],"text":"Run A/B test for a single question.\n\n Cache key = command line. This works because:\n - Binary is named codeix-{version} (version embedded in filename)\n - cwd is the project repo (so paths are relative)\n - All params (--max-turns, prompt, etc.) are in the command","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[187,188],"text":"Get commands first (needed for cache keys)\nThis is cheap - just builds the command strings","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[191,191],"text":"Cache key = command line","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[198,198],"text":"If both cached, skip setup entirely","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[200,200],"text":" Cache hit: {q['id']} ({q['category']})","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[204,204],"text":"Only setup (clone + build) if we need to run","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[206,206],"text":" Setup A failed for {q['id']}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[209,209],"text":" Setup B failed for {q['id']}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[212,212],"text":"Run A and B in parallel (only if not cached)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[235,235],"text":"Save to cache","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[241,241],"text":"Helper to check for errors","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[247,247],"text":"Check for rate limit in result","parent":"run_question.has_error"}
{"file":"scripts/bench/ab.py","kind":"string","line":[249,249],"text":"hit your limit","parent":"run_question.has_error"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[251,251],"text":"is_error with non-success subtype","parent":"run_question.has_error"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[256,256],"text":"Check for errors and log them","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[260,260],"text":" A error: {error_a}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[262,262],"text":" B error: {error_b}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[264,264],"text":"Skip judging if either response has an error","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[281,281],"text":" Done: {q['id']} (skipped judge due to error)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[284,285],"text":"Judge using subprocess (with caching)\nTruncate responses for judge prompt","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[289,289],"text":"Get costs for judge evaluation","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[294,294],"text":"\\n\\nCOST:\\nA: ${cost_a:.4f}\\nB: ${cost_b:.4f}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[296,309],"text":"\"\"Compare these two responses to the question: \"{q['question']}\"\n\nRESPONSE A ({config.label_a}):\n{response_a_text}\n\nRESPONSE B ({config.label_b}):\n{response_b_text}{cost_info}\n\nEvaluate:\n1. Accuracy - Which response is more correct?\n2. Completeness - Which found more relevant information?\n3. Efficiency - Consider cost (lower is better for similar quality)\n\nOutput JSON: {{\"winner\": \"A\"|\"B\"|\"tie\", \"reason\": \"brief explanation\"{config.extra_judge_fields}}}\"\"","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[311,311],"text":"Build judge command (for cache key)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[312,312],"text":"{\"type\":\"object\",\"properties\":{\"winner\":{\"type\":\"string\",\"enum\":[\"A\",\"B\",\"tie\"]},\"reason\":{\"type\":\"string\"}},\"required\":[\"winner\",\"reason\"]}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[315,315],"text":"--no-session-persistence","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[323,323],"text":"Validate judge response contains a winner, bust cache if not","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[328,328],"text":"Valid if structured_output has winner, or result has winner (legacy)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[338,338],"text":"Run judge via subprocess (no tools needed)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[340,340],"text":"With --json-schema, output is in structured_output field","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[345,345],"text":"Debug: log when judge fails to return winner","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[347,347],"text":"Judge failed for {q['id']}: structured={structured}, error={error_text[:200] if error_text else 'none'}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[360,360],"text":"No errors if we got here (errors returned early above)","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"string","line":[366,366],"text":" Done: {q['id']}","parent":"run_question"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[375,375],"text":"Run A/B benchmark with given configuration (async). Returns results list.","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[379,379],"text":"Questions file not found: {questions_file}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[386,386],"text":"Question '{question_id}' not found","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[389,389],"text":"Create temporary run directory with standard structure","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[396,396],"text":"Running {config.name} with {len(questions)} question(s) in parallel","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[397,397],"text":"Run dir: {ctx.run_dir}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[400,401],"text":"Setup binaries (once, before running questions)\nBinaries are named with version embedded (e.g., codeix-abc123)","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[403,403],"text":"A: {config.label_a} ({bin_a})","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[404,404],"text":"B: {config.label_b} ({bin_b})","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[406,406],"text":"Create semaphore to limit parallelism","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[413,413],"text":"Run all questions with limited parallelism","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[420,420],"text":"Cancel all pending tasks","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[423,423],"text":"\\n\\nInterrupted, stopping...","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[429,429],"text":"{CYAN}═══════════════════════════════════════════════════════════════{NC}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[430,430],"text":"{CYAN}{config.title:^63}{NC}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[431,431],"text":"{CYAN}═══════════════════════════════════════════════════════════════{NC}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[433,433],"text":"Show what A and B represent","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[434,434],"text":"A: {config.label_a}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[435,435],"text":"B: {config.label_b}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[437,437],"text":"{'Question':<30} {'Winner':^8} {'A cost':>8} {'B cost':>8}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[456,456],"text":"Show errors in output","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[465,465],"text":" [{', '.join(error_parts)}]","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[467,467],"text":"{r['question']['id']:<30} {winner:^8} {cost_a:>8} {cost_b:>8}{error_info}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[469,469],"text":"Summary row","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[473,473],"text":"A:{a_wins} B:{b_wins}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[476,476],"text":"{'TOTAL':<30} {wins_summary:^8} {cost_a_str:>8} {cost_b_str:>8}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[480,480],"text":"A ({config.label_a})","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[482,482],"text":"B ({config.label_b})","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[485,485],"text":"Winner: {overall}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"comment","line":[487,487],"text":"Cache stats","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"string","line":[492,492],"text":"Cache: A={cache_hits_a}/{len(results)}, B={cache_hits_b}/{len(results)}, judge={cache_hits_judge}/{len(results)}","parent":"run_async"}
{"file":"scripts/bench/ab.py","kind":"docstring","line":[501,501],"text":"Run A/B benchmark with given configuration. Returns results list.","parent":"run"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[1,1],"text":"Common utilities for benchmark suite."}
{"file":"scripts/bench/common.py","kind":"string","line":[1,1],"text":"Common utilities for benchmark suite."}
{"file":"scripts/bench/common.py","kind":"comment","line":[12,12],"text":"Project root (codeix repo)"}
{"file":"scripts/bench/common.py","kind":"comment","line":[16,16],"text":"Cache dir: persistent across runs (only for response cache)"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[23,23],"text":"Context for a benchmark run - fresh temp directory per run.","parent":"RunContext"}
{"file":"scripts/bench/common.py","kind":"comment","line":[24,29],"text":"Root: /tmp/codeix-bench-xxxxx/\nBinaries: run_dir/bin/\nRepos: run_dir/repos/ (for single-variant benchmarks)\nRepos for A: run_dir/repos/a/ (for A/B benchmarks)\nRepos for B: run_dir/repos/b/ (for A/B benchmarks)\nResults: run_dir/results/","parent":"RunContext"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[33,33],"text":"Create a fresh temporary run directory with standard structure.","parent":"create_run_context"}
{"file":"scripts/bench/common.py","kind":"comment","line":[61,61],"text":"Small repos"}
{"file":"scripts/bench/common.py","kind":"string","line":[62,62],"text":"https://github.com/colinhacks/zod"}
{"file":"scripts/bench/common.py","kind":"string","line":[62,62],"text":"Validation library"}
{"file":"scripts/bench/common.py","kind":"string","line":[63,63],"text":"https://github.com/gin-gonic/gin"}
{"file":"scripts/bench/common.py","kind":"string","line":[63,63],"text":"HTTP framework"}
{"file":"scripts/bench/common.py","kind":"string","line":[64,64],"text":"https://github.com/google/leveldb"}
{"file":"scripts/bench/common.py","kind":"string","line":[64,64],"text":"KV store, has submodules"}
{"file":"scripts/bench/common.py","kind":"comment","line":[65,65],"text":"Medium repos"}
{"file":"scripts/bench/common.py","kind":"string","line":[66,66],"text":"https://github.com/tokio-rs/tokio"}
{"file":"scripts/bench/common.py","kind":"string","line":[66,66],"text":"Async runtime"}
{"file":"scripts/bench/common.py","kind":"string","line":[67,67],"text":"https://github.com/pallets/flask"}
{"file":"scripts/bench/common.py","kind":"string","line":[67,67],"text":"Web micro-framework"}
{"file":"scripts/bench/common.py","kind":"string","line":[68,68],"text":"FizzBuzzEnterpriseEdition"}
{"file":"scripts/bench/common.py","kind":"string","line":[68,68],"text":"https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition"}
{"file":"scripts/bench/common.py","kind":"string","line":[68,68],"text":"Satirical over-engineering"}
{"file":"scripts/bench/common.py","kind":"string","line":[69,69],"text":"https://github.com/jedisct1/libsodium"}
{"file":"scripts/bench/common.py","kind":"string","line":[69,69],"text":"Crypto library"}
{"file":"scripts/bench/common.py","kind":"string","line":[70,70],"text":"https://github.com/faker-ruby/faker"}
{"file":"scripts/bench/common.py","kind":"string","line":[70,70],"text":"Data generation"}
{"file":"scripts/bench/common.py","kind":"string","line":[71,71],"text":"https://github.com/JamesNK/Newtonsoft.Json"}
{"file":"scripts/bench/common.py","kind":"string","line":[71,71],"text":"JSON library"}
{"file":"scripts/bench/common.py","kind":"comment","line":[72,72],"text":"Zig repo"}
{"file":"scripts/bench/common.py","kind":"string","line":[73,73],"text":"https://github.com/zigtools/zls"}
{"file":"scripts/bench/common.py","kind":"string","line":[73,73],"text":"Zig Language Server"}
{"file":"scripts/bench/common.py","kind":"string","line":[86,86],"text":"{BLUE}[bench]{NC} {msg}","parent":"log"}
{"file":"scripts/bench/common.py","kind":"string","line":[90,90],"text":"{GREEN}[bench]{NC} {msg}","parent":"log_success"}
{"file":"scripts/bench/common.py","kind":"string","line":[94,94],"text":"{RED}[bench]{NC} {msg}","parent":"log_error"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[98,98],"text":"Get path to local build, or None if not found.","parent":"get_local_codeix"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[106,106],"text":"Get codeix binary: CODEIX_BIN env var or local build. No PATH fallback.","parent":"get_codeix_bin"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[114,114],"text":"Get a short relative path for display.","parent":"get_short_path"}
{"file":"scripts/bench/common.py","kind":"comment","line":[116,116],"text":"Try relative to PROJECT_ROOT","parent":"get_short_path"}
{"file":"scripts/bench/common.py","kind":"comment","line":[121,121],"text":"Try relative to cwd","parent":"get_short_path"}
{"file":"scripts/bench/common.py","kind":"comment","line":[126,126],"text":"Just the filename","parent":"get_short_path"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[131,134],"text":"Build .codeindex for a single repo using the specified codeix binary.\n\n Returns True if index exists (already built or successfully built).","parent":"build_index"}
{"file":"scripts/bench/common.py","kind":"comment","line":[139,139],"text":"Build command: either direct binary or npx","parent":"build_index"}
{"file":"scripts/bench/common.py","kind":"string","line":[145,145],"text":"Building index: {repo_path.name}...","parent":"build_index"}
{"file":"scripts/bench/common.py","kind":"string","line":[148,148],"text":" Failed to build index: {result.stderr[:200]}","parent":"build_index"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[154,154],"text":"Clone a repo to a specific destination.","parent":"clone_repo_to"}
{"file":"scripts/bench/common.py","kind":"string","line":[159,159],"text":"Cloning {repo.name} to {dest.name}...","parent":"clone_repo_to"}
{"file":"scripts/bench/common.py","kind":"string","line":[171,171],"text":"Failed to clone {repo.name}","parent":"clone_repo_to"}
{"file":"scripts/bench/common.py","kind":"comment","line":[174,174],"text":"Shallow submodules if present","parent":"clone_repo_to"}
{"file":"scripts/bench/common.py","kind":"string","line":[177,177],"text":" Submodules: {repo.name}...","parent":"clone_repo_to"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[188,188],"text":"Get a Repo by name.","parent":"get_repo_by_name"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[196,196],"text":"Count files in repo, excluding common build dirs.","parent":"count_files"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[206,206],"text":"Count lines of code in common source files.","parent":"count_lines"}
{"file":"scripts/bench/common.py","kind":"comment","line":[219,221],"text":"============================================================================\nResponse Cache\n============================================================================"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[224,224],"text":"Get version string for a binary file (hash of contents).","parent":"get_binary_version"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[231,231],"text":"Get version of codeix from npm registry.","parent":"get_npm_codeix_version"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[247,247],"text":"Get version of claude CLI.","parent":"get_claude_version"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[263,269],"text":"Generate cache key from command line.\n\n The command line IS the cache key. This works because:\n - Binary is named codeix-{version} (version embedded in filename)\n - cwd is the project repo (so paths are relative)\n - All params (--max-turns, prompt, etc.) are in the command","parent":"get_cache_key_from_cmd"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[275,279],"text":"Get cached response if exists and is valid.\n\n Accepts error responses (they'll be busted when the error is fixed).\n Only rejects truly invalid cache (corrupted JSON, missing response).","parent":"get_cached_response"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[295,295],"text":"Delete a cached response.","parent":"delete_cached_response"}
{"file":"scripts/bench/common.py","kind":"docstring","line":[302,302],"text":"Save response to cache.","parent":"save_cached_response"}
{"file":"scripts/bench/index_speed.py","kind":"docstring","line":[1,1],"text":"Quantitative indexing speed benchmark."}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[1,1],"text":"Quantitative indexing speed benchmark."}
{"file":"scripts/bench/index_speed.py","kind":"docstring","line":[27,27],"text":"Benchmark indexing a single repo.","parent":"benchmark_repo"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[30,30],"text":"Directory not found: {path}","parent":"benchmark_repo"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[36,36],"text":"Clean existing index","parent":"benchmark_repo"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[50,50],"text":"Failed to index {repo.name}","parent":"benchmark_repo"}
{"file":"scripts/bench/index_speed.py","kind":"docstring","line":[68,68],"text":"Run quantitative indexing benchmark.","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[70,70],"text":"{CYAN}╔══════════════════════════════════════════════════════════════════════════════════════════════════╗{NC}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[71,71],"text":"{CYAN}║ CODEIX BENCHMARK ║{NC}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[72,72],"text":"{CYAN}╚══════════════════════════════════════════════════════════════════════════════════════════════════╝{NC}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[75,75],"text":"Check codeix - local build or CODEIX_BIN only","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[78,78],"text":"codeix not found (build with 'cargo build --release' or set CODEIX_BIN)","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[80,80],"text":"Using codeix: {codeix_bin}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[82,82],"text":"Create fresh run context","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[84,84],"text":"Run dir: {ctx.run_dir}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[90,90],"text":"Copy codeix binary to run dir for reproducibility","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[96,96],"text":"Clone phase","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[98,98],"text":"Phase 1: Cloning repositories...","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[106,106],"text":"Cloning complete in {clone_duration:.1f}s","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"comment","line":[108,108],"text":"Benchmark phase","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[110,110],"text":"Phase 2: Benchmarking indexing...","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[114,114],"text":"{'Repository':<18} │ {'Language':<10} │ {'Size':<7} │ {'Files':>6} │ {'Lines':>8} │ {'Time':>7} │ {'Speed':>8} │ Notes","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[115,115],"text":"───────────────────┼────────────┼─────────┼────────┼──────────┼─────────┼──────────┼─────────────────────────","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[123,125],"text":"{result['name']:<18} │ {result['lang']:<10} │ {result['size']:<7} │ \"\n f\"{result['files']:>6} │ {result['lines']:>8} │ {result['duration']:>6.2f}s │ \"\n f\"{result['files_per_sec']:>6}/s │ {result['notes']}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[128,128],"text":"{repo.name:<18} │ {repo.lang:<10} │ {repo.size:<7} │ {'FAILED':>6} │ {'-':>8} │ {'-':>7} │ {'-':>8} │ {repo.notes}","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[131,131],"text":"Benchmark complete!","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[133,133],"text":"{CYAN}Languages tested:{NC} TypeScript, Go, C++, Rust, Python, Java, C, Ruby, Zig","parent":"run"}
{"file":"scripts/bench/index_speed.py","kind":"string","line":[134,134],"text":"{CYAN}Structural tests:{NC} Small/Medium/Large repos, with/without submodules, polyglot","parent":"run"}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[1,1],"text":"Search quality benchmark: dev codeix vs prod codeix."}
{"file":"scripts/bench/search_quality.py","kind":"string","line":[1,1],"text":"Search quality benchmark: dev codeix vs prod codeix."}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[25,25],"text":"Run A/B: dev codeix vs prod codeix. Returns results list.","parent":"run"}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[28,33],"text":"Setup binaries in run dir, return (bin_a, bin_b).\n\n Binaries are named with version embedded for cache key stability:\n - codeix-{hash} for local dev build\n - codeix-{version} for npm package","parent":"run.setup_run"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[34,34],"text":"A: copy local dev binary with version in name","parent":"run.setup_run"}
{"file":"scripts/bench/search_quality.py","kind":"string","line":[37,37],"text":"No local codeix build found. Run 'cargo build --release' first.","parent":"run.setup_run"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[43,43],"text":"B: wrapper script for npx codeix, with version in name","parent":"run.setup_run"}
{"file":"scripts/bench/search_quality.py","kind":"string","line":[46,46],"text":"#!/bin/sh\\nexec npx codeix \\\"$@\\\"\\n","parent":"run.setup_run"}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[52,52],"text":"Clone repo and build index for A.","parent":"run.setup_a"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[59,59],"text":"Find the versioned binary (there's only one codeix-* in bin_dir for A)","parent":"run.setup_a"}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[64,64],"text":"Clone repo and build index for B.","parent":"run.setup_b"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[71,71],"text":"Find the versioned binary for B (the npm version one)","parent":"run.setup_b"}
{"file":"scripts/bench/search_quality.py","kind":"docstring","line":[77,82],"text":"Generate commands for A and B.\n\n Returns (cmd_a, cwd_a, cmd_b, cwd_b).\n cwd is set to project repo so paths are relative (for cache key stability).\n Binary paths use just the versioned name (e.g., \"codeix-abc123\") for stable cache keys.","parent":"run.get_commands"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[83,83],"text":"Find versioned binaries - use just the name, not full path","parent":"run.get_commands"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[88,88],"text":"Use just the binary name - we'll set PATH to include bin_dir","parent":"run.get_commands"}
{"file":"scripts/bench/search_quality.py","kind":"comment","line":[96,96],"text":"MCP config uses versioned binary name (PATH will be set to find it)","parent":"run.get_commands"}
{"file":"scripts/bench/search_quality.py","kind":"string","line":[103,103],"text":"search-quality benchmark","parent":"run"}
{"file":"scripts/bench/search_quality.py","kind":"string","line":[106,106],"text":"SEARCH QUALITY BENCHMARK","parent":"run"}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[1,1],"text":"Search value benchmark: codeix vs raw Claude."}
{"file":"scripts/bench/search_value.py","kind":"string","line":[1,1],"text":"Search value benchmark: codeix vs raw Claude."}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[26,26],"text":"Run A/B: codeix vs raw Claude. Returns results list.","parent":"run"}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[29,34],"text":"Setup binaries in run dir, return (bin_a, bin_b).\n\n Binaries are named with version embedded for cache key stability:\n - codeix-{hash} for local dev build\n - claude (version injected in prompt for B)","parent":"run.setup_run"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[35,35],"text":"A: copy local dev binary with version in name","parent":"run.setup_run"}
{"file":"scripts/bench/search_value.py","kind":"string","line":[38,38],"text":"No local codeix build found. Run 'cargo build --release' first.","parent":"run.setup_run"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[44,44],"text":"B: raw Claude (version will be injected in prompt)","parent":"run.setup_run"}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[50,50],"text":"Clone repo and build index for A.","parent":"run.setup_a"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[57,57],"text":"Find the versioned binary","parent":"run.setup_a"}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[64,64],"text":"Clone repo for B (raw Claude needs files to read).","parent":"run.setup_b"}
{"file":"scripts/bench/search_value.py","kind":"docstring","line":[72,76],"text":"Generate commands for A and B.\n\n Returns (cmd_a, cwd_a, cmd_b, cwd_b).\n cwd is set to project repo so paths are relative (for cache key stability).","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[77,77],"text":"Find versioned binaries","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[82,82],"text":"Use just the binary name - PATH will include bin_dir","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[89,89],"text":"MCP config uses versioned binary name (PATH will be set to find it)","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"comment","line":[91,91],"text":"B: inject claude version in prompt for cache busting","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"string","line":[92,92],"text":"[claude:{version_b}] {q['question']}","parent":"run.get_commands"}
{"file":"scripts/bench/search_value.py","kind":"string","line":[98,98],"text":"search-value benchmark","parent":"run"}
{"file":"scripts/bench/search_value.py","kind":"string","line":[101,101],"text":"CODEIX VALUE BENCHMARK","parent":"run"}
{"file":"scripts/bench/search_value.py","kind":"string","line":[106,106],"text":", \"codeix_value\": \"high|medium|low|none\"","parent":"run"}
{"file":"site/templates/index.html","kind":"string","line":[1256,1256],"text":"0px 0px -40px 0px"}
{"file":"site/templates/index.html","kind":"comment","line":[1262,1262],"text":"Sticky header: show after scrolling past the hero"}
{"file":"site/templates/spec.html","kind":"string","line":[471,471],"text":".spec-nav a[href^=\"#\"]"}
{"file":"site/templates/spec.html","kind":"string","line":[489,489],"text":"-20% 0px -60% 0px"}
{"file":"spec/codeindex.md","kind":"sample","line":[20,26],"text":".codeindex/\n index.json # manifest (required)\n files.jsonl # file registry (required)\n symbols.jsonl # symbol index (required, may be empty)\n texts.jsonl # text content index (required, may be empty)\n","parent":"`.codeindex` Format Specification/Directory layout"}
{"file":"spec/codeindex.md","kind":"sample","line":[42,49],"text":"{\n \"version\": \"1.0\",\n \"name\": \"my-project\",\n \"root\": \".\",\n \"languages\": [\"python\", \"typescript\"]\n}\n","parent":"`.codeindex` Format Specification/`index.json` — manifest"}
{"file":"spec/codeindex.md","kind":"sample","line":[66,70],"text":"{\"path\":\"src/main.py\",\"lang\":\"python\",\"hash\":\"a1b2c3d4e5f6a7b8\",\"lines\":142}\n{\"path\":\"src/utils/helpers.py\",\"lang\":\"python\",\"hash\":\"b2c3d4e5f6a7b8c9\",\"lines\":87}\n{\"path\":\"pytest.ini\",\"lang\":null,\"hash\":\"c3d4e5f6a7b8c9d0\",\"lines\":12}\n","parent":"`.codeindex` Format Specification/`files.jsonl` — file registry"}
{"file":"spec/codeindex.md","kind":"sample","line":[97,103],"text":"{\"file\":\"src/main.py\",\"name\":\"os\",\"kind\":\"import\",\"line\":[1,1]}\n{\"file\":\"src/main.py\",\"name\":\"utils.parse\",\"kind\":\"import\",\"line\":[2,2],\"alias\":\"parse\"}\n{\"file\":\"src/main.py\",\"name\":\"Config\",\"kind\":\"class\",\"line\":[22,45]}\n{\"file\":\"src/main.py\",\"name\":\"Config.__init__\",\"kind\":\"method\",\"line\":[23,30],\"parent\":\"Config\",\"sig\":\"def __init__(self, path: str, debug: bool = False)\"}\n{\"file\":\"src/main.py\",\"name\":\"main\",\"kind\":\"function\",\"line\":[48,60],\"sig\":\"def main(args: list[str]) -> int\"}\n","parent":"`.codeindex` Format Specification/`symbols.jsonl` — symbol index"}
{"file":"spec/codeindex.md","kind":"sample","line":[146,150],"text":"{\"file\":\"src/app.py\",\"name\":\"App\",\"kind\":\"class\",\"line\":[10,50]}\n{\"file\":\"src/app.py\",\"name\":\"App.__init__\",\"kind\":\"method\",\"line\":[11,15],\"parent\":\"App\",\"sig\":\"def __init__(self)\"}\n{\"file\":\"src/app.py\",\"name\":\"App.run\",\"kind\":\"method\",\"line\":[17,50],\"parent\":\"App\",\"sig\":\"def run(self) -> None\"}\n","parent":"`.codeindex` Format Specification/`symbols.jsonl` — symbol index/Nesting"}
{"file":"spec/codeindex.md","kind":"sample","line":[166,170],"text":"{\"file\":\"src/lib.rs\",\"name\":\"Client\",\"kind\":\"struct\",\"line\":[10,50],\"visibility\":\"public\"}\n{\"file\":\"src/lib.rs\",\"name\":\"Client.connect\",\"kind\":\"method\",\"line\":[12,25],\"parent\":\"Client\",\"visibility\":\"public\",\"sig\":\"pub fn connect(&self, url: &str) -> Result<()>\"}\n{\"file\":\"src/lib.rs\",\"name\":\"Client.retry_internal\",\"kind\":\"method\",\"line\":[27,40],\"parent\":\"Client\",\"visibility\":\"private\",\"sig\":\"fn retry_internal(&self, attempts: u32)\"}\n","parent":"`.codeindex` Format Specification/`symbols.jsonl` — symbol index/Visibility"}
{"file":"spec/codeindex.md","kind":"sample","line":[180,184],"text":"{\"file\":\"src/main.py\",\"kind\":\"docstring\",\"line\":[15,18],\"text\":\"Validates user credentials against the database.\",\"parent\":\"authenticate\"}\n{\"file\":\"src/main.py\",\"kind\":\"comment\",\"line\":[45,45],\"text\":\"TODO: add rate limiting\"}\n{\"file\":\"src/main.py\",\"kind\":\"string\",\"line\":[22,22],\"text\":\"Invalid credentials for user: %s\"}\n","parent":"`.codeindex` Format Specification/`texts.jsonl` — text content index"}
{"file":"spec/codeindex.md","kind":"sample","line":[258,264],"text":"my-project/\n .git/\n .codeindex/ # committed with the code\n src/\n package.json\n","parent":"`.codeindex` Format Specification/Distribution/Git repository (primary)"}
{"file":"spec/codeindex.md","kind":"sample","line":[284,287],"text":"https://example.com/.well-known/codeindex/index.json\nhttps://example.com/.well-known/codeindex/symbols.jsonl\n","parent":"`.codeindex` Format Specification/Distribution/HTTP discovery (future)"}
{"file":"spec/codeindex.md","kind":"sample","line":[292,294],"text":"https://raw.githubusercontent.com/org/repo/main/.codeindex/symbols.jsonl\n","parent":"`.codeindex` Format Specification/Distribution/HTTP discovery (future)"}
{"file":"spec/codeindex.md","kind":"sample","line":[314,318],"text":"{\"file\":\"api/users.py\",\"name\":\"GET /users\",\"kind\":\"endpoint\",\"line\":[15,30],\"sig\":\"GET /users?page=int&limit=int -> UserList\"}\n{\"file\":\"schema.graphql\",\"name\":\"Query.user\",\"kind\":\"query\",\"line\":[5,8],\"sig\":\"user(id: ID!): User\"}\n{\"file\":\"proto/service.proto\",\"name\":\"UserService.GetUser\",\"kind\":\"rpc\",\"line\":[12,14],\"sig\":\"GetUser(GetUserRequest) returns (User)\"}\n","parent":"`.codeindex` Format Specification/Scope and visibility/Remote APIs (future)"}
{"file":"src/cli/build.rs","kind":"docstring","line":[12,12],"text":"Result type for build_index_to_db: (MountTable, SearchDb)"}
{"file":"src/cli/build.rs","kind":"docstring","line":[15,16],"text":"Build the index into a database without flushing to disk.\nReturns MountTable + SearchDb for both build (flush to disk) and serve (keep in memory)."}
{"file":"src/cli/build.rs","kind":"docstring","line":[18,21],"text":"Uses `on_project_discovery` which:\n1. If load_from_cache=true: loads from .codeindex/ if it exists\n2. Otherwise indexes files (stopping at subproject boundaries)\n3. Recursively handles discovered subprojects"}
{"file":"src/cli/build.rs","kind":"docstring","line":[24,29],"text":"- `enable_fts`: If true, creates FTS5 tables for search (serve mode).\nIf false, skips FTS to reduce memory on large repos (build mode).\n- `load_from_cache`: If true (serve), try loading from .codeindex/ first.\nIf false (build), always re-index.\n- `tx`: If provided, initializes notify watchers during walk so directories\nare watched immediately (single walk strategy for serve --watch)."}
{"file":"src/cli/build.rs","kind":"string","line":[38,38],"text":"cannot resolve path: {}"}
{"file":"src/cli/build.rs","kind":"string","line":[40,40],"text":"building index at {}"}
{"file":"src/cli/build.rs","kind":"comment","line":[42,42],"text":"Create mount table and database"}
{"file":"src/cli/build.rs","kind":"string","line":[45,45],"text":"failed to create search database"}
{"file":"src/cli/build.rs","kind":"string","line":[47,47],"text":"failed to create search database"}
{"file":"src/cli/build.rs","kind":"comment","line":[50,51],"text":"Process root project (will recursively discover and handle subprojects)\nPass load_from_cache and tx (for notify watchers during walk, if provided)"}
{"file":"src/cli/build.rs","kind":"string","line":[52,52],"text":"failed to process root project"}
{"file":"src/cli/build.rs","kind":"docstring","line":[57,58],"text":"Build the index: scan the directory tree, parse files with tree-sitter,\nand write the `.codeindex/` output."}
{"file":"src/cli/build.rs","kind":"docstring","line":[60,61],"text":"Discovers .git/ boundaries and creates separate .codeindex/ for each\nproject found. Root is always treated as a project (with or without .git/)."}
{"file":"src/cli/build.rs","kind":"comment","line":[63,65],"text":"Build mode: disable FTS to reduce memory on large repos\nload_from_cache=false: always re-index (ignore .codeindex/)\ntx=None: no watcher"}
{"file":"src/cli/build.rs","kind":"comment","line":[68,68],"text":"Flush each dirty mount to disk"}
{"file":"src/cli/build.rs","kind":"string","line":[71,71],"text":"mount table lock poisoned: {e}"}
{"file":"src/cli/build.rs","kind":"string","line":[80,80],"text":"failed to flush index to disk for {}"}
{"file":"src/cli/build.rs","kind":"comment","line":[82,82],"text":"Get stats for this mount (use relative project path)"}
{"file":"src/cli/build.rs","kind":"string","line":[86,86],"text":"db lock poisoned: {e}"}
{"file":"src/cli/build.rs","kind":"string","line":[96,96],"text":"wrote .codeindex/ for '{}': {} files, {} symbols, {} texts"}
{"file":"src/cli/build.rs","kind":"string","line":[110,110],"text":"total: {} files, {} symbols, {} texts"}
{"file":"src/cli/build.rs","kind":"docstring","line":[117,118],"text":"Run the `build` subcommand: scan the directory tree, parse files with\ntree-sitter, and write the `.codeindex/` output."}
{"file":"src/cli/serve.rs","kind":"docstring","line":[12,13],"text":"Run the `serve` subcommand: load the index into an in-memory SQLite FTS5\ndatabase and start the MCP server over stdio."}
{"file":"src/cli/serve.rs","kind":"string","line":[17,17],"text":"cannot resolve path: {}"}
{"file":"src/cli/serve.rs","kind":"comment","line":[19,21],"text":"If watch mode: create channel BEFORE building\nThis way directories are watched during the single walk (no second walk needed)\nChannel carries (mount_root, event) tuples for direct mount lookup"}
{"file":"src/cli/serve.rs","kind":"string","line":[23,23],"text":"starting watch mode"}
{"file":"src/cli/serve.rs","kind":"comment","line":[30,33],"text":"Build index with FTS enabled (loads from .codeindex/ if exists, otherwise parses files)\nServe mode needs FTS for search functionality\nload_from_cache=true: load from .codeindex/ if available\nPass tx to initialize notify watchers during walk (single walk strategy)"}
{"file":"src/cli/serve.rs","kind":"string","line":[35,35],"text":"failed to build/load index"}
{"file":"src/cli/serve.rs","kind":"comment","line":[37,37],"text":"Flush any dirty mounts to disk (projects that were indexed, not loaded)"}
{"file":"src/cli/serve.rs","kind":"string","line":[41,41],"text":"mount table lock poisoned: {e}"}
{"file":"src/cli/serve.rs","kind":"string","line":[45,45],"text":"failed to flush {}"}
{"file":"src/cli/serve.rs","kind":"comment","line":[50,51],"text":"Spawn event loop AFTER build (needs mount_table and db)\nBut notify watchers are already initialized and watching during build"}
{"file":"src/cli/serve.rs","kind":"string","line":[58,58],"text":"event loop error: {}"}
{"file":"src/cli/serve.rs","kind":"comment","line":[63,63],"text":"Start the tokio runtime"}
{"file":"src/cli/serve.rs","kind":"string","line":[64,64],"text":"failed to create tokio runtime"}
{"file":"src/cli/serve.rs","kind":"string","line":[67,67],"text":"starting MCP server on stdio"}
{"file":"src/index/format.rs","kind":"docstring","line":[3,3],"text":"`index.json` manifest — top-level metadata for a `.codeindex/` directory."}
{"file":"src/index/format.rs","kind":"docstring","line":[12,12],"text":"One line in `files.jsonl` — metadata for a single indexed file."}
{"file":"src/index/format.rs","kind":"docstring","line":[21,21],"text":"File title extracted from the source (e.g., first heading, module doc)."}
{"file":"src/index/format.rs","kind":"docstring","line":[24,24],"text":"File description extracted from the source (e.g., docstring, frontmatter)."}
{"file":"src/index/format.rs","kind":"docstring","line":[29,29],"text":"One line in `symbols.jsonl` — a symbol extracted from the AST."}
{"file":"src/index/format.rs","kind":"docstring","line":[48,48],"text":"One line in `texts.jsonl` — a text block (docstring, comment, etc.)."}
{"file":"src/index/format.rs","kind":"docstring","line":[61,61],"text":"One line in `references.jsonl` — a reference to a symbol (call, import, type, etc.)."}
{"file":"src/index/format.rs","kind":"docstring","line":[64,64],"text":"File containing this reference"}
{"file":"src/index/format.rs","kind":"docstring","line":[66,66],"text":"Symbol being referenced (e.g. \"os.path.join\", \"MyClass\", \"fetch\")"}
{"file":"src/index/format.rs","kind":"docstring","line":[68,68],"text":"Kind of reference: \"call\", \"import\", \"type_annotation\", \"instantiation\", \"definition\""}
{"file":"src/index/format.rs","kind":"docstring","line":[70,70],"text":"Line range [start, end] where this reference appears (1-based)"}
{"file":"src/index/format.rs","kind":"docstring","line":[72,72],"text":"Optional: enclosing symbol where this reference appears (e.g. \"MyClass.method\")"}
{"file":"src/index/format.rs","kind":"docstring","line":[75,75],"text":"Project path (relative from workspace root, empty for root project)"}
{"file":"src/index/reader.rs","kind":"docstring","line":[9,9],"text":"Convenience alias for the tuple returned by `read_index`."}
{"file":"src/index/reader.rs","kind":"docstring","line":[18,19],"text":"Read an existing `.codeindex/` directory from disk.\nReturns the manifest, files, symbols, texts, and references."}
{"file":"src/index/reader.rs","kind":"string","line":[23,23],"text":"failed to read index.json"}
{"file":"src/index/reader.rs","kind":"string","line":[24,24],"text":"failed to parse index.json"}
{"file":"src/index/reader.rs","kind":"string","line":[27,27],"text":"failed to read files.jsonl"}
{"file":"src/index/reader.rs","kind":"string","line":[30,30],"text":"failed to read symbols.jsonl"}
{"file":"src/index/reader.rs","kind":"string","line":[32,32],"text":"failed to read texts.jsonl"}
{"file":"src/index/reader.rs","kind":"comment","line":[34,34],"text":"References are optional for backward compatibility with older indexes"}
{"file":"src/index/reader.rs","kind":"docstring","line":[40,40],"text":"Read a JSONL file into a Vec of deserialized items."}
{"file":"src/index/reader.rs","kind":"string","line":[52,52],"text":"failed to parse line {} of {}"}
{"file":"src/index/writer.rs","kind":"docstring","line":[9,9],"text":"Write a complete `.codeindex/` directory to disk."}
{"file":"src/index/writer.rs","kind":"docstring","line":[11,13],"text":"Note: Data is expected to be pre-sorted from the database export\n(files by path, symbols/texts by file then line). This avoids\nmemory-intensive copies for large repositories."}
{"file":"src/index/writer.rs","kind":"comment","line":[22,22],"text":"Create the output directory"}
{"file":"src/index/writer.rs","kind":"comment","line":[25,25],"text":"Write index.json (pretty-printed)"}
{"file":"src/index/writer.rs","kind":"comment","line":[30,30],"text":"Write JSONL files directly - data is pre-sorted from DB export"}
{"file":"src/index/writer.rs","kind":"docstring","line":[39,39],"text":"Write a slice of serializable items as JSONL (one JSON object per line)."}
{"file":"src/lib.rs","kind":"string","line":[21,21],"text":"target/.rustc_info.json"}
{"file":"src/lib.rs","kind":"comment","line":[23,23],"text":"matched() - what handler.rs uses"}
{"file":"src/lib.rs","kind":"comment","line":[25,25],"text":"matched_path_or_any_parents() - checks parent dirs too"}
{"file":"src/lib.rs","kind":"string","line":[28,28],"text":"matched: {:?}"}
{"file":"src/lib.rs","kind":"string","line":[29,29],"text":"matched_path_or_any_parents: {:?}"}
{"file":"src/lib.rs","kind":"string","line":[33,33],"text":"target/ files should be ignored via matched_path_or_any_parents"}
{"file":"src/main.rs","kind":"string","line":[10,10],"text":"Portable, composable code index\\n\\nhttps://codeix.dev"}
{"file":"src/main.rs","kind":"docstring","line":[19,19],"text":"Build the .codeindex/ for discovered projects"}
{"file":"src/main.rs","kind":"docstring","line":[21,21],"text":"Root directory to scan (defaults to current dir)"}
{"file":"src/main.rs","kind":"docstring","line":[25,25],"text":"Start the MCP server (default when no subcommand given)"}
{"file":"src/main.rs","kind":"docstring","line":[27,27],"text":"Root directory (defaults to current dir)"}
{"file":"src/main.rs","kind":"docstring","line":[30,30],"text":"Disable file watching"}
{"file":"src/main.rs","kind":"comment","line":[45,45],"text":"Interactive: no subcommand given, print help and exit"}
{"file":"src/main.rs","kind":"comment","line":[49,49],"text":"Piped stdin (e.g. MCP client): default to serve"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[13,14],"text":"Built-in gitignore patterns (always applied).\nThese are either internal directories, IDE config, or OS cruft."}
{"file":"src/mount/mod.rs","kind":"comment","line":[16,16],"text":"Git internals (but .git itself is used for project detection)"}
{"file":"src/mount/mod.rs","kind":"comment","line":[18,18],"text":"Our own output"}
{"file":"src/mount/mod.rs","kind":"comment","line":[20,20],"text":"Editor/IDE directories"}
{"file":"src/mount/mod.rs","kind":"comment","line":[24,24],"text":"OS cruft"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[30,30],"text":"Mount mode determines whether the index can be written to."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[33,33],"text":"Read-write: acquires exclusive flock, allows modifications."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[35,35],"text":"Read-only: no lock, index data is immutable."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[39,40],"text":"Check if an EventKind represents a removal operation.\nUsed to determine if we can canonicalize the path (removed files can't be canonicalized)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[48,49],"text":"Filesystem events emitted to external consumers (handler/DB).\nThese are the result of processing raw notify events through mount rules."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[52,52],"text":"A file was discovered or modified."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[54,54],"text":"Absolute path to the mount root."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[56,56],"text":"Path relative to mount root."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[59,59],"text":"A file was deleted."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[61,61],"text":"Absolute path to the mount root."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[63,63],"text":"Path relative to mount root."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[66,66],"text":"A subproject (.git/ directory) was discovered."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[68,68],"text":"Absolute path to the subproject root (parent of .git/)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[73,73],"text":"Event with mount identity attached (avoids lookup in handler)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[76,76],"text":"A single mounted directory with its index."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[78,78],"text":"Root directory of the mount."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[80,80],"text":"Mount mode (read-write or read-only)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[82,82],"text":"File lock handle (only present for ReadWrite mounts)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[84,84],"text":"Whether the index has been modified and needs flushing."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[86,87],"text":"Gitignore rules for this mount (built during walk, used by watcher).\nNone until walk() is called."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[89,89],"text":"All gitignore files discovered (for rebuilding when new ones are added)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[91,91],"text":"File system watcher (only present for ReadWrite mounts)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[93,93],"text":"Directories currently being watched."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[109,109],"text":"Create a new read-only mount (no lock, no watcher).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[125,126],"text":"Create a new read-write mount with exclusive flock.\nDoes NOT start notify - call `init_notify()` separately.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[165,165],"text":"Initialize gitignore with .git/info/exclude and root .gitignore.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[184,184],"text":"Build gitignore from all tracked files plus built-in patterns.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[207,207],"text":"Handle a filesystem event (from walker or notify).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[209,213],"text":"This is the central handler that applies ALL rules:\n- Gitignore filtering\n- Project detection (.git/)\n- .gitignore file updates\n- Watch management","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[215,217],"text":"Takes notify's `EventKind` directly - both walker and notify use the same type.\nReturns an external event if this should be forwarded to consumers.\nReturns None for event types we don't care about.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[333,333],"text":"Add a .gitignore file to the rules.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[343,343],"text":"Remove watch for a directory.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[352,352],"text":"Walk all files in this mount, emitting events via callback.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[354,355],"text":"This is a dumb walker - it just iterates and calls on_fs_event for each entry.\nAll the smart logic (gitignore, skip entries, project detection) is in on_fs_event.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[357,357],"text":"After walk completes, the built gitignore is stored for use by the watcher.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[418,418],"text":"Initialize the notify file system watcher for this mount.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[420,421],"text":"Must be called BEFORE walk() so that DirCreated events can add directories.\nDoes nothing for read-only mounts.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[423,424],"text":"Events are sent to the provided channel with mount root attached,\navoiding the need for mount lookup in the handler.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[447,447],"text":"Watch a directory (non-recursive).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[461,461],"text":"Get the number of watched directories.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[466,466],"text":"Check if a path should be ignored according to gitignore rules.","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[468,468],"text":"Returns false if gitignore hasn't been built yet (walk() not called).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[478,478],"text":"Get a reference to the gitignore matcher (if built).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[483,483],"text":"Mark this mount as dirty (needs flushing).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[488,488],"text":"Clear the dirty flag (after flushing).","parent":"Mount"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[503,503],"text":"Table of mounted directories."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[506,506],"text":"Root of the workspace (where codeix was launched)."}
{"file":"src/mount/mod.rs","kind":"docstring","line":[512,512],"text":"Create a new mount table with the given workspace root.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[520,520],"text":"Get the workspace root.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[525,526],"text":"Compute the relative project path from workspace root.\nReturns empty string for the root project.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[534,535],"text":"Get the absolute path for a relative project path.\nReturns None if the project is not mounted.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[551,551],"text":"Check if a path is already mounted (exact match, not prefix).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[556,556],"text":"Mount a directory, trying RW first, falling back to RO if lock is held.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[558,558],"text":"Returns the mount and its mode. Use this when you want best-effort RW.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[591,591],"text":"Mount a directory in read-write mode (acquires exclusive lock).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[607,607],"text":"Mount a directory in read-only mode (no lock).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[623,624],"text":"Find the mount that contains a given path (longest prefix match).\nCanonicalizes the path first to handle symlinks.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[630,632],"text":"Find the mount that contains a given path (longest prefix match).\nAssumes the path is already canonical - use for hot paths to avoid\nrepeated canonicalization overhead.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[641,642],"text":"Find the mount that contains a given path (mutable, longest prefix match).\nCanonicalizes the path first to handle symlinks.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[651,653],"text":"Find the mount that contains a given path (mutable, longest prefix match).\nAssumes the path is already canonical - use for hot paths to avoid\nrepeated canonicalization overhead.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[666,666],"text":"Unmount a directory (releases lock if held).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[679,679],"text":"Iterate over all mounts.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[684,684],"text":"Iterate over all mounts (mutable).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[689,689],"text":"Mark a path's mount as dirty.","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"docstring","line":[699,699],"text":"Mark a path's mount as dirty (assumes path is already canonical).","parent":"MountTable"}
{"file":"src/mount/mod.rs","kind":"comment","line":[725,725],"text":".codeindex/index.json should exist"}
{"file":"src/mount/mod.rs","kind":"string","line":[726,726],"text":".codeindex/index.json"}
{"file":"src/mount/mod.rs","kind":"comment","line":[749,749],"text":"File in subdir should match subdir mount"}
{"file":"src/mount/mod.rs","kind":"comment","line":[759,759],"text":"File in root should match root mount"}
{"file":"src/mount/mod.rs","kind":"comment","line":[810,810],"text":"Create .gitignore"}
{"file":"src/mount/mod.rs","kind":"comment","line":[813,813],"text":"Create files"}
{"file":"src/mount/mod.rs","kind":"string","line":[815,815],"text":"fn main() {}"}
{"file":"src/mount/mod.rs","kind":"comment","line":[825,825],"text":"Collect walked files"}
{"file":"src/mount/mod.rs","kind":"comment","line":[836,836],"text":"Should include src/main.rs"}
{"file":"src/mount/mod.rs","kind":"comment","line":[839,839],"text":"Should NOT include ignored files"}
{"file":"src/mount/mod.rs","kind":"comment","line":[846,847],"text":"Issue #36: symlinks in node_modules caused CPU spin\nVerify that follow_links(false) prevents infinite loops"}
{"file":"src/mount/mod.rs","kind":"comment","line":[850,850],"text":"Create a directory structure with symlinks"}
{"file":"src/mount/mod.rs","kind":"comment","line":[854,854],"text":"Create a symlink pointing to parent (would cause infinite loop if followed)"}
{"file":"src/mount/mod.rs","kind":"comment","line":[858,858],"text":"Symlink to parent directory"}
{"file":"src/mount/mod.rs","kind":"comment","line":[860,860],"text":"Symlink to self"}
{"file":"src/mount/mod.rs","kind":"comment","line":[873,873],"text":"Walk should complete without hanging (symlinks not followed)"}
{"file":"src/mount/mod.rs","kind":"comment","line":[884,884],"text":"Should find the real file"}
{"file":"src/mount/mod.rs","kind":"comment","line":[887,887],"text":"Should NOT have followed symlinks (no duplicates or infinite recursion)"}
{"file":"src/mount/mod.rs","kind":"comment","line":[896,896],"text":"Verify walk adds watches internally (no DirAdded events emitted)"}
{"file":"src/mount/mod.rs","kind":"string","line":[902,902],"text":"fn main() {}"}
{"file":"src/mount/mod.rs","kind":"string","line":[903,903],"text":"src/components/button.rs"}
{"file":"src/mount/mod.rs","kind":"string","line":[903,903],"text":"// button"}
{"file":"src/mount/mod.rs","kind":"comment","line":[906,906],"text":"RW to get watcher"}
{"file":"src/mount/mod.rs","kind":"comment","line":[910,910],"text":"Init watcher"}
{"file":"src/mount/mod.rs","kind":"comment","line":[926,926],"text":"Should have files"}
{"file":"src/mount/mod.rs","kind":"comment","line":[929,930],"text":"Should have watches registered internally\nroot, src, components, tests"}
{"file":"src/mount/mod.rs","kind":"comment","line":[935,935],"text":"Verify gitignore is available immediately after mounting"}
{"file":"src/mount/mod.rs","kind":"comment","line":[937,937],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/mount/mod.rs","kind":"string","line":[942,942],"text":"fn main() {}"}
{"file":"src/mount/mod.rs","kind":"comment","line":[949,949],"text":"Gitignore is built during mount creation"}
{"file":"src/mount/mod.rs","kind":"comment","line":[952,952],"text":"Can use is_ignored() for watcher filtering"}
{"file":"src/mount/mod.rs","kind":"comment","line":[960,960],"text":"Verify nested .gitignore files are respected"}
{"file":"src/mount/mod.rs","kind":"comment","line":[963,963],"text":"Root .gitignore"}
{"file":"src/mount/mod.rs","kind":"comment","line":[966,966],"text":"Nested directory with its own .gitignore"}
{"file":"src/mount/mod.rs","kind":"comment","line":[970,970],"text":"Create files"}
{"file":"src/mount/mod.rs","kind":"string","line":[972,972],"text":"// code"}
{"file":"src/mount/mod.rs","kind":"string","line":[975,975],"text":"subdir/local_ignore/secret.txt"}
{"file":"src/mount/mod.rs","kind":"comment","line":[992,992],"text":"Should include code.rs"}
{"file":"src/mount/mod.rs","kind":"comment","line":[995,995],"text":"Should NOT include .log files (from root .gitignore)"}
{"file":"src/mount/mod.rs","kind":"comment","line":[998,998],"text":"Should NOT include local_ignore/ (from nested .gitignore)"}
{"file":"src/parser/c_lang.rs","kind":"docstring","line":[1,1],"text":"C symbol and text extraction."}
{"file":"src/parser/c_lang.rs","kind":"docstring","line":[9,9],"text":"C-specific stopwords (keywords, common types, etc.)"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[21,21],"text":"Primitive types"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[30,30],"text":"Common standard types"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[35,35],"text":"Common macros and constants"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[38,38],"text":"Common variable patterns"}
{"file":"src/parser/c_lang.rs","kind":"docstring","line":[48,48],"text":"Filter C-specific stopwords from extracted tokens."}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[54,54],"text":"Filter uppercase constants"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[85,85],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[162,162],"text":"Check for static (file-scoped)"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[168,168],"text":"Extract tokens from function body"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[192,193],"text":"Top-level declarations: variables, function prototypes, extern declarations\nSkip if inside a function body (we only want top-level)"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[205,205],"text":"Walk declarators"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[210,210],"text":"Function prototype"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[215,215],"text":"Prototypes don't have a body, so no tokens"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[289,289],"text":"Anonymous struct/union, skip symbol but recurse for comments"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[313,313],"text":"Extract fields"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[373,373],"text":"Extract enum constants"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[401,401],"text":"The typedef name is typically the last declarator"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[426,426],"text":"Strip < > or \" \""}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[476,476],"text":"*name — recurse into the declarator"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[487,487],"text":"parenthesized_declarator"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[488,488],"text":"(name) — look inside"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[505,505],"text":"storage_class_specifier"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[524,524],"text":"symbol not found: {name}"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[529,535],"text":"int add(int a, int b) {\n return a + b;\n}\n\nstatic void helper() {\n printf(\\\"helper\\\");\n}"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[540,540],"text":"Token extraction is enabled (may be None if body has no tokens after filtering)"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[549,552],"text":"struct Point {\n int x;\n int y;\n};"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[568,572],"text":"enum Status {\n OK,\n ERROR,\n PENDING\n};"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[588,592],"text":"typedef int MyInt;\n\nint add(MyInt a, MyInt b) {\n return a + b;\n}"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[595,595],"text":"Function should definitely be extracted"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[602,606],"text":"int global = 100;\nstatic int file_scoped = 200;\nextern int external;\n\n#define MAX_SIZE 1000"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[622,623],"text":"#include <stdio.h>\n#include \\\"myheader.h\\\""}
{"file":"src/parser/c_lang.rs","kind":"string","line":[635,636],"text":"#define PI 3.14159\n#define MAX(a, b) ((a) > (b) ? (a) : (b))"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[648,652],"text":"union Data {\n int i;\n float f;\n char str[20];\n};"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[656,656],"text":"unions mapped to struct"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[664,666],"text":"/* Block comment */\n// Single line comment\nint foo() { return 0; }"}
{"file":"src/parser/c_lang.rs","kind":"string","line":[673,674],"text":"int add(int a, int b);\nextern void print(const char* msg);"}
{"file":"src/parser/c_lang.rs","kind":"comment","line":[679,679],"text":"Prototypes don't have bodies, so no tokens"}
{"file":"src/parser/cpp.rs","kind":"docstring","line":[1,1],"text":"C++ symbol and text extraction."}
{"file":"src/parser/cpp.rs","kind":"docstring","line":[3,3],"text":"Extends C extraction with classes, namespaces, templates, and access specifiers."}
{"file":"src/parser/cpp.rs","kind":"docstring","line":[11,11],"text":"C++-specific stopwords (C keywords + C++ keywords, types, etc.)"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[13,13],"text":"C keywords"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[23,23],"text":"C++ keywords"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[43,43],"text":"Primitive types"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[53,53],"text":"STL common"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[67,67],"text":"Common patterns"}
{"file":"src/parser/cpp.rs","kind":"docstring","line":[78,78],"text":"Filter C++-specific stopwords from extracted tokens."}
{"file":"src/parser/cpp.rs","kind":"comment","line":[84,84],"text":"Filter uppercase constants"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[117,117],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[158,158],"text":"Recurse into the templated declaration"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[178,178],"text":"`using Foo = ...;`"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[261,261],"text":"Extract tokens from function body"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[286,286],"text":"Skip declarations inside function bodies"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[323,323],"text":"Declarations don't have bodies"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[440,440],"text":"Walk class body with access tracking"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[442,442],"text":"Default access: private for class, public for struct"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[514,514],"text":"Extract enum values"}
{"file":"src/parser/cpp.rs","kind":"string","line":[526,526],"text":"{full_name}.{const_name}"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[552,552],"text":"Anonymous namespace"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[675,675],"text":"`using namespace std;` or `using std::string;`"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[752,752],"text":"namespace::name — use the full qualified name"}
{"file":"src/parser/cpp.rs","kind":"string","line":[764,764],"text":"parenthesized_declarator"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[775,775],"text":"operator+, operator<< etc."}
{"file":"src/parser/cpp.rs","kind":"string","line":[785,785],"text":"storage_class_specifier"}
{"file":"src/parser/cpp.rs","kind":"string","line":[804,804],"text":"symbol not found: {name}"}
{"file":"src/parser/cpp.rs","kind":"string","line":[809,815],"text":"int add(int a, int b) {\n return a + b;\n}\n\nstatic void helper() {\n std::cout << \\\"helper\\\";\n}"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[820,820],"text":"Token extraction is enabled (may be None if body has no tokens after filtering)"}
{"file":"src/parser/cpp.rs","kind":"string","line":[829,842],"text":"class Person {\npublic:\n Person(std::string name) {}\n\n std::string getName() const {\n return name;\n }\n\nprivate:\n void privateMethod() {}\n\nprotected:\n void helper() {}\n};"}
{"file":"src/parser/cpp.rs","kind":"string","line":[861,867],"text":"struct Point {\n void setX(int value) {}\n void setY(int value) {}\n\nprivate:\n void hidden() {}\n};"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[874,874],"text":"struct default"}
{"file":"src/parser/cpp.rs","kind":"string","line":[882,889],"text":"namespace utils {\n void helper() {}\n\n class Tool {\n public:\n void run() {}\n };\n}"}
{"file":"src/parser/cpp.rs","kind":"string","line":[907,916],"text":"enum Color {\n RED,\n GREEN,\n BLUE\n};\n\nenum class Status {\n OK,\n ERROR\n};"}
{"file":"src/parser/cpp.rs","kind":"string","line":[931,940],"text":"template<typename T>\nclass Container {\npublic:\n void add(T item) {}\n};\n\ntemplate<typename T>\nT max(T a, T b) {\n return (a > b) ? a : b;\n}"}
{"file":"src/parser/cpp.rs","kind":"string","line":[955,957],"text":"using namespace std;\nusing std::string;\nusing MyInt = int;"}
{"file":"src/parser/cpp.rs","kind":"string","line":[962,962],"text":"namespace std"}
{"file":"src/parser/cpp.rs","kind":"string","line":[975,976],"text":"#include <iostream>\n#include \\\"myheader.h\\\""}
{"file":"src/parser/cpp.rs","kind":"string","line":[988,990],"text":"namespace MyNamespace {\n void helper() {}\n}"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[993,993],"text":"Named namespace should be extracted"}
{"file":"src/parser/cpp.rs","kind":"comment","line":[998,998],"text":"Functions inside namespaces might be classified as methods"}
{"file":"src/parser/cpp.rs","kind":"string","line":[1004,1006],"text":"/* Block comment */\n// Single line comment\nclass Foo {};"}
{"file":"src/parser/csharp.rs","kind":"docstring","line":[1,1],"text":"C# symbol and text extraction."}
{"file":"src/parser/csharp.rs","kind":"docstring","line":[9,9],"text":"C#-specific stopwords (keywords, common types, etc.)"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[41,41],"text":"Primitive types"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[56,56],"text":"Common framework types"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[74,74],"text":"Common variable patterns"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[81,81],"text":"Test framework (NUnit, xUnit, MSTest) - lowercase for comparison"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[91,91],"text":"Common methods - lowercase for comparison"}
{"file":"src/parser/csharp.rs","kind":"docstring","line":[100,100],"text":"Filter C#-specific stopwords from extracted tokens."}
{"file":"src/parser/csharp.rs","kind":"comment","line":[106,106],"text":"Filter uppercase constants"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[137,137],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/csharp.rs","kind":"string","line":[157,157],"text":"interface_declaration"}
{"file":"src/parser/csharp.rs","kind":"string","line":[179,179],"text":"namespace_declaration"}
{"file":"src/parser/csharp.rs","kind":"string","line":[179,179],"text":"file_scoped_namespace_declaration"}
{"file":"src/parser/csharp.rs","kind":"string","line":[186,186],"text":"constructor_declaration"}
{"file":"src/parser/csharp.rs","kind":"string","line":[206,206],"text":"verbatim_string_literal"}
{"file":"src/parser/csharp.rs","kind":"string","line":[207,207],"text":"interpolated_string_expression"}
{"file":"src/parser/csharp.rs","kind":"string","line":[258,258],"text":" : {}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[261,261],"text":"{kind} {name}{type_params}{bases}"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[269,269],"text":"Extract tokens from type body"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[285,285],"text":"Walk body"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[335,335],"text":"Extract enum members"}
{"file":"src/parser/csharp.rs","kind":"string","line":[339,339],"text":"enum_member_declaration"}
{"file":"src/parser/csharp.rs","kind":"string","line":[347,347],"text":"{full_name}.{member_name}"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[394,394],"text":"Walk namespace body"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[410,410],"text":"File-scoped namespace: declarations are siblings, not children of body"}
{"file":"src/parser/csharp.rs","kind":"string","line":[411,411],"text":"file_scoped_namespace_declaration"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[412,412],"text":"Walk all siblings after this node"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[459,459],"text":"Extract tokens from method body"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[498,498],"text":"Extract tokens from constructor body"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[569,569],"text":"Walk variable declarators"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[635,635],"text":"Delegates don't have bodies"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[644,644],"text":"`using System.Linq;` or `using Foo = System.Bar;`"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[663,663],"text":"`using Alias = Namespace.Type;`"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[666,666],"text":"The actual type is the next sibling"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[702,702],"text":"XML doc comment"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[754,754],"text":"Check for modifiers list pattern (some tree-sitter versions)"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[765,765],"text":"C# default"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[778,778],"text":"Fallback: check the raw text"}
{"file":"src/parser/csharp.rs","kind":"string","line":[792,792],"text":"symbol not found: {name}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[797,812],"text":"public class Person\n{\n private string name;\n\n public Person(string name)\n {\n this.name = name;\n }\n\n public string GetName()\n {\n return name;\n }\n\n private void Helper() {}\n}"}
{"file":"src/parser/csharp.rs","kind":"comment","line":[818,819],"text":"Token extraction extracts identifiers from class body\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/csharp.rs","kind":"string","line":[835,839],"text":"public interface IRunnable\n{\n void Run();\n int Calculate(int x);\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[849,853],"text":"public struct Point\n{\n public int X;\n public int Y;\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[866,871],"text":"public enum Status\n{\n Active,\n Inactive,\n Pending\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[884,890],"text":"namespace MyApp.Utils\n{\n public class Helper\n {\n public void Run() {}\n }\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[900,900],"text":"MyApp.Utils.Helper.Run"}
{"file":"src/parser/csharp.rs","kind":"string","line":[906,910],"text":"public class Config\n{\n public string Name { get; set; }\n private int version;\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[924,928],"text":"public class Constants\n{\n public const int MAX_SIZE = 100;\n private static readonly string Version = \\\"1.0\\\";\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[942,944],"text":"using System;\nusing System.Collections.Generic;\nusing System.Linq;"}
{"file":"src/parser/csharp.rs","kind":"string","line":[952,952],"text":"System.Collections.Generic"}
{"file":"src/parser/csharp.rs","kind":"string","line":[962,962],"text":"public delegate void EventHandler(object sender);"}
{"file":"src/parser/csharp.rs","kind":"string","line":[972,978],"text":"public class Foo\n{\n public void PublicMethod() {}\n private void PrivateMethod() {}\n protected void ProtectedMethod() {}\n internal void InternalMethod() {}\n}"}
{"file":"src/parser/csharp.rs","kind":"string","line":[996,1002],"text":"/// <summary>\n/// XML doc comment\n/// </summary>\npublic class Documented {}\n\n// Single line\n/* Block comment */"}
{"file":"src/parser/go.rs","kind":"docstring","line":[1,1],"text":"Go symbol and text extraction."}
{"file":"src/parser/go.rs","kind":"comment","line":[29,29],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/go.rs","kind":"comment","line":[45,45],"text":"handled recursively"}
{"file":"src/parser/go.rs","kind":"string","line":[64,64],"text":"interpreted_string_literal"}
{"file":"src/parser/go.rs","kind":"comment","line":[95,95],"text":"Extract tokens from function body for FTS"}
{"file":"src/parser/go.rs","kind":"comment","line":[119,119],"text":"Extract receiver type: `func (r *Receiver) Method()`"}
{"file":"src/parser/go.rs","kind":"comment","line":[122,123],"text":"The receiver is a parameter_list with one entry\nTry to extract the type name"}
{"file":"src/parser/go.rs","kind":"comment","line":[125,125],"text":"Strip parens and pointer/reference"}
{"file":"src/parser/go.rs","kind":"comment","line":[138,138],"text":"Extract tokens from method body for FTS"}
{"file":"src/parser/go.rs","kind":"comment","line":[175,175],"text":"`type (...)` block or `type Foo ...`"}
{"file":"src/parser/go.rs","kind":"comment","line":[201,201],"text":"Determine kind from the type definition"}
{"file":"src/parser/go.rs","kind":"comment","line":[222,222],"text":"For structs, extract fields"}
{"file":"src/parser/go.rs","kind":"string","line":[229,229],"text":"field_declaration_list"}
{"file":"src/parser/go.rs","kind":"comment","line":[252,252],"text":"Extract comments inside struct"}
{"file":"src/parser/go.rs","kind":"comment","line":[258,258],"text":"For interfaces, extract method signatures"}
{"file":"src/parser/go.rs","kind":"comment","line":[316,316],"text":"Handle multiple names in one spec: `var a, b, c int`"}
{"file":"src/parser/go.rs","kind":"comment","line":[320,320],"text":"First identifier is captured by field \"name\", subsequent ones need manual check"}
{"file":"src/parser/go.rs","kind":"comment","line":[325,325],"text":"already captured"}
{"file":"src/parser/go.rs","kind":"comment","line":[373,373],"text":"Also handle single import: `import \"fmt\"`"}
{"file":"src/parser/go.rs","kind":"docstring","line":[443,443],"text":"Go-specific stopwords to filter from tokens."}
{"file":"src/parser/go.rs","kind":"comment","line":[445,445],"text":"Keywords and builtins"}
{"file":"src/parser/go.rs","kind":"comment","line":[461,461],"text":"Common short names"}
{"file":"src/parser/go.rs","kind":"comment","line":[481,481],"text":"Test framework"}
{"file":"src/parser/go.rs","kind":"docstring","line":[485,485],"text":"Filter Go-specific tokens from the extracted token string."}
{"file":"src/parser/go.rs","kind":"string","line":[503,503],"text":"symbol not found: {name}"}
{"file":"src/parser/go.rs","kind":"string","line":[508,516],"text":"package main\n\nfunc Hello(name string) string {\n return \\\"Hello, \\\" + name\n}\n\nfunc privateHelper() {\n println(\\\"private\\\")\n}"}
{"file":"src/parser/go.rs","kind":"comment","line":[521,522],"text":"Tokens contain identifiers from function body\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/go.rs","kind":"string","line":[531,541],"text":"package main\n\ntype Person struct {\n Name string\n}\n\nfunc (p *Person) Greet() string {\n return \\\"Hello, \\\" + p.Name\n}\n\nfunc (p Person) privateMethod() {}"}
{"file":"src/parser/go.rs","kind":"string","line":[558,564],"text":"package main\n\ntype Point struct {\n X int\n Y int\n z int\n}"}
{"file":"src/parser/go.rs","kind":"string","line":[580,585],"text":"package main\n\ntype Reader interface {\n Read() (int, error)\n close()\n}"}
{"file":"src/parser/go.rs","kind":"comment","line":[592,594],"text":"Interface methods may or may not be extracted depending on implementation\nJust verify the interface itself is extracted correctly\nat least package + interface"}
{"file":"src/parser/go.rs","kind":"string","line":[599,605],"text":"package main\n\nvar GlobalVar = 100\nvar privateVar = 200\n\nconst MaxSize = 1000\nconst minSize = 10"}
{"file":"src/parser/go.rs","kind":"string","line":[622,628],"text":"package main\n\nimport \\\"fmt\\\"\nimport (\n \\\"os\\\"\n io \\\"io/ioutil\\\"\n)"}
{"file":"src/parser/go.rs","kind":"string","line":[643,646],"text":"package main\n\ntype UserID int\ntype Handler func(string) error"}
{"file":"src/parser/go.rs","kind":"string","line":[658,660],"text":"package mypackage\n\nfunc Foo() {}"}
{"file":"src/parser/go.rs","kind":"string","line":[669,674],"text":"package main\n\n// Single line comment\nfunc Helper() {}\n\n/* Block comment */"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[1,1],"text":"Shared helpers for tree-sitter extraction across all languages."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[8,11],"text":"Universal stopwords filtered from token extraction.\nThese appear across most programming languages.\nLanguage-specific stopwords are handled in each parser.\nSingle-char identifiers are also filtered (< 2 chars)."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[13,13],"text":"Placeholder/example names"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[20,20],"text":"Test assertions"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[27,27],"text":"Control flow (9 languages)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[38,38],"text":"Common keywords (7+ languages)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[44,44],"text":"OOP keywords (5+ languages)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[55,55],"text":"Exception handling (5+ languages)"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[62,62],"text":"Get the text content of a tree-sitter node."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[69,69],"text":"Get the 1-based [start, end] line range for a node."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[71,71],"text":"tree-sitter is 0-based"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[73,74],"text":"When end_position().column == 0, the node ends at the start of the next line\n(e.g. line_comment includes trailing \\n), so the actual end line is the previous row."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[76,76],"text":"don't add 1, since it's actually the previous line"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[83,83],"text":"Find a child node by its field name."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[88,88],"text":"Check if a text string is too trivial to index."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[94,94],"text":"Skip whitespace-only strings"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[98,99],"text":"Skip short strings that look like code identifiers rather than prose.\nProse typically contains spaces or is substantially longer."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[106,106],"text":"Collapse multiple whitespace characters into single spaces."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[124,124],"text":"Strip `///` or `//!` prefix from each line of a doc comment."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[143,143],"text":"Strip `/* */` delimiters and leading `*` from block comments."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[166,166],"text":"Strip surrounding quotes from string literals."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[168,168],"text":"Triple-quoted strings (Python, etc.)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[175,175],"text":"Template literals (JS/TS)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[179,179],"text":"Raw strings: r\"...\" or r#\"...\"#"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[188,188],"text":"Byte strings: b\"...\""}
{"file":"src/parser/helpers.rs","kind":"comment","line":[193,193],"text":"F-strings: f\"...\" (Python)"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[211,211],"text":"Extract a comment node as a TextEntry (generic for C-style comments)."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[237,237],"text":"Hash-style comments (Python, Ruby, etc.)"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[258,258],"text":"Extract a string literal node as a TextEntry."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[284,284],"text":"Push a symbol entry (convenience builder)."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[310,311],"text":"Extract a function/method signature: everything from start to opening `{` or `:`.\nCollapses whitespace."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[329,329],"text":"Extract identifier tokens from a tree-sitter node for FTS indexing."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[331,333],"text":"Recursively walks the AST to collect all identifier nodes, filters by\nlength (>= 2 chars) and universal stopwords, then returns as a\nspace-separated string."}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[335,335],"text":"Language parsers can apply additional filtering on the result."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[344,344],"text":"Filter stopwords, short tokens, and invalid identifiers"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[348,348],"text":"Must be valid identifier (alphanumeric + underscore, not starting with digit)"}
{"file":"src/parser/helpers.rs","kind":"docstring","line":[364,364],"text":"Recursively collect identifier text from AST nodes."}
{"file":"src/parser/helpers.rs","kind":"comment","line":[366,366],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[371,371],"text":"Collect identifier nodes (tree-sitter uses \"identifier\" for most languages)"}
{"file":"src/parser/helpers.rs","kind":"comment","line":[377,377],"text":"Recurse into children"}
{"file":"src/parser/java.rs","kind":"docstring","line":[1,1],"text":"Java symbol and text extraction."}
{"file":"src/parser/java.rs","kind":"docstring","line":[9,9],"text":"Java-specific stopwords (keywords and common patterns)"}
{"file":"src/parser/java.rs","kind":"comment","line":[28,28],"text":"Primitive types"}
{"file":"src/parser/java.rs","kind":"comment","line":[37,37],"text":"Common class names (typically imported)"}
{"file":"src/parser/java.rs","kind":"comment","line":[56,56],"text":"Common variable patterns"}
{"file":"src/parser/java.rs","kind":"docstring","line":[61,61],"text":"Filter Java-specific stopwords from extracted tokens."}
{"file":"src/parser/java.rs","kind":"comment","line":[67,67],"text":"Also filter out uppercase-only tokens (likely type names)"}
{"file":"src/parser/java.rs","kind":"comment","line":[98,98],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/java.rs","kind":"string","line":[112,112],"text":"interface_declaration"}
{"file":"src/parser/java.rs","kind":"string","line":[131,131],"text":"annotation_type_declaration"}
{"file":"src/parser/java.rs","kind":"string","line":[153,153],"text":"constructor_declaration"}
{"file":"src/parser/java.rs","kind":"comment","line":[210,210],"text":"Build signature"}
{"file":"src/parser/java.rs","kind":"comment","line":[219,219],"text":"Extract tokens from class body"}
{"file":"src/parser/java.rs","kind":"comment","line":[235,235],"text":"Walk class body"}
{"file":"src/parser/java.rs","kind":"comment","line":[274,274],"text":"Extract tokens from method body"}
{"file":"src/parser/java.rs","kind":"comment","line":[313,313],"text":"Extract tokens from constructor body"}
{"file":"src/parser/java.rs","kind":"comment","line":[340,340],"text":"Check for static final → constant"}
{"file":"src/parser/java.rs","kind":"comment","line":[350,350],"text":"Find declarators"}
{"file":"src/parser/java.rs","kind":"comment","line":[382,382],"text":"Get the import path"}
{"file":"src/parser/java.rs","kind":"comment","line":[447,447],"text":"package-private (no explicit modifier)"}
{"file":"src/parser/java.rs","kind":"comment","line":[451,451],"text":"default: package-private"}
{"file":"src/parser/java.rs","kind":"string","line":[471,471],"text":" extends {}"}
{"file":"src/parser/java.rs","kind":"string","line":[475,475],"text":" implements {}"}
{"file":"src/parser/java.rs","kind":"string","line":[478,478],"text":"{kind} {name}{type_params}{extends}{implements}"}
{"file":"src/parser/java.rs","kind":"string","line":[490,490],"text":"symbol not found: {name}"}
{"file":"src/parser/java.rs","kind":"string","line":[495,507],"text":"public class Person {\n private String name;\n\n public Person(String name) {\n this.name = name;\n }\n\n public String getName() {\n return name;\n }\n\n private void helper() {}\n}"}
{"file":"src/parser/java.rs","kind":"comment","line":[513,514],"text":"Token extraction extracts identifiers from class body\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/java.rs","kind":"string","line":[533,536],"text":"public interface Runnable {\n void run();\n default void start() {}\n}"}
{"file":"src/parser/java.rs","kind":"string","line":[546,550],"text":"public enum Status {\n ACTIVE,\n INACTIVE,\n PENDING\n}"}
{"file":"src/parser/java.rs","kind":"string","line":[560,564],"text":"class Config {\n public static final int MAX_SIZE = 100;\n private int value;\n protected String name;\n}"}
{"file":"src/parser/java.rs","kind":"string","line":[581,591],"text":"class Calculator {\n public int add(int a, int b) {\n return a + b;\n }\n\n protected double divide(double x, double y) {\n return x / y;\n }\n\n private void log(String msg) {}\n}"}
{"file":"src/parser/java.rs","kind":"string","line":[607,609],"text":"import java.util.List;\nimport java.util.*;\nimport java.io.File;"}
{"file":"src/parser/java.rs","kind":"comment","line":[612,612],"text":"Check at least one import is extracted"}
{"file":"src/parser/java.rs","kind":"comment","line":[616,616],"text":"Check if we have any java.util imports"}
{"file":"src/parser/java.rs","kind":"string","line":[625,627],"text":"package com.example.app;\n\nclass Foo {}"}
{"file":"src/parser/java.rs","kind":"string","line":[636,638],"text":"class Foo {\n void packagePrivate() {}\n}"}
{"file":"src/parser/java.rs","kind":"comment","line":[642,642],"text":"default = package-private"}
{"file":"src/parser/java.rs","kind":"string","line":[650,654],"text":"/** Javadoc comment */\nclass Documented {}\n\n// Single line\n/* Block comment */"}
{"file":"src/parser/javascript.rs","kind":"docstring","line":[1,1],"text":"JavaScript symbol and text extraction."}
{"file":"src/parser/javascript.rs","kind":"docstring","line":[9,9],"text":"JavaScript-specific stopwords (common variable names, keywords, etc.)"}
{"file":"src/parser/javascript.rs","kind":"docstring","line":[43,43],"text":"Filter JavaScript-specific stopwords from extracted tokens."}
{"file":"src/parser/javascript.rs","kind":"comment","line":[78,78],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/javascript.rs","kind":"string","line":[89,89],"text":"generator_function_declaration"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[94,94],"text":"handled recursively"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[103,103],"text":"Recurse into the exported declaration"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[132,132],"text":"Recurse into children"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[184,184],"text":"Extract tokens from function body"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[227,227],"text":"Build class signature with extends"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[236,236],"text":"Extract tokens from class body (for class-level properties/static blocks)"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[252,252],"text":"Walk class body"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[283,283],"text":"Check for static/get/set/async modifiers"}
{"file":"src/parser/javascript.rs","kind":"string","line":[328,328],"text":"{prefix}{name}{params}"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[344,344],"text":"Extract tokens from method body"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[380,380],"text":"Determine if const"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[387,387],"text":"Walk declarators"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[395,395],"text":"Only index simple identifiers, not destructuring patterns"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[401,401],"text":"Check if the value is a function/arrow function"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[431,431],"text":"Extract tokens from variable value (for arrow functions etc.)"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[453,453],"text":"Get the source module"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[468,468],"text":"Default import: `import foo from \"...\"`"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[484,484],"text":"`import { foo, bar as baz } from \"...\"`"}
{"file":"src/parser/javascript.rs","kind":"string","line":[494,494],"text":"{source_module}.{imp_name}"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[511,511],"text":"`import * as foo from \"...\"`"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[514,514],"text":"In some grammars, the identifier is a direct child"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[552,552],"text":"JSDoc comment"}
{"file":"src/parser/javascript.rs","kind":"string","line":[586,586],"text":"generator_function_declaration"}
{"file":"src/parser/javascript.rs","kind":"string","line":[589,589],"text":"async function*"}
{"file":"src/parser/javascript.rs","kind":"string","line":[590,590],"text":"async function"}
{"file":"src/parser/javascript.rs","kind":"string","line":[595,595],"text":"{prefix} {name}{params}"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[599,599],"text":"Check for extends clause"}
{"file":"src/parser/javascript.rs","kind":"string","line":[612,612],"text":"class {name}{extends}"}
{"file":"src/parser/javascript.rs","kind":"string","line":[624,624],"text":"symbol not found: {name}"}
{"file":"src/parser/javascript.rs","kind":"string","line":[629,639],"text":"function hello(name) {\n return `Hello, ${name}!`;\n}\n\nasync function fetchData() {\n return await fetch('/api');\n}\n\nfunction* generator() {\n yield 1;\n}"}
{"file":"src/parser/javascript.rs","kind":"comment","line":[645,645],"text":"Token extraction is enabled (may be None if body has no tokens after filtering)"}
{"file":"src/parser/javascript.rs","kind":"string","line":[657,673],"text":"export class Person {\n constructor(name) {\n this.name = name;\n }\n\n greet() {\n return `Hi, ${this.name}`;\n }\n\n static create() {\n return new Person('default');\n }\n\n get fullName() {\n return this.name;\n }\n}"}
{"file":"src/parser/javascript.rs","kind":"string","line":[693,700],"text":"const MAX_SIZE = 100;\nlet debug = true;\nvar legacy = 'old';\n\nexport const API_KEY = 'secret';\n\nconst add = (a, b) => a + b;\nconst asyncFn = async (x) => x * 2;"}
{"file":"src/parser/javascript.rs","kind":"string","line":[721,724],"text":"import React from 'react';\nimport { useState, useEffect } from 'react';\nimport * as Utils from './utils';\nimport { render as renderDOM } from 'react-dom';"}
{"file":"src/parser/javascript.rs","kind":"string","line":[746,752],"text":"class Foo {\n publicMethod() {}\n\n _internalMethod() {}\n\n #privateMethod() {}\n}"}
{"file":"src/parser/javascript.rs","kind":"string","line":[776,784],"text":"/**\n * JSDoc comment\n */\nfunction documented() {}\n\n// Single line comment\nfunction helper() {}\n\n/* Block comment */"}
{"file":"src/parser/languages.rs","kind":"docstring","line":[4,4],"text":"Return the tree-sitter [`Language`] for the given language name."}
{"file":"src/parser/languages.rs","kind":"docstring","line":[6,6],"text":"Languages are feature-gated — only grammars enabled at compile time are"}
{"file":"src/parser/languages.rs","kind":"comment","line":[43,44],"text":"Markdown uses custom parser (tree-sitter-md) with MarkdownParser,\nbut we still register the block language for consistency"}
{"file":"src/parser/languages.rs","kind":"string","line":[48,48],"text":"unsupported language: {name}"}
{"file":"src/parser/languages.rs","kind":"docstring","line":[52,52],"text":"Detect the language from a file extension."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[1,1],"text":"Markdown symbol and text extraction using tree-sitter-md."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[3,4],"text":"Headings are extracted as symbols with `kind=\"section\"` and parent relationships\nreflecting the document hierarchy. Fenced code blocks are extracted as text entries."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[6,8],"text":"tree-sitter-md uses a two-tree architecture:\n- Block tree (`LANGUAGE`): document structure (headings, code blocks, paragraphs)\n- Inline trees (`INLINE_LANGUAGE`): inline content within blocks (text, emphasis, links)"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[17,17],"text":"Parse and extract symbols/texts from markdown using tree-sitter-md."}
{"file":"src/parser/markdown.rs","kind":"string","line":[25,25],"text":"failed to parse markdown: {}"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[30,30],"text":"Extract from block tree"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[34,34],"text":"Heading stack tracks (level, name) for building parent-child relationships"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[49,49],"text":"Walk the block tree to extract headings and code blocks."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[69,69],"text":"Recurse to children"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[78,78],"text":"Extract ATX-style heading (# heading)."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[109,109],"text":"Extract Setext-style heading (underlined with === or ---)."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[140,140],"text":"Extract fenced code block as text entry."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[148,148],"text":"Try to find code_fence_content child first"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[153,153],"text":"For code blocks, we don't filter as aggressively as other text types"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[173,173],"text":"Fallback: extract content between fence markers from raw text"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[194,195],"text":"Extract code content from fenced block raw text.\nStrips the opening and closing fence lines."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[202,202],"text":"Skip first line (opening fence) and last line (closing fence)"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[208,208],"text":"Find closing fence"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[222,222],"text":"Get heading text by extracting from child nodes."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[224,225],"text":"For ATX headings, we look for `heading_content` or `inline` children.\nFor Setext headings, we look for `paragraph` children."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[231,231],"text":"ATX heading content - may include trailing # which we need to strip"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[236,236],"text":"Setext heading: first paragraph is the heading text"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[245,245],"text":"Fallback: extract from raw text and strip markdown syntax"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[250,251],"text":"Strip optional closing sequence of # from ATX heading.\nPer CommonMark spec, the closing # sequence must be preceded by a space."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[253,253],"text":"Find the last non-# character"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[256,257],"text":"Check if it ends with space followed by #\nThe closing sequence is: optional whitespace, one or more #, optional whitespace"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[260,260],"text":"Check if everything after the last space is just #"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[262,262],"text":"This is an optional closing sequence - strip it"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[270,270],"text":"Strip markdown heading markers (# prefix and underlines)."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[274,274],"text":"ATX: strip leading # and optional trailing #"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[276,276],"text":"Get just the first line (ATX headings are single line)"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[278,278],"text":"Strip leading #"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[280,280],"text":"Strip trailing # (markdown allows optional closing hashes)"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[285,285],"text":"Setext: strip underline (text is on first line)"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[293,293],"text":"Count ATX heading level (number of leading #)."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[295,295],"text":"Look for atx_h1_marker, atx_h2_marker, etc."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[300,300],"text":"Extract level from marker name: atx_h1_marker -> 1"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[309,309],"text":"Fallback: count leading # characters"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[315,315],"text":"Get Setext heading level (1 for ===, 2 for ---)."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[317,317],"text":"Look for setext_h1_underline or setext_h2_underline"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[327,327],"text":"Fallback: check for underline character in last line"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[337,337],"text":"Default to h1"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[340,340],"text":"Compute qualified name and parent for a heading based on the heading stack."}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[342,346],"text":"The stack maintains (level, qualified_name) pairs. When we encounter a heading at level N:\n1. Pop all headings at level >= N (they're no longer ancestors)\n2. The parent is the top of the stack (if any)\n3. Build qualified name as \"parent/name\" (or just \"name\" if no parent)\n4. Push (N, qualified_name) onto the stack"}
{"file":"src/parser/markdown.rs","kind":"docstring","line":[348,348],"text":"Returns (qualified_name, parent_qualified_name)."}
{"file":"src/parser/markdown.rs","kind":"comment","line":[354,354],"text":"Pop all headings at same or deeper level"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[363,363],"text":"Parent is the top of the stack (the nearest ancestor heading)"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[366,366],"text":"Build qualified name"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[372,372],"text":"Push current heading onto the stack"}
{"file":"src/parser/markdown.rs","kind":"string","line":[384,384],"text":"# Top Level\\n\\nSome content.\\n\\n## Sub Section\\n\\nMore content.\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[388,388],"text":"Top Level"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[392,392],"text":"Qualified name includes parent path"}
{"file":"src/parser/markdown.rs","kind":"string","line":[393,393],"text":"Top Level/Sub Section"}
{"file":"src/parser/markdown.rs","kind":"string","line":[395,395],"text":"Top Level"}
{"file":"src/parser/markdown.rs","kind":"string","line":[401,401],"text":"# Chapter 1\\n## Section A\\n### Detail 1\\n### Detail 2\\n## Section B\\n# Chapter 2\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[406,406],"text":"Chapter 1 has no parent"}
{"file":"src/parser/markdown.rs","kind":"string","line":[407,407],"text":"Chapter 1"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[410,410],"text":"Section A's parent is Chapter 1"}
{"file":"src/parser/markdown.rs","kind":"string","line":[411,411],"text":"Chapter 1/Section A"}
{"file":"src/parser/markdown.rs","kind":"string","line":[412,412],"text":"Chapter 1"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[414,414],"text":"Detail 1's parent is Section A (qualified)"}
{"file":"src/parser/markdown.rs","kind":"string","line":[415,415],"text":"Chapter 1/Section A/Detail 1"}
{"file":"src/parser/markdown.rs","kind":"string","line":[416,416],"text":"Chapter 1/Section A"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[418,418],"text":"Detail 2's parent is Section A (same level as Detail 1)"}
{"file":"src/parser/markdown.rs","kind":"string","line":[419,419],"text":"Chapter 1/Section A/Detail 2"}
{"file":"src/parser/markdown.rs","kind":"string","line":[420,420],"text":"Chapter 1/Section A"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[422,422],"text":"Section B's parent is Chapter 1 (goes back up)"}
{"file":"src/parser/markdown.rs","kind":"string","line":[423,423],"text":"Chapter 1/Section B"}
{"file":"src/parser/markdown.rs","kind":"string","line":[424,424],"text":"Chapter 1"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[426,426],"text":"Chapter 2 has no parent (new top-level)"}
{"file":"src/parser/markdown.rs","kind":"string","line":[427,427],"text":"Chapter 2"}
{"file":"src/parser/markdown.rs","kind":"string","line":[433,433],"text":"Heading One\\n===========\\n\\nSome text.\\n\\nHeading Two\\n-----------\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[437,437],"text":"Heading One"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[440,440],"text":"Setext with --- is level 2, so parent is level 1"}
{"file":"src/parser/markdown.rs","kind":"string","line":[441,441],"text":"Heading One/Heading Two"}
{"file":"src/parser/markdown.rs","kind":"string","line":[442,442],"text":"Heading One"}
{"file":"src/parser/markdown.rs","kind":"string","line":[447,447],"text":"# Setup\\n\\n```rust\\nfn main() {\\n println!(\\\"Hello\\\");\\n}\\n```\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[455,455],"text":"fn main"}
{"file":"src/parser/markdown.rs","kind":"string","line":[461,461],"text":"Main Title\\n==========\\n\\n## ATX Subsection\\n\\nContent here.\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[465,465],"text":"Main Title"}
{"file":"src/parser/markdown.rs","kind":"string","line":[466,466],"text":"Main Title/ATX Subsection"}
{"file":"src/parser/markdown.rs","kind":"string","line":[467,467],"text":"Main Title"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[472,473],"text":"Per CommonMark: optional closing sequence is space + one or more # at end of line\nThe \"###\" in the middle is content (followed by space), only the final \" #\" is stripped"}
{"file":"src/parser/markdown.rs","kind":"string","line":[474,474],"text":"# Heading with trailing ### #\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[478,478],"text":"The middle \"###\" is content, final \" #\" is stripped"}
{"file":"src/parser/markdown.rs","kind":"string","line":[479,479],"text":"Heading with trailing ###"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[484,484],"text":"When the entire trailing part is the closing sequence"}
{"file":"src/parser/markdown.rs","kind":"string","line":[485,485],"text":"# Simple heading ##\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[489,489],"text":"Simple heading"}
{"file":"src/parser/markdown.rs","kind":"string","line":[494,494],"text":"# \\n## Real Heading\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[497,497],"text":"Empty heading should be skipped"}
{"file":"src/parser/markdown.rs","kind":"string","line":[499,499],"text":"Real Heading"}
{"file":"src/parser/markdown.rs","kind":"string","line":[504,504],"text":"```python\\nprint('hello')\\n```\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[510,510],"text":"No heading context"}
{"file":"src/parser/markdown.rs","kind":"string","line":[515,515],"text":"# H1\\n## H2\\n### H3\\n#### H4\\n##### H5\\n###### H6\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[525,525],"text":"Multiple \"Features\" sections under different parents - qualified names disambiguate"}
{"file":"src/parser/markdown.rs","kind":"string","line":[526,526],"text":"# v1.0\\n## Features\\n## Bug Fixes\\n# v2.0\\n## Features\\n## Bug Fixes\\n"}
{"file":"src/parser/markdown.rs","kind":"string","line":[532,532],"text":"v1.0/Bug Fixes"}
{"file":"src/parser/markdown.rs","kind":"string","line":[535,535],"text":"v2.0/Bug Fixes"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[540,540],"text":"Code block under a nested heading should have qualified parent"}
{"file":"src/parser/markdown.rs","kind":"string","line":[541,541],"text":"# Guide\\n## Installation\\n```bash\\nnpm install\\n```\\n"}
{"file":"src/parser/markdown.rs","kind":"comment","line":[550,550],"text":"Parent should be the qualified name"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[1,1],"text":"File metadata extraction (title and description)."}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[3,13],"text":"Extracts file-level metadata from source code for improved search relevance.\nEach language has specific conventions for documenting files:\n- Markdown: YAML frontmatter or first heading/paragraph\n- Python: Module docstring\n- Rust: `//!` module docs\n- JavaScript/TypeScript: Top-level JSDoc\n- Go: Package comment\n- Java: Top-level Javadoc\n- C/C++: File header comment\n- Ruby: Top file comment\n- C#: Top-level XML doc comment"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[20,20],"text":"File metadata: title and description."}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[37,37],"text":"Extract file metadata (title and description) from source code."}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[39,40],"text":"Returns `FileMetadata` with title and/or description if found.\nDescription is truncated to the first sentence or line."}
{"file":"src/parser/metadata.rs","kind":"comment","line":[79,79],"text":"Post-process: truncate description to first sentence/line"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[86,86],"text":"Helper to parse source and extract metadata using a tree-based extractor."}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[107,107],"text":"Truncate text to the first line (up to newline)."}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[116,116],"text":"Truncate text to the first sentence (up to period, or first line)."}
{"file":"src/parser/metadata.rs","kind":"comment","line":[120,120],"text":"First, try to find a sentence boundary (. followed by space or end)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[125,125],"text":"Period at end"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[130,130],"text":"Sentence boundary found"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[136,136],"text":"No sentence boundary, fall back to first line"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[140,142],"text":"---------------------------------------------------------------------------\nMarkdown metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[151,151],"text":"Try YAML frontmatter first"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[158,158],"text":"Fallback: first heading as title, first paragraph as description"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[166,166],"text":"Skip code blocks"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[175,175],"text":"Skip empty lines"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[180,180],"text":"First ATX heading as title"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[183,183],"text":"Strip optional closing hashes"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[191,191],"text":"First non-heading paragraph as description"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[203,203],"text":"YAML frontmatter starts with --- on first line"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[208,208],"text":"Find closing ---"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[234,236],"text":"---------------------------------------------------------------------------\nPython metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[243,243],"text":"Look for module docstring: first expression_statement containing a string"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[257,257],"text":"First line is title, rest is description"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[260,260],"text":"Stop at first non-docstring statement"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[269,271],"text":"---------------------------------------------------------------------------\nRust metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[279,279],"text":"Look for //! module doc comments at the start of the file"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[286,286],"text":"Regular comment, stop looking for module docs"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[292,292],"text":"Block doc comment"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[304,304],"text":"Non-comment node, stop"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[317,319],"text":"---------------------------------------------------------------------------\nJavaScript/TypeScript metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[326,326],"text":"Look for top-level JSDoc comment (/** ... */)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[331,331],"text":"JSDoc comment"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[343,343],"text":"Stop at first non-comment (except shebang)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[351,353],"text":"---------------------------------------------------------------------------\nGo metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[361,361],"text":"Look for package comment (comment block before package clause)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[379,379],"text":"Found package clause, use collected comments"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[382,382],"text":"Non-comment, non-package node"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[395,397],"text":"---------------------------------------------------------------------------\nJava metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[404,404],"text":"Look for top-level Javadoc comment (/** ... */)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[413,413],"text":"Same format as JSDoc"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[420,420],"text":"Stop at first non-comment"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[428,430],"text":"---------------------------------------------------------------------------\nC/C++ metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[438,438],"text":"Look for file header comment at the start"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[449,449],"text":"Skip copyright-only headers"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[455,455],"text":"Skip copyright lines"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[461,461],"text":"Stop at first non-comment"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[474,476],"text":"---------------------------------------------------------------------------\nRuby metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[484,484],"text":"Look for top file comment block"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[489,489],"text":"Skip shebang and encoding lines"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[494,494],"text":"Stop at first non-comment"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[507,509],"text":"---------------------------------------------------------------------------\nC# metadata extraction\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[517,517],"text":"Look for top-level XML doc comments (///)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[524,524],"text":"Regular comment, keep looking"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[528,528],"text":"Stop at first non-comment, non-using"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[537,537],"text":"Parse XML-like content for <summary>"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[548,548],"text":"Simple extraction of <summary>...</summary> content"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[569,571],"text":"---------------------------------------------------------------------------\nHelper functions\n---------------------------------------------------------------------------"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[573,573],"text":"Split a docstring into title (first line) and description (rest)."}
{"file":"src/parser/metadata.rs","kind":"comment","line":[580,580],"text":"First non-empty line is title"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[584,585],"text":"Rest is description: skip decoration lines (e.g., RST underlines like ~~~, ===, ---)\nand empty lines, take first real paragraph"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[607,607],"text":"Check if a line is a decoration/underline (e.g., RST ~~~, ===, ---, etc.)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[613,613],"text":"Common RST/markdown decoration characters"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[618,618],"text":"Clean a block comment by stripping leading * from each line."}
{"file":"src/parser/metadata.rs","kind":"comment","line":[623,623],"text":"Strip leading * (common in block comments)"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[631,631],"text":"Clean a JSDoc/Javadoc comment by stripping * and @ tags."}
{"file":"src/parser/metadata.rs","kind":"comment","line":[637,637],"text":"Strip leading *"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[640,640],"text":"Skip empty lines and @ tags (except @description/@fileoverview)"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[645,645],"text":"Extract content from @description or @fileoverview"}
{"file":"src/parser/metadata.rs","kind":"comment","line":[655,655],"text":"Skip other @ tags"}
{"file":"src/parser/metadata.rs","kind":"docstring","line":[665,665],"text":"Check if a comment is only copyright/license boilerplate."}
{"file":"src/parser/metadata.rs","kind":"string","line":[682,682],"text":"Hello world. This is more."}
{"file":"src/parser/metadata.rs","kind":"string","line":[683,683],"text":"Hello world."}
{"file":"src/parser/metadata.rs","kind":"string","line":[685,685],"text":"No period here"}
{"file":"src/parser/metadata.rs","kind":"string","line":[685,685],"text":"No period here"}
{"file":"src/parser/metadata.rs","kind":"string","line":[687,687],"text":"File v1.2.3 description. More info."}
{"file":"src/parser/metadata.rs","kind":"string","line":[688,688],"text":"File v1.2.3 description."}
{"file":"src/parser/metadata.rs","kind":"string","line":[694,694],"text":"First line\\nSecond line"}
{"file":"src/parser/metadata.rs","kind":"string","line":[694,694],"text":"First line"}
{"file":"src/parser/metadata.rs","kind":"string","line":[695,695],"text":"Single line"}
{"file":"src/parser/metadata.rs","kind":"string","line":[695,695],"text":"Single line"}
{"file":"src/parser/metadata.rs","kind":"string","line":[700,700],"text":"Title here\\n\\nDescription follows."}
{"file":"src/parser/metadata.rs","kind":"string","line":[701,701],"text":"Title here"}
{"file":"src/parser/metadata.rs","kind":"string","line":[702,702],"text":"Description follows."}
{"file":"src/parser/metadata.rs","kind":"string","line":[704,704],"text":"Just a title"}
{"file":"src/parser/metadata.rs","kind":"string","line":[705,705],"text":"Just a title"}
{"file":"src/parser/metadata.rs","kind":"string","line":[711,711],"text":"* First line\\n * Second line\\n * Third"}
{"file":"src/parser/metadata.rs","kind":"string","line":[713,713],"text":"First line\\nSecond line\\nThird"}
{"file":"src/parser/metadata.rs","kind":"string","line":[719,719],"text":"---\\ntitle: My Title\\ndescription: My description\\n---\\n# Heading"}
{"file":"src/parser/metadata.rs","kind":"string","line":[721,721],"text":"My Title"}
{"file":"src/parser/metadata.rs","kind":"string","line":[722,722],"text":"My description"}
{"file":"src/parser/metadata.rs","kind":"string","line":[728,728],"text":"# Main Title\\n\\nFirst paragraph here."}
{"file":"src/parser/metadata.rs","kind":"string","line":[730,730],"text":"Main Title"}
{"file":"src/parser/metadata.rs","kind":"string","line":[731,731],"text":"First paragraph here."}
{"file":"src/parser/mod.rs","kind":"comment","line":[7,7],"text":"Language-specific extractors"}
{"file":"src/parser/python.rs","kind":"docstring","line":[1,1],"text":"Python symbol and text extraction."}
{"file":"src/parser/python.rs","kind":"comment","line":[32,32],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/python.rs","kind":"comment","line":[44,44],"text":"handled recursively"}
{"file":"src/parser/python.rs","kind":"comment","line":[50,50],"text":"handled recursively"}
{"file":"src/parser/python.rs","kind":"string","line":[55,55],"text":"import_from_statement"}
{"file":"src/parser/python.rs","kind":"comment","line":[59,59],"text":"Recurse into the definition inside the decorator"}
{"file":"src/parser/python.rs","kind":"comment","line":[76,76],"text":"Check for module-level assignments and docstrings"}
{"file":"src/parser/python.rs","kind":"comment","line":[83,83],"text":"Could be a module/class docstring"}
{"file":"src/parser/python.rs","kind":"comment","line":[104,104],"text":"Recurse into children"}
{"file":"src/parser/python.rs","kind":"comment","line":[138,138],"text":"Determine if it's a method (inside a class) or function"}
{"file":"src/parser/python.rs","kind":"comment","line":[145,145],"text":"Check for decorators to detect properties, staticmethods, etc."}
{"file":"src/parser/python.rs","kind":"comment","line":[148,148],"text":"Extract tokens from function body for FTS"}
{"file":"src/parser/python.rs","kind":"comment","line":[171,171],"text":"Recurse into function body for nested definitions and references"}
{"file":"src/parser/python.rs","kind":"comment","line":[173,173],"text":"Check for docstring as first statement"}
{"file":"src/parser/python.rs","kind":"comment","line":[177,177],"text":"Check if first statement is a docstring"}
{"file":"src/parser/python.rs","kind":"comment","line":[185,185],"text":"Skip docstring, don't process as regular code"}
{"file":"src/parser/python.rs","kind":"comment","line":[188,188],"text":"Recurse into function body to find calls and nested definitions"}
{"file":"src/parser/python.rs","kind":"comment","line":[222,222],"text":"Extract tokens from class body for FTS"}
{"file":"src/parser/python.rs","kind":"comment","line":[245,245],"text":"Walk class body"}
{"file":"src/parser/python.rs","kind":"comment","line":[250,250],"text":"Check for class docstring"}
{"file":"src/parser/python.rs","kind":"comment","line":[284,284],"text":"`import foo, bar` or `import foo as bar`"}
{"file":"src/parser/python.rs","kind":"comment","line":[301,301],"text":"Also record as import reference"}
{"file":"src/parser/python.rs","kind":"comment","line":[328,328],"text":"Also record as import reference"}
{"file":"src/parser/python.rs","kind":"comment","line":[353,353],"text":"Get module name: `from X import ...`"}
{"file":"src/parser/python.rs","kind":"comment","line":[358,358],"text":"Iterate over imported names"}
{"file":"src/parser/python.rs","kind":"comment","line":[363,363],"text":"Skip the module name itself (already captured)"}
{"file":"src/parser/python.rs","kind":"comment","line":[387,387],"text":"Also record as import reference"}
{"file":"src/parser/python.rs","kind":"comment","line":[419,419],"text":"Also record as import reference"}
{"file":"src/parser/python.rs","kind":"comment","line":[447,447],"text":"Also record as import reference"}
{"file":"src/parser/python.rs","kind":"comment","line":[469,469],"text":"Module/class-level assignments: `FOO = ...` or `foo: type = ...`"}
{"file":"src/parser/python.rs","kind":"comment","line":[475,475],"text":"Only capture simple identifier assignments (not destructuring, subscripts, etc.)"}
{"file":"src/parser/python.rs","kind":"comment","line":[484,484],"text":"UPPER_CASE → constant, otherwise variable"}
{"file":"src/parser/python.rs","kind":"docstring","line":[510,511],"text":"Extract a function call as a reference.\nHandles: simple calls (foo()), method calls (obj.method()), chained calls (a.b.c())."}
{"file":"src/parser/python.rs","kind":"comment","line":[521,521],"text":"The \"function\" field contains the callable expression"}
{"file":"src/parser/python.rs","kind":"comment","line":[526,526],"text":"Extract the name of the called function"}
{"file":"src/parser/python.rs","kind":"comment","line":[529,529],"text":"Simple call: foo()"}
{"file":"src/parser/python.rs","kind":"comment","line":[533,534],"text":"Method call: obj.method() or chained: a.b.c()\nWe capture the full attribute chain"}
{"file":"src/parser/python.rs","kind":"comment","line":[538,539],"text":"Complex expression like lambda calls, subscript calls, etc.\nSkip these as they're hard to resolve statically"}
{"file":"src/parser/python.rs","kind":"comment","line":[544,544],"text":"Skip builtins and common patterns that aren't useful references"}
{"file":"src/parser/python.rs","kind":"docstring","line":[559,559],"text":"Check if a call is to a Python builtin that we want to skip."}
{"file":"src/parser/python.rs","kind":"comment","line":[561,561],"text":"Get the base name (first part for attribute chains)"}
{"file":"src/parser/python.rs","kind":"docstring","line":[657,657],"text":"Python-specific stopwords to filter from tokens."}
{"file":"src/parser/python.rs","kind":"docstring","line":[662,662],"text":"Filter Python-specific tokens from the extracted token string."}
{"file":"src/parser/python.rs","kind":"string","line":[680,680],"text":"symbol not found: {name}"}
{"file":"src/parser/python.rs","kind":"string","line":[685,692],"text":"def hello(name):\n return f'Hello, {name}!'\n\ndef _private():\n pass\n\nasync def fetch_data():\n return None"}
{"file":"src/parser/python.rs","kind":"comment","line":[698,699],"text":"Tokens should contain identifiers from the function body (name param filtered by stopwords)\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/python.rs","kind":"comment","line":[704,704],"text":"Empty body, no meaningful tokens"}
{"file":"src/parser/python.rs","kind":"comment","line":[708,708],"text":"Body just returns None, no meaningful tokens after filtering"}
{"file":"src/parser/python.rs","kind":"string","line":[714,722],"text":"class Person:\n def __init__(self, name):\n self.name = name\n\n def greet(self):\n return f'Hi, {self.name}'\n\nclass _Private:\n pass"}
{"file":"src/parser/python.rs","kind":"comment","line":[727,728],"text":"Class body tokens should contain identifiers from methods\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/python.rs","kind":"comment","line":[734,735],"text":"Method body has 'name' identifier\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/python.rs","kind":"string","line":[746,749],"text":"import os\nimport sys as system\nfrom pathlib import Path\nfrom typing import List, Dict as D"}
{"file":"src/parser/python.rs","kind":"comment","line":[764,764],"text":"Check import references were created"}
{"file":"src/parser/python.rs","kind":"string","line":[775,780],"text":"MAX_SIZE = 100\ndebug_mode = True\n\nclass Config:\n def __init__(self):\n self.version = '1.0'"}
{"file":"src/parser/python.rs","kind":"string","line":[795,806],"text":"def public_fn():\n pass\n\ndef _internal():\n pass\n\ndef __private():\n pass\n\nclass Foo:\n def __special__(self):\n pass"}
{"file":"src/parser/python.rs","kind":"comment","line":[819,819],"text":"__special__ starts with _ so it's internal (not __x without trailing __)"}
{"file":"src/parser/python.rs","kind":"string","line":[825,833],"text":"\\\"\\\"\\\"Module docstring\\\"\\\"\\\"\n\ndef foo():\n \\\"\\\"\\\"Function docstring\\\"\\\"\\\"\n pass\n\nclass Bar:\n \\\"\\\"\\\"Class docstring\\\"\\\"\\\"\n pass"}
{"file":"src/parser/python.rs","kind":"string","line":[840,846],"text":"def caller():\n result = some_function()\n obj.method_call()\n nested.deep.call()\n\ndef some_function():\n pass"}
{"file":"src/parser/python.rs","kind":"comment","line":[849,849],"text":"Check call references were created with caller context"}
{"file":"src/parser/ruby.rs","kind":"docstring","line":[1,1],"text":"Ruby symbol and text extraction."}
{"file":"src/parser/ruby.rs","kind":"docstring","line":[9,9],"text":"Ruby-specific stopwords (keywords, common patterns)"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[36,36],"text":"Common patterns"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[50,50],"text":"Common variable patterns"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[57,57],"text":"Very common methods (too generic)"}
{"file":"src/parser/ruby.rs","kind":"docstring","line":[78,78],"text":"Filter Ruby-specific stopwords from extracted tokens."}
{"file":"src/parser/ruby.rs","kind":"comment","line":[84,84],"text":"Filter uppercase constants (ALL_CAPS)"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[115,115],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[143,143],"text":"Capture `require`, `include`, `extend`, `attr_*`"}
{"file":"src/parser/ruby.rs","kind":"string","line":[195,195],"text":"def {name}{params}"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[209,209],"text":"Extract tokens from method body"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[225,225],"text":"Recurse for nested definitions"}
{"file":"src/parser/ruby.rs","kind":"string","line":[272,272],"text":"def self.{name}{params}"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[280,280],"text":"Extract tokens from singleton method body"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[296,296],"text":"Recurse for nested definitions"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[339,339],"text":"Check for superclass"}
{"file":"src/parser/ruby.rs","kind":"string","line":[341,341],"text":" < {}"}
{"file":"src/parser/ruby.rs","kind":"string","line":[344,344],"text":"class {name}{superclass}"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[352,352],"text":"Extract tokens from class body"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[368,368],"text":"Walk class body"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[452,452],"text":"CONSTANT = value"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[471,471],"text":"Module/class level assignment"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[473,473],"text":"Only capture top-level assignments"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[489,489],"text":"@var or @@var"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[532,532],"text":"Extract the required file"}
{"file":"src/parser/ruby.rs","kind":"string","line":[586,586],"text":"symbol not found: {name}"}
{"file":"src/parser/ruby.rs","kind":"string","line":[591,597],"text":"def hello(name)\n \\\"Hello, #{name}!\\\"\nend\n\ndef _private_helper\n puts 'private'\nend"}
{"file":"src/parser/ruby.rs","kind":"comment","line":[602,603],"text":"Token extraction extracts identifiers from method body\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/ruby.rs","kind":"string","line":[612,624],"text":"class Person\n def initialize(name)\n @name = name\n end\n\n def greet\n \\\"Hi, #{@name}\\\"\n end\n\n def self.create\n Person.new('default')\n end\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[640,649],"text":"module Utils\n def self.helper\n puts 'helping'\n end\nend\n\nmodule Logger\n class Writer\n end\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[668,673],"text":"MAX_SIZE = 100\nDEFAULT_NAME = 'Unknown'\n\nclass Config\n VERSION = '1.0'\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[686,689],"text":"class Foo\n @instance_var = 1\n @@class_var = 2\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[703,705],"text":"require 'json'\nrequire_relative 'config'\nrequire 'active_support'"}
{"file":"src/parser/ruby.rs","kind":"string","line":[717,724],"text":"class Animal\nend\n\nclass Dog < Animal\n def bark\n 'woof'\n end\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[736,740],"text":"class Utils\n def self.format(text)\n text.upcase\n end\nend"}
{"file":"src/parser/ruby.rs","kind":"string","line":[749,755],"text":"# Single line comment\ndef foo\nend\n\n=begin\nMulti-line comment\n=end"}
{"file":"src/parser/ruby.rs","kind":"string","line":[762,766],"text":"def public_method\nend\n\ndef _internal_method\nend"}
{"file":"src/parser/rust_lang.rs","kind":"docstring","line":[1,1],"text":"Rust symbol and text extraction."}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[29,29],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[66,66],"text":"impl is handled recursively inside extract_impl"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[79,79],"text":"Recurse into children"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[109,109],"text":"Extract tokens from function body for FTS"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[188,188],"text":"impl blocks are containers, no meaningful tokens"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[201,201],"text":"Walk children of the body to find methods"}
{"file":"src/parser/rust_lang.rs","kind":"docstring","line":[345,345],"text":"Rust-specific stopwords to filter from tokens."}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[350,351],"text":"Common std types/modules\nVery common short names in Rust"}
{"file":"src/parser/rust_lang.rs","kind":"docstring","line":[355,355],"text":"Filter Rust-specific tokens from the extracted token string."}
{"file":"src/parser/rust_lang.rs","kind":"docstring","line":[364,364],"text":"Rust-specific comment extraction (handles ///, //!, /**, etc.)"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[384,384],"text":"symbol not found: {name}"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[389,395],"text":"pub fn hello(name: &str) -> String {\n format!(\\\"Hello, {}!\\\", name)\n}\n\nfn private_helper() {\n println!(\\\"private\\\");\n}"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[401,402],"text":"Tokens contain identifiers from function body (format, name)\nToken may be None if all identifiers are filtered as stopwords"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[412,417],"text":"pub struct Point {\n pub x: i32,\n pub y: i32,\n}\n\nstruct Private;"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[432,440],"text":"struct Foo;\n\nimpl Foo {\n pub fn new() -> Self {\n Foo\n }\n\n fn private_method(&self) {}\n}"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[442,442],"text":"struct + impl + 2 methods"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[445,445],"text":"First is struct, second is impl"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[447,447],"text":"Impl tokens now contain the signature \"impl Foo\""}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[461,469],"text":"pub trait Display {\n fn fmt(&self) -> String;\n}\n\nimpl Display for Foo {\n fn fmt(&self) -> String {\n String::new()\n }\n}"}
{"file":"src/parser/rust_lang.rs","kind":"comment","line":[479,479],"text":"Trait impls are containers, no tokens"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[485,487],"text":"use std::collections::HashMap;\nuse std::io::{self, Read};\npub use std::fmt::Debug;"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[492,492],"text":"std::collections::HashMap"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[504,507],"text":"pub enum Result<T, E> {\n Ok(T),\n Err(E),\n}"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[516,517],"text":"pub mod utils;\nmod private_mod;"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[530,531],"text":"pub const MAX: usize = 100;\nstatic GLOBAL: i32 = 0;"}
{"file":"src/parser/rust_lang.rs","kind":"string","line":[545,550],"text":"/// This is a doc comment\n/// for the function\npub fn documented() {}\n\n// Regular comment\nfn helper() {}"}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[1,1],"text":"Single File Component (SFC) preprocessor."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[3,4],"text":"Extracts `<script>` blocks from Vue, Svelte, and Astro files so they can\nbe fed to the existing TypeScript/JavaScript tree-sitter extractors."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[6,6],"text":"No external dependencies — uses simple byte-level scanning."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[8,8],"text":"A script block extracted from an SFC file."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[10,10],"text":"The script content (without the surrounding tags)."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[12,12],"text":"The language to parse with: `\"typescript\"` or `\"javascript\"`."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[14,14],"text":"1-based line number where the content starts in the original file."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[18,18],"text":"Extract script blocks from an SFC file based on its extension."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[20,20],"text":"Returns an empty vec if no script blocks are found (e.g. template-only"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[32,34],"text":"---------------------------------------------------------------------------\nVue: <script> and <script setup>, with optional lang=\"ts\"\n---------------------------------------------------------------------------"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[40,42],"text":"---------------------------------------------------------------------------\nSvelte: <script> with optional lang=\"ts\"\n---------------------------------------------------------------------------"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[48,50],"text":"---------------------------------------------------------------------------\nAstro: --- frontmatter --- (always TS) + optional <script> blocks\n---------------------------------------------------------------------------"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[56,56],"text":"Extract frontmatter: content between first `---` and second `---`"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[60,60],"text":"Skip leading newline after opening ---"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[73,73],"text":"Count lines before the frontmatter content starts"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[86,86],"text":"Also extract any <script> tags in the body"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[92,94],"text":"---------------------------------------------------------------------------\nShared: extract <script> ... </script> blocks from HTML-like content\n---------------------------------------------------------------------------"}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[96,96],"text":"Extract all `<script ...>...</script>` blocks from HTML-like source."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[98,98],"text":"`default_lang` is used when no `lang=\"...\"` attribute is present."}
{"file":"src/parser/sfc.rs","kind":"comment","line":[109,109],"text":"Make sure it's actually a tag (next char after \"script\" should be whitespace or >)"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[125,125],"text":"Find the closing > of the opening tag"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[131,131],"text":"Extract the opening tag attributes"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[134,134],"text":"Detect language from lang=\"...\" attribute"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[137,137],"text":"Content starts after the > (skip leading newline if present)"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[148,148],"text":"Find the matching </script> — content ends where the close tag begins"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[156,156],"text":"Calculate the 1-based start line of the content"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[167,167],"text":"Move past the closing tag"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[169,169],"text":"Skip past </script>"}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[180,180],"text":"Detect the script language from an opening `<script ...>` tag."}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[182,183],"text":"Looks for `lang=\"ts\"`, `lang=\"typescript\"`, `lang='ts'`, etc.\nReturns `\"typescript\"` or `\"javascript\"`."}
{"file":"src/parser/sfc.rs","kind":"comment","line":[187,187],"text":"Match lang=\"ts\" or lang=\"typescript\" (with either quote style)"}
{"file":"src/parser/sfc.rs","kind":"comment","line":[201,201],"text":"No lang attribute — use the default"}
{"file":"src/parser/sfc.rs","kind":"docstring","line":[209,209],"text":"Count the number of newline characters in a string slice."}
{"file":"src/parser/sfc.rs","kind":"string","line":[220,220],"text":"<template>\\n <div>hello</div>\\n</template>\\n\\n<script setup lang=\\\"ts\\\">\\nimport { ref } from 'vue'\\nconst msg = ref('hi')\\n</script>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[226,226],"text":"import { ref }"}
{"file":"src/parser/sfc.rs","kind":"string","line":[227,227],"text":"const msg"}
{"file":"src/parser/sfc.rs","kind":"string","line":[232,232],"text":"<script>\\nexport default { name: 'Foo' }\\n</script>\\n\\n<script setup lang=\\\"ts\\\">\\nconst x = 1\\n</script>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[243,243],"text":"<template>\\n <div>hello</div>\\n</template>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[250,250],"text":"---\\nimport Layout from './Layout.astro'\\nconst title = 'Hello'\\n---\\n\\n<Layout title={title}>\\n <h1>Hello</h1>\\n</Layout>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[256,256],"text":"import Layout"}
{"file":"src/parser/sfc.rs","kind":"string","line":[261,261],"text":"<script lang=\\\"ts\\\">\\n let count = 0\\n function inc() { count++ }\\n</script>\\n\\n<button on:click={inc}>{count}</button>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[270,270],"text":"<!DOCTYPE html>\\n<html>\\n<head>\\n<script>\\nfunction greet(name) {\\n return 'Hello ' + name;\\n}\\n</script>\\n</head>\\n<body></body>\\n</html>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[276,276],"text":"function greet"}
{"file":"src/parser/sfc.rs","kind":"string","line":[281,281],"text":"<!DOCTYPE html>\\n<html><body><p>Hello</p></body></html>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[288,288],"text":"<html>\\n<body>\\n<script lang=\\\"ts\\\">\\nconst x: number = 42;\\n</script>\\n</body>\\n</html>\\n"}
{"file":"src/parser/sfc.rs","kind":"string","line":[297,297],"text":"<script lang=\\\"ts\\\">"}
{"file":"src/parser/sfc.rs","kind":"string","line":[301,301],"text":"<script lang='typescript'>"}
{"file":"src/parser/sfc.rs","kind":"string","line":[305,305],"text":"<script setup lang=\\\"ts\\\">"}
{"file":"src/parser/sfc.rs","kind":"string","line":[314,314],"text":"<script setup>"}
{"file":"src/parser/treesitter.rs","kind":"docstring","line":[9,9],"text":"Maximum recursion depth for AST traversal to prevent stack overflow on deeply nested code."}
{"file":"src/parser/treesitter.rs","kind":"docstring","line":[12,12],"text":"Parse a single file using tree-sitter and extract symbols, text blocks, and references."}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[18,18],"text":"SFC preprocessing: extract script blocks from Vue/Svelte/Astro files"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[31,31],"text":"Markdown uses a custom two-pass parser (tree-sitter-md with MarkdownParser)"}
{"file":"src/parser/treesitter.rs","kind":"string","line":[44,44],"text":"failed to parse {file_path}"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[97,97],"text":"For unsupported languages, just extract comments and strings"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[102,102],"text":"Merge consecutive doc comments (/// lines) into single entries"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[108,110],"text":"---------------------------------------------------------------------------\nGeneric text extraction (for unsupported languages)\n---------------------------------------------------------------------------"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[113,113],"text":"Use iterative traversal with explicit stack to avoid stack overflow"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[151,151],"text":"Push children in reverse order so they're processed in forward order"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[160,162],"text":"---------------------------------------------------------------------------\nPost-processing: merge consecutive doc comments\n---------------------------------------------------------------------------"}
{"file":"src/parser/treesitter.rs","kind":"docstring","line":[164,164],"text":"Merge consecutive text entries of the same kind on adjacent lines."}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[192,194],"text":"---------------------------------------------------------------------------\nSFC (Single File Component) handling\n---------------------------------------------------------------------------"}
{"file":"src/parser/treesitter.rs","kind":"docstring","line":[196,197],"text":"Parse an SFC file by extracting script blocks and running them through the\nappropriate JS/TS parser, adjusting line numbers back to the original file."}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[214,214],"text":"Parse each script block with the detected language"}
{"file":"src/parser/treesitter.rs","kind":"string","line":[220,220],"text":"failed to parse {} script block in {}: {}"}
{"file":"src/parser/treesitter.rs","kind":"comment","line":[229,230],"text":"Adjust line numbers: add the block's start_line offset (minus 1 because\nthe parser already counts from line 1)"}
{"file":"src/parser/typescript.rs","kind":"docstring","line":[1,1],"text":"TypeScript symbol and text extraction."}
{"file":"src/parser/typescript.rs","kind":"docstring","line":[3,5],"text":"TypeScript extends JavaScript with type annotations, interfaces,\nenums, type aliases, and namespaces. We reuse the JS extraction\nfor most constructs and add TS-specific ones."}
{"file":"src/parser/typescript.rs","kind":"docstring","line":[13,13],"text":"TypeScript-specific stopwords (JS keywords + TS type system keywords)"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[15,15],"text":"JavaScript common"}
{"file":"src/parser/typescript.rs","kind":"docstring","line":[72,72],"text":"Filter TypeScript-specific stopwords from extracted tokens."}
{"file":"src/parser/typescript.rs","kind":"comment","line":[107,107],"text":"Prevent stack overflow on deeply nested code"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[115,115],"text":"--- JS constructs ---"}
{"file":"src/parser/typescript.rs","kind":"string","line":[116,116],"text":"generator_function_declaration"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[148,148],"text":"--- TS-specific constructs ---"}
{"file":"src/parser/typescript.rs","kind":"string","line":[149,149],"text":"interface_declaration"}
{"file":"src/parser/typescript.rs","kind":"string","line":[153,153],"text":"type_alias_declaration"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[160,160],"text":"`namespace Foo { ... }` or `module Foo { ... }`"}
{"file":"src/parser/typescript.rs","kind":"string","line":[164,164],"text":"abstract_class_declaration"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[180,180],"text":"Recurse into children"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[195,195],"text":"--- Shared JS-like extraction (adapted for TS node names) ---"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[230,230],"text":"Extract tokens from function body"}
{"file":"src/parser/typescript.rs","kind":"string","line":[268,268],"text":"abstract_class_declaration"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[277,277],"text":"Extract tokens from class body"}
{"file":"src/parser/typescript.rs","kind":"string","line":[336,336],"text":"accessibility_modifier"}
{"file":"src/parser/typescript.rs","kind":"string","line":[354,354],"text":": {}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[375,375],"text":"{prefix}{name}{params}{return_type}"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[390,390],"text":"Extract tokens from method body"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[469,469],"text":"Extract tokens from variable value"}
{"file":"src/parser/typescript.rs","kind":"string","line":[527,527],"text":"{source_module}.{name}"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[572,572],"text":"--- TS-specific constructs ---"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[595,595],"text":"Build signature with type parameters and extends"}
{"file":"src/parser/typescript.rs","kind":"string","line":[606,606],"text":" extends {}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[609,609],"text":"interface {name}{type_params}{extends}"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[617,617],"text":"Extract tokens from interface body (type references)"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[633,633],"text":"Walk interface body for method signatures"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[647,647],"text":"Interface signatures don't have bodies, so no tokens"}
{"file":"src/parser/typescript.rs","kind":"string","line":[651,651],"text":"{full_name}.{member_name}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[693,693],"text":"type {name}{type_params}"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[701,701],"text":"Extract tokens from type definition"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[795,795],"text":"Recurse into namespace body"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[812,812],"text":"--- Helpers ---"}
{"file":"src/parser/typescript.rs","kind":"string","line":[857,857],"text":": {}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[867,867],"text":"async function"}
{"file":"src/parser/typescript.rs","kind":"string","line":[872,872],"text":"{prefix} {name}{type_params}{params}{return_type}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[890,890],"text":"abstract class"}
{"file":"src/parser/typescript.rs","kind":"string","line":[895,895],"text":"{prefix} {name}{type_params}{extends}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[907,907],"text":"symbol not found: {name}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[912,918],"text":"function greet(name: string): string {\n return `Hello, ${name}!`;\n}\n\nasync function fetch(): Promise<Data> {\n return await api.get();\n}"}
{"file":"src/parser/typescript.rs","kind":"comment","line":[924,924],"text":"Token extraction is enabled (may be None if body has no tokens after filtering)"}
{"file":"src/parser/typescript.rs","kind":"string","line":[932,940],"text":"export interface User {\n id: number;\n name: string;\n getEmail(): string;\n}\n\ninterface Private {\n data: any;\n}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[957,958],"text":"export type Result<T> = Success<T> | Error;\ntype ID = string | number;"}
{"file":"src/parser/typescript.rs","kind":"string","line":[972,976],"text":"export enum Status {\n Active,\n Inactive,\n Pending\n}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[986,1005],"text":"export abstract class Base {\n protected abstract doWork(): void;\n}\n\nexport class Worker extends Base {\n private data: string;\n\n constructor(data: string) {\n super();\n this.data = data;\n }\n\n protected doWork(): void {\n console.log(this.data);\n }\n\n public run(): void {\n this.doWork();\n }\n}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[1023,1025],"text":"export namespace Utils {\n export function helper(): void {}\n}"}
{"file":"src/parser/typescript.rs","kind":"string","line":[1038,1041],"text":"import React from 'react';\nimport { Component, useState } from 'react';\nimport * as Utils from './utils';\nimport type { User } from './types';"}
{"file":"src/parser/typescript.rs","kind":"string","line":[1059,1063],"text":"class Foo {\n public publicMethod(): void {}\n private privateMethod(): void {}\n protected protectedMethod(): void {}\n}"}
{"file":"src/server/db.rs","kind":"docstring","line":[6,7],"text":"An in-memory SQLite database with FTS5 virtual tables for fast text search\nover the code index."}
{"file":"src/server/db.rs","kind":"docstring","line":[10,10],"text":"Whether FTS5 virtual tables are enabled. Disabled in build mode to save memory."}
{"file":"src/server/db.rs","kind":"docstring","line":[15,15],"text":"Create a new in-memory database with FTS5 enabled (for serve mode).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[20,21],"text":"Create a new in-memory database without FTS5 (for build mode).\nThis significantly reduces memory usage for large repositories.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[26,26],"text":"Internal constructor with configurable FTS support.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[145,145],"text":"Load index data into the database for a specific project.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[238,240],"text":"Search or list symbols.\n- With query (no glob in file): FTS5 full-text search on symbol names (BM25-ranked)\n- Without query OR with glob file pattern: List matching symbols (ordered by file, line)","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[242,243],"text":"File filter supports glob patterns with * (e.g. \"src/*.py\").\nNote: When file contains glob patterns, uses SQL GLOB for filtering (case-sensitive).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[266,266],"text":"FTS5 search on symbol names (BM25-ranked).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[320,322],"text":"List symbols matching filters (no FTS, ordered by file and line).\nFile filter supports SQLite GLOB patterns: * matches any sequence, ? matches single char.\nQuery performs substring match on symbol name when provided.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[406,406],"text":"FTS5 search on text content, with optional kind, file, and project filters.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[453,453],"text":"FTS5 search on file paths, titles, and descriptions, with optional language and project filters.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[503,503],"text":"Get all symbols in a file, ordered by start line.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[533,533],"text":"Get direct children of a symbol in a file.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[563,563],"text":"Get all imports for a file (symbols with kind \"import\").","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[593,594],"text":"Get all references TO a symbol (who calls/uses this symbol).\nReturns references sorted by file, then line.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[642,643],"text":"Get all references FROM a symbol (what does this symbol call/use).\nReturns references sorted by file, then line.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[691,691],"text":"Search references by name using FTS5 (BM25-ranked).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[740,740],"text":"Get the hash of a file from the DB (for change detection).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[753,754],"text":"Remove all data for a file (from files, symbols, texts, refs tables).\nDoes not rebuild FTS indexes - caller should call rebuild_fts() after batch operations.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[779,781],"text":"Upsert a single file and its symbols/texts/references.\nRemoves old data for this path first, then inserts new data.\nDoes not rebuild FTS indexes - caller should call rebuild_fts() after batch operations.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[868,870],"text":"Rebuild all FTS5 indexes.\nCall this after batch upsert/remove operations.\nNo-op when FTS is disabled (build mode).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[886,886],"text":"Export all data from DB back to vecs (for flushing to disk).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[994,994],"text":"Export data for a specific project from DB back to vecs (for flushing to disk).","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[1106,1106],"text":"List all unique projects in the database.","parent":"SearchDb"}
{"file":"src/server/db.rs","kind":"docstring","line":[1120,1121],"text":"Quote a string for use in an FTS5 MATCH expression.\nWraps in double quotes and escapes any internal double quotes."}
{"file":"src/server/mcp.rs","kind":"comment","line":[21,21],"text":"Parameter structs for each tool"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[24,24],"text":"Search query for symbol names. If omitted, lists all symbols matching the filters."}
{"file":"src/server/mcp.rs","kind":"docstring","line":[26,26],"text":"Filter by symbol kind (e.g. function, struct, class, method)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[28,28],"text":"Filter by file path. Supports glob patterns with * (e.g. \"src/utils/*.py\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[30,30],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[32,32],"text":"Maximum number of results to return (default: 100)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[34,34],"text":"Number of results to skip for pagination (default: 0)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[36,36],"text":"Number of code snippet lines: 0=none, -1=all, N=N lines (default: 10)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[42,42],"text":"Search query for file paths"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[44,44],"text":"Filter by language (e.g. python, rust, javascript)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[46,46],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[52,52],"text":"Search query for text content"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[54,54],"text":"Filter by text kind (e.g. docstring, comment)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[56,56],"text":"Filter by file path"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[58,58],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[64,64],"text":"File path to get symbols for"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[66,66],"text":"Number of code snippet lines: 0=none, -1=all, N=N lines (default: 10)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[72,72],"text":"File path containing the parent symbol"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[74,74],"text":"Name of the parent symbol"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[76,76],"text":"Number of code snippet lines: 0=none, -1=all, N=N lines (default: 10)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[82,82],"text":"File path to get imports for"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[88,88],"text":"Symbol name to find callers for (e.g. \"my_function\", \"MyClass.method\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[90,90],"text":"Filter by reference kind (e.g. \"call\", \"import\", \"type_annotation\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[92,92],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[98,98],"text":"Symbol name to find callees for (e.g. \"my_function\", \"MyClass.method\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[100,100],"text":"Filter by reference kind (e.g. \"call\", \"import\", \"type_annotation\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[102,102],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[108,108],"text":"Search query for reference names"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[110,110],"text":"Filter by reference kind (e.g. \"call\", \"import\", \"type_annotation\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[112,112],"text":"Filter by file path"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[114,114],"text":"Filter by project (relative path from workspace root, e.g. \"libs/utils\")"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[116,116],"text":"Maximum number of results to return (default: 100)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[118,118],"text":"Number of results to skip for pagination (default: 0)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[122,122],"text":"Response wrapper for SymbolEntry with optional snippet."}
{"file":"src/server/mcp.rs","kind":"docstring","line":[131,131],"text":"MCP server exposing code-index query tools."}
{"file":"src/server/mcp.rs","kind":"docstring","line":[133,134],"text":"`SearchDb` wraps a `rusqlite::Connection` which is not `Sync`, so we protect\nit with a `Mutex` to satisfy rmcp's `Send + Sync` requirements."}
{"file":"src/server/mcp.rs","kind":"docstring","line":[159,159],"text":"Enrich symbols with snippets, filtering out symbols whose files are missing.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[191,191],"text":"Search or list symbols. With query: FTS5 search (BM25-ranked). Without query: list all matching filters.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[193,193],"text":"Search or list symbols. Provide query for full-text search, or omit to list all symbols matching filters. File filter supports glob patterns (e.g. 'src/*.py'). Returns code snippets by default.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[227,227],"text":"Search files by path using FTS5 full-text search (BM25-ranked).","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[228,228],"text":"Search files by path with optional language filter","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[251,251],"text":"Search text entries (docstrings, comments) using FTS5 full-text search (BM25-ranked).","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[253,253],"text":"Search text entries (docstrings, comments) with optional kind/file filters","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[278,278],"text":"Get all symbols in a file, ordered by line number.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[280,280],"text":"Get all symbols in a file, ordered by line number. Returns code snippets by default.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[305,305],"text":"Get direct children of a symbol (e.g. methods of a class).","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[307,307],"text":"Get direct children of a symbol (e.g. methods of a class). Returns code snippets by default.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[334,334],"text":"Get all import statements for a file.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[335,335],"text":"Get all import statements for a file","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[354,354],"text":"List all indexed projects with metadata from package manifests.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[356,356],"text":"List all indexed projects with metadata extracted from package manifests (package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml, *.gemspec). Returns name, description, and list of manifest files found.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[408,408],"text":"Get all references TO a symbol (who calls/uses this symbol).","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[410,410],"text":"Find all places that call or reference a symbol. Returns references sorted by file and line. Useful for understanding symbol usage and finding callers of a function.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[434,434],"text":"Get all references FROM a symbol (what does this symbol call/use).","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[436,436],"text":"Find all symbols that a given function/method calls or references. Returns references sorted by file and line. Useful for understanding dependencies and call chains.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[460,460],"text":"Search references by name using FTS5.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"string","line":[462,462],"text":"Search for symbol references (calls, imports, type annotations) using full-text search. Filter by kind, file, or project.","parent":"CodeIndexServer"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[494,494],"text":"Project info returned by list_projects, combining path with manifest metadata."}
{"file":"src/server/mcp.rs","kind":"docstring","line":[497,497],"text":"Relative path from workspace root (empty string for root project)"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[499,499],"text":"Metadata extracted from package manifests"}
{"file":"src/server/mcp.rs","kind":"docstring","line":[523,523],"text":"Start the MCP server over stdio with the given search database and mount table."}
{"file":"src/server/mcp.rs","kind":"string","line":[532,532],"text":"MCP serve error: {e}"}
{"file":"src/server/mcp.rs","kind":"string","line":[536,536],"text":"MCP runtime error: {e}"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[4,4],"text":"Extracts code snippets from source files at query time."}
{"file":"src/server/snippet.rs","kind":"docstring","line":[6,7],"text":"Resolves file paths relative to workspace root and reads\nthe specified line ranges from disk."}
{"file":"src/server/snippet.rs","kind":"docstring","line":[14,14],"text":"Create a new snippet extractor with the given workspace root.","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[19,19],"text":"Resolve absolute file path from project and relative file path.","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[28,28],"text":"Extract a code snippet from a file.","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[30,38],"text":"# Arguments\n* `project` - Relative project path from workspace root (e.g., \"libs/utils\", \"\" for root)\n* `file` - File path relative to project root\n* `line_start` - Starting line number (1-indexed, inclusive)\n* `line_end` - Ending line number (1-indexed, inclusive)\n* `snippet_lines` - Number of lines to include:\n- `0`: No snippet (returns None immediately)\n- `-1`: All lines in range (blank lines skipped)\n- `N > 0`: First N non-blank lines","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[40,41],"text":"Returns `None` if file cannot be read or snippet_lines is 0.\nAdds \"...\" suffix when truncated.","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"docstring","line":[99,99],"text":"Check if a file exists (for filtering symbols with missing files).","parent":"SnippetExtractor"}
{"file":"src/server/snippet.rs","kind":"string","line":[123,123],"text":"fn main() {\\n println!(\\\"hello\\\");\\n}\\n"}
{"file":"src/server/snippet.rs","kind":"string","line":[131,131],"text":"fn main() {\\n println!(\\\"hello\\\");\\n}"}
{"file":"src/server/snippet.rs","kind":"string","line":[138,138],"text":"line1\\nline2\\nline3\\nline4\\nline5\\n"}
{"file":"src/server/snippet.rs","kind":"string","line":[149,149],"text":"line1\\n\\n \\nline2\\n\\nline3\\n"}
{"file":"src/server/snippet.rs","kind":"string","line":[160,160],"text":"fn main() {}"}
{"file":"src/server/snippet.rs","kind":"string","line":[182,182],"text":"pub fn test() {}"}
{"file":"src/server/snippet.rs","kind":"string","line":[187,187],"text":"pub fn test() {}"}
{"file":"src/utils/hasher.rs","kind":"docstring","line":[5,6],"text":"Compute the BLAKE3 hash of a file's contents, truncated to 64 bits,\nreturned as a 16-character hex string."}
{"file":"src/utils/hasher.rs","kind":"docstring","line":[12,13],"text":"Compute the BLAKE3 hash of byte content, truncated to 64 bits,\nreturned as a 16-character hex string."}
{"file":"src/utils/hasher.rs","kind":"comment","line":[17,17],"text":"Truncate to first 8 bytes (64 bits), hex-encode to 16 chars"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[1,1],"text":"Package manifest parsing for project metadata extraction."}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[3,4],"text":"Parses common package manifests (package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml, *.gemspec)\nand returns both fixed metadata (name, description) and list of manifest files found."}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[11,11],"text":"Fixed project metadata extracted from manifests."}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[14,14],"text":"Human-readable project name (from first manifest found, or directory name)"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[16,16],"text":"Project description (from first manifest with description)"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[18,18],"text":"List of manifest files found (e.g., [\"package.json\", \"Cargo.toml\"])"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[22,22],"text":"Extract project metadata from all manifests found in the project root."}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[24,25],"text":"Checks for: package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml, *.gemspec\nReturns fixed metadata (name, description) plus list of manifest files found."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[31,31],"text":"Try each manifest type"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[66,66],"text":"go.mod has no description"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[90,90],"text":"Fallback: directory name"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[106,107],"text":"Parse package.json and return (name, description)\nHandles both regular packages and monorepo roots (private: true without name)."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[113,113],"text":"Try to get name from the package"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[122,122],"text":"Handle monorepo roots (private: true without name) - use directory name"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[139,140],"text":"Parse Cargo.toml and return (name, description)\nHandles both package manifests ([package]) and workspace manifests ([workspace])."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[146,146],"text":"Try [package] first (standard crate)"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[157,157],"text":"Try [workspace] (workspace root) - use directory name, no description"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[170,170],"text":"Parse pyproject.toml and return (name, description)"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[176,176],"text":"Try project.name (PEP 621)"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[187,187],"text":"Try tool.poetry.name (Poetry)"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[202,203],"text":"Parse go.mod and return the module name\ngo.mod has no description field"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[219,219],"text":"Use last segment as name, filter out empty strings"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[227,228],"text":"Parse pom.xml (Maven) and return (name, description)\nUses simple regex-based extraction to avoid adding an XML dependency."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[233,234],"text":"Extract artifactId as name (prefer <name> if present at top level)\nWe look for top-level elements, not nested in <parent> or <dependency>"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[243,244],"text":"Simple XML element extraction (first occurrence, top-level only).\nThis is a basic implementation that works for common pom.xml structures."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[254,254],"text":"Empty or contains nested elements"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[261,262],"text":"Parse *.gemspec (Ruby gem) and return (filename, name, description)\nLooks for .name and .summary/.description assignments."}
{"file":"src/utils/manifest.rs","kind":"comment","line":[264,264],"text":"Find *.gemspec file in the directory"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[273,273],"text":"Extract name: look for .name = \"...\" or .name = '...'"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[276,276],"text":"Extract description: prefer .summary, fall back to .description"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[283,283],"text":"Extract a Ruby string assignment like `s.name = \"value\"` or `spec.name = 'value'`"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[285,285],"text":"Pattern: <var>.field = \"value\" or <var>.field = 'value'"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[290,290],"text":"Find .field in the line (e.g., \"s.name\" or \"spec.name\")"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[296,296],"text":"Handle quoted strings"}
{"file":"src/utils/manifest.rs","kind":"docstring","line":[306,306],"text":"Extract a quoted string (single or double quotes)"}
{"file":"src/utils/manifest.rs","kind":"string","line":[330,330],"text":"{\"name\": \"my-app\", \"description\": \"A cool app\", \"version\": \"1.0.0\"}\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[336,336],"text":"A cool app"}
{"file":"src/utils/manifest.rs","kind":"string","line":[345,350],"text":"\n[package]\nname = \"my-crate\"\nversion = \"0.1.0\"\ndescription = \"A Rust library\"\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[356,356],"text":"A Rust library"}
{"file":"src/utils/manifest.rs","kind":"string","line":[365,370],"text":"\n[project]\nname = \"my-python-pkg\"\ndescription = \"A Python package\"\nversion = \"1.0.0\"\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[376,376],"text":"A Python package"}
{"file":"src/utils/manifest.rs","kind":"string","line":[385,390],"text":"\n[tool.poetry]\nname = \"poetry-pkg\"\ndescription = \"A Poetry package\"\nversion = \"2.0.0\"\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[396,396],"text":"A Poetry package"}
{"file":"src/utils/manifest.rs","kind":"string","line":[404,404],"text":"module github.com/user/myrepo\\n\\ngo 1.21\\n"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[410,410],"text":"go.mod has no description"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[417,417],"text":"No manifest files"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[420,420],"text":"Name should be the temp directory name (starts with '.')"}
{"file":"src/utils/manifest.rs","kind":"string","line":[431,431],"text":"{\"name\": \"npm-name\", \"description\": \"NPM desc\"}\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[436,440],"text":"\n[package]\nname = \"cargo-name\"\ndescription = \"Cargo desc\"\n\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[445,445],"text":"First found (npm) wins for name/description"}
{"file":"src/utils/manifest.rs","kind":"string","line":[447,447],"text":"NPM desc"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[448,448],"text":"But both manifest files are listed"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[456,456],"text":"package.json with name but no description"}
{"file":"src/utils/manifest.rs","kind":"string","line":[457,457],"text":"{\"name\": \"npm-name\"}\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[458,458],"text":"Cargo.toml with description"}
{"file":"src/utils/manifest.rs","kind":"string","line":[461,465],"text":"\n[package]\nname = \"cargo-name\"\ndescription = \"Cargo has the description\"\n\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[470,470],"text":"npm first"}
{"file":"src/utils/manifest.rs","kind":"string","line":[471,471],"text":"Cargo has the description"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[471,471],"text":"cargo provides description"}
{"file":"src/utils/manifest.rs","kind":"string","line":[479,488],"text":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project>\n <modelVersion>4.0.0</modelVersion>\n <groupId>com.example</groupId>\n <artifactId>my-java-app</artifactId>\n <version>1.0.0</version>\n <name>My Java Application</name>\n <description>A sample Java application</description>\n</project>\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[493,493],"text":"My Java Application"}
{"file":"src/utils/manifest.rs","kind":"string","line":[494,494],"text":"A sample Java application"}
{"file":"src/utils/manifest.rs","kind":"string","line":[503,509],"text":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project>\n <groupId>com.example</groupId>\n <artifactId>simple-app</artifactId>\n <version>1.0.0</version>\n</project>\n\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[514,514],"text":"Falls back to artifactId when <name> is not present"}
{"file":"src/utils/manifest.rs","kind":"string","line":[525,533],"text":"\nGem::Specification.new do |s|\n s.name = \"my_gem\"\n s.version = \"1.0.0\"\n s.summary = \"A sample Ruby gem\"\n s.description = \"A longer description of my gem\"\n s.authors = [\"Test Author\"]\nend\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[539,539],"text":"A sample Ruby gem"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[539,539],"text":"uses summary"}
{"file":"src/utils/manifest.rs","kind":"string","line":[548,554],"text":"\nGem::Specification.new do |spec|\n spec.name = 'another-gem'\n spec.version = '2.0.0'\n spec.summary = 'Single quoted summary'\nend\n\""}
{"file":"src/utils/manifest.rs","kind":"string","line":[560,560],"text":"Single quoted summary"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[567,567],"text":"Create a subdirectory with a specific name"}
{"file":"src/utils/manifest.rs","kind":"string","line":[572,576],"text":"\n[workspace]\nresolver = \"2\"\nmembers = [\"crate-a\", \"crate-b\"]\n\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[581,582],"text":"Uses directory name\nWorkspaces don't have description"}
{"file":"src/utils/manifest.rs","kind":"comment","line":[589,589],"text":"Create a subdirectory with a specific name"}
{"file":"src/utils/manifest.rs","kind":"string","line":[594,594],"text":"{\"private\": true, \"workspaces\": [\"packages/*\"]}\""}
{"file":"src/utils/manifest.rs","kind":"comment","line":[599,599],"text":"Uses directory name"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[23,23],"text":"Run the main event loop for file watching."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[25,27],"text":"Receives events from all mounts via `rx` (notify watchers already initialized).\nEach event includes the mount root, avoiding the need for mount lookup.\nUses `tx` for passing to new project discoveries."}
{"file":"src/watcher/handler.rs","kind":"string","line":[37,37],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[41,41],"text":"event loop ready ({} directories watched)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[43,43],"text":"Debounce state: path -> (last event time, event kind, mount root)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[48,48],"text":"Wait for events with timeout"}
{"file":"src/watcher/handler.rs","kind":"string","line":[57,57],"text":"notify error: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[60,60],"text":"Check for debounced events ready to process"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[63,63],"text":"Flush all dirty mounts before shutting down"}
{"file":"src/watcher/handler.rs","kind":"string","line":[65,65],"text":"event loop channel closed, shutting down"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[70,70],"text":"Process debounced events"}
{"file":"src/watcher/handler.rs","kind":"string","line":[84,84],"text":"error handling watch events: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[88,88],"text":"Flush dirty mounts to disk after quiet period"}
{"file":"src/watcher/handler.rs","kind":"string","line":[91,91],"text":"failed to flush index to disk: {}"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[100,101],"text":"Handle when a project is discovered (during walk or watch).\nMounts the project and loads/indexes it."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[104,106],"text":"- `load_from_cache`: If true (serve mode), try loading from .codeindex/ first\nIf false (build mode), always re-index\n- `tx`: If provided, initializes file watcher during walk"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[109,112],"text":"1. If already mounted, skip\n2. Try mount RW, fall back to RO if lock is held\n3. If load_from_cache && .codeindex/ exists, load from disk\n4. Otherwise, index files (walks and discovers subprojects)"}
{"file":"src/watcher/handler.rs","kind":"string","line":[122,122],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[124,124],"text":"Check if already mounted (exact match, not prefix match)"}
{"file":"src/watcher/handler.rs","kind":"string","line":[127,127],"text":"failed to canonicalize {:?}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[132,132],"text":"Mount the new project (tries RW, falls back to RO if lock held)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[145,145],"text":"Try loading from .codeindex/ first (only if load_from_cache is true)"}
{"file":"src/watcher/handler.rs","kind":"string","line":[152,152],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[161,161],"text":"failed to load index for '{}'"}
{"file":"src/watcher/handler.rs","kind":"string","line":[165,165],"text":"loaded '{}' ({}) from .codeindex/: {} files, {} symbols, {} texts, {} refs"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[174,174],"text":"Loaded from cache - no need to walk (subprojects have their own .codeindex/)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[179,179],"text":"Can't rebuild in RO mode, just warn"}
{"file":"src/watcher/handler.rs","kind":"string","line":[181,181],"text":"failed to read .codeindex/ for '{}' (read-only): {}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[188,188],"text":"failed to read .codeindex/ for '{}', rebuilding: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[192,192],"text":"Fall through to index files"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[196,196],"text":"No .codeindex/ and read-only in serve mode - nothing to do"}
{"file":"src/watcher/handler.rs","kind":"string","line":[198,198],"text":"mounted '{}' ({}) - no .codeindex/, read-only"}
{"file":"src/watcher/handler.rs","kind":"string","line":[205,205],"text":"indexing '{}' ({})"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[207,207],"text":"Walk and index all files in the new project (also discovers subprojects)"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[213,213],"text":"Walk a project directory, indexing files and discovering subprojects."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[215,215],"text":"Uses Mount's `walk()` method which handles gitignore filtering and subproject discovery."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[217,218],"text":"- `load_from_cache`: passed to recursive on_project_discovery calls for subprojects\n- `tx`: If provided, initializes watcher and adds directories during walk"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[226,226],"text":"Use relative project path from workspace root"}
{"file":"src/watcher/handler.rs","kind":"string","line":[230,230],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[234,235],"text":"Collect events first, then process them\nThis allows us to release the mount table lock before recursive calls"}
{"file":"src/watcher/handler.rs","kind":"string","line":[242,242],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[246,246],"text":"no mount found for {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[248,248],"text":"Initialize watcher before walk (if tx provided)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[253,254],"text":"Walk the mount, collecting events\nWatches are added internally by on_fs_event during walk"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[258,258],"text":"Reconstruct abs_path from mount + path"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[265,265],"text":"Not emitted during walk"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[269,269],"text":"MountTable lock released here"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[271,271],"text":"Process files"}
{"file":"src/watcher/handler.rs","kind":"string","line":[277,277],"text":"processed {} files so far for project '{}'"}
{"file":"src/watcher/handler.rs","kind":"string","line":[283,283],"text":"failed to index {}: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[287,288],"text":"Process subprojects (always - this is the single walk strategy)\nPass load_from_cache to recursive calls"}
{"file":"src/watcher/handler.rs","kind":"string","line":[291,291],"text":"failed to handle subproject {}: {}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[296,296],"text":"finished indexing project '{}': {} files, {} subprojects"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[302,302],"text":"Rebuild FTS after batch indexing"}
{"file":"src/watcher/handler.rs","kind":"string","line":[305,305],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[308,308],"text":"Mark mount as dirty"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[317,317],"text":"Handle a batch of file system events."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[319,320],"text":"All logic (gitignore, SKIP_ENTRIES, project detection, watches) is delegated\nto `Mount::on_fs_event()` - the same rules apply for notify events as for walker."}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[322,322],"text":"Each event includes the mount root, so we can directly get the mount without lookup."}
{"file":"src/watcher/handler.rs","kind":"string","line":[333,333],"text":"processing {} file events"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[335,335],"text":"Collect mount events to process"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[339,339],"text":"Early filter: skip .codeindex/ paths before expensive canonicalize()"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[344,345],"text":"For file removal, the path may not exist anymore\nFor creation/modification, canonicalize to handle symlinks"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[347,347],"text":"Use the path as-is for removal (can't canonicalize deleted files)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[352,352],"text":"Path doesn't exist"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[356,356],"text":"Get mount directly using the mount root from the event"}
{"file":"src/watcher/handler.rs","kind":"string","line":[359,359],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[361,361],"text":"Pass EventKind directly to on_fs_event (same type as walker uses)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[369,369],"text":"Process mount events"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[373,374],"text":"Discover the new project (watcher is initialized during walk)\nWatch mode always uses cache (load_from_cache=true)"}
{"file":"src/watcher/handler.rs","kind":"string","line":[376,376],"text":"failed to handle project discovery: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[382,382],"text":"Compute relative project path from workspace root"}
{"file":"src/watcher/handler.rs","kind":"string","line":[386,386],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[391,391],"text":"failed to process file {}: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[393,393],"text":"Mark mount as dirty"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[403,403],"text":"Compute relative project path from workspace root"}
{"file":"src/watcher/handler.rs","kind":"string","line":[407,407],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[411,411],"text":"file deleted: {} (project: {})"}
{"file":"src/watcher/handler.rs","kind":"string","line":[414,414],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"string","line":[416,416],"text":"failed to remove file {}: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[418,418],"text":"Mark mount as dirty"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[427,427],"text":"Rebuild FTS indexes once after all changes"}
{"file":"src/watcher/handler.rs","kind":"string","line":[431,431],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[438,438],"text":"Process a single file change (create or modify)."}
{"file":"src/watcher/handler.rs","kind":"comment","line":[445,445],"text":"Read file content once"}
{"file":"src/watcher/handler.rs","kind":"string","line":[447,447],"text":"failed to read {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[449,449],"text":"Hash the content"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[452,452],"text":"Check if hash changed"}
{"file":"src/watcher/handler.rs","kind":"string","line":[455,455],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[459,459],"text":"No change, skip"}
{"file":"src/watcher/handler.rs","kind":"string","line":[461,461],"text":"skipping unchanged file: {} (project: {})"}
{"file":"src/watcher/handler.rs","kind":"string","line":[469,469],"text":"indexing file: {} (project: {})"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[471,471],"text":"Count lines"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[474,474],"text":"Detect language"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[487,487],"text":"Parse source files for symbols, texts, and references"}
{"file":"src/watcher/handler.rs","kind":"string","line":[496,496],"text":"failed to parse {}: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[500,500],"text":"Extract file metadata (title and description)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[516,516],"text":"Upsert into database"}
{"file":"src/watcher/handler.rs","kind":"string","line":[519,519],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[525,525],"text":"Flush all dirty mounts to disk."}
{"file":"src/watcher/handler.rs","kind":"string","line":[532,532],"text":"mount table lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[534,534],"text":"Collect dirty RW mounts"}
{"file":"src/watcher/handler.rs","kind":"string","line":[543,543],"text":"failed to flush {}: {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[545,545],"text":"Clear dirty flag"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[555,555],"text":"Flush a single mount's index from memory to disk."}
{"file":"src/watcher/handler.rs","kind":"comment","line":[561,561],"text":"Use relative project path from workspace root"}
{"file":"src/watcher/handler.rs","kind":"string","line":[566,566],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[571,571],"text":"Clear project field for disk export - the .codeindex/ location implies the project"}
{"file":"src/watcher/handler.rs","kind":"string","line":[586,586],"text":"no files to flush for {}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[590,590],"text":"Collect languages"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[598,598],"text":"Derive project name from directory name"}
{"file":"src/watcher/handler.rs","kind":"string","line":[616,616],"text":"flushed index to disk for {}: {} files, {} symbols, {} texts, {} refs"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[627,628],"text":"Flush the entire index from memory to disk (legacy single-project).\nThis is used during initial index building before MountTable is set up."}
{"file":"src/watcher/handler.rs","kind":"string","line":[632,632],"text":"db lock poisoned: {e}"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[636,636],"text":"Collect languages"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[644,644],"text":"Derive project name from directory name"}
{"file":"src/watcher/handler.rs","kind":"string","line":[662,662],"text":"flushed index to disk: {} files, {} symbols, {} texts, {} refs"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[672,672],"text":"Count the number of lines in a byte buffer."}
{"file":"src/watcher/handler.rs","kind":"comment","line":[678,678],"text":"If file doesn't end with newline, the last line still counts"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[692,692],"text":"Helper to create a minimal .git directory (just the directory, not a real repo)"}
{"file":"src/watcher/handler.rs","kind":"docstring","line":[697,697],"text":"Helper to create a source file"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[708,708],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[711,711],"text":"Create a simple project structure"}
{"file":"src/watcher/handler.rs","kind":"string","line":[715,715],"text":"fn main() {\\n println!(\\\"hello\\\");\\n}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[719,719],"text":"pub fn greet() -> String {\\n \\\"hello\\\".to_string()\\n}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[722,722],"text":"Index the project (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[728,728],"text":"Verify: should have 2 files indexed"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[732,732],"text":"Root project has empty string"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[734,734],"text":"Search for the main function"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[744,744],"text":"Search for greet function"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[758,758],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[761,761],"text":"Create root project"}
{"file":"src/watcher/handler.rs","kind":"string","line":[763,763],"text":"fn app_main() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[765,765],"text":"Create a subproject"}
{"file":"src/watcher/handler.rs","kind":"string","line":[768,768],"text":"pub fn utility() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[770,770],"text":"Index from root (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[776,776],"text":"Verify: should have 2 projects"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[783,783],"text":"Root project should have app_main (search without filter, check project field)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[790,790],"text":"Subproject should have utility"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[801,801],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[804,804],"text":"Create root project"}
{"file":"src/watcher/handler.rs","kind":"string","line":[806,806],"text":"fn root_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[808,808],"text":"Create nested subprojects: root > libs/core > libs/core/nested"}
{"file":"src/watcher/handler.rs","kind":"string","line":[811,811],"text":"fn core_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[815,815],"text":"fn nested_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[817,817],"text":"Index from root (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[823,823],"text":"Verify: should have 3 projects"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[828,828],"text":"Each function should be in its respective project (search without filter, verify project)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[856,856],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[859,859],"text":"Create root with a subproject"}
{"file":"src/watcher/handler.rs","kind":"string","line":[861,861],"text":"fn root_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[865,865],"text":"fn sub_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[867,867],"text":"Index (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[873,873],"text":"Verify: sub.rs should NOT appear in root project"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[876,876],"text":"Search without project filter - should find both"}
{"file":"src/watcher/handler.rs","kind":"string","line":[883,883],"text":"root_fn should appear exactly once"}
{"file":"src/watcher/handler.rs","kind":"string","line":[884,884],"text":"sub_fn should appear exactly once"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[886,886],"text":"Verify project assignment"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[897,897],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[900,900],"text":"Create root with two subprojects"}
{"file":"src/watcher/handler.rs","kind":"string","line":[902,902],"text":"fn main() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[906,906],"text":"fn a() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[910,910],"text":"fn b() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[912,912],"text":"Index (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[918,918],"text":"Verify mount table has all 3 mounts"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[923,923],"text":"All should be mounted (lib_a/lib_b are already based on canonicalized root)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[932,932],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[935,935],"text":"Create two projects with same-named function"}
{"file":"src/watcher/handler.rs","kind":"string","line":[937,937],"text":"fn helper() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"string","line":[941,941],"text":"fn helper() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[943,943],"text":"Index (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[951,951],"text":"Without filter: should find 2 helpers"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[957,957],"text":"One should be root (empty project), one should be sub"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[963,963],"text":"With sub filter: should find 1"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[974,974],"text":"Canonicalize for macOS where /var -> /private/var"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[977,977],"text":"Create deeply nested subproject"}
{"file":"src/watcher/handler.rs","kind":"string","line":[981,981],"text":"fn deep_fn() {}\\n"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[983,983],"text":"Index (load_from_cache=false to force indexing)"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[989,989],"text":"Verify relative path is correct"}
{"file":"src/watcher/handler.rs","kind":"comment","line":[995,995],"text":"Symbol should have correct project"}