Workspace

CLI Reference

Every handoff-app command, grouped, with real flags from the CLI source.

Most commands accept two shared options: -d, --debug (verbose logging) and -f, --force (force action, meaning varies by command). They're omitted from the tables below. init and init:vercel are the exceptions: they don't register the shared options at all.

There's no config-path flag. To point the CLI at a different workspace directory, set the HANDOFF_WORKING_PATH environment variable, config resolution starts from there instead of process.cwd(), see handoff.config.* resolution.

Scaffolding a project

CommandFlagsWhat it does
initInteractive wizard (@clack/prompts): project name, Figma project ID + access token, TypeScript/JavaScript config, whether to include example components. Writes a starter handoff.config.*.
scaffoldGenerates component declaration stubs for components already pulled in via fetch, so you have a .handoff.ts/.js file per Figma component to fill in.

Figma & tokens

CommandFlagsWhat it does
fetchPulls the raw token/component export from Figma into the project's tokens.json snapshot.
tokens:build--skip-migrateAuto-migrates a legacy Figma export into design-system/tokens/ (DTCG), then runs Style Dictionary to produce design-system/dist/{css,scss,tailwind,dtcg}. See Token pipeline.
audit:figma-components--json, --fail-on-driftCompares fetched Figma components against locally registered ones; reports Figma-only components and missing/broken figmaComponentId links. --fail-on-drift exits non-zero on any drift (useful in CI).

Building & previewing

CommandFlagsWhat it does
startThe local preview command. Builds components, patterns, the main JS and the main CSS, then runs a custom dev server with file watchers and a WebSocket live-reload channel, filesystem-backed (StaticDataProvider). See Local preview.
devPlain next dev against the materialized app. Builds no components, so the preview renders empty. A debugging escape hatch for the Next.js app itself, not the command you want for previewing a design system.
build:app--skip-components, --mode dynamic|vercelBuilds the documentation application.
build:components [component]Builds all components, or a single one by name.
validate [component]--validators <ids>, --json, --ci, --updateRuns configured validators (axe/schema/contrast/custom) against built component data. --ci exits non-zero per config.validation.failOn. --update writes results back into the component's built JSON.
validate:components--skip-buildValidates components in the design system (legacy path predating the validate validator framework).

Auth

CommandFlagsWhat it does
login--url <origin>, --browser/--no-browserOAuth device flow: opens a browser for approval, saves the resulting bearer token to .handoff/cli-auth.json. --no-browser (or CI=1 / HANDOFF_LOGIN_NO_BROWSER=1) skips the browser open and just prints the verification URL.
logoutRemoves .handoff/cli-auth.json for the resolved deployment.

Sync (push / pull)

CommandFlagsWhat it does
push--components <ids>, --patterns <ids>, --pages <slugs>, --dry-run, --build/--no-build, --metadata-only, -m, --messagePushes local pages + component/pattern declarations + built preview artifacts via POST /api/sync/upload. Selective flags accept repeated or space-separated ids. --dry-run needs no cloud URL/token. -m records a short "why" shown in the changelog.
push:all--skip-{build,components,pages,config,theme,navigation,tokens,dtcg,icons,logos,fonts,figma-fills,image-slots,design-md}, -m, --messageFull workspace → registry sync: runs every push step in sequence (config → components/pages → theme → navigation → pages → tokens → dtcg → icons → logos → fonts → Figma image fills → image slot specs → refresh DESIGN.md). Any --skip-* flag omits that step. Non-fatal per-step failures are logged and summarized; the command exits non-zero if any step failed.
push:tokens--skip-figma, --skip-dtcgJust the Figma token snapshot + DTCG dist push, faster than push:all when only tokens changed.
pull--dry-runPulls remote edits (pages, component declarations, build artifacts, source files) via GET /api/sync/changes into the workspace. --dry-run prints what would change without writing files or updating .handoff/sync-state.json.
sync-statusPrints the remote sync cursor vs. local .handoff/sync-state.json.

AI/agent onboarding

CommandFlagsWhat it does
mcp-init--url, --root, --server-name (default handoff), --token-env (default HANDOFF_MCP_TOKEN), --embed, --browser/--no-browserOne-step MCP onboarding: signs in if needed, fetches DESIGN.md, writes/merges a .mcp.json entry, and upserts a "Design System" block into CLAUDE.md. --embed writes the literal token into .mcp.json (auto-gitignored) instead of an env-var reference. See MCP → Onboarding.
mcp-token--rootPrints only the MCP/sync bearer token to stdout: composes into export HANDOFF_MCP_TOKEN=$(handoff-app mcp-token).
init-claude--root, --server-name, --token-envOlder, equivalent one-shot wiring for Claude/agents (fetch DESIGN.md, register MCP server, update CLAUDE.md). It doesn't drive the login round-trip itself; expects .handoff/cli-auth.json to already have a token. mcp-init is the current recommended path.

Eject / make (customize the defaults)

CommandFlagsWhat it does
eject:configEjects the default configuration into the current working directory to customize it.
eject:pagesEjects the default pages into the current working directory.
eject:themeEjects the currently selected theme.
make:component <name>Scaffolds a new HTML code component you can embed in documentation.
make:page <name> [parent]Creates a new documentation page.
make:template <component> [state]Creates a new template for an existing component.

Deprecated (legacy per-project deploy model)

Superseded by push-to-registry

Both commands still work for existing legacy deployments but are slated for removal. Under the current model, a registry is its own handoff-app deployment and workspaces push content to it via push:all, see Registry → Deploy.

CommandFlagsWhat it does
prepare-runtime--skip-components[DEPRECATED] Materializes the Next.js app into .handoff/runtime/ for a CI/Vercel deploy of the workspace itself, without running next build.
vercel-build--skip-components[DEPRECATED] Materializes the app and runs a full next build in .handoff/runtime/: the legacy Vercel build command for per-project deploys. Auto-skips component builds when HANDOFF_REGISTRY_MODE or DATABASE_URL is set.
init:vercel--rootWrites a vercel.json + .env.vercel.example for deploying a registry (not a workspace) to Vercel, see Registry → Deploy.

Global options

OptionAliasPurpose
--debug-dVerbose logging.
--force-fForce the action (meaning depends on the command).
--helpShow help.
--versionShow the handoff-app version.

--help and --version are registered bare by yargs, there are no -h/-v short aliases.

On this page