Download Latest Version semlith-v0.51.1-x86_64-pc-windows-msvc.zip (24.5 MB)
Home / v0.30.0
Name Modified Size InfoDownloads / Week
Parent folder
semlith-v0.30.0-aarch64-apple-darwin.tar.gz 2026-09-26 24.0 MB
semlith-v0.30.0-aarch64-unknown-linux-gnu.tar.gz 2026-09-26 23.6 MB
semlith-v0.30.0-x86_64-pc-windows-msvc.zip 2026-09-26 21.7 MB
semlith-v0.30.0-x86_64-unknown-linux-gnu.tar.gz 2026-09-26 24.8 MB
SHA256SUMS 2026-09-26 448 Bytes
README.md 2026-09-26 8.0 kB
Semlith 0.30.0 source code.tar.gz 2026-09-26 3.0 MB
Semlith 0.30.0 source code.zip 2026-09-26 3.2 MB
Totals: 8 Items   100.3 MB 0

Agents use semlith, and it answers them well

A benchmark of 216 headless Claude Code sessions on 2026-09-25 found that the setup semlith setup wrote got 7 % of an agent's lookups, and that forcing the agent onto semlith cost answer quality, because the tools failed on exactly the questions agents ask. This release fixes the tools first, then the levers that bring the agent to them.

What breaks if this changes. semlith_impact walks from a definition, not a name: Fleet::search_preferring, module::function and Type.method resolve to the definition that owner holds, each reaching row carries the call-site line, and the answer stays under 16 000 characters at any depth — past the cap, rows collapse into per-file counts with a more: line. The same question at the default depth was 75 012 characters on 0.29.0, over Claude Code's MCP limit. The Rust extractor now records a method's owner and a receiver's declared type (self in impl T, x: T, T::new(), a field store: T), so the two search_preferring methods are told apart; callers of a name with several definitions say which one they mean (→ Fleet::search_preferring). semlith_neighbors and semlith_symbol take the same cap.

Answers an agent can act on. Paths in answers are relative to the store root, named once at the top, and semlith_read resolves them — src/lib.rs no longer matches the fixture copy. A locate row is one line and names the definition a chunk is about with its start line (search_preferring method @3295). semlith_read with a symbol name returns each definition whole, and serves an edited file's current lines from disk, marked, through the same secret scan. semlith_symbol takes up to 20 names and answers with one row per definition. semlith_files {tree: true} gives a directory view with counts, languages, per-file lines, symbols and first definitions, and what is on disk but not indexed, and why. brief gives its one text span to code for a code question, labels the others honestly, and leaves Markdown headings out of its graph lines. Tests rank below product code unless the question names tests, identical copies collapse into one hit, and semlith_stats collapses its long tail. semlith_search {exact: true} is grep over the index: every indexed line matching a regular expression, each file once, each line naming the definition it sits in, within the same max_tokens budget as a locate answer, the rest as per-file counts with the offset that continues — also semlith search --exact and the Search page's exact view. semlith_read of a bare path reads the file, or past 8 000 characters lists its definitions; it used to answer "nothing indexed". A git checkout no longer marks unchanged files stale. A .semlithignore leaves paths out of a store; this repository's leaves the retrieval corpus copy out.

Bringing the agent to them. semlith setup sets alwaysLoad on Claude Code's entry, writes a hook that reads Bash as well as Read, Grep and Glob and names one concrete semlith call (soft by default; --hook-mode gate or hard opt-in), a rewritten skill, and a read-only semlith-explorer research agent. The server instructions name the indexed folders and route by question. semlith doctor reports all of it, and doctor --fix clears a per-project disable for the current directory.

The secret scan tells test dummies from keys, and says what it did not index

A match that a declared rule says is a test dummy — a published documentation example, a body saying EXAMPLE or FAKE or one character repeated, a private-key header with no key — no longer refuses its file; one live-looking match anywhere still does. A secret-sounding name assigned a random literal, quoted or not, now refuses its file too, which catches an AWS secret access key beside its id. Every file that was not indexed is listed, per store, in five classes, and a secret carries a 0–100 % estimate that it is real with the signals behind it. A person — never an agent, never in bulk — can accept one file at a time, redacted or as-is, from semlith refused accept or the portal's Index page after a scan; the acceptance remembers salted fingerprints, never values, and a new secret refuses the file again. A credential file is never acceptable. Every run opens with a model-free scan phase. semlith index on a terminal stops for review only when something is the person's to decide; the portal holds every scan for a look at its plan.

The portal shows the plan before it embeds

The Index page's one button reads Scan: every run stops after its scan phase and the page shows what it found — files to embed and their size, unchanged, needing a decision, not indexed, and an estimate — even when nothing needs a decision. Each held-back file is a row with Accept redacted, Accept as-is (or Accept) and Keep refused, each accept behind a confirm with an "I have reviewed this file" tick, and one line counts the files not indexed that need nothing, with Show files to list them. The button then reads Start indexing; an undecided file stays refused, and Discard scan drops the held runs along with a store the scan made for a new folder. The Files page gains a Decisions tab, which lists only what a person decided — accepted, refused, or let through as test dummies — each with Revoke or Refuse instead, and a Tree tab, an editor-style explorer that opens one folder level at a time, with file icons, lines and symbols, and what is on disk but not indexed greyed with why; the Indexed tab shows paths relative to the store root. POST /api/index takes review: "always", a discarded scan's stop takes delete: true, and /api/files?tree=1&format=json answers one tree level.

Fixed

  • The remaining-time estimate no longer jumps to minutes while a run writes its index, and never more than doubles between polls. Closes [#143].
  • a_port_something_already_holds_is_seen_as_held no longer races the rest of the suite. Closes [#141].
  • The daemon's watcher said 0 indexed at startup for a catch-up it had only queued; it now says the catch-up was deferred, then what it found.
  • semlith start no longer fails while a terminal semlith index is writing one of its stores. That store is named as waiting and opened, watcher and catch-up included, when the run lets go.
  • Across several stores, brief names the store on every span and symbol, and a symbol's edges come from its own store rather than every store defining the name. A root-relative semlith_read that two stores both hold is refused naming each, as two roots inside one store already were.
  • The server instructions stayed over their 600-byte limit by the length of "folders" when the roots did not all fit.
  • The research agent reads a located span through semlith_read; Read is kept for files semlith does not index.
  • A run card's plan line is updated in place, so a poll no longer rebuilds it.
  • A run started from the portal shows its time estimate from the first batch: daemon runs now record the store's embed rate, and a store with none uses the last run the daemon watched.
  • A semlith_index forwarded to the daemon names every refusal of the run, its skips by reason, and how many files await review, as the in-process reply does. Files left out by .semlithignore count in the skip total.

Install

macOS and Linux

:::sh
curl -fsSL https://raw.githubusercontent.com/semlith/semlith/main/install.sh | sh

Windows

:::powershell
irm https://raw.githubusercontent.com/semlith/semlith/main/install.ps1 | iex

Or download the archive for your platform below, unpack it, and put semlith on your PATH. Intel macOS has no prebuilt binary: ONNX Runtime no longer publishes x86_64 macOS builds.

Verify a download against SHA256SUMS before running it.

Source: README.md, updated 2026-09-26