{"id":49570988,"url":"https://github.com/sutantodadang/zindeks","last_synced_at":"2026-05-27T13:02:05.655Z","repository":{"id":355402311,"uuid":"1227958712","full_name":"sutantodadang/zindeks","owner":"sutantodadang","description":"Zindeks is a dependency-light local code indexing engine written in Zig. It is designed for one-time indexing and many low-latency readers: AI agents can share a long-lived zindeks serve process over stdin/stdout JSON-RPC without reloading the index for each request.","archived":false,"fork":false,"pushed_at":"2026-05-17T07:07:54.000Z","size":13003,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-17T09:07:31.655Z","etag":null,"topics":["index","mcp","repository","zig"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sutantodadang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T11:59:49.000Z","updated_at":"2026-05-17T07:07:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sutantodadang/zindeks","commit_stats":null,"previous_names":["sutantodadang/zindeks"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/sutantodadang/zindeks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sutantodadang%2Fzindeks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sutantodadang%2Fzindeks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sutantodadang%2Fzindeks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sutantodadang%2Fzindeks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sutantodadang","download_url":"https://codeload.github.com/sutantodadang/zindeks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sutantodadang%2Fzindeks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33566873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["index","mcp","repository","zig"],"created_at":"2026-05-03T14:01:14.962Z","updated_at":"2026-05-27T13:02:05.649Z","avatar_url":"https://github.com/sutantodadang.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zindeks\n\nDependency-light code knowledge graph engine in Zig. One-time index, many low-latency readers. AI agents share a long-lived `zindeks serve` process over stdin/stdout JSON-RPC (MCP-compliant). Single static binary: ~3.4 MB, zero runtime dependencies.\n\n**Current status:** 20+ languages (tree-sitter), 14 MCP tools, SQLite graph database, BM25 search, call graph tracing, Leiden community detection, incremental indexing, cross-platform (6 targets).\n\n## Install from GitHub releases\n\nRelease binaries are published when a `v*` tag is pushed. Assets built for:\n\n- Linux: `x86_64`, `aarch64`\n- macOS: `x86_64`, `aarch64`\n- Windows: `x86_64`, `aarch64`\n\nUnix-like systems:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/sutantodadang/zindeks/main/scripts/install.sh | sh\n```\n\nWindows PowerShell:\n\n```powershell\n$repo = \"sutantodadang/zindeks\"\n$script = Join-Path $env:TEMP \"install-zindeks.ps1\"\nInvoke-WebRequest \"https://raw.githubusercontent.com/$repo/main/scripts/install.ps1\" -OutFile $script\n\u0026 $script -Repo $repo\n```\n\nTo install a specific release:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/sutantodadang/zindeks/main/scripts/install.sh | sh -s -- --version v0.1.0\n```\n\n```powershell\n\u0026 $script -Repo $repo -Version v0.1.0\n```\n\nUpdate the current install:\n\n```bash\nzindeks update\nzindeks update --version v0.1.1\n```\n\n`zindeks update` installs into the current executable directory by default. Use `--dir \u003cinstall-dir\u003e` for custom location, `--repo \u003cowner/repo\u003e` for forks, `--no-path-update` to skip Windows PATH edits, `--dry-run` to preview without downloading.\n\n### AI agent setup (one command)\n\nAfter installing the binary:\n\n```bash\nzindeks install            # interactive: picks your AI host(s), wires MCP, offers to index\nzindeks install --host claude-code --scope both --yes   # non-interactive\nzindeks doctor             # verify\n```\n\nSee [INTEGRATIONS.md](INTEGRATIONS.md) for per-host adapter details and exact paths written.\n\n## Quick start\n\n```bash\nzindeks index .                     # Index current repo (shows progress)\nzindeks search \"database pool\" .    # BM25 keyword search\nzindeks serve                       # Start MCP-compliant JSON-RPC server\nzindeks bench cold-index .          # Benchmark indexing speed (3 iters, prints min/mean/p99/peak_rss)\n```\n\n## Supported languages\n\n20+ languages via vendored tree-sitter grammars:\n\nC, C++, C#, CSS, Dart, Elixir, Go, Haskell, Java, JavaScript, JSON, Lua, Python, Rust, Scala, Swift, TOML, TypeScript, TSX, YAML, Zig\n\nAutomatic language detection by file extension. Symbol extraction currently implemented for Zig; other languages use the binary indexer for BM25 search and the SQLite graph for symbol storage.\n\n## Indexing pipeline\n\n`zindeks index` runs a two-phase pipeline:\n\n1. **Binary indexer** — scans source files, tokenizes identifiers, builds BM25 inverted index. Outputs 5 immutable binary files (meta, content, symbol, posting, graph) with mmap-based read access.\n\n2. **Knowledge graph builder** — re-scans files, parses with tree-sitter AST, extracts symbols (functions, structs, enums, variables, imports), and writes structured records to SQLite. Populates the graph database with typed nodes and edges.\n\nProgress is printed to stderr during indexing (`Indexing '...'... 100 source files scanned...`). Files larger than 256 MB are skipped with a warning.\n\n## Storage\n\n### Index store\n\nDefault indexes are written under the user's cache directory:\n\n| OS | Default root |\n| --- | --- |\n| Windows | `%LOCALAPPDATA%\\zindeks` |\n| Linux/BSD | `${XDG_CACHE_HOME:-~/.cache}/zindeks` |\n| macOS | `~/Library/Caches/zindeks` |\n\n```\nzindeks/\n  projects/\n    \u003cproject-name\u003e-\u003croot-hash\u003e/\n      project.json\n      current\n      lock\n      segments/\n        \u003csegment-id\u003e/\n          meta.idx    content.idx    symbol.idx    posting.idx    graph.idx\n          graph.db    (SQLite)\n```\n\nUse `--store-root \u003cdir\u003e` to choose another global store, or `--index-dir \u003cdir\u003e` for direct legacy-style index.\n\n### Binary files (mmap)\n\nFive immutable files for the BM25 search engine:\n\n| File | Contents |\n| --- | --- |\n| `meta.idx` | Document metadata, global string table |\n| `content.idx` | Chunked source bytes |\n| `symbol.idx` | Sorted symbol records + hash index |\n| `posting.idx` | Sorted term records + posting lists |\n| `graph.idx` | Import/dependency records |\n\nAll files use fixed-size records with offset tables. Read path is mmap-first — no deserialization.\n\n### Graph database (SQLite)\n\nSingle `graph.db` file with 5 tables:\n\n| Table | Purpose |\n| --- | --- |\n| `documents` | File paths, languages, content hashes, mtimes |\n| `symbols` | Extracted symbols (name, kind, location, community) |\n| `edges` | Typed relationships (CALLS, IMPORTS, DEFINES, etc.) |\n| `adrs` | Architecture Decision Records |\n| `traces` | Ingested runtime traces |\n\n9 indexes for fast querying. Schema auto-migrates on open.\n\n## Search engine\n\nFull BM25+ with IDF normalization:\n\n- **IDF:** `log(1 + (N - df + 0.5) / (df + 0.5))`\n- **TF:** `tf * (k1 + 1) / (tf + k1 * (1 - b + b * doc_len / avg_doc_len))`\n- **Defaults:** k1 = 1.5, b = 0.75\n- **Query-aware snippets** with newline-aligned context expansion\n- **CamelCase splitting** for tokenization\n- Deterministic sort by score then path\n\n## Knowledge graph\n\n### Graph operations\n\n- **Call graph tracing** — BFS traversal with cycle detection, inbound/outbound/both directions\n- **Architecture analysis** — fan-in/fan-out, entry points, module-level statistics\n- **Community detection** — Leiden algorithm (modularity gain + refinement), auto-partitions symbols\n- **Cypher queries** — lexer/parser/executor, `MATCH ... WHERE ... RETURN ...` translated to SQL\n\n### Edge types\n\n`CALLS`, `IMPORTS`, `DEFINES`, `IMPLEMENTS`, `INHERITS`, `CONTAINS`, `REFERENCES`, `HTTP_CALLS`, `FILE_CHANGES_WITH`\n\n## MCP server\n\n`zindeks serve` starts a JSON-RPC 2.0 server over stdin/stdout with MCP-compliant protocol framing (Content-Length headers, initialize handshake, capability negotiation).\n\n### 14 tools\n\n| Tool | Description |\n| --- | --- |\n| `index_repository` | Index a repo: binary + tree-sitter pipeline |\n| `list_projects` | List indexed projects in store |\n| `search_code` | BM25 keyword search with scored snippets |\n| `get_graph_schema` | Table counts and schema overview |\n| `search_graph` | Symbol search with kind/degree filters |\n| `get_code_snippet` | Source snippet by symbol name |\n| `query_graph` | Read-only SQL or Cypher against graph DB |\n| `detect_changes` | Find added/modified/deleted files vs index |\n| `index_status` | File-level staleness report |\n| `delete_project` | Remove project from store |\n| `trace_call_path` | BFS trace from a symbol (inbound/outbound/both) |\n| `get_architecture` | Fan-in/out, entry points, module stats |\n| `manage_adr` | Create/read/list Architecture Decision Records |\n| `detect_communities` | Run Leiden community detection |\n| `rename_symbol` | In-place symbol rename across files (dry-run default) |\n| `ingest_traces` | Ingest runtime trace data (JSON) |\n\nExample tool calls:\n\n```json\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"search_code\",\"arguments\":{\"query\":\"database pool\",\"limit\":10}}}\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"search_graph\",\"arguments\":{\"pattern\":\"%Handler%\",\"kind\":\"function\"}}}\n{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"trace_call_path\",\"arguments\":{\"name\":\"main\",\"direction\":\"outbound\",\"max_depth\":5}}}\n{\"jsonrpc\":\"2.0\",\"id\":4,\"method\":\"tools/call\",\"params\":{\"name\":\"get_architecture\",\"arguments\":{}}}\n{\"jsonrpc\":\"2.0\",\"id\":5,\"method\":\"tools/call\",\"params\":{\"name\":\"query_graph\",\"arguments\":{\"query\":\"MATCH (a)-[r:CALLS]-\u003e(b) RETURN a.name, b.name LIMIT 20\"}}}\n{\"jsonrpc\":\"2.0\",\"id\":6,\"method\":\"tools/call\",\"params\":{\"name\":\"detect_communities\",\"arguments\":{}}}\n```\n\n## Incremental indexing\n\n- `detect_changes` compares file metadata (size, mtime) against the SQLite documents table — returns added/modified/deleted sets without re-reading files\n- `index_status` shows per-file staleness\n- File watcher (`PollWatcher`) uses background thread polling for automatic re-index triggers\n- Changed files are transactionally deleted and re-inserted; unchanged files kept untouched\n\n## CLI\n\n```bash\nzindeks index [repo] [--store-root dir] [--index-dir dir]\nzindeks search \u003cquery\u003e [repo] [--store-root dir] [--index-dir dir]\nzindeks serve [--store-root dir] [--index-dir dir]\nzindeks update [--version tag|latest] [--repo owner/repo] [--dir dir] [--no-path-update] [--dry-run]\n```\n\n## Build from source\n\n```bash\nzig build -Doptimize=ReleaseFast\n./zig-out/bin/zindeks index .\n```\n\nRequires Zig 0.15.2. All dependencies vendored — no network access needed to build.\n\n## Performance\n\n- Binary indexer: mmap-based reads, fixed-size records, zero deserialization\n- SQLite: WAL mode, prepared statements, bounded result sets\n- BM25: posting slice scans, score-then-snippet (only top-k snippets built)\n- Scanner: single-pass file walk, streaming content, 256 MB file skip threshold\n- Cross-compiles to 6 targets from any host OS\n\n## Architecture Decision Records\n\nStore project decisions in the graph database:\n\n```json\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"manage_adr\",\"arguments\":{\"action\":\"create\",\"title\":\"Use SQLite for graph storage\",\"context\":\"Need fast local queries without external DB\",\"decision\":\"Embed SQLite via @cImport, auto-migrate schema\"}}}\n```\n\nADRs are queryable and version-tracked. Use `manage_adr` with `action: \"list\"` or `action: \"get\"` to retrieve them.\n\n## License\n\nZindeks is licensed under the [Apache License 2.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsutantodadang%2Fzindeks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsutantodadang%2Fzindeks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsutantodadang%2Fzindeks/lists"}