{"id":48330878,"url":"https://github.com/aaf2tbz/sqmd","last_synced_at":"2026-04-16T01:05:27.659Z","repository":{"id":349054393,"uuid":"1200875603","full_name":"aaf2tbz/sqmd","owner":"aaf2tbz","description":"sqmd is a code intelligence tool that gives AI agents structured access to codebases through local semantic search. It parses source files with tree-sitter, indexes every function, class, and import into a SQLite database, and exposes a layered search pipeline combining FTS, entity graphs, community detection, vector embeddings, and hint vectors.","archived":false,"fork":false,"pushed_at":"2026-04-13T01:32:21.000Z","size":637,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-13T02:29:37.822Z","etag":null,"topics":["ai-agents","coding-agent","mcp-client"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aaf2tbz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/ROADMAP.md","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-04-03T23:44:40.000Z","updated_at":"2026-04-13T01:32:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aaf2tbz/sqmd","commit_stats":null,"previous_names":["aaf2tbz/sqmd"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/aaf2tbz/sqmd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaf2tbz%2Fsqmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaf2tbz%2Fsqmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaf2tbz%2Fsqmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaf2tbz%2Fsqmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aaf2tbz","download_url":"https://codeload.github.com/aaf2tbz/sqmd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaf2tbz%2Fsqmd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31866361,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai-agents","coding-agent","mcp-client"],"created_at":"2026-04-05T01:02:22.509Z","updated_at":"2026-04-16T01:05:27.647Z","avatar_url":"https://github.com/aaf2tbz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sqmd\n\n**Code intelligence for AI agents. Drop any project in, get semantic search, dependency graphs, structured recall, and review-ready context — local-first, no API keys, one binary.**\n\nsqmd parses your codebase with tree-sitter, chunks functions/classes/structs/imports into a local SQLite index, then exposes layered search across FTS5, entity graphs, communities, vector embeddings, and hint vectors. An agent can ask \"how does authentication work?\" and get the exact functions, signatures, paths, callers, and dependency context it needs.\n\nIt is built for agent workflows:\n\n- Keep a local code index fresh while you edit.\n- Ask MCP tools for search, context, dependencies, chunks, and stats.\n- Re-index changed files from the agent without leaving the conversation.\n- Start embeddings in the background and poll progress instead of blocking.\n- Use the bundled `sqmd-review` skill for local pre-push review that checks the real git diff first and uses sqmd as extra codebase context.\n- Work from linked git worktrees while reusing the main worktree's `.sqmd/index.db`.\n\n## Benchmark Results\n\nNL query benchmark against the Signet codebase (1,268 files, 28,084 chunks, 60 queries):\n\n| Metric | FTS-only | Layered (multi-surface) |\n|--------|----------|------------------------|\n| **Hit@1** | 6 (10%) | 9 (15%) |\n| **Hit@3** | 10 (17%) | 23 (38%) |\n| **Hit@5** | 14 (23%) | 29 (48%) |\n| **Hit@10** | 16 (27%) | 38 (63%) |\n| **MRR** | 0.147 | 0.289 |\n\nMulti-surface embeddings provide a **31% MRR improvement** over body-only vector search by decomposing code identifiers into natural language and embedding names, signatures, and doc comments separately from function bodies.\n\nPerformance: ~0.55s per query, ~19 q/sec batch throughput. Native llama.cpp with Metal GPU acceleration on Apple Silicon.\n\nSee [BENCHMARKING.md](BENCHMARKING.md) for methodology and reproduction steps.\n\n## Table of Contents\n\n- [Why sqmd](#why-sqmd)\n- [Quick Start](#quick-start)\n- [Skills](#skills)\n- [Supported Harnesses](#supported-harnesses)\n- [What Gets Indexed](#what-gets-indexed)\n- [Languages](#languages)\n- [Search](#search)\n- [Architecture](#architecture)\n- [Feature Flags](#feature-flags)\n- [Supported Platforms](#supported-platforms)\n- [Build](#build)\n- [Commands](#commands)\n- [MCP Server](#mcp-server)\n- [Daemon Protocol](#daemon-protocol)\n- [Benchmarking](#benchmarking)\n- [Changelog](#changelog)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Why sqmd\n\nLLMs are bad at reading large codebases. They lose context, hallucinate file paths, and can't navigate import chains. sqmd solves this by giving agents structured, scored access to code:\n\n- **Semantic chunks, not files.** Each function, class, struct, and import is indexed individually with its name, signature, line range, and importance score.\n- **Entity graph.** Every named symbol becomes a first-class entity linked by structural relationships (extends, implements, contains) and import dependencies.\n- **Dependency-aware recall.** Import and call graphs let an agent trace \"who calls this\" across files, bidirectionally.\n- **Unified layered search.** 6-layer pipeline: FTS, graph expansion, community detection, vector KNN, multi-surface vector KNN, hint vector. No alpha-blending.\n- **Multi-surface embeddings.** Code identifiers are decomposed into natural language (`cosineSimilarity` → `cosine similarity`) and embedded separately as name, signature, and doc comment surfaces alongside the full body. At query time, all surfaces are searched and the best match per chunk is used as a targeted boost signal.\n- **Native llama.cpp runtime.** Embeddings run locally via llama.cpp with Metal GPU offloading. No external services required.\n- **MCP server.** JSON-RPC over stdio — plug sqmd directly into OpenCode, Codex, or Claude Code.\n- **Typed communities.** Module communities (files connected by imports) and type-hierarchy communities (extends/implements).\n- **Ranked retrieval.** Three-factor scoring (relevance x recency x importance) with diversity dampening.\n- **Token-budgeted context.** Assembles responses within a token budget, expanding dependencies only when budget allows.\n\n## Quick Start\n\n```bash\ncargo build --release\n\ncd /path/to/your/project\nsqmd init           # creates .sqmd/index.db\nsqmd index          # tree-sitter parse -\u003e chunk -\u003e store (incremental on re-runs)\nsqmd index --embed  # index + generate embeddings in one step\nsqmd embed          # generate vector embeddings (mxbai-embed-large via native llama.cpp)\n```\n\nsqmd looks for `gte-modernbert-base` GGUF in your local model store (default: `~/.ollama/models/`, or set `SQMD_NATIVE_MODEL` to a GGUF path). For hint generation, set `SQMD_HINT_MODEL` (default: `phi4-mini`) and ensure the GGUF is available.\n\n```bash\nsqmd search \"error handling\"                        # layered search (all 5 layers)\nsqmd search \"error handling\" --keyword              # FTS-only\nsqmd search \"User\" --type Struct                    # filter by chunk type\nsqmd context --query \"how does auth work\" --max-tokens 8000 --deps\nsqmd deps src/auth.ts --depth 2                     # trace dependency graph\n```\n\nUsing git worktrees? Run `sqmd init` and `sqmd index` once in the main checkout. When an MCP client starts from a linked worktree, sqmd can find that main-worktree index and still interpret changed file paths relative to the worktree/project root.\n\n## Skills\n\nsqmd ships with ready-to-use skills that plug into OpenCode, Codex, and Claude Code. Copy a skill directory into your tool's skills folder:\n\n```bash\n# OpenCode\ncp -r skills/sqmd-review ~/.config/opencode/skills/\n\n# Codex\ncp -r skills/sqmd-review ~/.codex/skills/\n\n# Claude Code\ncp -r skills/sqmd-review ~/.claude/skills/\n```\n\n### sqmd-review\n\nGit-connected code review using sqmd-indexed codebase context and GitHub PR history.\nRuns locally before pushing to prevent bot review comments before they happen. Adapted\nfrom [pr-reviewer](https://github.com/NicholaiVogel/pr-reviewer).\n\n**How it works:**\n\n1. Detects scope (staged, uncommitted, branch diff, commit, or PR-linked via `gh api`)\n2. Reads prior bot review comments and tracks dismissed/rebutted/addressed findings\n3. Assembles context from the git diff, `sqmd_deps` blast radius, and `sqmd_search`\n   structural search (FTS + entity graph — no embeddings needed)\n4. Runs a structured review with anti-hallucination rules and a convention checklist\n5. **Iterates** — fixes findings, re-reviews, repeats until verdict is `no_issues`\n6. Only then commits and pushes\n\nThe goal is **zero-comment pushes**: every issue the remote bot would flag is caught\nand fixed locally first. The review reads prior PR comments so dismissed findings\nare never re-flagged.\n\n**Works in two modes:**\n- **Offline** — uncommitted/staged/branch diffs, no GitHub connection needed\n- **PR-aware** — linked PR fetches prior review comments via `gh api` for\n  dismissal tracking and verification against stated PR goals\n\nUseful prompts:\n\n- \"review my changes\"\n- \"review before push\"\n- \"review this commit\"\n- \"review PR #42\"\n- \"self-review\"\n\n## Supported Harnesses\n\nsqmd exposes an MCP server (JSON-RPC 2.0 over stdio) that plugs into AI coding tools. All harnesses get the same tools: `search`, `context`, `deps`, `stats`, `get`, `index_file`, `embed`, `embed_start`, `embed_progress`, `embed_stop`, `ls`, and `cat`.\n\n| Harness | Config path | Format | Setup command |\n|---------|------------|--------|---------------|\n| **OpenCode** | `~/.config/opencode/opencode.json` | JSON | `sqmd setup opencode` |\n| **Codex** | `~/.codex/config.toml` | TOML | `sqmd setup codex` |\n| **Claude Code** | `~/.claude/settings.json` | JSON | `sqmd setup claude` |\n| **Cursor** | `\u003cproject-root\u003e/.cursor/mcp.json` | JSON | `sqmd setup cursor` |\n\nRun `sqmd setup` to register all four at once. Note: Cursor writes to the project root, not your home directory.\n\n### OpenCode\n\n```json\n{\n  \"mcp\": {\n    \"sqmd\": {\n      \"type\": \"local\",\n      \"command\": [\"/absolute/path/to/sqmd\", \"mcp\"],\n      \"enabled\": true\n    }\n  }\n}\n```\n\n### Codex\n\n```toml\n[mcp_servers.sqmd]\ncommand = \"/absolute/path/to/sqmd\"\nargs = [\"mcp\"]\n```\n\n### Claude Code\n\n```json\n{\n  \"mcpServers\": {\n    \"sqmd\": {\n      \"command\": \"/absolute/path/to/sqmd\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n### Cursor\n\nCursor reads MCP config from the project root (not your home directory). Run `sqmd setup cursor` from within your project:\n\n```json\n{\n  \"mcpServers\": {\n    \"sqmd\": {\n      \"command\": \"/absolute/path/to/sqmd\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n### Raw JSON-RPC\n\nAny tool that speaks MCP over stdio can use sqmd directly:\n\n```bash\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"my-tool\",\"version\":\"1.0\"}}}' | sqmd mcp\n```\n\nSupports both raw JSON lines and `Content-Length:` framed transport.\n\n### Worktrees and Index Discovery\n\nsqmd stores its index at `\u003cproject\u003e/.sqmd/index.db`. If you run agents from git worktrees, the MCP server handles the common setup where the index lives in the main worktree:\n\n```bash\ncd /path/to/main-checkout\nsqmd init\nsqmd index\n\ngit worktree add ../feature-branch -b feature-branch\ncd ../feature-branch\nsqmd mcp\n```\n\nWhen launched from the linked worktree, sqmd asks git for the common git directory, finds the main checkout's `.sqmd/index.db`, and still treats file paths as project-relative. When `.sqmd/` lives at `~/.sqmd/` (global index), the MCP server falls back to CWD for path resolution to prevent broken relative paths.\n\n### Per-Project Configuration\n\nCreate `.sqmd/config.toml` in your project root to override defaults:\n\n```toml\n[sqlite]\nmmap_size = \"512MB\"\ncache_size = \"16000 pages\"\nbusy_timeout = 10000\n\n[search]\ndefault_top_k = 20\n\n[chunking]\nmax_chunk_lines = 200\n\n[importance]\nfunction = 0.8\nclass = 0.9\n\n[hints]\nmin_importance = 0.6\n\n[embed]\nbatch_size = 16\n\n[context]\nmax_dep_chunks = 100\ncommunity_boost = 0.15\n```\n\nAll settings are optional — missing values use built-in defaults.\n\n### Plugin System\n\nsqmd supports custom chunkers and search layers via a JSON-over-stdio plugin interface. Configure plugins in `.sqmd/config.toml`:\n\n```toml\n[[plugin]]\nname = \"protobuf-chunker\"\ntype = \"chunker\"\ncommand = [\"python\", \"plugins/protobuf_chunker.py\"]\nextensions = [\".proto\"]\nlanguages = [\"protobuf\"]\npriority = 10\ntimeout_secs = 15\n```\n\nPlugins communicate via structured JSON messages on stdin/stdout. See the plugin module source for the full protocol spec.\n\n### Multi-Project Search\n\nRegister multiple projects and search across them from a single query:\n\n```bash\nsqmd projects add frontend ~/projects/frontend\nsqmd projects add backend ~/projects/backend\nsqmd projects search \"authentication\"\n```\n\nThe multi-project registry lives at `~/.sqmd/projects.toml`.\n\n## What Gets Indexed\n\nEvery function, method, class, struct, enum, trait, interface, type alias, import, module, and macro definition is extracted as a named chunk with:\n\n- Original source code (raw, not markdown)\n- Name and signature (first line, max 120 chars)\n- File path, language, line start/end\n- Content hash (SHA-256) for incremental updates\n- Importance score (0.0-1.0) based on chunk type\n- Import relationships (cross-file) and contains relationships (intra-file)\n- Template-based hints and (optionally) LLM-generated prospective hints\n\n## Languages\n\n### Tree-sitter grammars (17 languages)\n\n| Language | Grammar | Imports | Chunk types |\n|----------|---------|---------|-------------|\n| TypeScript / JSX | `tree-sitter-typescript` | `import { X } from '...'` | function, class, interface, type, enum, export |\n| TSX | `tree-sitter-typescript` (tsx) | same as TS | same as TS + JSX elements |\n| JavaScript | `tree-sitter-typescript` | `import ...` / `require(...)` | function, class, export |\n| Rust | `tree-sitter-rust` | `use crate::module::Item` | function, struct, enum, trait, impl, mod, const, type, macro |\n| Python | `tree-sitter-python` | `from module import X` | function, class, constant |\n| Go | `tree-sitter-go` | `\"fmt\"`, `import ()` blocks | function, method, struct, interface, type |\n| Java | `tree-sitter-java` | `import com.example.Class` | method, constructor, class, interface, enum |\n| C | `tree-sitter-c` | `#include \u003c...\u003e` / `#include \"...\"` | function, struct, enum, typedef, macro, constant |\n| C++ | `tree-sitter-cpp` | `#include \u003c...\u003e` / `#include \"...\"` | function, class, struct, enum, namespace, template, type, macro |\n| Ruby | `tree-sitter-ruby` | `require '...'` | function, method, class, module, constant |\n| HTML | `tree-sitter-html` | — | element (semantic landmarks) |\n| CSS | `tree-sitter-css` | — | rule_set, media/keyframes/supports |\n| CMake | `tree-sitter-cmake` | `find_package`, `add_subdirectory` | function, macro, target, dependency, config |\n| QML | `tree-sitter-qmljs` | `import QtQuick 2.15` | component, function, property, import |\n| YAML | `tree-sitter-yaml` | — | mapping (keyed sections) |\n| JSON | `tree-sitter-json` | — | pair (keyed entries) |\n| TOML | `tree-sitter-toml-ng` | — | table, table_array, pair |\n| Markdown | regex-based | — | section (heading splits) + fenced code blocks |\n| Meson | regex-based | `dependency()`, `subdir()` | target, dependency, function |\n\n### Line-based chunking (additional 21 languages)\n\nLanguages without dedicated tree-sitter grammars still get indexed using line-based chunking. These include: SCSS/SASS, Shell, SQL, Dockerfile, Makefile, Kotlin, Swift, C#, PHP, Lua, Dart, Scala, Haskell, Elixir, Zig, XML/SVG, GraphQL, Protobuf, JSX, and JavaScript (fallback).\n\n### Extension coverage\n\n| Language | Extensions |\n|----------|-----------|\n| TypeScript | `.ts` |\n| TSX | `.tsx` |\n| JavaScript | `.js`, `.mjs`, `.cjs` |\n| JSX | `.jsx` |\n| Rust | `.rs` |\n| Python | `.py`, `.pyi` |\n| Go | `.go` |\n| Java | `.java` |\n| C | `.c`, `.h` |\n| C++ | `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hxx`, `.hh` |\n| CMake | `.cmake`, `CMakeLists.txt` |\n| QML | `.qml` |\n| Meson | `meson.build`, `meson_options.txt` |\n| Ruby | `.rb` |\n| Markdown | `.md`, `.mdx` |\n| JSON | `.json`, `.jsonc` |\n| YAML | `.yml`, `.yaml` |\n| TOML | `.toml` |\n| HTML | `.html`, `.htm` |\n| CSS | `.css`, `.less` |\n| SCSS | `.scss`, `.sass` |\n| Shell | `.sh`, `.bash`, `.zsh`, `.fish` |\n| SQL | `.sql` |\n| Dockerfile | `Dockerfile`, `dockerfile` |\n| Makefile | `Makefile`, `makefile`, `GNUmakefile` |\n| Kotlin | `.kt`, `.kts` |\n| Swift | `.swift` |\n| C# | `.cs` |\n| PHP | `.php` |\n| Lua | `.lua` |\n| Dart | `.dart` |\n| Scala | `.scala`, `.sc` |\n| Haskell | `.hs` |\n| Elixir | `.ex`, `.exs` |\n| Zig | `.zig` |\n| XML | `.xml`, `.svg`, `.xsl`, `.xslt` |\n| GraphQL | `.graphql`, `.gql` |\n| Protobuf | `.proto` |\n\n## Search\n\n### Layered Search (default)\n\nSix retrieval layers run in sequence, each contributing results with tuned scoring:\n\n1. **FTS5** — Porter-stemmed full-text search. Includes hint boost and graph boost. Short-circuits on 3+ high-confidence hits.\n2. **Graph expansion** — 3-hop entity relationship traversal. 0.7x multiplier.\n3. **Community summaries** — Module and type-hierarchy community matching. 0.5x multiplier.\n4. **Vector KNN** — 768-dim gte-modernbert-base via native llama.cpp. New results at 0.6x; existing matches get +0.3 boost.\n5. **Multi-surface vector KNN** — Separate embeddings for decomposed names (1.5x), signatures (1.3x), and doc comments (1.2x). Best surface match per chunk boosts existing results at 2.0x.\n6. **Hint vector** — KNN over embedded hint text. Existing matches +0.2; new at 0.4x.\n\nAll results scored with `relevance x recency x importance`, then importance-boosted and diversity-dampened.\n\n### FTS-only (`--keyword`)\n\nRaw FTS5 search without graph, community, or vector layers.\n\n## Architecture\n\n```\nsource files\n    | tree-sitter (per-language grammar -\u003e AST)\n    | walk declarations -\u003e named chunks (function, class, struct, ...)\n    | extract imports -\u003e relationship edges\n     | extract structural relations -\u003e entity_dependencies\n     | detect overrides -\u003e overrides relationships\n     | promote symbols -\u003e entities (knowledge graph nodes)\n     | resolve imports -\u003e language-aware path resolution (tsconfig, Cargo, go.mod, pyproject)\n     | extract calls -\u003e tree-sitter AST-based call extraction\n     | generate template hints -\u003e hints (search anchors)\n    | detect communities -\u003e module + type-hierarchy groupings\n    | content-hash pipeline (skip / update / tombstone)\n    |\n    | [optional] sqmd hints -\u003e LLM hints (phi4-mini via native llama.cpp)\n    |\n    | native llama.cpp -\u003e gte-modernbert-base embeddings (Metal GPU)\n    |   |-- body embeddings -\u003e chunks_vec (768-dim, full source)\n    |   |-- name embeddings -\u003e names_vec (768-dim, decomposed identifiers)\n    |   |-- signature embeddings -\u003e sigs_vec (768-dim, name + signature)\n    |   |-- doc comment embeddings -\u003e docs_vec (768-dim, extracted doc blocks)\n    |   |-- hint embeddings -\u003e hints_vec (768-dim)\n    |\nSQLite database (schema v16)\n    |-- files            (path, language, hash, mtime)\n    |-- chunks           (raw code + metadata + doc_comment)\n    |-- chunks_fts       (FTS5 full-text index)\n    |-- chunks_vec       (768-dim vector index, body embeddings)\n    |-- names_vec        (768-dim vector index, decomposed name embeddings)\n    |-- sigs_vec         (768-dim vector index, signature embeddings)\n    |-- docs_vec         (768-dim vector index, doc comment embeddings)\n     |-- relationships    (imports, contains, calls, overrides, references)\n     |-- entity_dependencies (extends, implements, contains, overrides, references)\n     |-- entities         (symbol-level graph nodes)\n     |-- entity_aspects   (exports, implementation, constraints)\n     |-- entity_attributes (chunk-level entity annotations)\n     |-- hints + hints_fts (search hints)\n    |-- hints_vec        (768-dim vector index over hints)\n    |-- surface_embeddings (tracking table for multi-surface embedding progress)\n    |-- communities      (module, type-hierarchy summaries)\n    |-- embeddings       (vector blob fallback)\n    |-- episodes         (change provenance)\n    +-- schema_version   (migration tracking)\n```\n\nSingle-pass parsing with incremental re-indexing via content hashes.\n\n## Feature Flags\n\n| Feature | Dependencies | Purpose |\n|---------|-------------|---------|\n| `native` (default) | `llama-cpp-2` | Embeddings + hint generation via native llama.cpp |\n| `native-metal` (default on macOS) | `llama-cpp-2/metal` | + Metal GPU acceleration |\n\nNo external services required. All inference runs locally through llama.cpp.\n\nConfiguration:\n- `SQMD_NATIVE_MODEL` — Path to GGUF file or model name (default: auto-discover `gte-modernbert-base` from model store)\n- `OLLAMA_MODELS` — Path to local model store for GGUF discovery (default: `~/.ollama/models`)\n- `SQMD_HINT_MODEL` — Hint generation model (default: `phi4-mini`)\n- `SQMD_HINT_MODEL_PATH` — Direct path to hint model GGUF\n\n## Supported Platforms\n\n| OS | Architecture | GPU | Feature flag |\n|----|-------------|-----|-------------|\n| macOS 13+ (Ventura) | Apple Silicon (M1/M2/M3/M4) | Metal | `native-metal` (default) |\n| macOS 13+ | Intel | CPU | `native` |\n| Linux | x86_64, ARM64 | CPU | `native` |\n| Windows (WSL2) | x86_64 | CPU | `native` |\n\nNative Windows support (without WSL2) is not yet tested. All inference runs through llama.cpp — Metal GPU on Apple Silicon, CPU fallback on everything else.\n\n## Install\n\n**Homebrew (macOS):**\n```bash\nbrew tap aaf2tbz/sqmd\nbrew install sqmd\n```\n\n**One-line install (macOS/Linux):**\n```bash\ncurl -fsSL https://raw.githubusercontent.com/aaf2tbz/sqmd/main/install.sh | bash\n```\n\n**From source:**\n```bash\ngit clone https://github.com/aaf2tbz/sqmd.git ~/sqmd\ncd ~/sqmd \u0026\u0026 make install   # builds and installs to /usr/local/bin\n```\n\n**Quick demo:**\n```bash\nsqmd init --demo\n```\n\n## Build\n\n```bash\ncargo build --release                              # default: native llama.cpp + Metal GPU (macOS)\ncargo build --release --no-default-features        # no native features (no embeddings/hints)\ncargo build --release --features native             # CPU-only (Linux, macOS Intel, WSL2)\n```\n\nBuild requirements:\n- **Rust** 1.85+ (edition 2024)\n- **CMake** (`brew install cmake` on macOS, `sudo apt install cmake` on Linux)\n- **C compiler** (Xcode CLI tools on macOS, `build-essential` on Linux)\n\n## Commands\n\n### Indexing\n\n```bash\nsqmd init                            # create index at .sqmd/index.db\nsqmd index                           # full or incremental index\nsqmd index --embed                   # index + generate embeddings\nsqmd index src/auth.ts               # index a single file\nsqmd embed                           # generate embeddings for unembedded chunks\nsqmd watch                           # live re-index on file changes\n```\n\n#### Excluding files\n\nsqmd respects `.gitignore` rules and hardcodes common exclusions (`node_modules`, `target`, `.git`, `dist`, `build`, etc.). To add custom exclusions, create a `.sqmdignore` file in your project root using the same format as `.gitignore`:\n\n```gitignore\n# .sqmdignore\nvendor/\n*_test.go\n*.generated.ts\ndocs/generated/\n```\n\n### Search \u0026 Retrieval\n\n```bash\nsqmd search \"auth\"                   # layered search (all 5 layers)\nsqmd search \"auth\" --keyword         # FTS-only\nsqmd search \"config\" --file src/lib  # file-filtered search\nsqmd search \"User\" --type Struct     # type-filtered search\n\nsqmd deps src/auth.ts                # imports + dependents\nsqmd deps src/auth.ts --depth 2      # traverse 2 levels\n\nsqmd context --query \"how does X work\" --max-tokens 8000 --deps\nsqmd context --files a.ts,b.ts --max-tokens 4000\n```\n\n### Browsing\n\n```bash\nsqmd ls                              # list chunks (tree view)\nsqmd ls --type function              # filter by type\nsqmd ls --file src/auth.ts           # filter by file\nsqmd ls --language rust              # filter by language\nsqmd cat 42                          # get chunk by ID\nsqmd get src/auth.ts:42              # get chunk at file:line\nsqmd stats                           # index statistics\nsqmd entities                        # list knowledge graph entities\nsqmd entity-deps MyStruct            # show entity dependencies\nsqmd diff 2026-04-01T00:00:00Z       # chunks modified since timestamp\n```\n\n### Lifecycle\n\n```bash\nsqmd start                           # start daemon in background\nsqmd stop                            # stop running daemon\nsqmd serve                           # run daemon in foreground (Unix socket)\nsqmd mcp                             # start MCP server (JSON-RPC over stdio)\nsqmd setup                           # register sqmd in all AI tool configs\nsqmd setup opencode                  # register for OpenCode only\nsqmd doctor                          # run diagnostic checks\nsqmd doctor --check embed            # check embedding setup specifically\nsqmd update                          # update sqmd to latest version\nsqmd install                         # install sqmd from source\nsqmd reset                           # delete the index\n sqmd prune 30                        # purge soft-deleted chunks older than 30 days\n ```\n\n### Maintenance\n\n```bash\nsqmd maintain health                  # full index health report\nsqmd maintain clean-orphans           # remove orphaned rows from all tables\nsqmd maintain vacuum                  # reclaim WAL space\nsqmd maintain analyze                 # update query planner statistics\nsqmd maintain compact                 # clean-orphans + vacuum + analyze\n```\n\n### Multi-Project\n\n```bash\nsqmd projects add my-project /path/to/project   # register a project\nsqmd projects remove my-project                  # unregister a project\nsqmd projects list                               # list registered projects\nsqmd projects search \"authentication\"            # search across all projects\nsqmd projects search \"auth\" --project proj1,proj2 --top-k 20\n```\n\n### Hint Generation\n\n```bash\nsqmd hints                           # generate prospective hints (phi4-mini via native llama.cpp)\nsqmd hints --min-importance 0.7      # only high-importance chunks\nsqmd hints --limit 100               # process at most 100 chunks\n```\n\nSafe to re-run — duplicate hints are automatically ignored (deduped on chunk_id + hint_text).\n\nAfter generating hints, re-run `sqmd embed` to embed the hint text into `hints_vec`.\n\n## MCP Server\n\n`sqmd mcp` starts a JSON-RPC 2.0 server over stdio for use with AI tools:\n\n```bash\nsqmd mcp\n```\n\nExposes 14 tools:\n\n| Tool | Description |\n|------|-------------|\n| `search` | Layered search with query, top_k, file/type/source filters |\n| `context` | Assemble token-budgeted context with dependency expansion and community boosting |\n| `deps` | Get dependencies and dependents for a file path |\n| `stats` | Index statistics (files, chunks, embeddings, entities, communities) |\n| `get` | Get chunk by file path and line number |\n| `index_file` | Index a single file or all changed files (incremental) |\n| `embed` | Embed unembedded chunks via local llama.cpp (blocking, up to batch_size) |\n| `embed_start` | Start embedding in a background thread |\n| `embed_progress` | Poll embedding progress, percentage, progress bar, and ETA |\n| `embed_stop` | Request a graceful stop after the current batch |\n| `ls` | List chunks with file/type/language filters |\n| `cat` | Get full chunk content by ID |\n| `health` | Check index health — integrity, orphans, index/WAL size, FTS/vector consistency |\n| `projects` | List, add, remove, or cross-project search via the multi-project registry |\n\nAgents can index new files, keep embeddings up-to-date, and browse the codebase entirely through MCP — no CLI needed.\n\nRegister with `sqmd setup` or manually add to your tool's config:\n\n**OpenCode** (`~/.config/opencode/opencode.json`):\n```json\n{\n  \"mcp\": {\n    \"sqmd\": {\n      \"type\": \"local\",\n      \"command\": [\"sqmd\", \"mcp\"],\n      \"enabled\": true\n    }\n  }\n}\n```\n\n## Daemon Protocol\n\n`sqmd serve` listens on `~/.sqmd/daemon.sock`:\n\n```json\n{\"method\": \"search\", \"params\": {\"query\": \"authentication\", \"top_k\": 10}}\n{\"method\": \"layered_search\", \"params\": {\"query\": \"how does auth work\", \"top_k\": 10}}\n{\"method\": \"context\", \"params\": {\"query\": \"how does auth work\", \"max_tokens\": 8000, \"include_deps\": true}}\n{\"method\": \"deps\", \"params\": {\"path\": \"src/auth.ts\", \"depth\": 2}}\n{\"method\": \"index_file\", \"params\": {\"path\": \"src/main.rs\"}}\n{\"method\": \"stats\", \"params\": {}}\n```\n\nAll responses are JSON. Add `--json` to any CLI command for machine-readable output.\n\n## Benchmarking\n\nSee [BENCHMARKING.md](BENCHMARKING.md) for full methodology, reproduction steps, and historical results across datasets.\n\n```bash\ncargo run -p sqmd-bench --features native -- compare /path/to/index.db --ground-truth queries.json\n```\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full version history.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for branch policy, code style, and how to add a new language.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaf2tbz%2Fsqmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faaf2tbz%2Fsqmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaf2tbz%2Fsqmd/lists"}