Skip to content

Releases: nrupala/codetopo

codetopo-acp 0.4.0

Choose a tag to compare

@nrupala nrupala released this 11 Oct 04:28

Feature release for the ACP agent only: codetopo-acp 0.4.0 is on crates.io; the other six crates remain at 0.3.3. Release binaries for codetopo-acp (linux/macOS/Windows) are attached to this release.

  • codetopo-acp 0.4.0 — ACP Terminal Auth (trust setup): the agent now advertises one terminal auth method, codetopo-trust-setup, until setup is recorded (and only to clients declaring terminal-auth support, per the spec). codetopo-acp login provisions the HMAC proof-verification key locally (0600, hidden entry; keyless setup offered) — codetopo has no accounts, and the one secret in its trust model is that key. Snapshots the agent takes are signed when a key is provisioned, and answers cite the certificate serial and signer fingerprint. Design: docs/acp-trust-setup.md. Other crates unchanged at 0.3.3.

codetopo-mcp 0.3.4

Choose a tag to compare

@nrupala nrupala released this 11 Oct 05:09

Patch release for the MCP server only: codetopo-mcp 0.3.4 is on crates.io; the other crates are unchanged (five at 0.3.3, codetopo-acp at 0.4.0). Release binaries for both agent binaries are attached.

Windows build fixed. codetopo-mcp had never compiled on Windows — its stdio stdout seal used Unix-only fd APIs. The seal now has a Win32 implementation (duplicate the stdout handle for the protocol writer; SetStdHandle to NUL before std's lazy first handle fetch), and CI builds both agent binaries on Windows so this cannot regress silently. Found by the release-binaries pipeline — the first Windows build in the project's history.

codetopo 0.3.3

Choose a tag to compare

@nrupala nrupala released this 11 Oct 04:06

Patch release: all seven crates at 0.3.3 on crates.io with correctly rendered READMEs. No code changes from 0.3.0.

All seven crates; no code changes. Fixes how the crates appear on crates.io.

  • The hand-rolled crates.io publisher sent the README filename where the registry protocol expects the README content, so every version up to 0.3.2 renders a one-line placeholder instead of the README on its crates.io page. 0.3.3 is published with the corrected publisher; the full README (including the MCP Registry identity line) now renders. Functionality is identical to 0.3.0.
  • codetopo-mcp 0.3.1 and 0.3.2 were registry-listing iterations on the way here (ownership marker, then the marker as visible text); 0.3.3 supersedes them and restores one version across the workspace.

codetopo 0.3.0

Choose a tag to compare

@nrupala nrupala released this 11 Oct 03:26

First crates.io publication: all seven crates at 0.3.0 — cargo install codetopo-cli codetopo-server codetopo-mcp codetopo-acp.

Added

  • The Space bundle recaptures itself. The Hugging Face Space's
    data (space-static/data/) was a one-time capture from 0.2.5;
    the demo-graph workflow refreshed only the aimlds demo, so the
    Space kept rendering the old snapshot after merges. A new
    space-recapture workflow now rebuilds codetopo-server from
    every merge to main, re-indexes this repository with it, and
    commits a fresh byte-for-byte capture
    (scripts/capture-space-bundle.sh) — but only after the honesty
    gates pass (snapshot counts equal stats totals; snapshot audit
    head equals the verify head with a valid chain). The bot's data
    commit is what hf-sync then mirrors to the Space; two guards
    (paths-ignore + a head-commit check) keep the workflow from
    re-triggering on its own output.
  • Deterministic render: codetopo render. A layout spec
    (JSON) and an SVG drawing that are pure functions of the stored
    graph — same graph in, same bytes out, on any machine. Layers
    follow the longest dependency path over the SCC-condensed
    dependency DAG (cycles share a layer; containment is drawn but
    never layers); in-layer order is by node id; coordinates are
    integer grid cells. The spec is self-contained and versioned
    (layout_version: 1); the SVG consumes the spec alone. Rules
    and size behaviour: docs/render.md.
  • Self-hosted container. A multi-stage Dockerfile (four
    binaries on a slim Debian runtime — they link only libc/libm)
    and a docker-compose.yml that runs the HTTP API over a /data
    volume, with the server's env contract
    (CODETOPO_BIND/DATA_DIR/KEYS_FILE/METERING_LOG) wired in.
    The server still refuses to start without a keys file.
    Workspace crates version 0.2.8.

Fixed

  • MCP tools/call results are CallToolResults now. Success
    results were the tool's bare JSON object; the MCP schema requires
    a content array, and strict SDK clients parsed the old shape as
    no content at all (in-house tests read the bare object and stayed
    green — the defect class this fix's wire-level test exists to
    catch). Results now carry content (the result JSON as a text
    block) plus structuredContent with the same object.
  • ACP speaks ACP. The agent's wire protocol was a home-grown
    dialect: protocolVersion as the string "1.0" (the spec's is
    the integer 1), string prompts (the spec's are content-block
    arrays), invented session/new result fields, and answers in a
    custom field instead of a streamed agent_message_chunk +
    stopReason. Rewritten to ACP v1: spec handshake (integer
    version, honest capabilities — no session loading, text-only
    prompts, no auth methods), {sessionId} results, content-block
    prompt text, streamed chunks, end_turn/refusal stop reasons,
    and session/cancel handled as a notification. Workspace crates
    version 0.2.7; live frames from both protocol binaries validate
    against the protocols' official JSON schemas
    (docs/protocol-proof.md).

Added

  • Real import resolution in the graph builder. Discovery named
    the packages; this makes their imports link. use a::b::Item
    now lands on module a::b (the longest module prefix — before,
    every Rust use of an item became an external stub); bare
    workspace-package imports (npm from 'ui-kit', cross-crate
    use) resolve through their bindings to the defining module,
    with hyphen/underscore normalization; an extractor's
    external:: pre-mark no longer doubles (external::external::std
    is gone); a package's root module is its package node — the id
    collision that silently dropped root modules and rejected their
    imports with UnknownSymbol is fixed; and crate::-qualified
    calls resolve into the caller's package. Also: pyproject.toml
    ([project] / [tool.poetry]) joins Cargo.toml and package.json
    as a discovery manifest (CODE_SCHEMA names PyPI projects as
    packages). Rules documented in CODE_SCHEMA §3.1.
  • Package/workspace discovery in the indexer. Indexing now
    finds the manifest that owns each file — a Cargo.toml
    [package] name or a package.json name, nearest manifest
    wins — and indexes the file under that package with paths
    relative to the package root, which is what the extract
    contract always specified. Until now one caller-chosen package
    and repo-relative paths covered the whole tree, so a workspace
    indexed as corpus::crates::codetopo-core::src::…; ids now
    read codetopo-core::…. Files under no manifest keep the
    caller's package (--package, defaulting to the repo
    directory name) exactly as before. Workspace crates version
    0.2.6.

Added

  • Scale gate passed at 10,000 files (docs/scale-gate.md). A
    deterministic 10k-file fixture (generator:
    scripts/gen_scale_fixture.py; gate test:
    codetopo-cli/tests/scale_gate.rs, run deliberately in release
    mode) indexes in ~3.5 s at 134 MB peak RSS (46,001 nodes / 90,017
    edges), and the long-pole queries answer in well under a second
    in-process. Defect found and fixed: cycle detection (Tarjan
    SCC) was recursive — a 10,000-deep call chain overflowed a 2 MB
    thread stack and aborted the process; it is now an iterative
    Tarjan with identical results, so depth is bounded by heap, not
    by the caller's stack. Also corrected schemas/README.md's MCP
    tool count (eight → twelve). All seven crates bumped
    0.2.4 → 0.2.5.
  • Contract drift gates + ACP version honesty. The published
    contracts can no longer drift silently: workspace tests (run in CI)
    now fail when schemas/mcp-tools.json differs from the live MCP
    tool catalogue or its recorded server version, and when
    schemas/openapi.yaml's info version or route set differs from
    what codetopo-server serves (its version had been stale at 0.1.0;
    now 0.2.4). The ACP agent's initialize handshake reports the
    crate version instead of a hardcoded 0.1.0. All seven crates
    bumped 0.2.3 → 0.2.4.
  • One surface, three doors (final-shape W3). The CLI, HTTP API,
    and MCP server now answer the same questions with the same shapes:
    • Discovery everywhere. Graph::search_symbols (exact < prefix <
      contains ranking) plus codetopo search, GET …/search, and
      codetopo_search_symbols — before this, every query needed an
      exact node id nobody could discover from the tools themselves.
    • Neighborhood everywhere. CODE_SCHEMA §6 names the neighborhood
      query binding, but no surface exposed it. Now: codetopo neighborhood, GET …/neighborhood, codetopo_neighborhood,
      all serving the core Graph::neighborhood computation.
    • One symbol, in full: codetopo symbol, GET …/symbol,
      codetopo_get_symbol; and the schema itself: codetopo schema,
      GET /v1/schema, codetopo_describe_schema — one generator in
      the CLI library, so the three cannot drift.
    • One package identity. Indexing without an explicit package now
      derives the same name on every surface (the repository
      directory's file stem). The HTTP surface previously recorded
      unknown, so the same tree produced different node ids — and
      different query results — depending on the door used.
    • CLI --json on descendants / ancestors / blast-radius / path /
      stats, emitting the HTTP response shapes (minus index_id), so
      scripts get one format from either door.
    • schemas/mcp-tools.json regenerated from the live binary
      (twelve tools); schemas/openapi.yaml documents the new routes.
      (No version bump in this PR.)
  • Extractor conformance (final-shape W4). The graph now carries
    the schema's full edge vocabulary:
    • Reads/writes are first-class. A resolved ref is a reads edge
      and an assignment target is a writes edge — before this, reads
      hid inside references edges with a kind: "read" attribute,
      invisible to kind-walking queries (blast radius included).
      CODE_SCHEMA §4 amended accordingly (dated amendment note);
      references remains restorable from older snapshots.
    • Heritage edges. Rust impl Trait for Type → implements,
      trait supertraits → inherits; TypeScript extends /
      implements clauses likewise. New emit channel
      (FileSymbols.heritage) resolved by the builder.
    • Tiers classify. By node kind in the builder — skeleton
      (package/module/file) core, type declarations recommended,
      the rest optional — instead of every node carrying the default.
    • More of the tree is seen: .mjs / .cjs files, Markdown
      files as doc nodes, Rust type aliases and TS enums / type
      aliases as type symbols.
    • Verified on this repo's own code: 1,932 reads edges, writes,
      19 doc nodes, tiers distributed — and zero implements edges,
      correctly: every impl in this codebase targets an external trait.
      (No version bump in this PR — W2 owns the next one.)
  • Proof certificates v2 + standalone verification (final-shape W2).
    Snapshot certificates now carry a serial number, issuer, signer-key
    fingerprint, and a signed one-year validity window; an expired
    certificate is refused. Restore and the new
    codetopo verify-proof --snapshot command share one verification
    gate (schema major per CODE_SCHEMA §8, audit chain, certificate) —
    restore writes only after the gate passes, and verify-proof runs
    the same gate without writing. Certificate v1 files still verify
    and are reported as v1 (no serial or validity window). All seven
    crates bumped 0.2.2 → 0.2.3.
  • Persisted diagnostics + store format gate (restored from PR #13,
    see the reconciliation note below).
    Builder diagnostics are
    stored with the index and replaced on reindex; the new
    codetopo diagnostics --db command prints them after the fact.
    The store stamps a format version (PRAGMA user_version) and
    refuses databases from newer formats. The symbols: ...
Read more

v0.2.0

Choose a tag to compare

@nrupala nrupala released this 05 Oct 18:31
a4b5e7f

codetopo v0.2.0 — release notes

First release. v0.2.0 ships Phase 1 (engine + CLI), Phase 2 (API + MCP), and Phase 3 (ACP agent) together.

v0.2.0 — See your codebase the way an agent sees it

codetopo is a pure, domain-blind code-visualization engine written in Rust. It parses source code with tree-sitter extractors, builds a queryable model of the codebase (symbols, relationships, structure), and serves it headless — through a CLI, an HTTP API, an MCP server, and an ACP agent — so both humans and AI agents can explore code structurally instead of grepping through it.

What's in this release

Phase 1 — Engine + CLI

  • codetopo-core: workspace model — the codebase as a queryable graph of nodes and edges
  • codetopo-extract: tree-sitter extractors that turn source files into the core model
  • codetopo-store: SQLite-backed store with a hash-chained audit log, so every write is tamper-evident
  • codetopo (CLI): headless commands to index a codebase and query it — descendants, ancestors, path, snapshot — built for scripts, CI, and agent tooling

Phase 2 — API + MCP

  • codetopo-server: axum HTTP API, 8 endpoints under /v1, Bearer-token auth, JSONL usage metering
  • codetopo-mcp: stdio MCP server exposing the engine as 8 tools, so any MCP-capable agent can query a codebase directly
  • schemas/: OpenAPI 3.1 (openapi.yaml) and MCP tool definitions (mcp-tools.json) for the full surface

Phase 3 — ACP agent

  • codetopo-acp: stdio agent speaking the Agent Client Protocol — conversational sessions (initialize → session/new → session/prompt) for editors and clients that talk to agents instead of calling tools
  • Deterministic intent routing (descendants / ancestors / blast-radius / path / stats / snapshot / verify) to the same core queries — no LLM, no network, no file writes; edit requests get an honest read-only refusal

Install

From crates.io is not wired up yet — install from the repo:

cargo install --git https://github.com/nrupala/codetopo

This builds four binaries:

Binary What it does
codetopo Headless CLI — index a codebase, query descendants/ancestors/paths, take snapshots
codetopo-server HTTP API server (/v1, Bearer auth, JSONL metering)
codetopo-mcp stdio MCP server — 8 tools for agent code exploration
codetopo-acp stdio ACP agent — conversational code-structure sessions for editors

Build from source instead:

git clone https://github.com/nrupala/codetopo
cd codetopo
cargo build --release
# binaries land in target/release/

Requires a Rust toolchain (stable) and a C compiler (tree-sitter grammars). No runtime dependencies — one static-ish binary each.

License

  • Engine and servers (codetopo-core, extract, store, CLI, server, MCP, ACP): AGPL-3.0-or-later — see LICENSES/AGPL-3.0.txt
  • Schemas (schemas/, OpenAPI + MCP definitions): Apache-2.0 — see LICENSES/Apache-2.0.txt

Owned by Nrupal Akolkar · Built with Muse by Meta.