• v0.26.1 45558875f7

    code-index v0.26.1
    All checks were successful
    CI / cargo fmt (push) Successful in 46s
    CI / Grammar rebuild from source (weekly) (push) Has been skipped
    CI / OSS corpus tier-3 scale (weekly) (push) Has been skipped
    CI / cargo test (abi, 32-bit + wasm32) (push) Successful in 3m58s
    CI / cargo doc (intra-doc links) (push) Successful in 4m22s
    CI / cargo clippy (push) Successful in 5m1s
    CI / cargo check (MSRV 1.98) (push) Successful in 5m27s
    CI / cargo check (windows-gnu) (push) Successful in 5m39s
    CI / cargo deny (push) Successful in 5m55s
    CI / OSS corpus (tier 1) (push) Successful in 15m20s
    CI / cargo test (push) Successful in 17m51s
    CI / cargo test (daemon transport) (push) Successful in 6m32s
    CI / Plugin path cost + pool throughput (weekly) (push) Has been skipped
    CI (Windows) / fmt + clippy + build + test (windows) (push) Successful in 35m57s
    Release Build / Generate Version (push) Successful in 27s
    Release Build / Required CI green (push) Successful in 48s
    Release Build / Build linux-aarch64 (push) Successful in 12m36s
    Release Build / Build windows-x86_64 (push) Successful in 13m27s
    Release Build / Build linux-x86_64 (push) Successful in 15m22s
    Release Build / Build linux-x86_64-musl (push) Successful in 15m56s
    Release Build / Pack the XAML reference package (push) Successful in 52s
    Release Build / Create Forgejo Release (push) Successful in 2m52s
    Stable

    buildagent released this 2026-09-04 10:05:07 +02:00 | 479 commits to master since this release

    code-index v0.26.1

    Build: v0.26.1+574

    Four-binary release: code-index-mcp (MCP stdio bridge — the usual entry), code-index-daemon (long-lived watcher + RPC server, auto-spawned), code-index-plugin-host (sandboxed worker for plugin packages, spawned by the daemon), and code-index (CLI: init, index, watch, doctor, link, plugin).

    Every fix here is the same shape: a state the product could observe but
    had no way to report, so it reported the neighbouring state instead. All
    three were found by dogfooding v0.26.0 against this repository.

    Mistyped arguments now answer like every other argument error

    An MCP tool called with a wrong argument NAME has always answered with a
    structured error naming every accepted argument. A wrong argument TYPE
    did not: it fell through to the framework's own text —

    failed to deserialize parameters: invalid type: string "...", expected a sequence
    

    no error code, no hint, and not JSON at all, so a client that parses one
    could not parse the other. That is exactly the mistake a caller makes:
    passing a single value where a LIST is wanted, for arguments like
    task_terms, symbol_ids, handles and paths whose names read like
    they take one.

    A MISSING required argument had the same problem, one shape further
    along: find_callers with no arguments answered
    failed to deserialize parameters: missing field \symbol_id``.

    All three now answer in one envelope, read off the SAME published schema
    at the SAME boundary — so every registered tool and every declared
    argument is covered by construction, including the element types inside
    a list, and a tool added tomorrow is covered the day it is registered.

    The three are ordered by how much of your call is knowable, and the
    order is deliberate rather than incidental:

    1. an UNDECLARED argument, which has no declared type to be wrong
      against and no bearing on what is required — and a misspelled
      required argument is both defects at once, where naming both sides
      beats naming one;
    2. a MISSING required argument, because no amount of fixing types
      makes an incomplete call run;
    3. a WRONG TYPE, once the call is complete.

    Presence is not value: a required argument supplied as null is
    present, and is graded as a type. The two gates do not overlap.

    The leash actually holds on Windows

    code-index's test harness ties every daemon it spawns to the process
    that spawned it, so none outlives its fixture. On Windows that tie did
    NOTHING — attach returned an inert handle and kill_group had an
    empty body — and the suite that would have caught it was Unix-only, so
    the Windows leg reported running 0 tests. No implementation and no
    coverage, neither able to fail.

    Windows now gets a real Job Object: the job is created BEFORE the child,
    the child is started suspended and assigned while it is still frozen —
    so a grandchild it has not spawned yet cannot escape — and
    KILL_ON_JOB_CLOSE makes the operating system the killer, which is
    stricter than the Unix side, where a nanny process exists only because a
    Drop does not run when the holder is killed outright.

    A leash that CANNOT be established now says so, carrying what the OS
    reported, instead of being indistinguishable from one that was never
    asked for. The same conflation was fixed on Unix, where a child that
    leads no process group was also silently reported as "inert".

    This matters to you only if you run the test suite; it is why a Windows
    CI run could leave daemons behind.

    An admission that no rule proved says which it was

    The file watcher admits a path when nothing proves it should be skipped.
    There are two ways to reach that: the ignore rules were consulted and
    allowed it, or the path's relation to the project root could not be
    parsed at all, so no rule was ever applied. Those were the same number.

    They are now distinguishable. The verdict is UNCHANGED — an unparseable
    path is still admitted, deliberately, because reporting it as
    "deliberately excluded" would be its own lie — and a test now pins that
    so a future "repair" cannot quietly invert it.

    Also

    The release pipeline could not publish its own notes. Two defects, both
    of which produce a release whose changelog is not what its author wrote:

    • actions/checkout resolves a tag to the COMMIT it points at, so the
      annotation is absent in the runner even when the remote holds a real
      tag object. The tag ref is now re-fetched before the notes are read.
    • git tag -F runs git's default cleanup, which strips every line
      beginning with # — deleting every markdown heading from a notes
      file, silently. The pipeline now refuses notes with no heading and
      names --cleanup=verbatim as the repair.

    v0.25.0 shipped an internal narrative about zombie processes as its
    changelog because of the first of these. v0.26.0 caught it and refused
    to publish rather than publish the wrong text.

    Upgrading

    No action required, and no index schema change.

    Downloads

    Four platforms are built for every release. The table below says which ones THIS release published.

    Platform Archive
    Linux x86_64 (glibc) code-index-v0.26.1-linux-x86_64.tar.gz
    Linux x86_64 (static/musl) code-index-v0.26.1-linux-x86_64-musl.tar.gz
    Linux ARM64 code-index-v0.26.1-linux-aarch64.tar.gz
    Windows x64 code-index-v0.26.1-windows-x86_64.zip

    XAML plugin package

    de.h-dv.xaml-0.1.0.cip makes .xaml files carry symbols and references instead of being text-only: x:Class and Click= handlers bind into the paired C# code-behind, x:Name becomes a searchable declaration, and {Binding …} stays unresolved because no bridge can reach it.

    It is NOT installed by installing code-index. Packages are installed into a user-controlled store and approved per project, and installing grants nothing — enable is the grant.

    Download de.h-dv.xaml-0.1.0.cips too and keep the .cips beside the .cip. Packages are signed and an unsigned one is refused (signature_missing) with no flag that accepts it. You do NOT need to anchor us first: this release's publisher key is compiled into the binary, so the install below works on a machine that has anchored nobody. code-index plugin trust list shows it, marked [BUILTIN], and code-index plugin trust remove sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c withdraws it — see About that key.

    code-index plugin install de.h-dv.xaml-0.1.0.cip --sha256 sha256:584fe7183b234e7133fa7d257cc8a8d687f38bfb43d235cfda657ba13b1186dd
    code-index plugin check   sha256:584fe7183b234e7133fa7d257cc8a8d687f38bfb43d235cfda657ba13b1186dd
    code-index plugin enable  sha256:584fe7183b234e7133fa7d257cc8a8d687f38bfb43d235cfda657ba13b1186dd \
        --capabilities bridge_source \
        --bridges 'de.h-dv.xaml/xaml:type->csharp:class,de.h-dv.xaml/xaml:call->csharp:method'
    

    The digest above is the one this release packed and it is what --sha256 pins; de.h-dv.xaml-0.1.0.cip.digest.txt carries it and the extraction identity. A digest that changes between releases means the package changed — re-pin, and read the notes.

    Only .xaml is claimed. .dataset and other markup remain text-only (searchable, no symbols).

    About that key

    sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c is a long-lived Ed25519 key held as a secret in this project's CI, used to sign released packages automatically, and it is compiled into the binaries in this release. That trusts this project's release pipeline, not only its maintainers: anyone who can run a release workflow here can produce a package that verifies under it. It adds nothing you had not already granted — the bytes are inside the program you are running, so forging that anchor means forging the binary — but you are entitled to know it is there before a package installs rather than after.

    There is no expiry — deliberately, because offline installations must not break on a timer — and withdrawal is on your side and works: code-index plugin trust remove sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c. A compiled-in key has no file to delete, so that writes one instead, carrying denied = true; the key stops verifying at the next load, plugin trust list shows it marked [DENIED], and deleting that file (the command prints its path) is the only undo. If the key is ever rotated, the new fingerprint is published here and in tests/packages/first-party.fingerprint, and a build that predates the rotation will not trust it.

    You may anchor it yourself instead — code-index plugin trust add code-index-publisher.pub --fingerprint sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c --name 'a label you choose', with code-index-publisher.pub from this release's assets. Your file replaces the compiled-in entry, and the --name is a label YOU choose: nothing in the package, the key file or the signature can name its own publisher.

    macOS is not currently built. No x86_64-apple-darwin or aarch64-apple-darwin archive is published — macOS users should build from source (cargo build --release). This is a deliberate deferral, tracked in #59; no date is promised.

    Wire into Claude Code

    { "mcpServers": { "code-index": { "command": "/usr/local/bin/code-index-mcp", "args": ["--root", "/path/to/your/project"] } } }
    

    SHA256 checksums (.sha256 files) available for every archive.

    Downloads