Overview
Scaffold ships as one tool with two install surfaces: the scaffold CLI
(distributed on npm as @zigrivers/scaffold and via Homebrew) and an optional
Claude Code plugin that auto-activates the runner and pipeline-reference
skills. The CLI is the core; the plugin only adds interactive guidance on top of
it. The published npm package exposes the single scaffold binary
(package.json:37) and bundles the compiled CLI plus the pipeline content,
knowledge entries, and skills (package.json:27).
This guide is for users installing, updating, and bootstrapping projects.
Maintainers releasing Scaffold itself follow a separate flow in
docs/architecture/operations-runbook.md docs/architecture/operations-runbook.md:326.
Prerequisite — Node.js 18.17+. The CLI requires Node.js >=18.17.0
(package.json:34). The Homebrew formula installs and manages Node as a
dependency, so you don't install Node separately; the npm install uses your
system Node.
Installing
Pick one of the three surfaces below. The npm and Homebrew tabs install the CLI; the plugin tab adds the optional Claude Code skills on top.
npm install -g @zigrivers/scaffold
Verify with scaffold version. This is the recommended path — it uses your
system Node and updates with npm update -g.
brew tap zigrivers/scaffold
brew trust zigrivers/scaffold # only if the next command refuses the tap
brew install scaffold
The formula installs and manages Node as a dependency, so no separate Node
install is needed. Verify with scaffold version.
Newer Homebrew refuses to load a formula from a tap it doesn't trust. If you see
Refusing to load formula … from untrusted tap zigrivers/scaffold, run
brew trust zigrivers/scaffold once — it's Scaffold's own official tap — then
retry. This is a local Homebrew policy, not a problem with the release.
Inside a Claude Code session:
/plugin marketplace add zigrivers/scaffold
/plugin install scaffold@zigrivers-scaffold
This is optional and complements the CLI — it auto-activates the Scaffold
Runner and pipeline-reference skills for interactive guidance. Everything the
plugin does is also reachable via scaffold run <step>. CLI-only users don't
need it: scaffold init installs the skills automatically and later CLI
commands keep them current.
Installing mmr (the review CLI)
mmr is a separate package — installing scaffold does not install it. The
review workflow (scaffold run review-pr / review-code, and the mandatory
post-PR review) drives mmr, so install it alongside:
npm install -g @zigrivers/mmr # or: brew install mmr (same zigrivers/scaffold tap)
mmr doctor # which reviewer CLIs are installed + authed, and how to fix each
Both surfaces are published on every mmr-v* tag, so pick whichever matches how
you installed scaffold. Keep it current with npm update -g @zigrivers/mmr or
brew update && brew upgrade mmr.
mmr orchestrates other CLIs — it does not bundle any model. mmr doctor
tells you which of codex, claude, grok, agy, and opencode are present
and authenticated, and prints the exact recovery command for each. A channel
whose CLI simply isn't installed is skipped rather than compensated, so a fresh
machine typically needs at least two of them before a review yields a usable
verdict — see the MMR reference.
Keeping current
Check what you have and whether a newer release exists with scaffold version
(or scaffold update --check-only); both query the npm registry for the latest
@zigrivers/scaffold (src/cli/commands/version.ts:93). scaffold update
detects how you installed and prints the right upgrade command rather than
running the install for you — Homebrew installs map to brew upgrade scaffold
(src/cli/commands/update.ts:47), npm-global installs to
npm update -g @zigrivers/scaffold (src/cli/commands/update.ts:51), and
anything else falls back to npx @zigrivers/scaffold@latest
(src/cli/commands/update.ts:55).
The Homebrew command it prints is exactly brew upgrade scaffold — it does
not include the brew update prefix. Homebrew users must prepend it
themselves and run brew update && brew upgrade scaffold, or the upgrade can
silently no-op against a stale tap cache (see the danger callout below).
Run the upgrade for your channel:
npm update -g @zigrivers/scaffold
brew update && brew upgrade scaffold
/plugin marketplace update zigrivers-scaffold
Homebrew: run brew update before brew upgrade. brew outdated and
brew upgrade both read from the local tap cache. Without a preceding
brew update, the cache stays stale and a freshly-published release reports
"already installed" / nothing-outdated even though a newer formula is live on
GitHub. Always upgrade with brew update && brew upgrade scaffold
docs/architecture/operations-runbook.md:326.
After upgrading the CLI, run scaffold status inside any existing project. The
state manager auto-migrates old step keys, drops retired steps, and normalizes
artifact paths — no manual editing of .scaffold/state.json is needed.
Starting fresh vs. adopting
Both scaffold init and scaffold adopt operate on the current project
directory. Use init to set up a project from scratch and adopt to
bootstrap pipeline state from documentation you already have.
scaffold init
scaffold init initializes Scaffold for the current project
(src/cli/commands/init.ts:152): it runs a wizard, writes .scaffold/
config and state, and installs the skills. The wizard detects whether the
directory is brand new or already has code and suggests a methodology preset
(mvp, deep, or custom) accordingly. To re-initialize a project that
already has a .scaffold/ directory, pass --force — it backs up the existing
state before reinitializing (src/cli/commands/init.ts:157).
scaffold adopt
scaffold adopt adopts an existing project into Scaffold
(src/cli/commands/adopt.ts:168). It classifies the project as
greenfield, brownfield, or v1-migration
(src/project/adopt.ts:72), discovers which pipeline outputs (PRD,
tech-stack, coding-standards, etc.) you already have on disk, and marks the
corresponding steps complete so you don't re-run work you've already done.
It writes nothing by default. Since v3.48.0, adopt renders an Adoption
Plan and stops. To execute it, pass --apply together with the plan you
approved:
scaffold adopt # render the plan, write nothing
scaffold adopt --write # also write docs/adoption-plan.md
scaffold adopt --format json # machine-readable plan, includes plan_key
scaffold adopt --apply --plan-key <sha256> # execute the approved plan
--dry-run is deprecated and does nothing: plan mode is already the default
(src/cli/commands/adopt.ts:117).
adopt initializes for you. It writes the .scaffold/ config and state
itself and selects the brownfield methodology. Do not run scaffold init
first on an existing codebase: init would select deep, and adopt would
then have to replace it.
Troubleshooting
scaffold: command not found after npm install. Your global npm bin
directory isn't on PATH. Find it with echo "$(npm prefix -g)/bin" (the
binaries live in the bin subdirectory of npm prefix -g) and add that
directory to your shell PATH, or reinstall with a prefix that's already on
PATH.
- Homebrew says "already installed" after a release. You skipped
brew update. Runbrew update && brew upgrade scaffold(see the danger callout above). - Wrong version reported. Run
scaffold versionto see the installed version, Node version, platform, and the latest registry version side by side. If two installs collide (e.g. both npm-global and Homebrew), remove one. - Node too old. The CLI needs Node 18.17+ (package.json:34). Upgrade Node, or use the Homebrew install, which installs and manages Node as a dependency.
scaffold updateonly prints a command. That's intentional — it never runs installs for you. Copy the printed upgrade command for your channel and run it yourself.--check-onlyreports the same information and exits — it still names the upgrade command when one is available; the difference is that it emits a check-shaped JSON payload under--format json.--skip-buildis accepted but currently has no effect:scaffold updatenever installs or rebuilds anything, so there is no build to skip.- Existing project behaves oddly after upgrade. Run
scaffold statusto trigger automatic state migration before anything else.
See also
- Pipeline reference{mode=advisory} — what the steps are and the order they run in.
- CLI reference{mode=advisory} — every
scaffoldsubcommand. - Multi-agent workflow{mode=advisory} — running the pipeline across parallel worktrees.