Scaffold CLI Reference

Overview

This is a terse index of the whole scaffold command surface. It tells you which command does what and points to the deep guides where a subsystem earns its own page. For the full mental model of a subsystem, follow the links:

All 30 commands are registered on a single yargs root (src/cli/index.ts:116) and every command accepts the global options --format json, --auto, --verbose, --root <dir>, and --force (src/cli/index.ts:146).

All commands at a glance

CommandGroupWhat it does
scaffold initSetup & adoptionInitialize scaffold for this project
scaffold adoptSetup & adoptionAdopt an existing project into scaffold
scaffold nextPipeline navigationShow next eligible step(s)
scaffold run <step>Pipeline navigationRun a pipeline step (assemble + emit the prompt)
scaffold complete <step>Pipeline navigationMark a step done (for steps run outside scaffold run)
scaffold reworkPipeline navigationRe-run steps by phase for depth/cleanup
scaffold skip <step..>Pipeline navigationSkip one or more steps
scaffold reset [step]Pipeline navigationReset a step (or the whole pipeline) to pending
scaffold check <step>Pipeline navigationCheck whether a conditional step applies here
scaffold statusStatus & dashboardShow pipeline progress and step statuses
scaffold info [step]Status & dashboardShow project info, or detail on one step
scaffold listStatus & dashboardList methodologies, platform adapters, and tools
scaffold decisionsStatus & dashboardShow recorded decisions
scaffold dashboardStatus & dashboardOpen the visual pipeline dashboard in a browser
scaffold observe event <type>ObservabilityWrite a ledger event
scaffold observe progressObservabilityShow the build-progress snapshot (with --replay)
scaffold observe auditObservabilityRun the audit lenses and report findings
scaffold observe ack <prefix-or-id>ObservabilityAcknowledge or reopen a finding by ID prefix
scaffold observe harvestObservabilityFlush a worktree ledger to the primary archive
scaffold knowledge <subcommand>KnowledgeManage knowledge entries (list|show|update|reset)
scaffold knowledge-freshness <command>KnowledgeRun knowledge-base freshness audits
scaffold validateValidationValidate meta-prompts and config
scaffold validate-knowledgeValidationValidate frontmatter on all knowledge entries
scaffold versionVersion & updateShow version and check for updates
scaffold updateVersion & updateCheck for and display CLI updates
scaffold buildPlatform & skillsGenerate platform adapter output files
scaffold skill <action>Platform & skillsManage scaffold skills for Claude Code / shared agents
scaffold guides [topic]Platform & skillsOpen, list, or build the reference guides
scaffold doctorOperationsHealth-check the installed surface (pipeline, beads, hooks, gate, queue, scheduler)
scaffold agent-ops <action>OperationsInstall or drift-check the agent-ops script bundle
scaffold hooks installOperationsRegister the Claude Code agent hooks into .claude/settings.json
scaffold mq <action>OperationsLocal batching merge queue — enqueue, daemon, status, stats
scaffold tia <action>OperationsTest-impact analysis — coverage map + affected-test selection
scaffold sched <action> [job]OperationsManage local scheduler jobs (launchd / systemd user timers)

Setup & adoption

Two entry points: init for a fresh project, adopt for an existing codebase.

scaffold init
scaffold adopt                              # render the plan, write nothing
scaffold adopt --apply --plan-key <sha256>  # execute the approved plan

Pipeline navigation

The core loop. next tells you what's eligible, run emits the assembled prompt, complete records work done outside the CLI, and rework/skip/reset adjust state. See the Pipeline guide for phase ordering and dependencies.

scaffold next                 # what can I run now?
scaffold run user-stories     # emit the prompt for a step
scaffold rework --through 3   # re-run phases 1 through 3

Status & dashboard

Read-only views of project and pipeline state.

Observability — scaffold observe …

observe is the build-observability surface: a durable event ledger, a fused progress timeline, a multi-lens audit, and worktree-ledger harvesting. It demands a subcommand (src/cli/commands/observe.ts:398). This guide only lists the verbs — the Build Observability guide documents the event schemas, the nine audit lenses, verdicts, stall signals, and config.

SubcommandWhat it does
observe event <type> --branch <branch> [--task-id <id>] [payload flags]Write one ledger event (task_claimed, decision_recorded, blocker_hit, …); --branch is required
observe progressSnapshot of in-flight/completed work; --replay fuses git/gh/mmr/state/tests
observe auditRun the audit lenses; exits 1 when blocked
observe ack <prefix-or-id>Acknowledge or reopen a finding by ID prefix
observe harvestFlush a worktree ledger to the primary archive; --recover sweeps stale ones
scaffold observe progress --replay
scaffold observe audit --scope docs --profile full
scaffold observe ack 3a8c1f02 --status acknowledged --note "tracked in #412"
scaffold observe harvest --worktree ../wt-alice

Knowledge

Two distinct command trees: knowledge manages the entries themselves; knowledge-freshness audits them for staleness.

scaffold knowledge list
scaffold knowledge show react-state-management

Validation

Version & update

Platform & skills

scaffold guides --list --format json   # discover guides (agents)
scaffold guides cli --markdown         # read this guide's source
scaffold guides --build                # regenerate index.html (maintainer/CI)

Agents read markdown, never HTML. Use scaffold guides <topic> --markdown or read the bundled content/guides/<topic>/index.md directly. The generated index.html is for humans.

Operations — the parallel-agent kit

These six commands are orthogonal to the pipeline: they install and run the machinery that lets several agents work one repo at once. None of them touch pipeline state.

All six are registered on the root CLI, so they always appear in scaffold --help. What is opt-in is the machinery they drive: until you run scaffold agent-ops install, there are no queue scripts, no gate seeds, and no poller for them to operate on, and most will tell you so rather than do anything.

CommandWhat it does
scaffold doctor [--fix] [--json]Run every health check across the installed surface and print remediation for each. --fix applies only the safe ones.
scaffold agent-ops install [--component <c>] [--force]Copy the agent-ops script bundle into the project and record a manifest.
scaffold agent-ops checkDrift-check the installed bundle against its manifest.
scaffold hooks installDeep-merge the Claude Code agent hooks into .claude/settings.json — append-only and idempotent.
scaffold mq <action>The local batching merge queue (see below).
scaffold tia <action>Test-impact analysis: record a coverage map, select the affected tests.
scaffold sched <action> [job]Install/inspect local scheduler jobs — launchd on macOS, systemd user timers on Linux.

scaffold doctor

Ten checks across six sections — pipeline (completed steps actually produced their outputs), beads (binary, live database, backup, guard), hooks (registered scripts exist and are executable), gate (the check / check-affected make targets resolve), queue (daemon lock, not paused), and scheduler (the poller schedule is loaded) (src/doctor/checks.ts:419). Each check reports ok / warn / error / skip with its own remediation line.

Three checks can self-heal under --fix: the live-Beads check delegates to bd doctor --fix, hook registration re-runs the installer, and the scheduler check reloads the job. Everything else still only reports its fix.

doctor's exit code is a severity, not the usual envelope code. It exits 1 when any check warns and 2 when any check errors (src/doctor/run.ts:89) — so 2 here means "a check failed", not the enum's MissingDependency. Branch on the --json report rather than the code if you need per-check detail.

scaffold agent-ops

Installs the project-owned script bundle that worktree and merge-queue workflows call. --component selects what lands:

--componentInstalls
gitWorktree setup, branch cleanup, main-sync, doctor, Beads guard + snapshot, primary-checkout guard, regen-artifact check, claim reaping, agent-ops.mk. Note there is no teardown script in the bundle — see the callout below
stagingStaging-env and Docker helper scripts under scripts/ops/, plus a compose env example
merge-queuescripts/mq-guard.sh, the post-merge poller, and a .mq/ gitignore entry
ciSelf-hosted-runner setup plus the post-merge and nightly workflows
gateSeeds the project-owned scripts/gate-check.sh + scripts/gate-check-affected.sh (the merge-queue gate contract)
all (default)git + staging only

--component takes exactly one value; it is not repeatable, so --component merge-queue --component ci fails with AGENT_OPS_INVALID_COMPONENT. Run the command once per component.

all deliberately does not include merge-queue, ci, or gate — each of those changes how the repo merges or what CI runs, so they stay explicit opt-ins.

Teardown is not in the bundle. The git component installs setup-agent-worktree.sh but no teardown counterpart — scripts/teardown-agent-worktree.sh exists only in Scaffold's own repo. If your project relies on the harvest-before-remove ordering the multi-agent guide describes, copy that script in yourself or run scaffold observe harvest --worktree <path> before git worktree remove. Removing a worktree without harvesting loses its ledger permanently.

Seeded files (gate) are generated once and never overwritten without --force. Every install writes .scaffold/agent-ops-manifest.json and .scaffold/agent-ops-version; scaffold agent-ops check compares the tree against that manifest and exits 1 on a stale version, a locally modified file, or a missing file (files the manifest doesn't know about are reported but never fail the check).

scaffold mq — the merge queue

A local batching merge queue: PRs are enqueued, gated in batches, and merged in order, so parallel agents don't each re-run the full suite against a moving main.

ActionWhat it does
enqueue --pr <N>Add a PR to the queue (fire-and-forget; auto-starts the daemon)
daemon [--foreground]Run the queue daemon; --foreground also logs to stdout
status [--pr <N>] [--format json]Queue state, the paused banner, per-PR states
eject --pr <N>Withdraw a PR from the queue
release --pr <N>Return a HELD_HUMAN (overlap-zone) PR to the queue; it lands solo-gated
statsCalibration metrics — arrivals, gate outcomes, median gate time, flakes, cache hits, TIA map age
bootstrap --pr <N> [--finish]Guided FIRST merge for a repo installing the queue in its own PR; --finish resumes a partial run
gate-cache --check-tree <sha> / --record-tree <sha>Look up or record a tree in the gate-result cache (which lets the queue skip a gate when this exact tree already ran green). Both flags are hidden from --help; a bare gate-cache exits with MQ_GATE_CACHE_NO_TREE.

Queue state lives under .mq/ — an append-only journal.jsonl that the queue state is a reduction of, plus the gate cache, logs, and the daemon lock. Configuration is the merge_queue: block of .scaffold/agent-ops.yaml (src/merge-queue/types.ts:95); notable keys are gate_command (default make check-affected), full_gate_command (default make check), batch_cap (16), ready_label (mq:ready), overlap_zones, and overlap_zone_policy (solo | hold).

scaffold tia — test-impact analysis

ActionWhat it does
affected --base <ref>Print the selected test list plus a confidence verdict
record-duePredicate: is a coverage-map recording due right now?
ingestFold a V8 coverage dump into .mq/tia/map.json

Two exit codes here are answers, not failures. scaffold tia affected exits 3 to mean "don't trust this selection — run the full suite", and it fails closed: any uncertainty, and any thrown error, produces a 3 (src/cli/commands/tia.ts:115). scaffold tia record-due exits 1 to mean "not due" (src/cli/commands/tia.ts:136) and prints nothing. Treat a non-zero here as a routing decision, not an error.

Recording cadence is merge_queue.tia.record in .scaffold/agent-ops.yaml — scheduled (default; first green pass per UTC day), always, or off.

scaffold sched

install / uninstall / status / list for local scheduler jobs, using launchd on macOS and systemd user timers on Linux. One job ships today, post-merge-poller (src/sched/jobs.ts:38), which runs the merge queue's post-merge full gate; --interval <seconds> sets its period on install (default 600). It requires scripts/ops/post-merge-poller.sh, so run scaffold agent-ops install --component merge-queue first. sched status exits 1 when the job is not loaded, so it doubles as a liveness probe.

See also

Driving scaffold from an agent

Every command below is safe to run with no TTY. Pass --format json and read stdout; human-readable progress goes to stderr and can be discarded.

Exit codes

CodeNameMeaning
0SuccessThe command did what was asked.
1ValidationErrorBad or missing input. errors[0].recovery names the fix.
2MissingDependencyA required external tool is absent.
3StateCorruption.scaffold/state.json could not be read or migrated, or a lock could not be acquired.
4UserCancellationAn interactive prompt was cancelled.
5BuildErrorAdapter generation failed.
6AmbiguousOperator action required, such as detection finding two equally plausible project types. Re-run with --project-type.

Source of truth: src/types/enums.ts. A bats gate asserts this table and the enum agree in both directions, so a code cannot change on one side only.

The output envelope

Success:

{"success": true, "data": {}, "errors": [], "warnings": [], "exit_code": 0}

Failure:

{
  "success": false,
  "data": null,
  "errors": [
    {
      "code": "INIT_AUTO_FLAG_REQUIRED",
      "message": "--cli-interactivity is required in auto mode for cli projects",
      "exitCode": 1,
      "recovery": "Pass --cli-interactivity <args-only|interactive|hybrid>"
    }
  ],
  "warnings": [],
  "exit_code": 1
}

Branch on success. Where the envelope is emitted, it carries at least one entry in errors, every entry carries a recovery string naming the flag or command that fixes it, and exit_code always matches the process exit status.

Coverage is CLI-wide as of v3.53.0, and a static test fails the build if a command reports a failure any other way.

Deliberate exceptions — commands whose exit code is the answer. A handful of operations commands are predicates or severity reporters, not envelope emitters. Read their code as a result, not as a failure:

CommandNon-zero means
scaffold tia record-due1 = not due (0 = due). Prints nothing, emits no envelope.
scaffold tia affected3 = don't trust the selection, run the full suite (fails closed on any error).
scaffold doctor1 = a check warned · 2 = a check errored.
scaffold agent-ops check1 = the installed bundle is stale, modified, or missing files.
scaffold sched status1 = the job is not loaded.
scaffold mq gate-cache --check-tree1 = cache miss (0 = hit).
scaffold observe audit1 = verdict is blocked (see the observability guide).

Choosing init or adopt

Run scaffold adopt when the directory already contains source code or docs. Run scaffold init for an empty or brand-new directory.

adopt runs in two steps. Bare scaffold adopt writes nothing — it renders an Adoption Plan and stops. scaffold adopt --apply --plan-key <sha256> then executes it, and that step writes .scaffold/ and selects the brownfield methodology itself. So no separate scaffold init is needed either way — but nothing is written until you approve the plan.

Flags --auto cannot default

Nine project types need one flag chosen explicitly, because there is no defensible default. They are annotated [required with --auto] in scaffold init --help.

--project-typeRequired flag
web-app--web-rendering
backend--backend-api-style
cli--cli-interactivity
library--lib-visibility
mobile-app--mobile-platform
data-pipeline--pipeline-processing
ml--ml-phase
research--research-driver
mcp-server--mcp-language

game, browser-extension, macos-native, data-science and web3 need none. A type-specific flag implies its project type, so scaffold init --auto --cli-interactivity args-only is sufficient on its own.

Any non-interactive mode implies --auto: a piped invocation, or --format json, will refuse to invent an answer rather than silently choosing one.

The driving loop

scaffold next --format json          # .data.eligible[].command is runnable as-is
scaffold run <slug>                  # prints the assembled meta-prompt on stdout
scaffold complete <slug> --format json

Repeat until .data.pipeline_complete is true.

Adoption plan keys

plan_key is content-addressed: it hashes the plan's dispositions and initialize payload, and deliberately excludes project_root and generated_at (src/project/adoption-plan.ts). Two repos whose plans are identical therefore share a key. Do not cache a key across repositories; always read the key from the plan you just rendered.