Skip to content

CLI — Client

View as Markdown

The client CLI talks to a running StoryShelf server over /api/v1 and carries no Playwright or server dependencies. Run it with your package manager’s runner:

Terminal window
npx storyshelf --help

Package reference: For install and programmatic use see @storyshelf/cli.

Initialize the current Storybook with .storybook/storyshelf.json (client config). Fails if .storybook/main.* is not found.

Terminal window
storyshelf init --url http://localhost:3000 --slug my-design-system --build-dir storybook-static
# or with prompts:
storyshelf init
# ? Server URL? http://localhost:3000 (detected React-Vite • 1 addons)
# ? Project slug? my-design-system
# also: --build-dir, --build-command, --build-script-name, --skip, -c/--config

Writes .storybook/storyshelf.json: { "slug": "...", "url": "...", "buildDir": "...", "skip": "..." } (no token, see Configuration). Token stays in STORYSHELF_TOKEN env / --token.

Create a project on the server (requires site-admin token) and write .storybook/storyshelf.json.

Terminal window
storyshelf create --url http://localhost:3000 --name "My Design System" --token $STORYSHELF_ADMIN_TOKEN
# also reads STORYSHELF_ADMIN_TOKEN / ADMIN_TOKEN env if --token omitted

Prints Project slug: ... and CI token: ....

Build the Storybook output without uploading — same buildDir/buildCommand resolution as upload, but no server contact.

Terminal window
storyshelf build
storyshelf build --force-build
storyshelf build --build-dir dist-storybook --build-command "nx run app:build-storybook"

Prints Build ready: <dir> and fails fast when the output lacks index.json.

Build (optionally), zip, and upload a Storybook build for capture.

Terminal window
# explicit flags
storyshelf upload \
--url http://localhost:3000 \
--slug my-design-system \
--token shelf_xxx \
--sha "$GITHUB_SHA" \
--branch "$GITHUB_REF_NAME"
# with .storybook/storyshelf.json present (no args defaults to upload)
storyshelf
storyshelf upload --token shelf_xxx --sha $GITHUB_SHA --branch main
FlagDescription
--urlServer URL (or file / STORYSHELF_URL)
--slugProject slug (or file / STORYSHELF_SLUG)
--tokenProject API token (Authorization: Bearer, or STORYSHELF_TOKEN)
--shaRevision SHA (flag, CI env, local git HEAD, or synthesized local-*)
--branchBaseline namespace (flag, CI env, local git branch, or local)
--build-dir / -dBuilt Storybook directory (default storybook-static)
--config / -cConfig file path (default .storybook/storyshelf.json)
--build-commandCustom build command (mutually exclusive with --build-script-name)
--build-script-name / -bnpm script to build (default build-storybook)
--force-buildForce rebuild even if buildDir exists
--skipGlob to skip upload (e.g. "main")
--messageBuild message
--author-name, --author-emailAuthor attribution
--label key=valueAttach a build label (repeatable)
--fullDisable affected capture for this upload (render every story)
--untraced <glob>Exclude matching files from affected tracing (repeatable, e.g. "**/*.generated.ts"; unions with untraced in config)
--stats-file <path>Bundler stats file (default <buildDir>/preview-stats.json)
--dry-runValidate/build but send no requests

Affected capture is on by default: the CLI traces git diff baseline..HEAD through the build’s dependency graph, posts the affected set, and prints a summary (Affected capture: rendering 3 stories (baseline abc1234)). Anything it cannot prove unchanged renders anyway — see Affected capture. STORYSHELF_FULL=1 and "affectedOnly": false opt out the same way as --full.

Servers without testing. An instance that hosts Storybooks only reports testing: false when the build is created. storyshelf upload then skips the affected-capture computation, uploads as usual, and ends with Testing is off on this server: the Storybook is published, but no captures or visual checks will run.

Large Storybooks on hosts without a job consumer. A zip over the server’s maxInlineUnzipSize is normally published by a background job. A serverless host runs no consumer, so it answers 413 with a message pointing to the file-by-file route (/dedup, /content, /manifest). storyshelf upload handles that by itself: it prints Zip is over the server's inline publish limit; uploading file by file instead, hashes the build directory, uploads only the files the server lacks, and posts the manifest, which completes publishing. A 413 for maxUploadBytes is not retried this way; raise the limit instead.

Terminal window
storyshelf doctor
# ✓ Storybook setup found
# ✓ Config loaded (slug "my-design-system")
# ✓ Connection: http://localhost:3000 / my-design-system (token present)
# ✓ Server reachable
# ! Build output missing — upload would run: npm run build-storybook -- --output-dir storybook-static
# ✓ Affected capture ready (history and stats available)
storyshelf whoami
# Server: http://localhost:3000
# Project: My Design System (my-design-system)
Terminal window
storyshelf retry --url http://localhost:3000 --slug my-design-system --build-id <id> [--token $STORYSHELF_TOKEN]
storyshelf purge --url http://localhost:3000 --token $STORYSHELF_ADMIN_TOKEN

retry re-runs capture without a new revision. purge triggers retention GC (normally scheduled).

Print, validate and (only with --apply) write the branch rule that makes StoryShelf gate merges. It talks to GitHub or GitLab directly with an admin token; it does not contact your StoryShelf server.

Terminal window
storyshelf protect --provider github --repo acme/widgets [--branch main] [--prefix storyshelf] [--gate testing|review] [--token $GITHUB_TOKEN] [--apply]
storyshelf protect --provider gitlab --repo group/project [--host https://gitlab.example.com] [--token $GITLAB_TOKEN] [--apply]

It always prints the required check names (<prefix>/testing, or <prefix>/review with --gate review) and the manual steps. With a token (--token, or GITHUB_TOKEN / GITLAB_TOKEN) it also compares them with the branch’s rule: the exit code is 1 when something is missing and nothing was written (dry run, the default). --apply adds only the missing part. See Let StoryShelf set the rule for what each host supports.

See Configuration for file/env precedence and Labels for persistent tagging.