Project plans that
live in Git.
Projector keeps each project’s plan as a Markdown file in the repository, under docs/projects/. Developers and coding agents read and update it with the same command-line tool.
curl -fsSL https://projector.bot/install.sh | bashPython 3.11 or newer · MIT license · plugins for Claude Code and Codex
$ project listnow: resume ready Resumecompleted: session-switcher completed Session Switcher $ project checkProject plans are valid.Output from the plans in ninjudd/trip, the project used as the example below.
Create a project
A project is a directory under docs/projects/ with a lowercase readme.md. The file opens with two frontmatter fields and continues as an ordinary Markdown plan.
project init writes the convention file once per repository, and project create makes the directory and the plan. project status changes one frontmatter field, project done marks the project completed, and project list groups what exists by priority. Add --json to any of them for scripts and agents.
Because the plan is a file in the repository, it comes with every clone, along with its history. A status change is a one-line diff in the pull request that makes it true, so the plan and the code are reviewed together. Two people working on two projects edit two different files, so there is no shared status list to conflict on. The directory never moves, so links to a plan keep working. There is no server and no account.
status tracks progress: draft, ready, in-progress, or completed. priority tracks when you want to work on it: now, next, or later. The two are independent. A draft can be the current priority while it is still being written, and in-progress work can drop to later without pretending it never started. A completed project needs no priority.
project initproject create session-switcher --priority nowproject status session-switcher ready---
status: ready
priority: now
---
# Session Switcher
## 1. Outcome
The session list becomes the hub of trip rather than a special case of
`enter`. Three changes, one interaction model:
- **The detach key opens a chooser.** Pressing it inside an attached session
(`TRIP_DETACH_KEY`, `^\` by default) detaches the *view* and shows the
interactive session list.The excerpt is the first lines of a real plan. Read the whole file on GitHub.
An example: the session switcher in trip
trip is a terminal session runtime that keeps its plans with Projector. Its session-switcher project went from plan to completion in four pull requests, and the plan recorded each step.
- 1
The plan merges on its own
The pull request added the plan and no code, so the design was reviewed before anything was built. Its frontmatter said
ninjudd/trip#13readyandnow. Among the decisions it listed as worth arguing with: sort the current workspace first, so its sessions hold the low digits. - 2
Implementation marks it completed
The pull request that built the switcher set the status to
ninjudd/trip#16completedin the same change. Two things the plan got wrong were recorded as a new section 9 rather than by editing the sections that had been reviewed. A retry the plan specified could never fire, so it became an allocation, and a daemon response the plan relied on turned out to be dead code. - 3
A decision changes after use
After a day with the switcher, the ordering changed from current workspace first to most recently opened first, like a task switcher. Section 9.10 records the new rule and the create gesture it retired. Section 3.5 still holds the original reasoning, so the tradeoff can be read from both sides.
ninjudd/trip#17 - 4
A later fix lands the same way
A keyboard-protocol leak found in use was fixed and recorded as section 9.11. The file has not moved since the first pull request.
ninjudd/trip#18
-status: ready
+status: completed
priority: now39814bc Ground the terminal's keyboard protocol on every re-render (#18) 5d7c2a5 Order the chooser by when sessions were last opened (#17) 3cc4333 Implement the session switcher (#16) 66de6c6 Plan the session switcher (#13)
Why I built it
Before Projector, the repositories I work in kept their plans in shared now.md, next.md, and later.md files. Every branch that changed a project’s status edited the same three files, so unrelated branches conflicted with each other, and the plans sat next to my personal agent configuration, where nothing about them could be reused. Projector started as a plan for fixing that, written in the format it proposed, before the CLI existed.
Use with Claude Code or Codex
Projector’s plugin adds skills to Claude Code and Codex. A skill is a written procedure the agent follows, and each one works through the same project command you use, so what the agent saves is a file you can open and edit. No MCP server is involved.
- 1
Spec a project
/projector:spec a session chooser opened by the detach key
The agent reads the repository and the existing projects first, asks only what the code cannot answer, and writes the plan with
project create. It leaves the change for ordinary review, so the plan can go up as its own pull request, the way trip’s did. - 2
Come back and build it
/projector:implement session-switcher
A later session starts from the file, not from the earlier conversation. The agent moves the status to
in-progressin the implementation branch, builds the work, and appends what implementation settled to the plan instead of rewriting the sections that were reviewed. - 3
Finish it
/projector:finish session-switcher
The agent checks each acceptance criterion in the plan against the repository, records whether the work shipped, was abandoned, or was superseded, and runs
project donein the change that completes it.
In Codex the same skills are $spec, $implement, and $finish. The plugin also carries the review skills described next; summarize-pr, which summarizes the changes in a large pull request as a guided page for its reviewers; and write, which writes or revises any prose so that it follows Projector’s writing guide. Its marketplace also serves GitHub’s gh-stack skill, for splitting a large change into a chain of dependent pull requests. Plugin guide
Automated reviews
review-pr reviews one pull request’s current head when you ask, and fix-pr fixes what a review found and resolves merge conflicts. Two more skills, start-review-loop and start-watch-loop, run them in the background while you keep working. The plans and the CLI do not depend on any of them.
- 1
You push
A new commit lands on one of your pull requests, whichever session opened it.
- 2
The review loop reviews it
It checks out that exact commit locally, reads the change, and posts what it finds as one comment review. Each pull request keeps its own reviewer, so the next review knows the last, and a large one gets a summary on the repository’s site.
- 3
The watch loop fixes it
Each finding is checked, fixed, committed, and pushed, and a branch that conflicts with its base gets the base merged in. The loop replies with the commit and resolves the thread. Each pull request keeps its own fixer, so the next round knows the last.
- 4
The draft becomes ready
The reviewer verifies each finding on the new head, resolving what is fixed and reopening what is not. When nothing is left open, the pull request is marked ready for a person to review.
Until then the pull request stays a draft, so draft means the loops still have something to say. A clean loop is one model’s reading of one commit. It catches what a careful first pass catches, and it is not proof that the change is correct, so a human review still follows. The rules the loops follow on GitHub, including who may mark a draft ready and how findings are labeled, are in the skill documents. The loop runs a pull request’s tests only when it trusts who could push to it, and asks you before running code from anyone else.
Publish a site
Every repository can serve its projects, its reviews, and its docs as a site on GitHub Pages, built from what is already in the repository. project init sets it up.
Projects
The home page groups every plan by status. Each project opens with its files, nested projects, and the reviews that touched it.
Reviews
Guided summaries of large pull requests, which the
summarize-prskill writes and publishes, one for each head the pull request reaches.Docs
The README and everything under
docs/. Markdown renders in place, and an HTML page, such as an explorer or a WebAssembly playground, runs inside the site.
project initproject site serveproject init turns on Pages and adds the workflow that deploys the site whenever the docs change or a review is published. It keeps a private repository’s site private, and refuses to deploy one that would be public. project site serve shows the same site on your machine, with no Pages at all, and rebuilds it as you edit.
Install
One command installs the CLI and the plugin for the coding agents you use. Or install each yourself.
Everything, in one command
Installs the project command from the newest release, and the plugin for Claude Code and Codex, whichever you have. It needs Python 3.11 or newer, and no git. Run project upgrade later to move everything to the newest release.
curl -fsSL https://projector.bot/install.sh | bashproject upgradeOr step by step: the CLI
pipx gives you an isolated project command, built from the newest release.
pipx install https://github.com/ninjudd/projector/archive/v0.tar.gzproject helpClaude Code
Adds the repository as a plugin marketplace and installs the plugin for your user. Skills are invoked as /projector:<skill>.
claude plugin marketplace add ninjudd/projector --scope userclaude plugin install projector@projector --scope userCodex
The same repository, installed as a Codex plugin. Skills are invoked as $<skill>.
codex plugin marketplace add ninjudd/projectorcodex plugin add projector@projectorInstalling from a clone, and checking whether an installed command is stale, are covered in the plugin guide. Settings, such as a different projects directory, live in .projector.toml files and are described in the CLI reference.