Repository navigation
Releases: nrupala/codetopo
Release list
codetopo-acp 0.4.0
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 loginprovisions 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
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
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-mcp0.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
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-recaptureworkflow now rebuildscodetopo-serverfrom
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 whathf-syncthen 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 adocker-compose.ymlthat 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/callresults are CallToolResults now. Success
results were the tool's bare JSON object; the MCP schema requires
acontentarray, 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 carrycontent(the result JSON as a text
block) plusstructuredContentwith the same object. - ACP speaks ACP. The agent's wire protocol was a home-grown
dialect:protocolVersionas the string"1.0"(the spec's is
the integer1), string prompts (the spec's are content-block
arrays), inventedsession/newresult fields, and answers in a
custom field instead of a streamedagent_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/refusalstop reasons,
andsession/cancelhandled 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 modulea::b(the longest module prefix — before,
every Rustuseof an item became an external stub); bare
workspace-package imports (npmfrom '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 withUnknownSymbolis fixed; andcrate::-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.jsonname, 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 ascorpus::crates::codetopo-core::src::…; ids now
readcodetopo-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 correctedschemas/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 whenschemas/mcp-tools.jsondiffers from the live MCP
tool catalogue or its recorded server version, and when
schemas/openapi.yaml's info version or route set differs from
whatcodetopo-serverserves (its version had been stale at 0.1.0;
now 0.2.4). The ACP agent'sinitializehandshake reports the
crate version instead of a hardcoded0.1.0. All seven crates
bumped0.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) pluscodetopo 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 coreGraph::neighborhoodcomputation. - 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
--jsonon descendants / ancestors / blast-radius / path /
stats, emitting the HTTP response shapes (minusindex_id), so
scripts get one format from either door. schemas/mcp-tools.jsonregenerated from the live binary
(twelve tools);schemas/openapi.yamldocuments the new routes.
(No version bump in this PR.)
- Discovery everywhere.
- 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
readsedge
and an assignment target is awritesedge — before this, reads
hid insidereferencesedges with akind: "read"attribute,
invisible to kind-walking queries (blast radius included).
CODE_SCHEMA §4 amended accordingly (dated amendment note);
referencesremains restorable from older snapshots. - Heritage edges. Rust
impl Trait for Type→implements,
trait supertraits →inherits; TypeScriptextends/
implementsclauses likewise. New emit channel
(FileSymbols.heritage) resolved by the builder. - Tiers classify. By node kind in the builder — skeleton
(package/module/file)core, type declarationsrecommended,
the restoptional— instead of every node carrying the default. - More of the tree is seen:
.mjs/.cjsfiles, Markdown
files asdocnodes, 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 zeroimplementsedges,
correctly: every impl in this codebase targets an external trait.
(No version bump in this PR — W2 owns the next one.)
- Reads/writes are first-class. A resolved ref is a
- 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 --snapshotcommand 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 bumped0.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 --dbcommand prints them after the fact.
The store stamps a format version (PRAGMA user_version) and
refuses databases from newer formats. Thesymbols:...
v0.2.0
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
indexa 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/codetopoThis 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 — seeLICENSES/Apache-2.0.txt
Owned by Nrupal Akolkar · Built with Muse by Meta.