Commands

Every command a person runs in this repo, by area, with what it does and the page that explains it.

2026-11-07

Every command a person runs in this repo, by area. Run them from the repo root unless the command says otherwise; pnpm --filter <package> <script> runs one package's script, and arguments for the script go after --. Each row links to the page that explains when and why. Scripts that only CI runs (scripts/ci/*, the prepare and prebuild hooks) are left out, apart from the two worth running locally.

Setup and dev

Command What it does Explained in
pnpm install Installs the workspace; the prepare hook points git at scripts/hooks, so the pre-commit hook is on from the first install Installation
pnpm dev Runs every package's dev task through Turbo — the web app on :3000 Installation
pnpm --filter @v4/web dev The web app alone, on :3000 Installation
pnpm --filter @v4/web build then pnpm --filter @v4/web start A production build of the web app and a server for it (the build sets a 12 GB heap) Deployment
pnpm --filter @v4/storybook dev Storybook on :6006 (stages the Figma reference images first) Testing
pnpm --filter @v4/docs dev This docs site on :4400, with the docs chat Docs assistants
pnpm --filter @v4/cortex-sso stage-test A standalone app for trying a real sign-in against Cortex's stage platform @v4/cortex-sso

Build, lint, test

Command What it does Explained in
pnpm build Turbo-cached build of every package and app Monorepo and packages
pnpm lint ESLint everywhere, zero warnings allowed Pull requests and gates
pnpm check-types TypeScript in every package Pull requests and gates
pnpm test Every package's unit suite, the story suite and the e2e, through Turbo Testing
pnpm --filter <package> test One package's unit suite (test:watch where the package has it) Testing
pnpm format / pnpm format:check Prettier: write, or check only Pull requests and gates
pnpm verify The cheap CI gates in one run: Prettier, lint, types, unit suites, the bridge check, composition drift and app codegen drift Pull requests and gates
pnpm --filter @v4/storybook test The story suite: every story rendered in a browser, with its play function and accessibility check Testing
pnpm --filter @v4/e2e test The Playwright e2e on every project; boots Storybook on :6006 or reuses a running one Testing
pnpm --filter @v4/e2e test:chromium / test:cross-browser / test:full-matrix / test:ui The Chromium projects only; WebKit and Firefox only; every spec on every project; Playwright's UI Testing
E2E_PORT=6016 pnpm --filter @v4/e2e test -- <spec> The e2e against a Storybook on another port, when :6006 belongs to another checkout Troubleshooting
node scripts/hooks/docs-drift.mjs --range=origin/develop..HEAD The docs-drift check CI runs: asks whether the docs mapped to the changed paths still hold (needs ANTHROPIC_API_KEY) Pull requests and gates

Components and Storybook

Command What it does Explained in
pnpm --filter @v4/ghost-core new-component <kebab-name> Scaffolds a ghost-core component's files and registrations Create a component
pnpm --filter @v4/ghost-content check-dist (and ghost-video, ghost-basketball) Checks a sibling package's build output and that its OWN_THEMES list matches its themes Create a component
pnpm --filter @v4/storybook visual-diff -- --story <id> --ref <png> Scores a story against a Figma reference PNG (pixelmatch) Testing
node apps/storybook/scripts/contrast-table.mjs --story <id> (or --component <name>) Measures every text and background pair a story renders, for the accessibility page (Storybook running) Accessibility
pnpm --filter @v4/storybook build / chromatic A static Storybook; a Chromatic upload Testing

Tokens and Figma

These need FIGMA_PAT in the root .env, except where a row says offline.

Command What it does Explained in
pnpm --filter @v4/tokens-euro-league generate Regenerates the club's tokens and the competition theme layers from its tokens.json — run after every Token Studio push Token packages
pnpm --filter @v4/tokens generate Regenerates the Ghost defaults from the vendored tokens.json Token packages
pnpm --filter @v4/tokens check / pnpm --filter @v4/tokens-euro-league check Parses and validates a tokens.json without writing (offline) Token packages
pnpm --filter @v4/tokens sync-icons Regenerates the icon components from the Ghost Figma file Token packages
pnpm --filter @v4/tokens drift The design-drift report: has the Ghost file moved since each bridge's version? Token pipeline
pnpm --filter @v4/tokens-euro-league coverage How much of the Ghost contract the club export re-specifies (offline) @v4/tokens-euro-league
pnpm --filter @v4/tokens-euro-league figma-colour-check Checks every colour the club tokens emit equals what Figma paints @v4/tokens-euro-league
pnpm --filter @v4/token-parser exec v4-tokens coverage -c <components-dir> [-n <component>] [--write] Recomputes binding coverage from the cached extractions (offline) @v4/token-parser
node packages/token-parser/scripts/check-bridges.mjs Offline: every bridge names a Figma file this repo is built from, and every cached extraction agrees with its bridge (also in pnpm verify) Refactor a component
node packages/token-parser/scripts/design-status.mjs --file <key> [--ready] [--unbuilt] The design and development status the client's Figma file records per component Refactor a component
node packages/token-parser/scripts/fork-diff.mjs --upstream <ghostKey> --client <clientKey> [--only <component>] Diffs a component's bindings between the Ghost file and the client fork, ranked by difference Refactor a component
node packages/token-parser/scripts/design-drift.mjs [--only <component>] [--state <file>] Has the client design moved since each extraction was cached? Refactor a component
node packages/token-parser/scripts/extract-figma-bindings.mjs / extract-colour-ways.mjs Writes a component's Token Studio bindings (or its colour-way variants) into its tokens/ folder Create a component
node packages/token-parser/scripts/export-figma-screenshots.mjs Exports a component's Figma reference PNGs Testing
node packages/token-parser/scripts/verify-against-figma.mjs / verify-bindings.mjs --components=a,b Checks a bridge and a component's bindings against the live file Refactor a component

Do not run pnpm --filter @v4/tokens-euro-league sync-tokens: Token Studio pushes the club's tokens.json straight to the repo, and the old sync source would revert the palette.

Model and Contentful

These read CONTENTFUL_SPACE_ID and CONTENTFUL_CMA_TOKEN from the root .env; --env is always explicit, and protected environments are refused outside CI.

Command What it does Explained in
node packages/model/scripts/migrate.mjs --env=<env> [--dry] [--until=<migration>] [--skip-apps] Applies pending migrations, then syncs the Contentful apps Change the content model
node packages/model/scripts/lint-migrations.mjs Ownership, numbering and contract-marker checks on every migration Change the content model
pnpm --filter @v4/model drift Re-vendors the schema, regenerates the types and the app codegen, and fails on any difference Change the content model
pnpm --filter @v4/model sync-schema / generate The two halves of that: introspect the schema; regenerate the types Code generation
pnpm --filter @v4/web generate (and @v4/content-app, @v4/video-app, @v4/basketball-app) Regenerates one package's query types; drift does the same and fails on a difference Code generation
pnpm --filter @v4/model seed -- --env=<env> [--only=content,video] [--dry] Creates and publishes the demo content, idempotently Change the content model
pnpm --filter @v4/model push-dictionary / sync-dictionary Seeds new dictionary keys in Contentful; pulls the labels into the generated snapshot Dictionary keys
pnpm --filter @v4/model sync-apps -- --env=<env> [--apply|--check] / lint-apps Installs and binds the Contentful apps (dry by default); lints the app registry Change the content model
pnpm --filter @v4/model sync-webhooks / sync-preview-urls (--env, --url) Points the space's webhooks and preview URLs at a site Caching and revalidation
node packages/model/scripts/add-locale.mjs --code=<locale> --name="…" [--env=<env>] Adds a locale to the space Localisation
node packages/model/scripts/import-articles.mjs --source=<file> [--map=<mapper>] Turns a foreign CMS export into article seed fixtures (writes nothing to Contentful) Change the content model
node packages/model/scripts/backfill-article-competition.mjs --env=<env> [--apply] Data script: sets each article's competition Staging
node packages/model/scripts/merge-players-into-profile.mjs --env=<env> [--apply] Data script: merges the player entries into their profiles Staging
node packages/model/scripts/migrate-text-tags.mjs --env=<env> [--apply] Data script: free-text tags to public tags Content models
pnpm --filter @v4/content-app check-addresses -- --env=<env> Checks the content addresses an environment's entries produce @v4/content-app
pnpm --filter @v4/competition-engine sync-spec / check-spec Re-vendors the Competition Engine's OpenAPI spec; reports whether it has moved @v4/competition-engine
pnpm --filter @v4/competition-engine generate / record-fixtures Regenerates the engine's API types; records live responses as typed mocks @v4/competition-engine

Composition and template updates

Command What it does Explained in
pnpm compose (-- --check in CI) Regenerates the route shims and the model composition from club.config.ts Template config
pnpm add-feature Adds a bought domain to the site Add a domain
pnpm sync-upstream Offers the template's changes to this repo as a pull request Take template updates

pnpm new-club is also in the root scripts because it came with the template: it is the command that cut this repo, and is not run here.

Tickets

pnpm --filter @v4/tickets <script>. Every board write is dry until --apply.

Script What it does Explained in
tickets-doctor Read-only: every ticket setting is set and working @v4/tickets
lint-tickets / lint-ac-voice / lint-cms-fields / drift Schema, criteria wording and CMS-field checks; the pre-push check @v4/tickets
verify-ticket -- --only=<slug> Plays a ticket back against the code, the model and Figma @v4/tickets
build-cms-model -- --from=contentful Rebuilds the content model the tickets are checked against @v4/tickets
push-jira -- [--epic=<slug>] [--only=<slugs>] [--apply] Pushes tickets to the board (--create, --design-only, --criteria-only, --links-only, --resync) @v4/tickets
match-figma <file-key> --write / sync-screenshots Repoints design links at the client's files; attaches screenshots for finished designs @v4/tickets
adopt-board / register-epics Records a hand-cloned board's keys; records the epics @v4/tickets
write-panels -- --key=<KEY> --proposal=<file> / mark-refined / ready-for-dev Writes approved panels to one issue; labels it refined; moves it to ready for development @v4/tickets
render-board <out.html> / list-epic A board preview; an epic's tickets @v4/tickets

Release

Command What it does Explained in
Actions → release → Run workflow (version) Releases a release branch: fast-forwards main, tags, publishes the GitHub Release, marks the Jira version released Releasing
node scripts/ci/release-jira.mjs build --ref=origin/release/<version> The release ticket report, dry (add --apply to write) Releasing
node --test scripts/ci/release-lib.test.mjs Tests the release script's helpers Releasing

Sweeps of a running site

Run against the app on :3000 (or the paths given).

Command What it does Explained in
node scripts/page-audit.mjs [path …] Text the colour of its background, zero-size components, broken images, overflow and console errors, at five widths; CONTRAST=1 adds every pair below AA Testing
node scripts/clip-sweep.mjs [path …] Content clipped out of reach (overflow: hidden with more inside) Testing
node scripts/rung-census.mjs [--list] How many components step at each breakpoint, per package (reads the code) Responsive rungs
node scripts/loadtest/eviction-storm.mjs A load test of mass cache eviction (see scripts/loadtest/README.md) Scale and performance

Claude skills

The /<skill> commands (/generate-from-figma, /preflight, /ticket-work and the rest) run inside Claude Code; they are listed, with what each runs, in the skills catalogue.