pma 0.2.0

Lint TODO.md files across many git repositories and rank their tasks in an Eisenhower matrix
pma-0.2.0 is not a library.

pma

Maintenance across many repositories from one place.

Status: every stage of the design: lint, scan, matrix, health, agent dispatch with review and ship, Issues sync, notes, the deps signal, and a TUI. claude is the only agent.

Install

cargo install pma

From a clone: make install.

Requirements:

  • macOS or Linux. The database location is derived from HOME.

  • Rust 1.89 or later, and a C compiler: SQLite is compiled in.

  • git on PATH.

  • gh, authenticated, for CI status. Without it, CI is recorded as unknown and left out of health; pma scan --offline skips GitHub on purpose. Also for fix-CI dispatch, publish = pr, and pma sync.

  • claude, logged in, for pma dispatch.

TODO.md format

# TODO

## Critical

- [ ] segfault on empty input #bug gh:42

## High

- [ ] support ggml 0.9 due:2026-10-01

## Medium

## Low

- [x] drop python 3.9

The section gives the priority. A finished item is ticked where it stands; pma prune removes finished items. A ### heading inside a section groups the items below it. Trailing #tag, due:YYYY-MM-DD and gh:N (a linked issue) are optional. The full rules are in the design.

Commands

pma lint                        # ./TODO.md
pma lint ~/projects/*/          # every project; a directory means its TODO.md
pma prune ~/projects/*/         # plan: finished items and `## Done` to remove; --apply

Output is path:line: severity: message. Exit status is 1 when any file has an error or cannot be read. Warnings alone exit 0.

pma root add ~/projects/          # git repos directly under it are projects
pma tier topproj 1                # 1 (most important) to 5, or none
pma scan                          # TODO.md, git state, CI via gh; about 15s for 95 repos
pma scan --offline topproj        # one project, without GitHub
pma scan --deps                   # also count outdated cargo, uv and go dependencies
pma matrix                        # tiered projects' tasks in the Eisenhower matrix
pma matrix -q q1 --all
pma status --explain              # projects by health, with each signal's share
pma config                        # every setting; `pma config tiers.2 0.7`, `--reset`
pma tui                           # the matrix in the terminal; q quits
pma note add "move CI to reusable workflows"   # portfolio notes; `pma note` lists

matrix and status read the last scan; they do not rescan. Only tiered projects appear in them.

pma dispatch cynn:31              # a TODO.md line from the last scan; or cynn:ci, cynn:deps
pma dispatch cynn:critical        # every open item under ## Critical; or high, medium, low
pma dispatch cynn:q1              # every task the last matrix placed in that quadrant
pma dispatch cynn                 # the project's tasks, in a list with checkboxes
pma dispatch -a pi -m sonnet cynn:31   # this agent and model, not the configured ones
pma dispatch --auto -n 3          # the top 3 dispatchable tasks in the matrix
pma review                        # runs not yet shipped or rejected; settles merged PRs
pma review 4                      # task, verify result, cost, summary, diff
pma review 4 --approve            # or --reject, or --rework "feedback"
pma ship                          # commit, push or open a PR, remove worktrees

A target that names one task fails when that task cannot run. One that names many passes each over with its reason and dispatches the rest. -a and -m outrank pma config agent, pma config model and any applied route; without -m the agent picks its own model, and pma config model applies only to the agent it was set alongside.

Each run gets a worktree of the remote default branch under ~/.config/pma/worktrees, so a dirty clone is never touched. The agent runs without push credentials. pma then runs the project's tests itself: set the command with pma config projects.cynn.verify "make check", or let it be detected. Limits: max_parallel, batch_budget, agent_budget, timeout. publish is pr by default; pma config publish push pushes to the default branch instead. A run shipped as a PR stays pr-open until the PR is merged or closed, and its task is not dispatched again meanwhile.

dispatch, ship, and review --reject or --rework hold a lock on session.lock, so only one of them runs at a time; an open task list holds it too. Other commands, including pma review to watch a batch, can run alongside. The agent may edit files and run the verify command; other shell commands are denied unless your Claude Code settings allow them. pma ship resumes after a failure without publishing twice.

pma sync                          # plan: issues to open, items to mark done
pma sync --apply topproj           # carry it out for one project

Each ## Critical item gets an issue labelled pma:critical, and gh:N is written into its line. An item whose issue is closed is ticked. TODO.md edits are left uncommitted; scripts/commit_todo.py commits them.

The database is ~/.config/pma/projects.db, or $PMA_HOME/projects.db. Dates are compared as UTC calendar days.

Development

make test     # cargo test, then pytest on scripts/
make check    # fmt check, clippy -D warnings, test