Skip to content

Install

The manual routes — plugin or plain clone — and the optional Desktop launcher.

You need Claude Code; the skill itself needs just Bash. The console additionally needs Node 22.18 or newer (or 23.6+) with npm — its client is built output: one npm ci && npm run build inside viewer/ per machine. You do not have to remember that: an unbuilt console serves a page naming the two commands and the exact directory to run them in.

Pick a route. A and B give you the skill and the console from one tree; C gives a project its own supervised console from a clone inside the project's folder. There is no package: the repository is the only channel, and a release is a tag on it — docs/releasing.md.

A plugin is a package Claude Code installs for you. A marketplace is a catalog that lists plugins. This repository is both — it ships a catalog called mobin containing one plugin, itself. So installing is one command for each.

Step 1. Open Claude Code in any project and type:

/plugin marketplace add zsarir/phased-execution

Claude Code clones this repository, checks the catalog inside it, and remembers it as mobin. Nothing is installed yet — a marketplace is only a list.

Step 2. Install the plugin from that catalog:

/plugin install phased-execution@mobin

The @mobin part says which catalog to take it from. It matters once you have several registered.

Step 3. Load it:

/reload-plugins

Or just restart Claude Code. Type /plugin to confirm it is listed — that screen also has an Errors tab if something failed.

What you now have. The skill, as /phased-execution:phased-execution — Claude Code puts every plugin's skills under the plugin's name so two plugins can both ship a review skill without clashing. Type /phased and let autocomplete finish it. You will rarely type it at all: the skill describes itself well enough that Claude reaches for it on its own when work is phased. You also get phase-console, a command that starts the web app from any directory — the first run serves a page naming the client's one-time build (npm ci && npm run build, with the exact path printed, since a plugin lives in a cache directory you would otherwise have to hunt for).

Keeping it current. /plugin update phased-execution. This plugin sets no version number on purpose, which puts it on the commit channel: every push to main counts as a new release, and Claude Code also refreshes in the background. Restart to apply an update. An update moves the plugin to a fresh directory, so the console will ask for its build once more — same two commands, same printed path. (npm and Homebrew are the tagged channel instead: releases are vX.Y.Z tags with a CHANGELOG, packed and published by CI with provenance. Same tree, two cadences — the plugin tracks every commit, the packages track releases.)

Removing it. /plugin uninstall phased-execution@mobin, then optionally /plugin marketplace remove mobin.

Route B — as a plain folder (if you want to edit the skill, or script against its path)

git clone https://github.com/zsarir/phased-execution.git ~/.claude/skills/phased-execution

Restart Claude Code. The skill is /phased-execution — no prefix, because it is not inside a plugin. Build the console's client once (cd ~/.claude/skills/phased-execution/viewer && npm ci && npm run build), then start it with ~/.claude/skills/phased-execution/start. Update with git pull, then rebuild — ./start --agent-update does both build and restart if it runs as a background agent.

Route C — a console copy inside your hub folder (one console per project, supervised)

The shape the console is developed and run in: the repository sits INSIDE the folder it serves — <hub>/phased-execution/ (a submodule) or <hub>/console/ (a plain clone) — and that copy installs itself as the login agent for that hub. Nothing lives under ~/.claude but the skill.

git clone https://github.com/zsarir/phased-execution ~/work/hub/phased-execution   # or `git submodule add …`
~/work/hub/phased-execution/installer/install.sh          # macOS, Linux, WSL2
# Windows: powershell -ExecutionPolicy Bypass -File installer\install.ps1  (runs the same script in WSL2)

installer/install.sh builds the client once, writes and starts the unit (launchd on macOS, systemd --user on Linux) for the hub folder holding the copy, and puts a launcher on the Desktop that starts exactly this copy. It remembers --remote/--remote-user from an existing unit, so a re-install never turns a Tailscale-published console into a wall of 421s. --root DIR serves another project; --minimal installs with no capability switch; --dry-run prints the command and installs nothing; installer/uninstall.sh removes the unit. Updating is git pull in the copy, then the installer again. Details: installer/README.md.

Which route?

PluginCloneHub copy
Installtwo commands, inside Claude Codeone git cloneone git clone, then installer/install.sh
Updatesautomatic, every commit to mainwhen you git pullgit pull, then the installer again
Skill name/phased-execution:phased-execution/phased-execution/phased-execution, after phase-console install-skill
Consolephase-console, from anywhere./start, from the foldera login agent for that project, with a Desktop launcher
Lives ata per-version cache directory that moves on every updatewherever you cloned it, permanently<hub>/phased-execution/ or <hub>/console/
Suitswanting it present and current, with nothing to maintainscripting against the path, or editing the skill itselfone console per project, supervised, surviving reboots

Plugin and clone at once works, but you would see the skill twice and pay its always-on cost twice — pick one of those two for the skill; a hub copy can sit beside either for the console.

Linux, and Windows through WSL2

Every route above works on Linux exactly as written. The differences are below; there is no native Windows build, and on Windows the whole thing (Claude Code included) runs inside WSL2.

  • The background agent is a systemd user service. phase-console --install-agent --root <repo> writes ~/.config/systemd/user/phase-console.service (Restart=always, same 150s stop grace as the launchd plist) and starts it — the app's own Restart and Shut-down buttons work the same as on macOS. It stops at logout unless you run loginctl enable-linger $USER once. Installing a console for a second project writes its own unit, phase-console-<id>.service, so the one you already have is never renamed; phase-console list prints which unit belongs to which project.
  • On WSL, systemd must be on (it is on current WSL2 installs). If the install says so: add [boot] + systemd=true to /etc/wsl.conf, run wsl --shutdown from Windows, reopen. Until then — or instead — just run phase-console --root <repo> in a tmux window. WSL parks its VM when nothing runs in it, so the console is up whenever WSL is.
  • The browser. On a Linux desktop the console opens via xdg-open. On WSL it hands the URL to Windows (wslview); if nothing can open one it prints the URL — WSL2 forwards localhost, so http://127.0.0.1:4123 in your Windows browser just works.
  • The Terminal page (optional). Its native module (node-pty) has no Linux prebuilds, so npm compiles it during install if build tools exist — sudo apt-get install -y build-essential python3 first. Skipping this loses only the in-browser shell: board, writes, autopilot and agent sessions all run without it, and the Terminal page names exactly what is missing.
  • The Desktop launcher below is macOS-only (a Finder .command file). On Linux the systemd agent is the equivalent — it is the supervised mode the launcher's SUPERVISED="yes" provides.

Give yourself a launcher (optional, macOS — the double-click way to a supervised console)

A double-click that starts the console. Started with SUPERVISED="yes" it installs a launchd agent, which is what makes the app's own Restart and Shut down buttons work — those exist only where a clean exit comes back, and a window you double-clicked is the server's parent, not its supervisor. Paste this into Claude Code:

Set up a Phase Console launcher on my Desktop.

1. Find the skill: whichever of ~/.claude, ~/.claude-a or ~/.claude-b contains
   skills/phased-execution/viewer/server/index.ts — or, for a packaged install,
   $(npm root -g)/phase-console or $(brew --prefix phase-console)/libexec.
2. Copy viewer/deploy/desktop-launcher.command from there to
   "~/Desktop/Phase Console.command", and make it executable.
3. Open the copy and walk me through the knobs at the top, one at a time:
     ROOT        the repository the console reads — it must contain docs/plans
     WRITES      --allow-writes: scaffold plans/handoffs, record QA, take locks, close plans
     RUNS        --allow-run: spawn unattended Claude sessions that edit ROOT
     TERM_FLAG   --allow-terminal: a real shell in the browser, running as me
     AGENT       --allow-agent: interactive claude sessions + the New-plan wizard
     ACCOUNTS    --allow-accounts: register more than one Claude account and let a
                 run move to one with headroom (the usage meters work without it)
     MCP         --allow-mcp: register MCP servers and attach them to plans and
                 phases (reading the registry and its statuses works without it)
     PORT        leave blank — each project derives its own; set one to pin it
     SUPERVISED  leave "yes" — it installs a launchd agent, and that is what makes
                 the app's own Restart and Shut down buttons work
   Blank out any door I do not want opened, and explain any I am unsure about
   before changing it.
4. Then tell me to double-click it — do not run it yourself. Its first run can
   install a background agent that starts at login, and that is my call.

The Desktop file is a copy, not a link: updating the skill does not update it.
Re-copy it after an update — it prints a warning when it is older than the one
in the repo.
Installing from a terminal instead — for dotfiles scripts and container images
claude plugin marketplace add zsarir/phased-execution
claude plugin install phased-execution@mobin
claude plugin details phased-execution@mobin      # components + token cost
claude plugin update phased-execution
claude plugin uninstall phased-execution@mobin