Problems lazyplan solves
Plans rot in chat logs and scattered markdown. lazyplan answers “what are we doing, why, and what is done?” with one local journal both you and your agent share.
🗂️ Projects with a why, a what, and acceptance criteria
One hierarchy, one tree: projects carry a title, a priority p0–p3, a why, a what, and acceptance criteria. Stories cut a project into slices; prioritized tasks cut each story into units of work. That is the whole model — no dates, owners, labels, or estimates.
⌨️ Keyboard-first TUI, CLI for agents
The TUI is keys only — no command entry. Agents drive the same DB from the shell with add-task --story 1 --title x. Nano-style bottom bar, in-place editing.
🤖 Agent-native by design
Stdlib-only CLI, --json everywhere, machine-readable exit codes, --actor NAME attribution in feed. New project? The agent interviews you first — why, what, acceptance criteria — then cuts prioritized stories and tasks.
🗄️ One repo, one SQLite DB
.lazyplan/lazyplan.db sits next to the code it plans — every subdir resolves to it. JSON export/import for backup.
🔎 Search, filter, follow
Status / project filters and a live feed that toasts arrivals while the TUI runs. lpui feed --json --follow tails activity from any script.
📦 Installs anywhere
pipx, vendored .deb/.rpm (only python3 ≥ 3.11 required), or the curl|sh one-liner — with man pages and shell completions included.
Quickstart
Three commands to a live plan — then drive it from the keyboard or the shell:
cd ~/my-project
lpui init --yes # creates .lazyplan/lazyplan.db + .lazyplan/config.json
lpui add-project --title "my-project" --why "reason" --what "scope" --priority p1
lpui # TUI (same as `lpui ui`)
Plan from the shell with the same verbs agents use:
lpui add-criteria --kind project --id 1 --text "Works offline"
lpui add-story --project 1 --title "Auth refresh" --priority p0
lpui add-task --story 1 --title "Rotate tokens" --priority p1
lpui list
lpui status --kind task --id 1 --to doing
lpui show --kind project --id 1 # full context: why/what + criteria + children
TUI keys (also: lpui help, or ? inside):
j/k navigate · click select · enter/double-click edit · ←/→ fold
n new (context) · P/S/T new project/story/task · e edit · d delete
space cycle status · c tick criteria · z/Z fold one/all
f/o filters
? help · r refresh · q quit
Agent API
The CLI is stdlib-only (no Textual import): --json on every verb, exit codes machines can branch on, --actor NAME on every write.
lpui --actor helper list --json # read the tree
lpui --actor helper show --kind project --id 1 # why/what + criteria
lpui --actor helper add-task --story 1 --title "Draft proposal" --priority p1
lpui feed --json --follow & # tail activity
- Never invent ids —
listfirst; preferupdate/statusover delete + recreate. - New project? Interview the human first — why, what, acceptance criteria, priority. Never guess the definition.
- Cut stories, then prioritized tasks, once the definition is agreed — work p0 first.
- Full agent contract ships in the repo:
.agents/skills/lazyplan/SKILL.md—lpui initinstalls it into your coding agent.
Install
Each v* tag ships an sdist + wheel (PyPI) plus .deb/.rpm per arch (.github/workflows/release.yml) attached to that tag's GitHub Release — pick your installer:
Isolated install from PyPI
The recommended path — pipx installs lazyplan-tui into its own venv and puts lpui (plus the lazyplan alias) on your PATH:
pipx install lazyplan-tui
lpui --help
# later releases:
pipx upgrade lazyplan-tui
Native packages (vendored deps)
Self-contained under /usr/lib/lazyplan — the only requirement is python3 ≥ 3.11. Wrappers land in /usr/bin; man pages and shell completions included:
# Fedora / RHEL / openSUSE
sudo dnf install ./lazyplan-0.13.0-1.x86_64.rpm # or -1.aarch64.rpm on ARM
# Debian / Ubuntu
sudo apt install ./lazyplan_0.13.0-1_amd64.deb # or -1_arm64.deb on ARM
One script, every method
install.sh auto-picks rpm/deb on supported distros, else pipx, else an isolated venv — POSIX sh, never writes as root except through the system package manager:
curl -fsSL https://github.com/fluxion-dev/lazyplan/releases/latest/download/install.sh | sh
# pin + choose:
sh install.sh --version X.Y.Z --method rpm|deb|pipx|venv
# uninstall:
sh install.sh --uninstall
Hacking on lazyplan itself — editable install with dev extras:
git clone https://github.com/fluxion-dev/lazyplan.git
cd lazyplan
python3 -m venv .venv && source .venv/bin/activate
python -m pip install -e ".[dev]"
./tools/check.sh # lint + format + types + unittest (both interpreters)
Prefer to browse? All releases on GitHub — every tag also attaches the sdist, wheel, and install.sh one-liner.
| Arch | deb (Debian/Ubuntu) | rpm (Fedora/RHEL/SUSE) |
|---|---|---|
| amd64 / x86_64 | lazyplan_0.13.0-1_amd64.deb | lazyplan-0.13.0-1.x86_64.rpm |
| arm64 / aarch64 | lazyplan_0.13.0-1_arm64.deb | lazyplan-0.13.0-1.aarch64.rpm |
- System packages need only
python3 ≥ 3.11— dependencies ride along under/usr/lib/lazyplan. - Man pages (
man lpui) and bash/zsh completions ship in every package. - No root for user installs:
pipxand thevenvpath stay in your home directory.
Exit codes & data
Four codes, one DB rule — scripts and CI steps can branch on both with confidence.
0 Success
Wrote, listed, or rendered — including --help
1 Not found
Row id doesn't exist (e.g. task #7)
2 Usage error
Bad flags, validation, or error: … on stderr
3 No TUI
Textual missing — reinstall with dependencies
Where the data lives
First match wins — run lpui info when in doubt:
# example config — not executed
--db PATH # explicit override
$LAZYPLAN_DB # environment override
./.lazyplan/lazyplan.db # inside a repo (via git rev-parse)
~/.local/share/lazyplan/lazyplan.db # global fallback
LAZYPLAN_PG_DSN(or--dsn) targets the Postgres replica forlpui sync.- Back up with
lpui export --format json, restore withlpui import --file.