{"id":48512942,"url":"https://github.com/uchebnick/unch","last_synced_at":"2026-04-10T01:27:04.899Z","repository":{"id":347447865,"uuid":"1194097027","full_name":"uchebnick/unch","owner":"uchebnick","description":"Local-first semantic code search for repository annotations via GGUF embeddings and sqlite-vec.","archived":false,"fork":false,"pushed_at":"2026-04-06T09:29:38.000Z","size":15020,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-06T09:49:21.050Z","etag":null,"topics":["cli","code-search","embeddings","gguf","golang","local-first","sqlite","sqlite-vec"],"latest_commit_sha":null,"homepage":"https://unch.mintlify.app/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uchebnick.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-03-27T23:13:49.000Z","updated_at":"2026-04-06T09:33:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/uchebnick/unch","commit_stats":null,"previous_names":["uchebnick/unch-searcher","uchebnick/unch"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/uchebnick/unch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchebnick%2Funch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchebnick%2Funch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchebnick%2Funch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchebnick%2Funch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uchebnick","download_url":"https://codeload.github.com/uchebnick/unch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uchebnick%2Funch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31522574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["cli","code-search","embeddings","gguf","golang","local-first","sqlite","sqlite-vec"],"created_at":"2026-04-07T18:00:52.676Z","updated_at":"2026-04-07T18:01:09.172Z","avatar_url":"https://github.com/uchebnick.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/unch-logo.svg\" alt=\"unch logo\" width=\"300\"\u003e\n\u003c/p\u003e\n\n# unch\n\n[![Release](https://img.shields.io/github/v/release/uchebnick/unch?display_name=tag)](https://github.com/uchebnick/unch/releases/latest)\n[![Homebrew Tap](https://img.shields.io/badge/Homebrew-uchebnick%2Ftap-FBB040?logo=homebrew\u0026logoColor=white)](https://github.com/uchebnick/homebrew-tap)\n[![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/uchebnick/unch/gh-pages/coverage/coverage-badge.json)](https://github.com/uchebnick/unch/actions/workflows/ci.yml)\n[![Go 1.25+](https://img.shields.io/badge/Go-1.25%2B-00ADD8?logo=go\u0026logoColor=white)](https://github.com/uchebnick/unch)\n[![Docs](https://img.shields.io/badge/Docs-unch.mintlify.app-0F172A)](https://unch.mintlify.app/)\n[![Telegram Chat](https://img.shields.io/badge/Telegram-Chat-26A5E4?logo=telegram\u0026logoColor=white)](https://t.me/unchchat)\n\n**Semantic code search for code symbols and docs.**\n\n`unch` indexes functions, methods, types, classes, interfaces, and attached docs with Tree-sitter, then lets you search them from the terminal. It is useful when you know what the code does, but not the symbol name or file path. Local indexing is the default; remote publishing is optional.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/unch-demo.gif\" alt=\"Terminal demo of unch indexing gorilla/mux and returning semantic search matches\" width=\"920\"\u003e\n\u003c/p\u003e\n\n## Why `unch`\n\n- **Indexes symbols, not just lines.** `unch` stores top-level API objects and attached docs for `Go`, `TypeScript`, `JavaScript`, and `Python`.\n- **Keeps the local workflow simple.** Build an index once, search from the CLI, and keep everything on your machine unless you explicitly publish a remote index.\n- **Still works with CI.** If you want a shared index, GitHub Actions publishing is available, but it is not required for the normal local flow.\n\n## Install\n\nHomebrew on macOS:\n\n```bash\nbrew install uchebnick/tap/unch\n```\n\nRelease installer on macOS and Linux:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/uchebnick/unch/main/install.sh | sudo sh -s -- -b /usr/local/bin\n```\n\nThis installs `unch` into a system `PATH` directory so you can run it immediately after the installer finishes.\nOn Apple Silicon macOS, use `/opt/homebrew/bin` instead of `/usr/local/bin`:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/uchebnick/unch/main/install.sh | sudo sh -s -- -b /opt/homebrew/bin\n```\n\nPowerShell installer on Windows:\n\n```powershell\niwr https://raw.githubusercontent.com/uchebnick/unch/main/install/install.ps1 -useb | iex\n```\n\nThis makes `unch` available immediately in the current PowerShell session.\nTo keep it available in future PowerShell or terminal sessions, add `$HOME\\AppData\\Local\\Programs\\unch\\bin` to your user `PATH`.\n\nSource install:\n\n```bash\ngo install github.com/uchebnick/unch/cmd/unch@latest\n```\n\nThis install path requires a cgo-capable Go toolchain. It is smoke-tested in CI in the official Debian-based Go container image. To pin a specific release, use `@\u003ctag\u003e`.\n\nIf you want to build from the current checkout:\n\n```bash\ngo build -o unch ./cmd/unch\n```\n\nPublished release archives:\n\n- macOS: `arm64`, `x86_64`\n- Linux: `arm64`, `x86_64`\n- Windows: `arm64`, `x86_64` (`unch.exe`)\n\nOn those targets, the installers use published release archives by default, so Go is not required. `install.sh` and `install/install.ps1` only fall back to `go install` when no matching archive is available. `install.sh` is smoke-tested in CI on Ubuntu, Debian, Arch, and NixOS-like environments, including the default no-`-b` path selection flow; the PowerShell installer is smoke-tested on Windows `arm64` and `x86_64`.\n\nVerify the installed binary:\n\n```bash\nunch --version\nunch --help\n```\n\nSee [Compatibility](docs/compatibility.md) for the support matrix and upgrade rules, and [Benchmarks](docs/benchmarks.md) for the checked-in `smoke`, `ci`, and `default` suites.\n\nModel selection accepts either a known model id or a direct `.gguf` path:\n\n```bash\nunch index --model embeddinggemma\nunch index --model qwen3\nunch search --model qwen3 \"create a new router\"\n```\n\n## Quick Start\n\n```bash\ncd path/to/repo\nunch index --root .\nunch search \"create a new router\"\nunch search --details \"get path variables from a request\"\n```\n\nReal output from indexing [`gorilla/mux`](https://github.com/gorilla/mux):\n\n```text\n$ unch index --root .\nLoaded model       dim=768\nIndexed 278 symbols in 16 files\n\n$ unch search \"create a new router\"\n1. mux.go:32  0.7747\n2. mux.go:314 0.8135\n\n$ unch search --details \"get path variables from a request\"\n1. mux.go:466  0.7991\n   kind: function\n   name: Vars\n   signature: func Vars(r *http.Request) map[string]string\n   docs: Vars returns the route variables for the current request, if any.\n```\n\nThe first run may download the default embedding model, fetch local `yzma` runtime libraries, and create `./.semsearch/`.\n\nEach model keeps its own active index snapshot. Rebuilding `qwen3` does not replace the active `embeddinggemma` snapshot until the new run finishes successfully.\n\n## What It Supports Today\n\n- Tree-sitter indexing for `Go`, `TypeScript`, `JavaScript`, and `Python`\n- Top-level API objects and attached documentation\n- Local indexing and search first, optional remote publishing through GitHub Actions\n- `auto`, `semantic`, and `lexical` search modes\n- Legacy `--comment-prefix` and `--context-prefix` only for `index` fallback on unsupported files or parser failures\n\n## Core Commands\n\n### `index`\n\nBuild or refresh the local index for a repository.\n\n```bash\nunch index --root .\n```\n\nUseful flags:\n\n- `--exclude` to skip generated, vendor, or irrelevant paths\n- `--model` to use `embeddinggemma`, `qwen3`, or a custom `.gguf` path\n- `--ctx-size` to override the selected model context size; `0` uses the model default\n- `--lib` to use an existing `yzma` runtime directory\n- `--state-dir` to keep index state in a custom `.semsearch` directory\n\n### `search`\n\nQuery the current index.\n\n```bash\nunch search \"sqlite schema\"\nunch search --mode lexical \"Run\"\n```\n\nUseful flags:\n\n- `--mode` for `auto`, `semantic`, or `lexical`\n- `--limit` to control result count\n- `--max-distance` to narrow semantic matches\n- `--model` to search with `embeddinggemma`, `qwen3`, or a custom `.gguf` path\n- `--ctx-size` to override the selected model context size; `0` uses the model default\n- `--state-dir` to search against a custom `.semsearch` directory\n- `--details` to print symbol metadata, signature, docs, and body context for each match\n\n## Remote / CI\n\nRemote indexing is optional. Use it when you want GitHub Actions to publish an index for a repository. The generated workflow file is `.github/workflows/unch-index.yml`.\n\nCreate the workflow scaffold:\n\n```bash\nunch create ci\n```\n\nBind the local repository state to a GitHub repo or workflow URL:\n\n```bash\nunch bind ci https://github.com/uchebnick/unch\n```\n\nAfter the workflow is committed and runs successfully once, `unch search` can refresh the published index automatically when a newer remote version exists. Use `unch remote sync` when you want to force a refresh before searching.\n\nThe cross-platform benchmark matrix stays separate from ordinary push CI. It runs on release-tag pushes and manual `workflow_dispatch`, uses the checked-in `ci` suite with a lighter `1 cold / 1 warm / 1 search repeat` profile, and publishes per-platform summaries for Linux, macOS, and Windows.\n\n## Contributing and Feedback\n\n- See [CONTRIBUTING.md](CONTRIBUTING.md) for the local dev loop.\n- Open a [bug report](https://github.com/uchebnick/unch/issues/new?template=bug_report.md) if search quality or indexing behavior looks wrong.\n- Open a [feature request](https://github.com/uchebnick/unch/issues/new?template=feature_request.md) if you want new language support, ranking behavior, or workflow features.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchebnick%2Funch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuchebnick%2Funch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuchebnick%2Funch/lists"}