planwright
A maker of plans. Keep your plan as a plain Markdown table; planwright tells you the three things a project manager actually needs to know:
- what is ready to start now,
- what can run in parallel,
- what the critical path is (the floor on how long the remaining work can take).
The plan is data — a Markdown file in git. The engine is deterministic and has zero runtime dependencies. And a Claude Code hook keeps the plan honest: it refuses to let the plan drift into a cycle or a dangling dependency.
Use it as a Python CLI, as a library, or as a Claude Code plugin (slash commands + a planning skill + the hook). It is built to plug into any project or agent and get out of the way.
Why it exists
Most "project-manager" agents are a prompt persona: they write a nice plan and then forget everything — no source of truth, no enforcement, so the work drifts back into a pile. planwright inverts that. The plan lives in a file you own, the schedule is computed from facts (not guessed by a model), and the discipline is enforced by a hook rather than good intentions. See POSITIONING.md.
Install
pip install planwright # the CLI + library
Or use it straight from a checkout with no install:
PYTHONPATH=src python3 -m planwright.cli graph PLAN.md
The plan file
A plain GitHub-flavoured Markdown table. ID and Title are the only required
columns; the rest are optional. Headers are case-insensitive and accept aliases
(including Portuguese), so planwright reads a plan written in your own words.
| ID | Title | Status | Owner | Est | Depends | Track |
|----|----------------------------|--------|-------|------|---------|-------|
| A1 | Design the data model | done | ana | 1d | - | core |
| A2 | Build the parser | doing | ana | 2d | A1 | core |
| A3 | Build the dependency graph | todo | luis | 2d | A1 | core |
| A4 | Wire the CLI | todo | ana | 1d | A2, A3 | core |
| B1 | Write the README | todo | bea | 0.5d | - | docs |
- Status:
todo · doing · blocked · done(aliases:open/aberto,wip/em curso,bloqueado,fechado, …). - Est: a size
S/M/L/XL, or a duration2h/3d/1w;-= not sized yet. - Depends: ids this item waits on (comma/space separated);
-= none. - Track: any label to group items (a feature, a workstream, a phase).
The table can live inside a larger document — planwright reads the first table
that has ID and Title and ignores everything else.
Commands
planwright graph PLAN.md # ready now · parallel layers · blocked · critical path
planwright action PLAN.md # a manager's action plan: ranked ready, who-unblocks-what, critical
planwright mermaid PLAN.md # Mermaid diagrams (deps + Kanban board + gantt) — render in GitHub/Markdown
planwright gantt PLAN.md # Mermaid gantt of relative effort (not a calendar)
planwright load PLAN.md # effort grouped by owner (estimate, not a calendar)
planwright cost PLAN.md # indicative token/USD from Complexity (not the ledger)
planwright next PLAN.md # just the ids ready to start now (one per line)
planwright export PLAN.md # emit the stable JSON contract for an execution runner
planwright validate PLAN.md [--strict] # check the plan is sound (and disciplined)
planwright status PLAN.md # one-line status counts
graph/next/status take --json; mermaid takes --view deps|board|gantt|all.
The path defaults to PLAN.md (override with $PLANWRIGHT_PLAN).
gantt / load / cost are views: relative effort bars, effort by owner, and
indicative token/USD from Complexity. They are not a calendar scheduler and
not the billing ledger — real dates and real usage belong to the execution
runtime. cost reads an optional override table from $PLANWRIGHT_COST_MODEL
(stdlib JSON); absent, it uses built-in indicative defaults.
See it, don't read it
planwright mermaid emits mermaid blocks that render natively on GitHub,
so a manager sees the dependency graph (coloured by status) and a Kanban board
without reading the CLI. planwright action ranks what to start now by leverage:
human decisions that unblock others first, then the critical path, then the rest.
Hand-off to an execution runner
planwright export PLAN.md emits a stable, versioned JSON contract
(planwright-plan/v1) — the clean boundary between planning (planwright) and
execution (a runner). planwright describes the plan; a runner imports it,
authorizes, runs, and records. autonomy/complexity travel as signals for
the runner's selection logic, never as runtime policy, and planwright holds no
authz/budget/tools/events. See the monorepo's docs/architecture/PLAN-CONTRACT.md.
Optional columns (for routing)
Two optional columns feed autonomy/complexity-aware routing; absent, they are ignored:
- Autonomy —
auto(an agent can close it) ·assisted·human(needs a person). - Complexity —
C1..C4(cognitive risk, for cheap→expensive model routing), independent ofEst(effort). A task can beEst=SandC4.
Example:
$ planwright graph PLAN.md
plan: 5 items (todo 3, doing 1, blocked 0, done 1)
READY NOW (3): start these today
A2 Build the parser (2d @ana)
A3 Build the dependency graph (2d @luis)
B1 Write the README (4h @bea)
PARALLEL LAYERS (2): each layer can run at once
L0: A2, A3, B1
L1: A4
CRITICAL PATH: 4d — A1 -> A2 -> A4
(the floor on remaining time; shortening the plan means shortening this)
As a Claude Code plugin
planwright is also a plugin. Load it straight from a checkout:
claude --plugin-dir oss/planwright # from the monorepo root
# or, once published as its own repo / marketplace:
# /plugin install planwright --marketplace <owner>/<repo>
You then get:
/planwright:plan-status— the schedule, summarised./planwright:plan-new— start a plan or add an item through the method./planwright:plan-triage— sort a crowded backlog into real vs. resolvable vs. stale.- the
governed-planningskill — the five-gate method (idea → research → spec → WBS → execute) and the one rule (nothing starts without an estimate and explicit dependencies). - a
PostToolUsehook — after any edit to a plan file (PLAN.mdor*.plan.md), it validates and blocks on an unsound schedule so the plan never silently rots. SetPLANWRIGHT_STRICT=1to also block on governance warnings.
Validation rules
Errors (not a sound schedule — fix before trusting the graph): a parse failure, a duplicate id, a dependency naming no item, a self-dependency, a cycle.
Warnings (schedulable but undisciplined; --strict turns these into
failures): an item marked doing/done with no estimate; a done item that
still depends on unfinished work.
Library
from planwright.parse import parse_plan
from planwright.graph import Graph
plan = parse_plan("PLAN.md")
g = Graph(plan)
print([i.id for i in g.ready()]) # ready now
print(g.parallel_layers()) # [[...], [...]]
print(g.critical_path().hours) # float (hours)
Part of a proven composition (the accountability layer)
planwright describes and prioritizes; it does not execute. Paired with an execution runner it becomes an accountability layer for agent work: a plan that cannot silently rot, handed to a runner that gates, budgets and verifies. The hand-off is a thin, versioned contract — and the whole path is proven by tests, not asserted:
- the contract (
planwright export→ a runner imports it): monorepodocs/architecture/PLAN-CONTRACT.md; - the canonical scenario — one run with a human gate, a budget cap and
completion checked by evidence:
docs/architecture/CANONICAL-SCENARIO.md; - where it fits vs. frameworks and persona collections:
docs/initiatives/COMPETITIVE-ANALYSIS.md.
The signals planwright exports (Autonomy/Complexity) travel as planning
intent, never as runtime policy — the runner stays the authority at runtime.
License
MIT. No third-party runtime dependencies. See LICENSE and NOTICE.
Metadata
Release files for planwright 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| planwright-0.4.0.tar.gz | 33.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| planwright-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.2 kB
Release files / planwright-0.4.0.tar.gz
| Download URL | planwright-0.4.0.tar.gz |
|---|---|
| Size | 33.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b72cdf71bd62831233e82dcb8542a9f3e12bc736296cfa2791eb0f4616015a3d
|
|
BLAKE2b-256 checksum How to use checksums |
1e0dd8ff820d3f51f6a37779cf4afc5555c0a830dae15b99c0003d024219abc5
|
| 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 Oct 11, 2026.
Transparency logRelease files / planwright-0.4.0-py3-none-any.whl
| Download URL | planwright-0.4.0-py3-none-any.whl |
|---|---|
| Size | 27.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ec0170b1bc744cc3a31d20f7d62032791e3ecce1fe65cd6c6d9a389c7f1c8098
|
|
BLAKE2b-256 checksum How to use checksums |
e71a179b6db301bcca62f9728eb255fd1f6eb9f329117ededeebda0891d37b9a
|
| 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 Oct 11, 2026.
Transparency log