Skip to content

Releases: jimsimon/trouve

v2.0.0

Choose a tag to compare

@jimsimon jimsimon released this 05 Jul 23:37
52a77f7

Major bump: the crate, CLI binary, and npm packages are renamed, which breaks
existing installs and MCP configurations pointing at the trouve binary or
the trouve-plugin npm package. See INSTALL.md to migrate.

Changed

  • Rename for the @trouve-ai npm org: the crates.io crate and CLI binary
    are now trouve-search (the bare trouve name is reserved for future
    products). @trouve-ai/search-core ships the native binary and MCP
    launcher, with per-platform binaries installed via @trouve-ai/search-*
    optional dependencies — npm i -g @trouve-ai/search-core needs no separate
    install step, and MCP configs default to npx -y @trouve-ai/search-core.
    @trouve-ai/search-plugin replaces trouve-plugin and now carries the
    whole plugin surface: the OpenCode/Kilo native tools plus the Claude Code
    and Codex bundles (MCP config, workflow skill, sub-agent, session hook)
    formerly in plugins/trouve — one directory (npm/search-plugin), two
    install channels (npm registry and git marketplace).
  • npm/ is now an npm workspace (search-core + search-plugin, one shared
    lockfile), and @trouve-ai/search-core is plain ESM JavaScript with a type
    declaration, so it runs under Node 18+ (npx) and Bun alike.
  • Dependency updates: hf-hub 0.5, tokenizers 0.23, safetensors 0.8.

Added

  • NAME.md: where the name trouve comes from and how to pronounce
    it.

Full Changelog

v1.1.0...v2.0.0

What's Changed

  • Update Rust crate hf-hub to 0.5 by @renovate[bot] in #26
  • Update dependency python to 3.14 by @renovate[bot] in #25
  • Fix Renovate digest lookup for github-action-benchmark by @jimsimon in #28
  • Update GitHub Actions (major) by @renovate[bot] in #32
  • Update dependency typescript to v6 by @renovate[bot] in #31
  • Update Rust crate tokenizers to 0.23 by @renovate[bot] in #30
  • Update Rust crate safetensors to 0.8 by @renovate[bot] in #29
  • Rename to trouve-search and ship npm packages under @trouve-ai by @jimsimon in #34
  • Add NAME.md explaining the trouve name by @jimsimon in #35
  • Prepare the v2.0.0 release by @jimsimon in #37

New Contributors

Full Changelog: v1.1.0...v2.0.0

v1.1.0

Choose a tag to compare

@jimsimon jimsimon released this 04 Jul 03:35
2bfc1f8

Added

  • Persistent clone cache: remote git URLs are cloned once into
    <cache>/clones and refreshed with a cheap git fetch at most once per
    freshness window (TROUVE_CLONE_TTL seconds, default 300) instead of
    re-cloned per query. Clones are lock-protected against concurrent trouve
    processes, evicted after a week idle, and removed by trouve clear index.
    A stale clone is served (with a warning) when the remote is unreachable.
  • The MCP server now re-validates git URLs after the same cooldown as local
    paths — a revalidation is now a TTL-gated fetch plus an incremental
    rebuild, not a re-clone.
  • .trouveignore files: exclude files from indexing without git-ignoring
    them, replacing upstream's .sembleignore (same syntax, same per-directory
    inheritance; .trouveignore wins where patterns conflict).
  • .semble/ directories are now skipped during walks, alongside
    .trouve/, matching upstream's default ignore list.
  • Native OpenCode custom tools: a standalone custom-tool file
    (src/agents/opencode-tool.ts, copied to
    ~/.config/opencode/tools/trouve.ts) exposes trouve_search and
    trouve_find_related as native OpenCode tools. An alternative to an MCP
    entry: it avoids the MCP transport, needs no JSON config edits, and
    defaults repo to the session worktree.
  • INSTALL.md:
    step-by-step manual setup for every integration route — plugins, the
    OpenCode native tool file, and MCP server entries (config file, key, and
    snippet for 14 agents), plus optional trouve-search sub-agent files.
  • 23 new tree-sitter grammars (~50 languages total): CMake, D, Dart, Elm,
    ERB/EJS embedded templates, Erlang, Fortran, Gleam, GraphQL, Groovy,
    HCL/Terraform, Julia, Make, Nix, Objective-C, Perl, PowerShell, Protocol
    Buffers, R, Solidity, SQL, Svelte, and XML (incl. DTD). Files in these
    languages now get syntax-aware chunk boundaries instead of the line-based
    fallback.
  • Unified agent plugin (plugins/trouve): one package serving four
    harnesses. As the npm package trouve-plugin it exposes trouve_search
    and trouve_find_related as native tools in OpenCode and Kilo Code,
    backed by a single persistent trouve server process per session
    (preserving the in-process index cache, including for remote git URLs).
    The same directory carries the Claude Code plugin bundle (MCP server +
    trouve-search sub-agent + workflow skill, installed via the marketplace
    catalog at .claude-plugin/marketplace.json) and the Codex plugin bundle
    (MCP server + skill, via .agents/plugins/marketplace.json). All
    manifests pass their official validators and ship at the crate version.
  • Session-start index warming: the OpenCode/Kilo plugin builds or
    refreshes the project index in the background when it loads and
    (throttled) on every session.idle event, so the first search never pays
    the index build and later searches absorb the agent's own edits
    ("warm": false disables). The Claude Code bundle ships an equivalent
    SessionStart hook running trouve stats in the background.
  • Version sync tooling: scripts/sync_versions.py keeps every published
    artifact (npm plugin packages, Claude Code and Codex plugin manifests) on
    the exact crate version from Cargo.toml, and lint CI fails when anything
    drifts (--check). The release workflow refuses tags that don't match the
    crate version and publishes all npm plugin packages at the crate version
    alongside the crates.io publish (skipped until NPM_TOKEN is configured).
  • Model-backed end-to-end tests: TROUVE_E2E=1 cargo test -- --ignored
    (already documented in the README and run by CI) now actually runs a small
    e2e suite against the real default model — cold index, semantic and
    identifier queries, find_related, and a warm rebuild that recomputes
    nothing.

Changed

  • MSRV raised from 1.87 to 1.89 (std file locking for the clone cache).

Fixed

  • .trouveignore now works in git repositories: ignore rules were only
    consulted by the directory walker (non-git roots); git repositories build
    their manifest from git ls-files/git status and skipped them entirely.
    Rules are now applied on top of the git listing — before any hashing I/O —
    for tracked and untracked files alike.
  • MCP protocol violations: tool failures were returned with
    isError: false (clients treated them as successful output) and a
    malformed request with an id but no method got no response at all, hanging
    the client; failures now set isError: true and malformed requests get a
    -32600 Invalid Request error. top_k: 0 is rejected as the schema
    advertises, and max_snippet_lines: null now means the documented default
    instead of being an undocumented full-chunk escape hatch.
  • Git manifest correctness: tracked symlinks were keyed by the blob OID
    of the link target path while indexing read the target file's content,
    serving stale chunks whenever the target changed; symlinks are now skipped
    like the walker already did. Merge-conflicted (unmerged) paths are treated
    as dirty and indexed from the working tree instead of an arbitrary
    conflict stage.
  • Snapshot compatibility checks: snapshots now record the store format
    version and chunk length, and the incremental patch path rejects
    mismatches instead of silently splicing rows chunked under different rules
    (snapshot format bumped to v4; old snapshots are rebuilt automatically).
    save() also verifies a pre-existing snapshot file's embedded hash and
    rewrites partial or foreign files instead of trusting them forever.
  • Model loading robustness: corrupt or mismatched model artifacts
    (out-of-range mapping entries, undersized embedding tables, token-id gaps)
    are rejected with a clear error at load time instead of panicking
    mid-index, and a tokenizer failure on one text now embeds it as the zero
    vector with a one-time warning instead of aborting the whole build.
  • Accurate cache statistics: files_from_store no longer counts rows
    spliced zero-copy from a previous snapshot (reported separately as
    files_from_snapshot), and trouve stats now emits the documented
    cache_hit_rate.

Removed

  • trouve install / trouve uninstall: the interactive installer is
    gone. Every integration it configured is now documented as a manual (and
    easily reversible) step in
    INSTALL.md:
    plugins for OpenCode/Kilo/Claude Code/Codex, the OpenCode native tool
    file, one MCP config entry per agent, and optional sub-agent files.
    Editing user configs programmatically was the installer's main risk
    (JSONC files had to be skipped, TOML edits could clobber user changes); a
    documented one-line config entry per agent is simpler and safer.

Deprecated

  • .sembleignore files: still honoured, but log a warning and will be
    removed in a future release. Rename to .trouveignore.
  • SEMBLE_CACHE_LOCATION, SEMBLE_MODEL_NAME, SEMBLE_CLONE_TIMEOUT:
    now honoured as fallbacks when the TROUVE_* equivalent is unset, but log
    a warning and will be removed in a future release. Use
    TROUVE_CACHE_LOCATION, TROUVE_MODEL_NAME, and TROUVE_CLONE_TIMEOUT.

Full Changelog

v1.0.0...v1.1.0

What's Changed

  • Add Renovate config by @jimsimon in #2
  • Benchmark git vs non-git roots; gate CI on benchmark regressions by @jimsimon in #1
  • Add tree-sitter grammars for 23 more languages by @jimsimon in #5
  • Fix new stable clippy lint manual_is_multiple_of by @jimsimon in #3
  • Update LICENSE copyright holder to James Simon by @jimsimon in #13
  • Add trouve-native config names with deprecated semble fallbacks by @jimsimon in #14
  • Consolidate all agent plugins into one trouve-plugin package by @jimsimon in #12
  • Keep crate, plugin, and package versions in sync — enforced in CI and releases by @jimsimon in #11
  • Cache shallow clones of remote repositories persistently by @jimsimon in #4
  • Add native OpenCode custom tools as an opt-in alternative to MCP by @jimsimon in #6
  • Validate store parameters on snapshot open; verify existing files in save by @jimsimon in #16
  • Fix MCP protocol violations and parameter handling by @jimsimon in #18
  • Report snapshot reuse separately and add the documented cache hit rate by @jimsimon in #19
  • Docs cleanup: fix inaccuracies found in review by @jimsimon in #23
  • Remove the interactive installer in favor of manual install docs by @jimsimon in #22
  • Honor .trouveignore in git repositories by @jimsimon in #15
  • Handle tracked symlinks and merge conflicts in the git manifest by @jimsimon in #17
  • Validate model artifacts at load time; never panic on tokenizer failure by @jimsimon in #20
  • Add the model-backed e2e tests that README and CI already promised by @jimsimon in #21
  • Prepare the v1.1.0 release by @jimsimon in #24

New Contributors

Read more

v1.0.0

Choose a tag to compare

@jimsimon jimsimon released this 03 Jul 08:40

First stable release. trouve is a Rust port of MinishLab/semble — fast, accurate code search for agents — rebuilt around an incremental, branch- and worktree-aware index. Retrieval behaviour matches upstream: mean NDCG@10 within 0.0002 on the upstream annotated benchmark, with identical chunk boundaries and BM25 scores.

Highlights

  • Content-addressed chunk store — per-file artifacts (chunks, embedding rows, BM25 token lists) keyed by content hash: git blob OIDs for clean files (no file reads at all), BLAKE3 for dirty/untracked files. Editing one file re-embeds one file.
  • Branch- and worktree-aware caching — one store per repository, keyed by the git common directory and shared across all branches and worktrees. Switching branches only pays for content the store has never seen.
  • Memory-mapped snapshots — warm queries load embeddings and BM25 postings zero-copy; incremental builds patch the previous snapshot, so cost is proportional to the edit, not the repository.
  • Bounded cache — snapshot pruning plus a daily mark-and-sweep GC with a one-hour grace period for concurrent builds.
  • In-house model2vec engine — memory-mapped embedding table and a WordPiece fast path with per-word memoisation; bit-identical to model2vec-rs per text, with batch-independent embeddings.
  • Fully parallel pipeline — hashing, parsing, chunking, tokenizing, embedding, and BM25 construction across all cores via rayon.
  • Faithful retrieval port — tree-sitter chunking for ~28 languages, potion-code-16M embeddings, Lucene-variant BM25, RRF fusion, and upstream's code-tuned reranking.
  • CLI + MCP serversearch, find-related, stats, savings, clear, and an interactive install covering eleven coding agents; bare trouve runs an MCP stdio server.

Performance

Measured on kubernetes/kubernetes (30,563 tracked files) vs upstream Python semble (BENCHMARKS.md):

Scenario trouve Python semble Speedup
Cold index + query 3.3 s ~3 min 54x
Incremental (1 file touched) 0.86 s ~3 min 212x
Warm query 0.55 s 7.2 s 13x

Binaries

Prebuilt for Linux (glibc and static musl; x64 and arm64), macOS (x64 and arm64), and Windows (x64 and arm64), with SHA-256 checksums. Or cargo install trouve.

Credits

trouve's retrieval design comes from Semble by Thomas van Dongen and Stephan Tulkens of MinishLab — see the citation guide and DIFFERENCES.md.

Full Changelog

https://github.com/jimsimon/trouve/commits/v1.0.0