Skip to main content

leo-cub

leo-cub is an experimental Rust library and command-line tool for reading, validating, browsing, and modifying Leo Editor outlines.

The installed command is cub; the Rust library namespace is leo.

Documentation

The project guide is built with Zensical and published to GitHub Pages from the main branch. The source files live in docs/, and the local preview can be started with:

python -m pip install zensical
zensical serve

Screenshot

image

Why

Leo outlines are not ordinary XML trees. A GNX identifies shared vnode content, while an outline position identifies one occurrence of that vnode. Cloned nodes can therefore appear in several places. leo-cub keeps those concepts separate and exposes transactional operations intended for scripts and AI tools.

Current features

  • Parse and validate .leo XML outlines.
  • Preserve XML outside the rewritten <vnodes> and <tnodes> sections.
  • Represent clone identity separately from outline positions.
  • Apply atomic JSON operation batches with optional text preconditions.
  • Parse Leo 5 thin derived-file sentinels.
  • Reconstruct @file, @thin, and @file-thin hierarchies and bodies.
  • Resolve ancestor @path directives in the TUI.
  • Browse outlines with a small Ratatui interface.
  • Highlight node bodies with Syntect, using @language, @rst ancestors, or source extensions, including bundled reStructuredText, Nushell, and Rhai syntax support.
  • Open a derived node's full source file at its sentinel line using $VISUAL or $EDITOR.

Install

The recommended installation method is uv:

uv tool install leo-cub

This installs the cub command. You can also use pip install leo-cub, or download the appropriate archive from the latest GitHub release.

Termux

The PyPI release includes an Android API 24 ARM64 wheel suitable for current 64-bit Termux installations:

uv tool install leo-cub

Installation from source

From the repository root, install the cub command with Cargo:

cargo install --path .

Install the bundled local agent skill after installing the command:

cub install-skills

This writes ~/.claude/skills/leo-cub/SKILL.md and overwrites an existing copy, so it is safe to rerun after upgrading.

TUI

cub outline.leo

Giving cub an outline without a subcommand opens the TUI. The explicit cub tui outline.leo form is equivalent.

The browser resolves external thin files in memory. Outline headlines highlight Leo directives, external-file names, and section-reference markers. A red * marks each node changed since the outline was loaded or last saved; saving or reloading clears the markers.

TUI keybindings

Browsing and display

Key Action
↓ / ↑ Select next/previous node
Shift-↓ / Shift-↑ Extend or shrink a contiguous multi-node selection
→ Expand selected node
Enter Open the selected node's body editor
← Collapse selected node
Home / End Select the first/last visible node
PageUp / PageDown Scroll the selected node's body by one page
f Toggle a full-width body pane
Shift-F Toggle a full-width outline pane
↑ / ↓ in full-width mode Scroll the body vertically by one line
← / → in full-width mode Scroll the body horizontally
Ctrl-P Find a headline incrementally; use ↑/↓ to cycle matches
o Edit the node body in $VISUAL/$EDITOR; for derived nodes, open the real source at its sentinel
y Toggle syntax highlighting
? Show command help

Outline editing

Key Action
Ctrl-I or Tab Insert a new sibling and enter headline editing
Ctrl-H or Backspace Edit the selected headline
c Copy the selected tree
x Cut the selected tree
v Paste an independent copy with fresh node identities
Shift-V Paste as clones, retaining node identities
Ctrl-↑, Ctrl-↓ Move the selected node or multi-selection among siblings
Ctrl-←, Ctrl-→ Promote or demote the selected node or multi-selection
Ctrl-R Reload from disk; press twice to discard unsaved changes
Ctrl-S Save outline changes
q or Esc Quit; press twice to discard unsaved changes

Headline editing

Key Action
Printable characters Replace the initial selection, or insert at the cursor
← / →, Home / End Keep the headline and position the cursor
Backspace / Delete Delete the selection or a character
Enter Accept the headline
Esc Cancel editing; a newly inserted node is removed

Use --no-derived to display only the hierarchy physically present in the .leo XML file.

For source navigation, cub recognizes common position arguments for Vim, Neovim, Nano, Emacs, VS Code, Microsoft Edit, Helix, and Kakoune. Other editors receive the file path without a line argument.

Demo flow

Starting in a project containing README.md and a src/ directory, create a new outline with destinations for source code, documentation, and tasks:

cub new project.leo --headline "Project"
cub add project.leo \
  "Project/Source" \
  "Project/Documentation" \
  "Project/Tasks/Backlog"

Import the source tree below Project/Source, preserving its directory structure, then import the README as an editable node below the documentation branch:

cub import project.leo src \
  --recursive --mode auto --paths \
  --parent "Project/Source"
cub import project.leo README.md \
  --mode edit \
  --parent "Project/Documentation"

Finally, inspect the resulting tree and validate the file:

cub inspect project.leo
cub validate project.leo

@auto source nodes are reconstructed from their files when inspected or opened, while the @edit README node stores its text in the outline.

Headless commands

cub new outline.leo
cub new notes.leo --headline "Notes"
cub add outline.leo "Project/Tasks/First task" "Project/Notes"
cub inspect outline.leo
cub inspect outline.leo src/main.rs
cub inspect outline.leo --gnx ekr.20260811210000.1
cub inspect outline.leo --position 0/2/1
cub inspect outline.leo --search 'render_(compact|json)'
cub inspect outline.leo --search TODO --search FIXME
cub inspect outline.leo src/main.rs --format json
cub validate outline.leo
cub import outline.leo src --recursive --mode auto --paths
cub import outline.leo README.md --mode edit --no-paths
cub import outline.leo README.md --parent "Project/Notes"
cub sync outline.leo
cub sync outline.leo src/main.rs --dry-run
cub sync outline.leo --gnx ekr.20260811210000.1
cub diff before.leo after.leo
cub inspect-derived path/to/derived.py --summary
cub apply outline.leo operations.json --dry-run

new creates a valid outline with one empty root node. It refuses to overwrite an existing file.

add creates nodes from slash-separated headline paths and reuses shared or existing prefixes. import --parent accepts either an exact GNX or a unique slash-separated headline path. Paths with duplicate matching siblings are rejected as ambiguous.

import creates Leo external-file nodes in auto, edit, or clean mode. Markdown, Python, Rust, Rhai, C#, Go, JavaScript/JSX, TypeScript/TSX, and XSLT @auto files are expanded transiently with Tree-sitter when they are loaded by inspect or the TUI; the generated tree is not stored in the .leo file. Unsupported source types remain available as a plain root node. Markdown also supports Leo's @auto-md and @auto-markdown headlines and leo-noheader markers. Directory imports are recursive only with --recursive and preserve their layout with @path nodes by default. Use --no-paths to put all imported files directly below the destination, --parent GNX_OR_PATH to choose that destination, and --dry-run to validate without saving.

@auto-dir <dir-or-glob> is a directive you write directly into a headline rather than a mode of import: it expands to one @auto child per matching file, live, on every load, instead of one node per file being created once and left to go stale. @auto-dir src lists the immediate files in src (non-recursive, matching import's own one-level default); @auto-dir src/*.rs glob-filters that same listing; @auto-dir src/**/*.rs opts into a recursive walk. Add a file that matches and it appears next time the outline is opened, with no outline edit. leo-cub's own leo-cub.leo and demos/cub-demos.leo both use it.

inspect uses a compact text format containing position paths, GNXs, headlines, and bodies. Repeated clone content is shown as =GNX. Use --format json for structured output in scripts. --search accepts a Rust regular expression and searches headlines and body lines. Search results include line-numbered excerpts with two surrounding lines instead of printing entire matching bodies. Repeat --search to match any of several expressions. Thin external files are scanned first and reconstructed only when they may contain a search or GNX match.

An operation batch is a JSON object:

{
  "operations": [
    {
      "op": "set-body",
      "node": "ekr.20260811210000.1",
      "expected": "old body",
      "body": "new body"
    }
  ]
}

Operations are applied to a copy and committed only if the complete batch is valid. expected provides optimistic conflict detection for headline and body edits.

Status and safety

This project is early and the file format support is incomplete. In particular, it does not dynamically interpret every @comment/@delims change or fully reconstruct all doc-part forms. Keep backups and use --dry-run when testing write operations on important outlines.

The TUI permits structural and headline edits in @file, @thin, and @file-thin trees and writes changed thin files on Ctrl-S. It validates and stages generated files before replacing their external sources; unchanged external files are not rewritten. Generated @auto descendants remain read-only because writing them requires language-specific exporters. Use o to edit a derived node's full external source directly. Unsaved changes require a second q before they are discarded.

License

MIT

Metadata

Release files for leo-cub 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for leo-cub 0.5.0
File Actions
leo_cub-0.5.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for leo_cub-0.5.0-py3-none-win_amd64.whl
leo_cub-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for leo_cub-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
leo_cub-0.5.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for leo_cub-0.5.0-py3-none-macosx_11_0_arm64.whl
leo_cub-0.5.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for leo_cub-0.5.0-py3-none-macosx_10_12_x86_64.whl
leo_cub-0.5.0-py3-none-android_24_arm64_v8a.whl Python 3 none Android API level 24+ ARM64 v8a Details for leo_cub-0.5.0-py3-none-android_24_arm64_v8a.whl

Total release size: 27.1 MB

Release files / leo_cub-0.5.0-py3-none-win_amd64.whl

Download URL leo_cub-0.5.0-py3-none-win_amd64.whl
Size 5.1 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
c40ba241dd9be5497deda5a3e87965c2a8cb8a9bbc1dffc5024f12820c1f6325
BLAKE2b-256 checksum
How to use checksums
edd237204020bbffd7abf36f44fed64b64ae83b5f0bad3e81e5fbaa259e0faa6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / leo_cub-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL leo_cub-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 5.6 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
2ed356567d3ba8d2686f904cd12ef3357a09c34aad164ef0ff795efef4c96cd7
BLAKE2b-256 checksum
How to use checksums
7052c9fbdad7e5c462892089d1e06dd8ea07d83f8ee76a736475f705449d81bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / leo_cub-0.5.0-py3-none-macosx_11_0_arm64.whl

Download URL leo_cub-0.5.0-py3-none-macosx_11_0_arm64.whl
Size 5.3 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c621577257d989e6fc645ee52616ab9820e41034df0162d69246eeaac1d7f116
BLAKE2b-256 checksum
How to use checksums
85ce15522da57b3ff554c97f6605519ec7c0452099ae39efc959b30f1597680f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / leo_cub-0.5.0-py3-none-macosx_10_12_x86_64.whl

Download URL leo_cub-0.5.0-py3-none-macosx_10_12_x86_64.whl
Size 5.4 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
02a1a310afdbf0410b70c84309985c70a339e629dadfb59fbc8d8e551df05215
BLAKE2b-256 checksum
How to use checksums
7e97d0c9221e953b0c5cbaa9c3679f3b6a36747b3775068f023c76f516acd69c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / leo_cub-0.5.0-py3-none-android_24_arm64_v8a.whl

Download URL leo_cub-0.5.0-py3-none-android_24_arm64_v8a.whl
Size 5.6 MB
Tags Android API level 24+ ARM64 v8a Python 3
SHA-256 checksum
How to use checksums
24cad32d7e313700de8af155e02b71ef699b2c9541b8bd154cecfc944fe60111
BLAKE2b-256 checksum
How to use checksums
2caccd2f475dff45f1d929241d98810adbc428bf16645679f425aae9e6257f57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Security for leo-cub 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for leo_cub-0.5.0-py3-none-win_amd64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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