Releases: smochan/polycodegraph
Release list
v0.1.2
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[Unreleased]
[0.1.2] — 2026-05-31
Removed
- Dead
mcp.enabledconfig block..codegraph.ymlcarried an
mcp.enabled: falsedefault that no code path ever read — confusing
next to the activeregister_mcp: true. Removed fromCodegraphConfig;
the model is set to silently ignore the field so existing 0.1.x configs
still load without error. New configs no longer emit it.
Added
codegraph cleansubcommand + auto-prune of.codegraph/explore/.
codegraph servegenerated a pyvis HTML page per explored function
and never pruned them — long-lived projects could grow this cache to
hundreds of MB. New modulecodegraph/cache_prune.pyimplements LRU
eviction by mtime (prune_cache_to_size(path, max_size_mb)), and the
newcodegraph cleansubcommand exposes it with--max-size-mb 50
(default) and--all(wipe everything).codegraph serveruns the
prune on startup and prints the current cache size.- Auto-populate ignore patterns from detected ecosystem during
init.
The free-text "Extra ignore patterns" prompt was a footgun — a user
once typedythinking it was yes/no and gotignore: [- y]in
their YAML. Init now sniffs the repo forpyproject.toml,
package.json(with React Native detection),go.mod,Cargo.toml,
pom.xml,build.gradle, and pre-fills the matching ignore patterns
(__pycache__/,.venv/,node_modules/,ios/Pods/,
android/build/,vendor/,target/,build/, …). The user
confirms the auto-detected list with a single yes/no; the free-text
extras prompt is still there for project-specific paths but no longer
the only path to safety. codegraph initwrites agent guidance toCLAUDE.mdandAGENTS.md.
After a fresh install on a project, coding agents (Claude Code,
Cursor, Codex, …) defaulted to grep even with polycodegraph's MCP
server registered, because they had no hint that polycodegraph was
available. Init now prompts (default: yes) and writes a short
"## polycodegraph" section telling the agent which MCP tool to use
for each kind of structural query (find-symbol, callers, callees,
blast-radius, dataflow-trace, untested, dead-code). Mirrors the
.mcp.jsonbehaviour: creates the file when absent, appends when
present without the section, leaves alone when the section is
already there. Both files are written so Codex / GitHub Copilot CLI
(which readAGENTS.md) get the hint too.
Changed
- Edge classification:
externalvsunresolved-local. The
unresolved_edgesmetric used to lump together imports of external
packages (fastapi,os,react) — which static analysis without a
venv/site-packages parse cannot resolve and isn't supposed to — with
edges that pointed at in-repo symbols but couldn't be matched (rename
drift, dynamic import). One number, two very different meanings.
compute_metricsnow also returnsexternal_edges(root module not
in the repo) andunresolved_local_edges(root is in-repo, symbol
missed). Theunresolved_edgestotal is kept as the sum for
back-compat. Markdown report + MCPmetricstool both expose the
split. (Surfaced by a user adding polycodegraph to a FastAPI project
who saw "1,423 unresolved edges" and asked whether the tool was
broken; almost all were external imports.)
Fixed
-
codegraph initnow writes a robust.mcp.json— uses the absolute
path to thecodegraphbinary (resolved from the running interpreter's
bin dir, thenshutil.which, then bare fallback), passes an explicit
--db .codegraph/graph.dbflag, and setscwdto the repo root. The
0.1.1 fix wrote the file but used a barecodegraphcommand with no
--dband nocwd, which forced users to hand-edit the file when
their MCP client's$PATHor working directory didn't line up. Old
pre-0.1.2 default entries are migrated forward in place; user-customised
entries are left alone. (Surfaced when a user added polycodegraph to a
FastAPI project — Claude reported needing to fix all three.) -
Type-annotation-only references no longer count as dead code. The
Python parser now emits a reference edge from a function/method to
each capitalized type name appearing in its parameter and return type
annotations. Edges go through the existingunresolved::<TypeName>
resolver pipeline, so they rewrite to realCLASSids when the type
is defined in the repo. The flagship case is FastAPI Pydantic
request-body models —def create_defect(body: RetroDefect): ...was
flagged dead because the only reference toRetroDefectcame through
the type annotation; that loop is now closed. Stdlib typing
scaffolding (Optional,Annotated,Union, …) and FastAPI
dependency markers (Body,Depends, …) are blocklisted so the
graph stays clean. Framework-agnostic: any function with type
annotations benefits, not just route handlers. -
MCP server returns an actionable error when the graph isn't built.
Previously, every tool would happily return an empty result against
a missing.codegraph/graph.db. Claude / Cursor paraphrased that as
"workspace is empty," sending users down the wrong rabbit hole. Now
the dispatcher catches the missing-db case and returns a structured
{error: "graph_not_built", message: "polycodegraph: no graph found at <path>. Run \codegraph build` in the repo root first.", db_path:
...}. NewGraphNotBuiltErrorexposed fromcodegraph.mcp_server.server` for callers that want to handle it
explicitly. -
workspace_stateMCP tool now distinguishes "not configured" from
"no repos". When~/.codegraph/workspace.ymldidn't exist, the
tool returned{workspace_size: 0, repos: []}— indistinguishable
from a configured-but-empty workspace. LLMs paraphrased this as
"everything is broken" and cascaded into wrong-answer territory.
Result now carries astatusfield
(workspace_not_configured/workspace_empty/ok) with an
actionable message: "local-graph MCP tools work independently — this
only affects cross-repo tools. Runcodegraph workspace init…". -
semantic_searchandhybrid_searchMCP tools distinguish
"not enabled" from "not built". Both used to return a bare
{error: <stringified-exception>}when called without the optional
embeddings index. LLMs read this as catastrophic. Now both tools
return{status, message}:embeddings_not_enabled— the optionalcodegraph.embedimport
failed (dep not installed). Message: install with
pip install polycodegraph[embed].embeddings_not_built— module imports fine but no index for the
repo. Message: runcodegraph embed(~140 MB, ~30s).
Both messages spell out that the structural query tools
(find_symbol, callers, callees, blast_radius, dataflow_trace) work
without embeddings, so the LLM doesn't escalate the partial degrade
into "everything is broken". -
Bench harness: repomapper venv now bootstraps on Python 3.14.
aider-chat(transitive dep of repomapper) failed to install because
the bundled pip didn't provisionsetuptools.build_metaquickly
enough; build aborted withModuleNotFoundError: No module named 'setuptools.build_meta'.bench.runners._venv.ensure_venvgained a
build_deps=[...]kwarg that installs build-time deps in a separate
pip installbefore the main one; the repomapper runner sets it to
["setuptools", "wheel"]. Bench-side only — does not affect end
users.
[0.1.1] — 2026-05-24
Fixed
codegraph initnow actually writes.mcp.jsonwhen the user accepts
the "Register MCP server" prompt. Previously the prompt was labelled
"Phase 3 implementation" and only storedregister_mcp: truein
.codegraph.ymlwhile doing nothing on disk — which meant the README's
"Claude Code and Cursor auto-pick up polycodegraph" claim was broken in
0.1.0. Init now writes a project-local.mcp.json, merges into an
existing file when present, and preserves any user-customisedcodegraph
entry it already finds. The prompt default also flipped fromFalseto
True. (Issue surfaced when a user ranpipx install polycodegraphon
a fresh project and Cursor saw no MCP server.)
Upgrading from 0.1.0
If you ran codegraph init on 0.1.0 and answered yes to the MCP
register prompt, your .codegraph.yml says register_mcp: true but no
.mcp.json was ever written. Re-run codegraph init after upgrading
— it will re-prompt (defaults are pre-filled from your existing config)
and now actually write the file. Your existing graph + config are
preserved.
Post-launch-sprint additions (still pre-release)
Go language support — .go files parse + analyze cleanly
The Go ecosystem is the single biggest community pull outside Python/JS,
and a code graph that spans services + tooling + libraries was the
obvious next move. v1 of the Go extractor lives at
codegraph/parsers/go.py and produces the same node/edge shape as the
Python and TypeScript parsers, so every existing tool (analyze,
workspace_blast_radius, MCP queries) works on Go code immediately.
- New module
codegraph/parsers/go.py— tree-sitter Go grammar via
tree-sitter-go>=0.23(added topyproject.toml). - Node kinds emitted:
MODULE(one per.gofile, qualname = the
package Xname so files in the same package share an addressable
namespace),FUNCTION(top-levelfunc),METHOD(qualname
module.ReceiverType.Name, with receiver + pointer-ness in metadata),
CLASS(the closest analog to Go'stype X struct {...}and
type X interface {...}),TEST(*_test.gofiles). - Edge kinds emitted: `DEFINED_IN...
v0.1.1
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[Unreleased]
[0.1.1] — 2026-05-24
Fixed
codegraph initnow actually writes.mcp.jsonwhen the user accepts
the "Register MCP server" prompt. Previously the prompt was labelled
"Phase 3 implementation" and only storedregister_mcp: truein
.codegraph.ymlwhile doing nothing on disk — which meant the README's
"Claude Code and Cursor auto-pick up polycodegraph" claim was broken in
0.1.0. Init now writes a project-local.mcp.json, merges into an
existing file when present, and preserves any user-customisedcodegraph
entry it already finds. The prompt default also flipped fromFalseto
True. (Issue surfaced when a user ranpipx install polycodegraphon
a fresh project and Cursor saw no MCP server.)
Upgrading from 0.1.0
If you ran codegraph init on 0.1.0 and answered yes to the MCP
register prompt, your .codegraph.yml says register_mcp: true but no
.mcp.json was ever written. Re-run codegraph init after upgrading
— it will re-prompt (defaults are pre-filled from your existing config)
and now actually write the file. Your existing graph + config are
preserved.
Post-launch-sprint additions (still pre-release)
Go language support — .go files parse + analyze cleanly
The Go ecosystem is the single biggest community pull outside Python/JS,
and a code graph that spans services + tooling + libraries was the
obvious next move. v1 of the Go extractor lives at
codegraph/parsers/go.py and produces the same node/edge shape as the
Python and TypeScript parsers, so every existing tool (analyze,
workspace_blast_radius, MCP queries) works on Go code immediately.
- New module
codegraph/parsers/go.py— tree-sitter Go grammar via
tree-sitter-go>=0.23(added topyproject.toml). - Node kinds emitted:
MODULE(one per.gofile, qualname = the
package Xname so files in the same package share an addressable
namespace),FUNCTION(top-levelfunc),METHOD(qualname
module.ReceiverType.Name, with receiver + pointer-ness in metadata),
CLASS(the closest analog to Go'stype X struct {...}and
type X interface {...}),TEST(*_test.gofiles). - Edge kinds emitted:
DEFINED_IN,IMPORTS(per-import-path,
preserves aliases as metadata),CALLS(bare names likeFoo,
dotted-package likefmt.Println, receiver-method likeg.Greet),
INHERITS(Go composition — embedded fields in a struct become
INHERITSedges to the embedded type). - Registry hookup:
builder.pyimportscodegraph.parsers.goat
module load so the@register_extractordecorator fires.init's
language-detection map now includesgo: [".go"]. - Smoke test against
spf13/cobra: 36 files parsed, 715 Go nodes
(427 functions + 168 methods + 17 structs/interfaces + 17 test files- 19 modules), 2541 CALLS edges, 190 IMPORTS, 0 errors, 0.25s.
- 19 new parser tests at
tests/test_go_parser.pycovering every
emitted node/edge shape plus edge cases (empty file, missing file,
test-file detection, aliased imports, pointer receivers).
Limitations the parser is honest about up front:
- Generic type parameters land as text in metadata; not in qualnames.
- Interface satisfaction (does
*FooimplementBar?) is not detected
by the parser — that needs a whole-package pass and belongs in the
resolver layer, not the extractor. init()andmain()get no special treatment yet.
Cross-repo workspace mode — treat N repos as one mental unit
Solo devs and small teams routinely switch between 3–10 repos a day. Until
now codegraph was strictly single-repo — every command resolved against
the .codegraph/graph.db in the current working directory. The new
codegraph workspace subcommand group lets you register N repos once and
then query them as a union.
- New CLI subcommands (
codegraph/cli.py):codegraph workspace init— create~/.codegraph/workspace.ymlcodegraph workspace add <repo>— register a repo (validates that the
path exists and is a directory; idempotent)codegraph workspace remove <repo>— deregister (the per-repo
.codegraph/graph.dbis untouched, only the membership)codegraph workspace list— table of registered repos and whether
each has a built graphcodegraph workspace status— per-repo git state: branch, dirty file
count, last commit subject + timestamp, graph freshness, error notescodegraph workspace sync [--only <name>]— rebuild the graph for
every registered repo (or just one)
- New module at
codegraph/workspace/:config.py—WorkspaceConfigPydantic model + YAML load/save with
CODEGRAPH_WORKSPACE_FILEenv-var override (useful for tests +
per-shell workspaces)operations.py— pure functions returning JSON-safe dicts so the CLI
and MCP server share one implementation
- 3 new MCP tools (
codegraph/mcp_server/server.py):workspace_state()— git + graph state for every registered repoworkspace_diff_since(ref="main")— cross-repo file changes since a
git ref; combines committed (<ref>...HEAD) and uncommitted (HEAD)workspace_blast_radius(symbol, depth=None)— unioned blast radius
across all repos; reuses the existing single-repoblast_radius()so
behaviour matches exactly per-repo
- Pollution prevention — workspace MCP tools self-load their per-repo
graphs from the workspace config; the MCP_call_tooldispatch
bypasses the usual_load_graph()forworkspace_*names so the
server doesn't materialize a stray.codegraph/graph.dbin the cwd
when the user only calls workspace tools. - Conflict handling — when the same memory
idexists on both sides
with different bodies at the sameupdated_at, the conflicting remote
copy is saved as<id>.conflict-<timestamp>.mdnext to the local
file for manual merging. Sync never silently clobbers. - 39 new tests under
tests/test_workspace_{config,ops,cli,mcp}.py
covering config round-trip, real-tmp git-repo state probes,
CliRunner-based CLI integration, and direct MCP handler invocation.
Full suite remains green at 576 passing (was 537). - README updated with a new "Cross-repo Workspace mode" collapsible
block under CLI subcommands; MCP tools table now lists 18 total (was 15).
v0.3 unified trace — Architecture view shows the real chain
- Per-handler
dataflowfield on the HLD payload (PR #22). Each route
entry now carries adataflow.hops[]array shaped to the v0.3 contract,
so the dashboard can render the actual frontend → backend → DB chain
without re-running analysis client-side. - Phase 4 of the Learn Mode lifecycle modal renders real hops (PR #23).
The previously-generic "project-specific data layer" phase now shows
the actual handler → service → repo → model chain across sequence,
pipeline, and diagram modes. Empty / low-confidence states render
gracefully with a "no trace data" panel. - Argument-flow propagation — pick a parameter, watch it travel (PRs #24,
#25). Per-hoparg_flow: dict[str, str | None]mapping starting keys to
their locally-renamed names. Frontend renders a chip-strip param picker
and animates the selected param along the swimlane (sequence) or the
bezier path (diagram, via SMILanimateMotion). Rename annotations
((was userId)) surface where the local name diverges. Snake_case ↔
camelCase ↔ PascalCase all normalise to the same key. - ROUTE entry hop args backfilled from handler params (PR #26). The
trace walker can't supply args at the entry hop (no incoming CALLS edge),
so URL-template handlers (e.g./api/users/{user_id}) used to produce
emptyarg_flow. Backfilled from the handler node's DF0metadata.params
(skippingself/cls). Closes the launch demo's hero shot.
Cleanup + analyzer hardening
- Examples directory excluded from dead-code / untested analysis
(PR #19) —examples/cross-stack-demois documentation, not call-graph-
traceable code. - Unused
_propagate_class_role_to_membershelper deleted (PR #19). # pragma: codegraph-public-apianalyzer support (PR #21). Functions
and classes preceded by the pragma comment (Python#or TypeScript
//style, with optional# codegraph: public-apialias) are exempted
fromfind_dead_code(). Applied to all 15 known intentional public-API
methods (EmbeddingStorefacade,SQLiteGraphStore.upsert_node/
vacuum, allto_dict/as_dictserializers,_register.decorator
closure). Self-graph dead-code count: 15 → 0, honestly.
Docs & developer experience
- README refresh (PR #20). 15 MCP tools listed; DF1–DF4 + Architecture
view documented in the headline feature list; "What it doesn't do yet"
rewritten to drop already-shipped items; numeric stats current. - SESSION_HANDOFF.md (PR #20) rewritten as a self-contained briefing
for the next session. PLAN_V0_3_UNIFIED_TRACE.md(PR #20) — concrete spec for the unified
trace work; now marked shipped as of PRs #22–#26.
Cross-stack data-flow tracing (DF0 → DF4)
- DF0 — function signatures + per-call-site arguments. Python and
TypeScript parsers capture parameter lists, return-type annotations,
and the literal text of each call-site argument and kwarg. - DF1 — HTTP routes + SQL data access. FastAPI / Flask / aiohttp
ROUTEedges; SQLAlchemyREADS_FROM/WRITES_TOedges including
self.session.Xrepository-pattern detection. - DF1.5 — role classification. Functions and classes are tagged
HANDLER/SERVICE/COMPONENT/REPObased on framework patterns. - **DF2 — frontend
FETCH_CALLextractio...
v0.1.0
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[Unreleased]
0.1.0 is in-progress / pre-release. The README, CLI, MCP server, and 3D
dashboard reflect the current state ofmain, but the package has not yet
been pushed to PyPI. Items below describe what has shipped onmainand
will roll into the eventual 0.1.0 tag. Install from source for now
(pip install -e .).
Post-launch-sprint additions (still pre-release)
Go language support — .go files parse + analyze cleanly
The Go ecosystem is the single biggest community pull outside Python/JS,
and a code graph that spans services + tooling + libraries was the
obvious next move. v1 of the Go extractor lives at
codegraph/parsers/go.py and produces the same node/edge shape as the
Python and TypeScript parsers, so every existing tool (analyze,
workspace_blast_radius, MCP queries) works on Go code immediately.
- New module
codegraph/parsers/go.py— tree-sitter Go grammar via
tree-sitter-go>=0.23(added topyproject.toml). - Node kinds emitted:
MODULE(one per.gofile, qualname = the
package Xname so files in the same package share an addressable
namespace),FUNCTION(top-levelfunc),METHOD(qualname
module.ReceiverType.Name, with receiver + pointer-ness in metadata),
CLASS(the closest analog to Go'stype X struct {...}and
type X interface {...}),TEST(*_test.gofiles). - Edge kinds emitted:
DEFINED_IN,IMPORTS(per-import-path,
preserves aliases as metadata),CALLS(bare names likeFoo,
dotted-package likefmt.Println, receiver-method likeg.Greet),
INHERITS(Go composition — embedded fields in a struct become
INHERITSedges to the embedded type). - Registry hookup:
builder.pyimportscodegraph.parsers.goat
module load so the@register_extractordecorator fires.init's
language-detection map now includesgo: [".go"]. - Smoke test against
spf13/cobra: 36 files parsed, 715 Go nodes
(427 functions + 168 methods + 17 structs/interfaces + 17 test files- 19 modules), 2541 CALLS edges, 190 IMPORTS, 0 errors, 0.25s.
- 19 new parser tests at
tests/test_go_parser.pycovering every
emitted node/edge shape plus edge cases (empty file, missing file,
test-file detection, aliased imports, pointer receivers).
Limitations the parser is honest about up front:
- Generic type parameters land as text in metadata; not in qualnames.
- Interface satisfaction (does
*FooimplementBar?) is not detected
by the parser — that needs a whole-package pass and belongs in the
resolver layer, not the extractor. init()andmain()get no special treatment yet.
Cross-repo workspace mode — treat N repos as one mental unit
Solo devs and small teams routinely switch between 3–10 repos a day. Until
now codegraph was strictly single-repo — every command resolved against
the .codegraph/graph.db in the current working directory. The new
codegraph workspace subcommand group lets you register N repos once and
then query them as a union.
- New CLI subcommands (
codegraph/cli.py):codegraph workspace init— create~/.codegraph/workspace.ymlcodegraph workspace add <repo>— register a repo (validates that the
path exists and is a directory; idempotent)codegraph workspace remove <repo>— deregister (the per-repo
.codegraph/graph.dbis untouched, only the membership)codegraph workspace list— table of registered repos and whether
each has a built graphcodegraph workspace status— per-repo git state: branch, dirty file
count, last commit subject + timestamp, graph freshness, error notescodegraph workspace sync [--only <name>]— rebuild the graph for
every registered repo (or just one)
- New module at
codegraph/workspace/:config.py—WorkspaceConfigPydantic model + YAML load/save with
CODEGRAPH_WORKSPACE_FILEenv-var override (useful for tests +
per-shell workspaces)operations.py— pure functions returning JSON-safe dicts so the CLI
and MCP server share one implementation
- 3 new MCP tools (
codegraph/mcp_server/server.py):workspace_state()— git + graph state for every registered repoworkspace_diff_since(ref="main")— cross-repo file changes since a
git ref; combines committed (<ref>...HEAD) and uncommitted (HEAD)workspace_blast_radius(symbol, depth=None)— unioned blast radius
across all repos; reuses the existing single-repoblast_radius()so
behaviour matches exactly per-repo
- Pollution prevention — workspace MCP tools self-load their per-repo
graphs from the workspace config; the MCP_call_tooldispatch
bypasses the usual_load_graph()forworkspace_*names so the
server doesn't materialize a stray.codegraph/graph.dbin the cwd
when the user only calls workspace tools. - Conflict handling — when the same memory
idexists on both sides
with different bodies at the sameupdated_at, the conflicting remote
copy is saved as<id>.conflict-<timestamp>.mdnext to the local
file for manual merging. Sync never silently clobbers. - 39 new tests under
tests/test_workspace_{config,ops,cli,mcp}.py
covering config round-trip, real-tmp git-repo state probes,
CliRunner-based CLI integration, and direct MCP handler invocation.
Full suite remains green at 576 passing (was 537). - README updated with a new "Cross-repo Workspace mode" collapsible
block under CLI subcommands; MCP tools table now lists 18 total (was 15).
v0.3 unified trace — Architecture view shows the real chain
- Per-handler
dataflowfield on the HLD payload (PR #22). Each route
entry now carries adataflow.hops[]array shaped to the v0.3 contract,
so the dashboard can render the actual frontend → backend → DB chain
without re-running analysis client-side. - Phase 4 of the Learn Mode lifecycle modal renders real hops (PR #23).
The previously-generic "project-specific data layer" phase now shows
the actual handler → service → repo → model chain across sequence,
pipeline, and diagram modes. Empty / low-confidence states render
gracefully with a "no trace data" panel. - Argument-flow propagation — pick a parameter, watch it travel (PRs #24,
#25). Per-hoparg_flow: dict[str, str | None]mapping starting keys to
their locally-renamed names. Frontend renders a chip-strip param picker
and animates the selected param along the swimlane (sequence) or the
bezier path (diagram, via SMILanimateMotion). Rename annotations
((was userId)) surface where the local name diverges. Snake_case ↔
camelCase ↔ PascalCase all normalise to the same key. - ROUTE entry hop args backfilled from handler params (PR #26). The
trace walker can't supply args at the entry hop (no incoming CALLS edge),
so URL-template handlers (e.g./api/users/{user_id}) used to produce
emptyarg_flow. Backfilled from the handler node's DF0metadata.params
(skippingself/cls). Closes the launch demo's hero shot.
Cleanup + analyzer hardening
- Examples directory excluded from dead-code / untested analysis
(PR #19) —examples/cross-stack-demois documentation, not call-graph-
traceable code. - Unused
_propagate_class_role_to_membershelper deleted (PR #19). # pragma: codegraph-public-apianalyzer support (PR #21). Functions
and classes preceded by the pragma comment (Python#or TypeScript
//style, with optional# codegraph: public-apialias) are exempted
fromfind_dead_code(). Applied to all 15 known intentional public-API
methods (EmbeddingStorefacade,SQLiteGraphStore.upsert_node/
vacuum, allto_dict/as_dictserializers,_register.decorator
closure). Self-graph dead-code count: 15 → 0, honestly.
Docs & developer experience
- README refresh (PR #20). 15 MCP tools listed; DF1–DF4 + Architecture
view documented in the headline feature list; "What it doesn't do yet"
rewritten to drop already-shipped items; numeric stats current. - SESSION_HANDOFF.md (PR #20) rewritten as a self-contained briefing
for the next session. PLAN_V0_3_UNIFIED_TRACE.md(PR #20) — concrete spec for the unified
trace work; now marked shipped as of PRs #22–#26.
Cross-stack data-flow tracing (DF0 → DF4)
- DF0 — function signatures + per-call-site arguments. Python and
TypeScript parsers capture parameter lists, return-type annotations,
and the literal text of each call-site argument and kwarg. - DF1 — HTTP routes + SQL data access. FastAPI / Flask / aiohttp
ROUTEedges; SQLAlchemyREADS_FROM/WRITES_TOedges including
self.session.Xrepository-pattern detection. - DF1.5 — role classification. Functions and classes are tagged
HANDLER/SERVICE/COMPONENT/REPObased on framework patterns. - DF2 — frontend
FETCH_CALLextraction.fetch/axios/useSWR/
useQuery/ api-client patterns emitFETCH_CALLedges with method,
url, and body-key metadata. - DF3 — URL stitcher (
match_route). Stitches frontendFETCH_CALL
URLs to backendROUTEhandlers with placeholder normalisation
(/users/{id},${id},:id, numeric segments) and a body-key
overlap bonus. - DF4 —
codegraph dataflow trace. Walks the call graph + cross-layer
edges and emits an orderedDataFlow. Available as a CLI subcommand and
the MCPdataflow_tracetool.
v0.3 embedding layer
codegraph/embed/— chunker + embedder + LanceDB / JSON store.codegraph embedCLI. Default modelnomic-ai/CodeRankEmbed
(Apache 2.0, ~140 MB, 768-dim).- MCP tools
semantic_searchandhybrid_search. Hybrid reranks...