chadtmiller.com/knotless
git that lives in your Atmosphere account
knotless-serve searches public repositories' code with Zoekt
MergedThis pull adds Zoekt-backed code search to knotless-serve. code.rs runs zoekt-webserver and zoekt-git-index and follows the index to keep shards current. It adds the dev.knotless.searchCode lexicon and handler, the CI, image and compose changes, and the docs pages (serve.md, api.md). I read code.rs. I did not read the index.rs hooks, the handler or the workflow line by line, and the full diff was too large to open in one piece. In code.rs I found nothing that must change before merge.
Two small observations, neither blocking:
MaxDocDisplayCountis applied inside Zoekt, but hits from repositories the index no longer lists are dropped afterwards. A taken-down repository can therefore use up result slots and return fewer thanlimitfiles. This fits the shortcomings you listed, and it hides nothing.chunk()computesr.start.byte_offset - basewithout a guard. This is fine if Zoekt keeps ranges inside the chunk, as it does today. Asaturating_subwould stop a malformed reply from panicking the request.
The only change since my last review is in the searching_code test. It now counts only shards whose names start with the test account's DID, with : written _3a. The PDS is shared, so shards of other accounts' repositories were being counted. That fixes the shard-count assertion that was probably failing the test check. It touches no production code, and I found nothing new to ask for. My two earlier notes stand and are not blocking: chunk() could use saturating_sub on r.start.byte_offset - base, and slots can be lost to taken-down repositories. The queue ejected the pull because the test check failed at the earlier commit, so check that it passes at this head.
9 passed, 1 skipped
What changes
Code search in serve. With
--code-index <dir>, knotless-serve runs Zoekt beside it.zoekt-webserverserves searches from shards on disk, on a loopback port of its own.zoekt-git-indexwrites a repository's shards from its mirror, of its default branch. A background task indexes one repository at a time: each public repository with no shards as serve starts, then each again as a feed moves its refs or its record. A deleted repository's shards are dropped when its turn comes.dev.knotless.searchCode. A new query takingqin Zoekt's query language, an optionalrepoURI, andlimit(20, at most 50). It answers files with their repository view, path, language and chunks (startLine,content, matchrangesin UTF-8 bytes per line), plusfileCountandmatchCount. Repositories the index no longer lists, or has taken down, are left out, so a takedown hides code at once. A server without the flag answers 501, and a query Zoekt cannot read answers 400.Build and deploy. The test check builds
zoekt-git-indexandzoekt-webserverat a pinned commit into/opt/tools, cached. The image builds them in a Go stage, and the compose file turns code search on with/data/code.Why
This is the engine behind the search page. Zoekt is a trigram index built for code: substrings and regular expressions across every repository at once, in milliseconds, with little memory, since its shards are memory-mapped. Running it as a sidecar behind our own lexicon keeps the API ours, so the engine can change later without the pages or clients changing.
How it was checked
A new serve test,
searching_code, pushes two repositories, starts indexing, and checks that a search finds both. It then checks one result's exact shape and ranges, a search within one repository, that a later push is found, that a bad query answers 400, that a server without code search answers 501, and that a deleted repository's results and shards go. Unit tests cover how chunks are cut into lines and how shard names are made. The serve binary test starts with--code-index.just lexpasses. The full test run is left to CI, which builds Zoekt.Shortcomings
fileCountandmatchCountinclude files in repositories that are taken down but not yet re-indexed.Review
Start at
crates/knotless-serve/src/code.rs, then the index hooks inindex.rs(reindex,listed,code_repos).🤖 Generated with Claude Code