leda

module
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: MIT

README

leda

Linked-edge dependency analyzer for LLM agents. Given a codebase and a natural-language prompt, leda builds a directed dependency graph from source files, seeds entry points from the prompt, and returns only the files the agent actually needs. One call replaces several grep/read cycles.

Benchmarks

Across four passing runs on real-world repos (pinned SHAs, unassisted baseline vs. same agent with leda wired in):

target language tokens (baseline → with leda) Δ
lira Go 108,730 → 72,812 −33.0%
kafka Java 64,650 → 41,208 −36.3%
tokio Rust 56,018 → 44,690 −20.2%
iced Rust 53,212 → 37,620 −29.3%
aggregate 282,610 → 196,330 −30.5%

Per-prompt mean Δ%: lira −26.7%, kafka −30.2%, tokio −11.9%, iced −36.7%. Runs are within-corpus; cross-corpus asymmetry is expected and reflects repo shape and doc density. Methodology, manifest, and full log: BENCHMARKS.md, benchmarks/reference-sets/manifest.toml, Dockerfile.benchmark.

Install the CLI

go install github.com/jgabor/leda/cmd/leda@latest

That alone gives you the leda binary. To get the full value, install one of the agent integrations below.

Agent integrations

Each integration ships two features, independently toggleable:

  • Prime: on session start and after compaction, injects leda's routing rules into the model's context so the agent knows leda query exists.
  • Intercept: on each outgoing Grep/Read/Glob/Bash call, a classifier checks for a structural shape and nudges the agent toward leda query. Never blocks. Fails open on every error path.

Both defensively no-op outside leda-shaped projects (no .leda, go.mod, package.json, pyproject.toml, Cargo.toml, etc.) and when leda is not on PATH. Set LEDA_INTERCEPT=off to disable the interceptor only.

Claude Code

This repo is a Claude Code plugin. Install it via the claude CLI:

claude plugin marketplace add jgabor/leda
claude plugin install leda@leda

Uninstall with claude plugin uninstall leda@leda. Target a specific scope with --scope user|project|local. The plugin declares SessionStart (prime) and PreToolUse (intercept) hooks via .claude-plugin/plugin.json + hooks/hooks.json.

For local development against a checkout, skip the marketplace step and load the repo directly:

claude --plugin-dir /path/to/leda

Manual install (without the plugin system) is still supported: the hook fragments in integrations/claude-code/ can be merged into ~/.claude/settings.json. See integrations/claude-code/README.md.

OpenCode

OpenCode ships a plugin-install CLI subcommand (opencode plugin <npm-module>) that installs a published npm package and updates opencode.json. Leda's OpenCode plugins are not yet published to npm, so for now install via file drop:

# project-local
mkdir -p .opencode/plugins
cp integrations/opencode/leda-plugin.ts .opencode/plugins/

# or user-global
mkdir -p ~/.config/opencode/plugins
cp integrations/opencode/leda-plugin.ts ~/.config/opencode/plugins/

Files in .opencode/plugins/ (or ~/.config/opencode/plugins/) are auto-loaded at startup. Uninstall with rm. OpenCode hooks wired by the single plugin file: experimental.chat.system.transform + experimental.session.compacting (prime), tool.execute.before (intercept). Details: integrations/opencode/README.md. An npm-packaged install (opencode plugin leda) is on the roadmap below.

Manual priming (any other agent)

If your agent framework exposes a system-prompt mechanism, run leda prime and inject its output verbatim. For a static equivalent, append this to your project's CLAUDE.md / AGENTS.md:

## leda

ALWAYS run `leda query` first for structural codebase questions.

- `leda query "how does X work?"` for structural questions (auto-builds graph if needed)
- `leda stats` for most-depended-on files and hot paths
- `leda query --strategy symbol --context narrow 'X'` for exact identifier lookup

Fall back to Read/Grep only when the exact file is already known.
Verifying an install
# Claude Code plugin hook (run from a leda-shaped project)
leda prime   # should print the GUIDANCE blob

# OpenCode plugin smoke test (prime + intercept)
go build -o ./build/leda ./cmd/leda
PATH="$PWD/build:$PATH" bun run integrations/opencode/leda-plugin.smoke.ts

# Intercept classifier (both harnesses)
sh integrations/leda-intercept-e2e.sh

CLI

leda build     Build and serialize a dependency graph (writes .leda)
leda query     Query the graph with a natural-language prompt
leda stats     Print graph statistics (per-file or grouped by directory)
leda extract   Extract structured metadata from a source file
leda prime     Print the GUIDANCE blob used by integrations
leda version   Print the leda version

Common flags: --root <dir> (default .), --lang go,ts,..., --format json|llm|text, --exclude 'glob,glob', --context narrow|wide, --strategy filename|symbol|path.

leda query auto-builds the graph if .leda is missing; leda build caches it for large repos. --exclude skips worktree-style sub-trees that .gitignore doesn't cover. Leda's built-in exclude list covers .git, node_modules, vendor, .next, __pycache__, .tox, dist, build.

Supported languages

All parsers use tree-sitter.

Language CLI alias Resolver
Go go Go module + relative
TypeScript ts Relative
JavaScript js Relative
Python py Relative
Rust rs Cargo + module tree
Java java Classpath
C++ cpp Includes + CMake/Make
PHP php PSR-4 / PSR-0

New languages: add a langConfig in internal/parser/languages.go.

How it works

  1. Build: walk the project tree, parse each file for symbols and imports, construct a directed graph.
  2. Seed: tokenize the prompt, split identifiers on camelCase/snake_case boundaries, and match against filenames, symbols, or paths.
  3. Isolate: traverse the graph from seeds. A single seed gives seed + descendants; multiple seeds give shortest paths between them plus descendants of targets.
  4. Budget: optionally cap results by file count or estimated token count.

Project structure

cmd/leda/               CLI entry point
internal/leda/          Graph building, context isolation, seeding
internal/parser/        Tree-sitter parsers (imports + symbols)
internal/resolve/       Import path → file resolution
integrations/           Claude Code + OpenCode plugin sources
hooks/                  Claude Code plugin hooks manifest
.claude-plugin/         Claude Code plugin manifest
testdata/               Integration test fixtures

Roadmap

Major features only. Harness, benchmark additions, and bug fixes live in CHANGELOG.md.

Shipped
  • v0.5.0: first validated benchmark. Agent session tokens reduced by a −36% median across three repos.
  • v0.6.0: SessionStart priming integrations for Claude Code and OpenCode, including post-compaction re-injection. leda query auto-builds the graph, removing the mandatory leda build step.
  • v0.6.1: prime template compressed by −37% (bytes) with no loss in adoption.
  • v0.7.0: PreToolUse interception for both agent harnesses. Classifier nudges the agent toward leda query on structural Grep / Read / Glob / Bash calls. Fails open on every error path.
  • v0.7.1: import resolvers for Java, PHP, C++, and Rust. Multi-language benchmark expansion showed a −28.5% median across four passing runs (Go, Java, Rust).
  • v0.7.5: classifier rule coverage widened to ripgrep, recursive grep, and find -name. 29 true positives, 0 false positives on re-validation.
  • v0.8.0: prime template simplified. Prime-only token reduction −14% vs an unprimed baseline; passes a ±5 pp pre-registered gate.
Planned
  • Redesign the interception nudge delivery channel. v1 had 0 false positives but did not lift adoption; the remediation moves from rule tuning to the delivery shape itself.
  • Root-cause the two languages that currently regress instead of save (between +5% and +7% cost). Preliminary evidence points to session-budget exhaustion on large monorepos rather than a priming failure.
  • Cross-runner evaluation. Add a second model to the benchmark matrix to separate runner-specific behaviour from leda's signal.
  • Publish the OpenCode plugins to npm so opencode plugin leda becomes a one-liner install, matching the Claude Code path.

Acknowledgements

Inspired by graph-oriented-generation.

License

MIT. Jonathan Gabor (@jgabor).

Directories

Path Synopsis
cmd
leda command
Command leda builds dependency graphs and isolates context for LLM tools.
Command leda builds dependency graphs and isolates context for LLM tools.
internal
leda
Package leda provides dependency-graph context isolation for LLM tools.
Package leda provides dependency-graph context isolation for LLM tools.
parser
Package parser provides interfaces and implementations for extracting import dependencies and exported symbols from source files.
Package parser provides interfaces and implementations for extracting import dependencies and exported symbols from source files.
resolve
Package resolve turns raw import strings into absolute file paths.
Package resolve turns raw import strings into absolute file paths.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL