pma 0.3.0

Lint TODO.md files across many git repositories and rank their tasks in an Eisenhower matrix
pma-0.3.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, opencode and omp come as worker templates; any coding agent with a headless mode is a record rather than a code change.

Workflows -- a graph of agents over a project, specified in JSON or a Rhai script -- are in progress: a document is read, costed and stored, and a pass runs every node a rule decides. A node an agent decides is planned and priced, and spends nothing until you approve it. Design: workflows.md.

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.

  • A coding agent for pma dispatch: claude, opencode or omp, logged in or holding its own provider key. pma runs agents and is not an API client, so ANTHROPIC_API_KEY, OPENAI_API_KEY and OPENROUTER_API_KEY are inherited by the agent from your session; what it strips is what lets a child push.

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.

pma agent                       # the workers; `pma agent show claude` prints one whole
pma preset set claude-haiku  claude haiku
pma preset set omp-luna-high omp    gpt-5.6-luna --thinking high
pma preset                      # every named worker, model and configuration
pma preset use omp-luna-high    # the default; -p <name> uses one for a command
pma dispatch -p claude-haiku cynn:31

A preset names a worker, a model and the arguments that configure it. Effort is arguments rather than a field, because what expresses it differs per agent. Highest first: -a and -m, then -p, then an applied route, then pma config preset, then pma config agent.

pma workflow check lib.rhai     # read a document and print its worst case
pma workflow propose lib.rhai   # store it as a draft revision
pma workflow activate 1         # unless its worst case exceeds workflow_budget
pma workflow run review cynn --dry-run
pma workflow run review cynn -p claude-haiku

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