🪜 Ladder
Track every branch, stage, and alternative path in your AI pair-programming sessions.
When pair-programming with AI, every decision presents multiple paths. You pick one. The others vanish into scrollback. Three hours later, you realize you needed that other path too.
Ladder captures every branch, stages them by effort, and lets you climb back to any rung.
Install
pipx install ladder-cli
ladder is a CLI tool, not a library — pipx installs it into
its own isolated environment and puts the ladder command on your PATH, so it
can't collide with dependencies in whatever project you're standing in.
pip install ladder-cli also works if you're already inside a virtualenv. On a
PEP 668–protected Python (Homebrew, some system installs), plain pip will refuse
to install outside a venv — that's pip protecting itself, not a bug in this
package; use pipx, a venv, or pip install --user instead.
Claude Code plugin (optional)
Skip the copy-paste system prompt — wire the ladder directly into Claude Code:
claude plugin marketplace add tanamsethi31/ladder
claude plugin install ladder@ladder
Claude sees the current ladder status automatically at session start and follows
the ladder-tracking skill's rules (log new options as rungs, mark choices,
show real command output) for the rest of the session — no manual ladder prompt
paste needed. Requires ladder-cli installed and on PATH.
Quick Start
# 1. Initialize a ladder in your project
cd my-project
ladder init --project "My API"
# 2. Paste the system prompt into your AI assistant
ladder prompt
# 3. Start building — the AI populates the ladder automatically
# 4. Check your progress anytime
ladder status
How It Works
Ladder uses a Markdown + YAML file (.ladder/ladder.md) that both you and your AI can read and write:
---
project: My API
version: 1
---
## foundation
- [x] **R001** — Project scaffold → *small*
- Context: Setting up the repo
- Why: Everything builds on this
## core
- [ ] **R003** — User authentication → *medium*
- Context: REST API auth
- Why: Everything else depends on this
- [x] JWT with refresh tokens
- [ ] Session-based with Redis
- [ ] OAuth2 social login
- Blocked by: ~none~
Why this format wins:
- ✅ Git-friendly — clean diffs, full history
- ✅ AI-friendly — any LLM reads/writes markdown natively
- ✅ Human-friendly — open in any editor, understand in 30 seconds
- ✅ CLI-friendly — trivial to parse and render
Architecture
flowchart LR
Dev["Developer"] -->|ladder init| Dir[".ladder/"]
Dev -->|ladder prompt, or\nauto-injected by the\nClaude Code plugin| Prompt["System prompt / skill"]
Prompt -->|read by| AI["Any AI assistant\nClaude, GPT-4, Cursor, Copilot"]
AI <-->|reads / writes| File[".ladder/ladder.md\nMarkdown + YAML"]
Dir --> File
CLI["ladder CLI\nstatus · next · sprint · tree · export"] <--> File
Dev -->|runs| CLI
No API calls, no server — the markdown file is the interface between you, the CLI, and whatever AI you're using. The Claude Code plugin is a thin, optional automation layer on top of that: same file, same CLI, it just auto-loads the rules instead of you pasting them.
Real output
This project dogfoods itself — its own .ladder/ladder.md tracks its own roadmap:
$ ladder status
🪜 ladder v1 25 done · 0 active · 1 exploring · 0 open · 0 blocked
$ ladder next
🎯 Suggested next rungs
1. R021 Ambiguous pronoun references to rungs are unreliable → medium
Discovered via R008's A/B test: 'why is that still undecided' with multiple
candidate rungs failed in both terse (derailed into logging talk, never
answered) and full (confidently named the wrong rung) conditions. Not a
terse-vs-full issue - a real, separate gap in resolving vague references
when several rungs could match.
💡 `plugin` is 20/21 done — consider finishing it before moving on.
Small, well-understood work sorted ahead of bigger bets, automatically. R008 (terse vs. full SessionStart injection) is finally settled for real — a 12-trial controlled A/B test (same fixture, only the injected context differed) showed no behavioral cost to terse on the scenarios designed to expose one, and comparable tool-call counts either way. That test also surfaced R021, a genuine unrelated gap it wasn't looking for.
Commands
| Command | Description |
|---|---|
ladder init |
Create a new ladder in the current directory |
ladder status |
Show the full project ladder |
ladder show R003 |
Detailed info for a specific rung |
ladder do R003 |
Mark a rung as in-progress |
ladder complete R003 |
Mark a rung as done |
ladder abandon R003 --reason "deprecated" |
Mark a rung as abandoned |
ladder tree |
Show dependencies as an ASCII tree |
ladder note R003 "text" |
Attach a note to a rung |
ladder sprint --budget 5 |
Pick unblocked rungs that fit an effort budget |
ladder export |
Export the ladder as a static HTML file |
ladder scan <text> |
Check text for signs of an unlogged decision (no ladder required — reusable by any tool's hook system) |
ladder prompt |
Print the system prompt for your AI |
Why Ladder?
- Works with any AI — Claude, GPT-4, Cursor, Copilot, whatever
- No lock-in — your data is plain Markdown in your repo
- Auto-commits — optionally commits ladder changes to git
- Dependency aware — knows when a rung is blocked by another
- Effort-weighted — small/medium/large so you can plan sprints
- Zero-friction in Claude Code — the optional plugin auto-loads the rules and current status, no copy-pasting a system prompt every session
Contributing
- Fork the repo
pip install -e ".[dev]"pytest- Open a PR
Contact
Built by Tanam Sethi. Questions, bug reports, or feature requests — open an issue or reach out directly.
License
MIT — see LICENSE
Release files for ladder-cli 0.7.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ladder_cli-0.7.1.tar.gz | 640.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ladder_cli-0.7.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 665.8 kB
Release files / ladder_cli-0.7.1.tar.gz
| Download URL | ladder_cli-0.7.1.tar.gz |
|---|---|
| Size | 640.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0edfba71ce6f4aa25bc104db17ed225723144f4d046d30c67ebf650612117761
|
|
BLAKE2b-256 checksum How to use checksums |
1a04a020bdfcf0fb7ccc9404698ecc454b787ca666abdb7ddd2957216e6df29d
|
| 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 Aug 24, 2026.
Transparency logRelease files / ladder_cli-0.7.1-py3-none-any.whl
| Download URL | ladder_cli-0.7.1-py3-none-any.whl |
|---|---|
| Size | 25.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6b1a0b006fac5e3fcc612330c6296a5fb811bc178971230b57b444d75aa9ca27
|
|
BLAKE2b-256 checksum How to use checksums |
9470689c68eefc67b1b4b085156a5d9f9ebb5f6b7d924f26cbb7eacf8efd6869
|
| 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 Aug 24, 2026.
Transparency log