Skip to main content

Leaxp

Leaxp

CI codecov PyPI Python License

Learn -> experience — a bridge sharing experience between agentic sessions.

Leaxp gives your coding agent a memory it can carry between sessions — and lets you package that memory as a file other projects can install.

Every new agent session starts from zero: it greps the same files, rediscovers the same conventions, and repeats the mistake the last session already worked out. Leaxp fixes that with a per-project knowledge database — .xp/, plain Markdown records indexed by a small local embedding model — that agents search, read and write through four MCP tools.

Leaxp
Where knowledge lives Markdown files in .xp/, git-tracked and human-editable
Who writes it your own agent CLI (claude / codex) and your agent at runtime
How it is searched a small local ONNX embedding model — vectors in index.npy
What it costs no LLM API, no API keys, no services, no torch
How it travels .xp files — zip of Markdown + a sha256 manifest, installable anywhere

The payoff: smaller context, cheaper inference, model-agnostic knowledge, and 3–5 turns of orientation instead of a full-repo grep.

Status: MVP — file and GitHub repository installs work end-to-end; the hosted registry is coming.

How it works

  your codebase                                        teammate / another project
       │                                                          ▲
       │ exp learn / exp forge                                    │ exp install
       ▼                                                          │
  your agent CLI  ───────►  .xp/local/*.md  ───── exp share ─────► my-skills.xp
  (claude / codex)          (Markdown, yours)                     (zip + sha256)
                                   │
                                   ▼  local embeddings
                            index.npy + index.json
                                   │
                                   ▼  recall / expand / remember / forget  (MCP)
                            your agent, every next session

Install

pip install leaxp

Python 3.11+. Search runs on a small local ONNX embedding model (fastembed) that downloads itself on first use — no torch, no services, no API keys.

Quickstart

Four commands take you from an empty project to an agent with memory.

1. Wire Leaxp into your agent

exp use --with claude

Creates .xp/, leaxp.toml and leaxp.lock, then registers the MCP server and the prompt hook in .mcp.json and .claude/settings.json. Claude Code is the supported target today.

Run it from the environment Leaxp is installed in — the wiring stores that environment's absolute exp path, because your coding agent runs outside the project's virtualenv. Start a fresh agent session afterwards to pick it up.

2. Teach it your codebase

exp learn --goal "onboard new contributors"

Drives your own claude / codex CLI over the repo. It distills the recurring patterns into one Markdown record per topic under .xp/local/, and Leaxp indexes whatever appeared. The records are yours: git-tracked, reviewable in a PR, editable in your editor.

3. Install skills from GitHub

exp install https://github.com/org/repo --skill name

Pulls a repository's SKILL.md skills into .xp/share/org-repo/ and declares the package in leaxp.toml + leaxp.lock. Drop --skill to install every skill the repo publishes.

4. Upgrade an installed package

exp install https://github.com/org/repo --upgrade

Re-resolves the source to its newest version and moves the lock to it. Without --upgrade, installs replay the locked version, so they stay reproducible.

That is the whole loop. From here your agent gets a memory recall on its first prompt of every session and writes back what it learns.

Repository knowledge management

Day-to-day upkeep once memory is in place.

Command Reach for it when
exp sync --upgrade you pulled a leaxp.toml change, edited records by hand, or want newer skill releases
exp share -o pkg.xp you want to hand your project's knowledge to a teammate or another repo
exp install -f pkg.xp you received an .xp file and want it in this project
exp exec "…" you want to see exactly what an agent gets back for a query
exp forge memory has drifted: duplicates, stale statements, rules buried in long records

Keep dependencies and the index current

exp sync             # install declared packages at their locked version, then reindex .xp/
exp sync --upgrade   # ...and check every unpinned package for a newer version

Three steps in one pass: install every [[packages]] entry that is missing or drifted from the lock → with --upgrade, re-resolve unpinned packages against their source → reindex .xp/, so hand-edited records become searchable too.

Share your project's knowledge

exp share -o my-project.xp

Packs .xp/local/ into a portable .xp file — a zip of the Markdown plus a sha256-signed manifest. Embeddings are not shipped; they are recomputed on install, so the same pack works with any embedding model.

Install from a file

exp install -f my-project.xp          # → .xp/share/<name>/ — a read-only dependency
exp install -f my-project.xp --self   # → .xp/local/ — adopted as your own, editable

See exactly what your agent sees

exp exec "create stripe subscription"
exp exec "define new cli subcommand" -s "error handling" -n 5

Prints the raw recall tool output, byte for byte what a connected agent receives — the fastest loop for tuning record titles and descriptions.

Consolidate memory that drifted

exp forge

remember keeps the database consistent one write at a time, but a long series of sessions still drifts: near-duplicates accumulate, statements go stale against the code they describe, and rules stay buried in long records instead of being flagged as conventions.

exp forge is the periodic repair pass. It drives your own agent through a consolidation flow:

  1. cluster .xp/local/ by file name;
  2. write the clusters down as a plan in .xp/consolidation-<dtime>.md;
  3. walk that plan — grounding every statement in the real codebase, merging duplicates found via recall, splitting rules out as one-paragraph conventions;
  4. run the full exp sync pass, so the reshaped memory is reindexed.

The plan file doubles as a review log: every cluster gets a Consolidation Result, plus Consolidation Gaps where the agent noticed knowledge that is missing.

What your agent sees

Once wired, agents get an initial memory recall on their first prompt and four tools:

Tool What it does
recall(query, subquery?, limit?) Search records. Returns scored titles + expected outcomes, grouped into <package> blocks, low-relevance hits already filtered out. Conventional records come fully expanded as <rule> entries in a separate <conventions> block.
expand(id | [ids]) Fetch full Markdown bodies — one record or several at once.
remember(title, description, content, id?, convention?) Write new knowledge, or update a record in place by passing its id. Pass convention=true for a one-paragraph rule.
forget(id | [ids]) Delete records that became duplicates or went out of date.

Two things make this a consistent memory rather than an append-only log:

  • remember reviews itself. Its answer replays a recall against the title just written, so duplicates and stale neighbours surface at write time instead of piling up — the agent is told to merge them and forget the leftovers.
  • Only local is writable. remember and forget refuse ids from installed packages and say why; shared records are dependency content that exp sync would restore anyway.

Concepts

Record

One Markdown file with YAML frontmatter, under .xp/local/ (yours, git-tracked) or .xp/share/<pkg>/ (installed, git-ignored):

---
index: create stripe subscription
description: Know which helper to call and which webhook confirms the charge
tags: []
---

# create stripe subscription

Call `billing.subscribe(customer, plan)` — never the Stripe SDK directly.

## Confirming the charge

...

Titles follow [action] [package|entity] [subject?]create stripe subscription, define new cli subcommand, downgrade alembic migration — so queries and titles speak the same language. One topic per file; 5–20 focused records beat one huge dump.

Convention

A record flagged convention: true: a single short paragraph stating one rule (naming, structure, which tool or skill to use) plus its rationale. Conventions are searched separately and rendered in full on every matching recall, no expand needed — which is how a project rule gets followed instead of merely found.

Index

index.npy + index.json. Exactly one vector per Markdown-heading breadcrumb (Stripe API > Webhooks > Error Handling), searched by cosine similarity with a relevance floor so agents never wade through noise. Results are grouped by package and labelled with its description — from leaxp.toml for local, from the install manifest for shared packages.

Record ids are row numbers, and rows never move: rewriting a record reuses its rows, forgetting one tombstones them. An id an agent recalled keeps pointing at the same record until the next full reindex.

.xp file

A zip of record Markdown plus a sha256-signed manifest (xp_version, name, version, digest, record counts). Portable and model-agnostic — embeddings are recomputed locally on install.

Dependency

A [[packages]] entry in leaxp.toml (what you declare) resolved into a leaxp.lock entry (what is installed: version, exact ref, digest). exp sync installs whatever is missing or drifted at the locked version; --upgrade re-resolves each unpinned package.

Skill repos have no versioning convention, so a GitHub package's version is its newest release tag (v1.2.3) when it publishes one, and the default branch's commit sha otherwise. Pin a specific one with /tree/<ref> in the source or version = "…" in leaxp.toml--upgrade leaves pins alone.

Wiring

exp use writes .mcp.json and .claude/settings.json with the absolute launcher of the environment it ran in (<venv>/bin/exp mcp, or <python> -m leaxp mcp when no console script exists). A bare exp would only work for a global install, since your coding agent runs outside the project's virtualenv.

That makes the wiring machine-specific: after cloning, run exp use once in your own environment — it repoints a stale command instead of adding a second one.

What lives where

your-project/
├── leaxp.toml                 # what you declare: project meta, models, packages
├── leaxp.lock                 # what is installed: version, exact ref, digest
├── .mcp.json                  # MCP wiring (absolute launcher) — written by `exp use`
└── .xp/
    ├── .gitignore             # written by `exp use` — tracks local/, ignores everything else
    ├── local/                 # your records — git-tracked, editable, the only writable package
    │   └── create-stripe-subscription.md
    ├── share/                 # installed packages — git-ignored, read-only
    │   └── org-repo/
    ├── index.npy              # one vector per heading breadcrumb
    ├── index.json             # record metadata + package descriptions
    ├── .sessions/             # once-per-session hook markers
    └── consolidation-*.md     # one review log per `exp forge` run

Command reference

Command What it does
exp use --with claude Create .xp/, config and lock; wire the MCP server + prompt hook.
exp learn [--goal …] [--agent …] Drive your agent CLI over the codebase into .xp/local/, then index.
exp forge [--agent …] Consolidate .xp/local/ — verify, dedupe, split conventions — then sync.
exp share -o pkg.xp Pack .xp/local/ into a shareable .xp archive.
exp install <url|name> [--skill …] [-U] Install from GitHub or the registry; index and lock it.
exp install -f pkg.xp [--self] Install from a local archive; --self adopts it into .xp/local/.
exp sync [-U] Install declared packages, optionally upgrade, reindex .xp/.
exp exec "<query>" [-s …] [-n …] Print the raw recall output for a query.
exp mcp [-t stdio|http] Run the MCP server (your agent does this for you).
exp --version Print the installed version.

Every command accepts --path to target a project directory other than the current one.

Docs

Document Contents
CLAUDE.md Package architecture overview — modules, data flow, key abstractions
AGENTS.md Ground rules for coding agents working on this repo
CHANGELOG.md Per-version release notes
RELEASING.md How a new version gets published

Development

uv sync                                  # create venv, install deps
uv run pre-commit install                # enable hooks
uv run ruff check . && uv run pyright    # lint + typecheck (pyright strict)
uv run pytest --cov                      # tests with coverage (100% gate)
uv run exp --help

License

Apache-2.0 — see LICENSE.txt.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

leaxp-0.4.0.tar.gz (84.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

leaxp-0.4.0-py3-none-any.whl (83.9 kB view details)

Uploaded Python 3

File details

Details for the file leaxp-0.4.0.tar.gz.

File metadata

  • Download URL: leaxp-0.4.0.tar.gz
  • Upload date:
  • Size: 84.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for leaxp-0.4.0.tar.gz
Algorithm Hash digest
SHA256 cbb705d758989d1e1f2d91103d73bfb2154823f5815b5425dbc60f5cd12d09ce
MD5 8ed2bd561e5d7f80f3fb026dffc4156b
BLAKE2b-256 c6b1af168e9f73dfc77df271edd5e309cd7c47ca7fc60b40bd97000465669fed

See more details on using hashes here.

Provenance

The following attestation bundles were made for leaxp-0.4.0.tar.gz:

Publisher: release.yml on vunone/leaxp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file leaxp-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: leaxp-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 83.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for leaxp-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff9f681f7478d521928ac8404846e729372fc3b043e5ea2030ebc2c09f1037b2
MD5 68c9303ac594c1c3019fc2e66ff22e0c
BLAKE2b-256 44dfc0cdd08d46f6e296b8bbb57913b2f212f799a914a3c3dc1ea4d93c88d59a

See more details on using hashes here.

Provenance

The following attestation bundles were made for leaxp-0.4.0-py3-none-any.whl:

Publisher: release.yml on vunone/leaxp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.1

2 files

0.5.0

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page