Skills and agents

The Claude tooling in this repo's .claude folder: the skills, agents, rules and references, what each does and how to run it.

2026-11-07Status: Live in .claude/
1

Overview

Everything under .claude/ is the Claude Code tooling for this repo: the skills you invoke as /<name>, the sub-agents the component pipeline runs, the rules Claude reads before editing a given kind of file, and the references and plans behind them. Most of it came with the template this repo was generated from and keeps arriving through /sync-upstream; the ELB-specific parts — the motion-spec digest, the ELB Figma inventories, the SSO references and the working plans — are this project's own.

It is built for one job above all: turning ELB's Figma files into typed vanilla-extract components, then keeping the content model, the tickets and the docs in step with the code. Generated token contracts are the source of truth throughout — no skill hand-writes a token value; changes route through tokens.json and the @v4/token-parser regeneration loop.

38skills in .claude/skills/ (35 in use here)
9agents (3 design-to-code + 6 quality gates)
14rules files
6reference folders (tokens, figma, model, motion, SSO, tickets)
1canonical token-mapping table

Layout

.claude/
├── mcp.json                  Figma MCP server (npx figma-developer-mcp, FIGMA_PAT in root .env)
├── manifest.json             machine-readable asset registry, Figma file keys, templateCommit (the template baseline)
├── rules/
│   ├── frontend/             component-architecture · vanilla-extract-conventions · theme-variant-patterns · fork-refactor · intermediate-rungs · motion
│   ├── testing/              test-conventions (.test.tsx, vitest)
│   ├── documentation/        storybook-conventions · ai-tooling-docs (this page's currency rule)
│   ├── model/                contentful-model (the @v4/model hard rules + field lessons) · contentful-apps (app registry → lint-apps → sync-apps → lock)
│   └── tickets/              acceptance-criteria · tickets-as-code · platform-and-client
├── reference/tokens/         token-reference.md — THE canonical Token Studio ↔ contract mapping
├── reference/motion/         elb-motion-spec.md — the digest of ELB's motion spec (patterns, tokens, decisions)
├── reference/figma/          ghost-core, ghost-content and ghost-basketball inventories and plans, the ELB – Web – Core chrome inventory, the ghost-video plan, the C9–C14 content briefs
├── reference/model/          contentful-model-plan.md — the @v4/model build plan + deployment contract
├── reference/SSO/            the Cortex SSO developer overview (PDF) and sso-mvp-plan.md — the plan @v4/cortex-sso was built from
├── reference/tickets/        tickets-plan.md — the @v4/tickets contract
├── plans/                    working plans and audits for in-flight campaigns (motion spec, basketball, video, news, analytics, …)
├── skills/                   38 skills (36 with frontmatter; add-feature and sync-upstream have none)
└── agents/                   design-to-code/ + quality-gates/ sub-agent definitions

.mcp.json (repo root)         the docs-MCP server, v4-docs (packages/docs-mcp)

One structural principle runs through it: one canonical body per concern. Where a skill and an agent cover the same ground (accessibility, test ids), the skill holds the content and the agent is a thin wrapper; the Token Studio ↔ contract mapping exists once, in reference/tokens/token-reference.md.

Ownership. .claude/skills, agents, rules and reference are template-owned paths: a /sync-upstream pull request patches them, so a local edit to a template file conflicts with the next update unless it is made in the template too. Files that exist only here (the ELB references) are left alone, and .claude/plans/ and manifest.json are never offered — they are this project's. See Take template updates.

2

Skills catalogue

.claude/skills/ holds thirty-eight skills, each invocable as /<name>. Thirty-five of them do work in this repo and are listed in three tables below: ten for building components and taking template updates, fifteen for the content model and the rest of the site, and ten for tickets. The other three arrive with the template's .claude/ but have no job here — see the note at the end.

Component and template-update skills

Skill What it does
generate-from-figma The flagship: generate a typed vanilla-extract component in @v4/ghost-core — or any sibling package with --package=<name> (default ghost-core) — from a Figma component set: token extraction, contract-first .theme.ts, tests, stories, quality gates, and a ≥90% visual-comparison loop (max 5 iterations). Seven phases with tiered orchestration (sequential-blocking → parallel sub-agents → main-context vision) and a hard "no more Figma calls" checkpoint. For ELB, point it at the ELB file, not Ghost — the forks preserve node ids (see /fork-status).
extract-figma-tokens Pull Token Studio bindings for a component from the Figma REST API into tokens/states/*.json + manifest — colour-set-aware, with the primary-variant rule that prevents 700-node bloat, and a new Phase 7 that diffs extracted tokens against the generated contract. Package-aware via --package=<name> (default ghost-core).
sync-figma-styles Refresh a component's theme wiring against Figma without hand-writing token values. Contract gaps route to tokens.json + regeneration; only structural styles and hand-authored (code-only) themes are edited directly. Keeps the 3-step approval flow.
review-against-figma Evidence-driven exhaustive audit of a built component against Figma — anti-sampling rules, recursive child review (30-component cap), severity model, three fix modes, and a refuse-to-auto-fix list that now includes generated files.
convert-css-modules-to-vanilla Convert an SCSS-module component from Stadion's previous (v3) platform into a typed vanilla-extract component, treating the SCSS as behavioural reference only — the visual truth is the Figma file. Ships with a legacy v3 CSS-variable lookup so old values can be traced to contract paths. Rarely needed here: the site's components are built from ELB's Figma with /generate-from-figma.
validate-registrations Audits the six registration points a component must keep in sync, including contract wiring: generated contracts with no consumer, and Token Studio namespaces unclaimed by code.
component-accessibility Static WCAG A/AA review of a component — semantic HTML, ARIA, keyboard and focus, screen-reader text, contrast structure, motion — with safe auto-fixes. Stable check IDs (A2.1–A8.2), widget ARIA patterns, live-region politeness rules.
add-test-ids Add data-testid via the PH_PREFIX constants model, with a type-check verification step.
add-feature Add a template domain this site does not have yet (it has content, video and basketball). Restores the domain's files from the template ref (the template's own domains.json says what the domain owns), its ownership-map block and composition entry, the apps/web deps + transpile wiring, then re-baselines the model and composes. Prints the Contentful-space migration + bespoke wiring as follow-ups.
sync-upstream Take template updates into this repo as a PR. Diffs templateCommit..template/<ref> over the template-owned paths (design system, tooling, model core/content + this site's domains, .claude), applies with git apply --3way onto a branch, records the new baseline, and (with --create-pr) opens the PR. Never touches what this project owns (club.config.ts, the club token package, migrations/club/, the ticket board config). See Take template updates.

Content model and site skills

Skill What it does
model-migration The ONE way content-model changes happen: scaffold the numbered migration, expand/contract lint, sandbox-apply on an ephemeral env clone, regenerate schema + types against it, curate fragments/transforms, commit as one change. The PR gate re-proves the pairing in CI.
model-review Review a model PR: expand/contract discipline, ledger integrity, fragment pruning, generated-artefact drift, protected-env safety.
model-bootstrap-club Stand up a Contentful space onto the model-as-code: baseline apply, ledger init, app installs, webhooks, locales and key scoping. Used once here, when the space 12gd2cvfgb6b replaced the trial space (9 Oct 2026); needed again only if the site moves to a new space. This project's own model changes go in migrations/club/, never in core/.
model-fragment Curate a fragment + transform for one surface: all-fields draft from the vendored schema.graphql, pruning review (every kept field must have a consumer), codegen validation, paired transform + test. Page queries stay in the app, spreading these fragments.
model-dictionary Manage localised copy keys: vocabulary lives in src/dictionary/keys.ts (reviewed), labels in Contentful. Add a key → seed the entry (push-dictionary) → regenerate typed locale maps (committed, not drift-gated). promote --from --to copies labels between environments — create+update for vocabulary keys, never touching anything else; protected targets refused outside CI. Proven live on a throwaway env clone.
model-locale Add a locale to the model via scripts/add-locale.mjs (CMA — contentful-migration doesn't manage locales), then regenerate schema + types + dictionary maps in one drift run and record the baseline. Surfaces the translation gap as an editorial task.
new-package Bootstrap a sibling @v4/ghost-* package by copying ghost-video, with every banked trap as a step: owner-keyed theme emission (OWN_THEMES + createPackageTheme), the global-surface namespace and club adapter, register-LAST, Storybook top-level group, e2e, the hardcoded package lists, and a fresh-Storybook proof before writing components. A package created here is this project's own (like @v4/ghost-basketball), not a template domain.
generate-token-contracts Drive @v4/token-parser to turn Token Studio tokens.json into the generated defaults and typed per-component contracts + icons, safely — surfacing the modify-extension traps (darken/lighten/alpha, hsl quantisation) that once collapsed every brand ramp. In this repo, never run the club token package's sync (pnpm --filter @v4/tokens-euro-league sync-tokens): it pulls stadionHQ/elb-web-tokens, which is older than the repo's copy, and silently reverts the ELB palette. Token Studio commits packages/tokens-euro-league/tokens.json straight to the repo; run that package's generate after each push.
new-route Scaffold a route in a domain route-package (content-app/video-app) as a per-route factory, wired through routes.json, codegen and the pnpm compose shims — the product surface that previously had no tooling.
content-type The content-type lifecycle — add, update or delete a Contentful content type end-to-end as an expand/contract-safe migration plus schema, generated types, fragments and transforms in one reviewed change. Extends model-migration for whole-type operations.
preflight Prepare a branch for PR: run verify + docs-drift, then enforce the cross-cutting "same-commit" obligations that are silent when forgotten — catalogue currency, the e2e↔token coupling, expand/contract markers, and explicit-path staging on a shared worktree.
fork-status Where a client Figma fork and this repo disagree, in one pass: which designs are FINISHED, which components are measuring the WRONG file (the fork preserves node ids, so a bridge naming upstream resolves perfectly while being built to a design the client is not using), and which finished designs have no component at all. Then CROSSES them — on ELB the 34 components "measuring the wrong design" and the 11 that were design-complete had an EMPTY intersection, so the loud backlog was not the queue.
write-e2e-test Author a Playwright component e2e (apps/e2e) that asserts resolved token values, per-instance overrides, RTL and per-rung breakpoints — encoding the ~15 hard-won harness traps (viewport-not-project, tabTo, aria-disabled, page.evaluate races, kebab story ids, cold-server timing). Promotes the e2e-test-generator agent to a directly invocable skill.
model-seed Populate a Contentful environment with a coherent DEMO site so the pages render end-to-end (a bootstrapped environment has the model but zero entries) — how develop got its demo content. Reviewed fixtures in packages/model/seed/<domain>/*.json, created + published in dependency order, idempotent, scoped to this site's domains, and guarded against protected envs like the migrate runner.
test-caching-revalidation Full-scale LIVE test of the caching stack against a deployed environment: the Next→Redis on-demand path (Contentful publish → webhook → /api/revalidate → revalidateTag, coarse + slug tags) AND the Cloudflare edge in front of it. Publishes a throwaway articlePage, asserts it reaches origin + edge, the article sitemap refreshes, a re-publish updates the OWN page, unpublish removes it — then deletes it. Also guards the frozen-cache class (a stale [object Object] body).

Ticket skills (tickets as code)

This repo works in Client mode: its board is ELB's own (ELBWEB), and once a ticket is on it, Jira is the source of truth — the .ticket.ts files in packages/tickets are the template's blueprint of each feature, not the live specification. The rules live in .claude/rules/tickets/ — platform-and-client.md first (which source each tool reads in this mode), then tickets-as-code.md and acceptance-criteria.md. Full detail: @v4/tickets.

Skill What it does
ticket-new Draft a ticket — or a linked set for a feature — as typed code in packages/tickets to the house standard, scoped to a real component, page or feature. Claude writes it; you approve it.
ticket-work Pick a ticket up by Jira key or code slug, read its built-in guidance, implement it on a ticket-ID branch running the skills it names, run the repo's gates, open a PR and update Jira. Jira-first here: without a Jira connection it stops rather than reading the .ticket.ts.
ticket-setup The entry point for the ticket tooling — run it before any other ticket-* skill on a new machine. Checks credentials, asks for the board, one Figma file per domain and the Contentful space, writes jira.defaultProject and figma.files on approval, then DETECTS whether the board needs a push or an adopt (and stops when the evidence is ambiguous). Ends with tickets-doctor.
ticket-review Review a ticket against the standard and, where Jira is connected, report drift between the code ticket and its issue. Here Jira is authoritative: drift means the board has moved on from the blueprint, not that the board is wrong.
ticket-push ONE-WAY push to the ELBWEB board: create-only (--create, one epic at a time), records the returned keys, wires blocker and Relates links. Jira is the source of truth once a ticket lands there, and a resync refuses any ticket whose description someone edited in Jira.
ticket-design Match a client Figma file's pages and components to tickets and populate their design links. Screenshots only once the design is final — which design-status.mjs is how you check.
ticket-board Render the current ticket set to a shareable board preview, grouped by epic in the house layout, and publish it for sign-off — the quick “show me the board” command.
ticket-status Pull the live Jira status of the set into a standup view (read-only): status, assignee, blockers, and what is done, in progress or blocked, grouped by epic.
ticket-update Brings ONE Jira ticket to ready-for-development: reads it against the client’s Figma and Contentful, works out what the client has customised against the component code, attaches the screenshot, and proposes rewrites to CMS, TECH, acceptance criteria and the Claude guidance for approval.
ticket-update-epic /ticket-update for a whole epic: lists the epic's tickets FROM JIRA (list-epic; locked tickets named and skipped, a repo ticket not on the board reported, never drafted), drafts each ticket's panels as the client's specification from the live description, the code, the client's Figma and Contentful, asks its questions in batches, and only after approval writes through write-panels, syncs the screenshots, and labels each written ticket refined-for-client. Never rewrites a .ticket.ts, never resyncs or creates.
Present but not used here

Three skills come with the template's .claude/ and do nothing in this repo: new-club cuts a new client repo from the template (it is how this one was made), new-contentful-app scaffolds into apps/contentful, which lives only in the template — the Contentful apps installed in this space are built there and installed here by sync-apps — and ticket-resolve works on the template's own board and refuses to run here.

3

Agents, rules & references

Sub-agents

Agents are the parallel workers generate-from-figma orchestrates. Design-to-code agents build; quality gates verify. Every agent takes the owning package (--package on the skill, default ghost-core) and resolves its paths, --filter, registrations and story/e2e folders from it.

Agent Role
design-to-code/figma-parser Node-map and variant-axis classification, wrapper-frame detection, and master-node resolution — an instance shows one variant, the master carries all of them.
design-to-code/component-scaffolder Owns the scaffold and every component file template (.component.tsx, .css.ts, contract-first .theme.ts, .types.ts, .test.tsx, stories, MDX docs), so the generation detail lives here rather than in the skill.
design-to-code/prop-inference Detection rules (repeated INSTANCE → typed array; Selected=Yes/No → boolean; 3+-state axis → CSS-only) plus accessibility-requirement inference; writes props-inference.json and confirms before generation.
quality-gates/code-quality-gate Tier-1 early-bail static checks (including the ph prefix, never gam, and no hand-edited generated content) then lint/type phases; one-line output contract.
quality-gates/visual-regression-check Static story validation, then the iterative capture/compare/fix loop (≥90%, max 5). Wrong values traced to a generated contract are flagged upstream, never hand-edited. CI-grade regression stays with Chromatic.
quality-gates/accessibility-review, add-test-ids Thin wrappers over their canonical skills, so each checklist exists in one place.
quality-gates/e2e-test-generator Phase 2.9 (Tier 3): generates apps/e2e/tests/{package}/{name}.e2e.ts (specs are foldered by owning package) — computed token resolution against manifest values, per-instance overrides, interaction states, RTL and both breakpoint projects.
quality-gates/extract-to-utils Shared-code extraction with target homes in the @v4/ghost-core theme/utils layer, the owning package's own src/utils, or a planned packages/core (there is no @v4/theme); a component family sharing 3+ artefacts triggers a family-refactor suggestion.

Rules

  • frontend/component-architecture.md — per-file responsibilities, flat component dirs, the six registration points, contract-first theming with a code-only fallback, and the "naming convention is the API" rule (Figma namespace ↔ component name ↔ --ph__* vars).
  • frontend/vanilla-extract-conventions.md — style() vs recipe() vs globalStyle(), the what-goes-where table (.theme.ts = colours/spacing/radius; .css.ts = layout/states/breakpoints), motion utilities with automatic reduced-motion, and performance rules.
  • frontend/theme-variant-patterns.md — colour sets are the theming axis, never an onDark prop; the five override levels, owner-keyed theme emission, and how the app emits the ELB theme in parts.
  • frontend/fork-refactor.md — the playbook for how this project's design works: ELB's Figma files are COPIES of the Ghost files, modified heavily in place, and we refactor the code to match. The fork PRESERVES node ids, so a bridge naming the upstream file resolves perfectly while measuring the wrong design — four of four components audited on ELB were built to upstream. Covers the preserved-id trap, why a coverage percentage means "matches whichever file the extraction came from", hollow client masters, bindings that contradict their own render, and the ordered sequence that actually works.
  • frontend/intermediate-rungs.md — the two bands the design does not draw (tablet 768–1023, laptop 1024–1439): a band binds the page measure (min(100% − 2 × gutter, ContainerWidth.XL)) on its outermost container, families declare an md step from the M grid, the header hands off at 1440 by design, and the rungs stay measured (census script, audit defaults, Playwright tablet / laptop).
  • frontend/motion.md — what moves and how much, from ELB's design-owned motion spec (v0.3, 27 Oct 2026; digest at reference/motion/elb-motion-spec.md): every animation names its spec pattern (P-CASCADE, P-REORDER…), values come from the motion.* tokens and never literals, reduced motion gets the complete page instantly, entrances play once per visit, ads and logos never animate, the animation budget is measured, and each pattern is tested in both directions.
  • testing/test-conventions.md — .test.tsx, vitest, required coverage list, colour-set render cases, --ph__* token-override assertions.
  • documentation/storybook-conventions.md — stories live in apps/storybook, category map, the required AllColourSets story, and the figma.mdx / accessibility.mdx companion-doc specs.
  • documentation/ai-tooling-docs.md — this catalogue stays current: any commit that adds, removes or repurposes a skill, agent, rules file or reference updates these pages (and CLAUDE.md's skill list) in the same commit.
  • model/contentful-model.md — the model-as-code spine: domain-sliced migrations with ownership lint, expand/contract discipline, the vendored-schema drift gate, fragment curation rules and the dictionary-key flow.
  • model/contentful-apps.md — the Contentful apps installed in the space. Their source is built and released in the template; what this repo has is the registry, the lock and the sync. Declared only in packages/model/apps/registry.json, checked by lint-apps, installed and bound by sync-apps (which migrate.mjs runs after the migrations) and recorded in the generated apps.lock.json. Migrations bind an app by slug, never by definition id; each app has a develop and a production release channel that follows the environment.
  • tickets/tickets-as-code.md — tickets are authored as typed TS in packages/tickets and pushed ONE-WAY to Jira: the spine, the board bindings, and the hard rules (derived titles and labels, one Figma feature frame per ticket, the resync fingerprint that refuses a ticket someone edited in Jira).
  • tickets/acceptance-criteria.md — the single source for what an acceptance criterion says and how it is worded: written for a QA tester or an editor, purely functional, no developer vocabulary, and every content type and field named as Contentful shows it. lint-ac-voice and lint-cms-fields enforce it.
  • tickets/platform-and-client.md — this repo is in Client mode: the ELBWEB board, the Contentful space and ELB's own Figma files are authoritative, not the repo. Read before changing where any ticket tool reads facts from: a tool that silently assumes the repo is authoritative passes every gate and is wrong on the board.

Reference

reference/tokens/token-reference.md is the single canonical Token Studio ↔ contract-path mapping. Every skill points here instead of embedding its own table. Where it and the generated packages/tokens/src/__generated__/tokens.ts disagree, the generated file wins.

The other references:

  • reference/motion/elb-motion-spec.md — the digest of ELB's motion spec: every pattern, value and open decision, with a "code today" column.
  • reference/figma/ — the component inventories and build plans (ghost-core, ghost-content, ghost-basketball, the ELB – Web – Core chrome inventory, the ghost-video plan) and the ghost-content batch briefs. Read the ghost-core and ghost-content inventories with the fork rule in mind: they record Ghost node ids, which resolve in ELB's files too.
  • reference/model/contentful-model-plan.md — the @v4/model build plan and the deployment contract.
  • reference/SSO/ — the Cortex SSO developer overview and the MVP plan @v4/cortex-sso was built from.
  • reference/tickets/tickets-plan.md — the full @v4/tickets contract behind the ticket rules.

Working plans for in-flight campaigns live beside these in .claude/plans/; they are records of a piece of work rather than standing rules.

4

How the pieces fit together

Several skills, agents and rules cover neighbouring ground. These are the boundaries, so you reach for the right one and do not expect two of them to do the same job.

One canonical body per concern

  • Accessibility. /component-accessibility holds the checklist (stable check ids, the widget ARIA table, live-region politeness rules). The quality-gates/accessibility-review agent is a thin wrapper over it.
  • Test ids. Likewise /add-test-ids and its agent.
  • Token mapping. The Token Studio ↔ contract table exists once, in reference/tokens/token-reference.md; where it disagrees with the generated packages/tokens/src/__generated__/tokens.ts, the generated file wins.
  • Generation detail. /generate-from-figma is the seven-phase orchestration; the Figma parsing lives in the figma-parser agent and the file templates in the component-scaffolder agent, which its first phases run.

Reviewing a component against Figma: which skill

  • /review-against-figma — the exhaustive audit-and-fix: every token, spacing, typography, colour and child component, recursively. Colour gaps it finds are routed back to the token pipeline.
  • /sync-figma-styles — the targeted refresh of theme wiring and structural styles. It ignores colours and routes contract gaps to tokens.json.
  • /fork-status — run first, before either: it says which ELB designs are finished and which components are bridged to the wrong file. Reviewing a component against a design that is still moving, or against Ghost instead of ELB, is the expensive mistake (.claude/rules/frontend/fork-refactor.md).

House terms the tooling assumes

Every skill uses the same vocabulary: colour set (code key colourSet1, never "color set" or "colourTheme"), the ph CSS-variable prefix (never gam), @v4/ghost-core for the theme helpers (there is no separate @v4/theme package), the six registration points a component must keep in sync, and compoundVariants over contract paths for the colour-set × state matrix. A skill that says otherwise is out of date — raise it rather than following it.

Frontmatter

36 of the 38 skills carry YAML frontmatter, with names matching their directories; add-feature and sync-upstream have none, so Claude Code lists them without a description, but they run as /add-feature and /sync-upstream all the same.

5

Gaps: what the tooling does not cover yet

Work this project does by hand today because no skill covers it. New skills arrive from the template through /sync-upstream, so a gap that applies beyond this site is best raised there.

Gap Status What it would do
performance-review Open A Tier-2 quality gate for re-renders, CSS output size and bundle hygiene. Today the performance work (the club theme emitted in parts, the global layer on :root) is found by Lighthouse runs and done by hand.
Motion patterns Open No skill builds or tests a motion pattern; .claude/rules/frontend/motion.md and the spec digest are followed by hand, and the developer pack (motion tokens) has not arrived yet.

Using the tooling today

Everything listed in the catalogue is live in this repo. The Figma MCP server (.claude/mcp.json) and the Figma-dependent skills need FIGMA_PAT in the root .env; the ticket skills need JIRA_EMAIL and JIRA_API_TOKEN there too. Skills invoke as /generate-from-figma, /review-against-figma, and so on; how to run each one, with or without Claude, is on the next page.

6

Running a skill: manually vs /skill

Every skill under .claude/skills/ can be run two ways, and they read from the same source. /<name> in Claude Code loads that skill's SKILL.md and Claude executes it. Running it manually means following the same SKILL.md yourself — and for a large share of the skills a deterministic pnpm/node command IS the heart of the procedure, so the "manual path" is just invoking that command with the right arguments.

So the useful question is not "which skills have a manual path" (all of them do — the SKILL.md) but "does a single command do the real work, or is the work judgment?". That splits the thirty-five skills used here cleanly in two: twenty script-backed, fifteen orchestrated by Claude. (The three template-only skills — new-club, new-contentful-app, ticket-resolve — are left out; see the catalogue.)

Script-backed skills — a command is the deterministic core

Here a pnpm/node entrypoint does the mutating work. The skill wraps it with an interview (collect the arguments), a sandbox step (an ephemeral Contentful clone for the model skills), and verification (drift/regen/tests) — but you can drive the command directly when you already know the arguments, and CI does exactly that. Run the skill for the guided flow; run the command when you want just the one step.

Skill Deterministic entrypoint (the manual path) What the skill adds around it
new-package pnpm --filter @v4/<name> build && … check-types && … test Scaffolds the package skeleton (package.json, tsconfig, exports) before the build/verify.
new-route pnpm compose Authors the route factory in the domain's route package, then regenerates the app shims.
add-feature pnpm add-feature -- --domain=<name> [--ref=main] Restores a template domain this site does not have yet from the template ref, re-baselines the model and composes; prints the Contentful-space migration + bespoke wiring follow-ups.
sync-upstream pnpm sync-upstream -- [--ref=main] [--create-pr] Diffs this repo's templateCommit against the template ref over the template-owned paths, 3-way applies to a branch, and opens a PR for review.
model-migration node packages/model/scripts/lint-migrations.mjs → node packages/model/scripts/migrate.mjs --env=<clone> Scopes the change, scaffolds the numbered .cjs, applies on an ephemeral clone, regenerates and curates fragments/transforms as one change.
content-type node packages/model/scripts/migrate.mjs --env=model-dev-<topic> The model-migration flow specialised to creating a whole content type.
model-fragment edit src/<domain>/fragments/*.graphql → pnpm --filter @v4/model generate Picks the fields the surface consumes (prune, never select-all); codegen validates them against the vendored schema.
model-review pnpm --filter @v4/model drift Reads the schema+regen diff and reports what a model PR would change.
model-seed pnpm --filter @v4/model seed -- --env=develop [--only=…] [--dry] Authors/curates the demo fixtures under seed/<domain>/ before the idempotent, domain-scoped push.
model-locale node packages/model/scripts/add-locale.mjs --code=… --name="…" Adds the locale (contentful-migration cannot) and covers the fragment/dictionary follow-ups.
model-dictionary edit src/dictionary/keys.ts → pnpm --filter @v4/model push-dictionary / sync-dictionary Adds the reviewed key + default copy, seeds the entry (never overwrites editors' labels), pulls the generated locale files.
model-bootstrap-club node packages/model/scripts/migrate.mjs --env=<env> (full core sequence) Applies the composed baselines to a new space plus locales, webhooks and per-env delivery keys. Done once for this project's space.
generate-token-contracts pnpm --filter @v4/tokens-euro-league generate (and pnpm --filter @v4/tokens generate for the Ghost defaults) Regenerates the typed contracts and reviews the diff for the modify traps. In this repo Token Studio commits the club's tokens.json directly, so skip the skill's sync-tokens step: the club package's sync reverts the ELB palette.
preflight node scripts/verify.mjs (= pnpm verify) and node scripts/hooks/docs-drift.mjs The machine gates are only the first half: the skill then walks the same-commit checklist (catalogue currency, e2e ↔ token coupling, expand/contract markers…) — obligations no command checks, which are judgment.
fork-status node packages/token-parser/scripts/design-status.mjs --file <clientFileKey> [--ready] [--unbuilt] and node packages/token-parser/scripts/fork-diff.mjs --upstream <ghostKey> --client <clientKey> Runs both and crosses them: which components' designs are finished, which measure the wrong file, and which finished designs have no component.
test-caching-revalidation node .claude/skills/test-caching-revalidation/run.mjs [--read-only] [--json] Checks the prerequisites (a deployed environment, the webhook secret, origin and edge URLs) and reads the result against the caching test plan.
ticket-setup pnpm --filter @v4/tickets tickets-doctor (then adopt-board / register-epics) Writes the board, Figma files and Contentful settings, and decides push vs adopt.
ticket-push pnpm --filter @v4/tickets push-jira -- --epic=<slug> [--create] [--apply --verify] Refreshes the model and Figma links first (build-cms-model, match-figma), pushes one epic at a time, then registers epics and syncs screenshots.
ticket-design pnpm --filter @v4/tickets match-figma <file-key> [--write] / sync-screenshots [--apply] Matches the client file's frames to tickets; screenshots only for finished designs.
ticket-board pnpm --filter @v4/tickets render-board <out.html> Publishes the rendered board as an artifact for sign-off.

Claude-orchestrated skills — the work is judgment, not a command

These have no single mutating command: the work is gathering evidence (from the Figma REST API, or across the codebase) and making calls a script cannot — which token a node binds, whether a discrepancy is a bug or a cleanup, which WAI-ARIA pattern applies. The SKILL.md is the manual procedure, step by step. The command listed is only the verification or build step you run after the judgment work — never a substitute for it.

Skill Manual procedure Verification / build step
generate-from-figma The 7-phase pipeline in its SKILL.md: extract → contract-first theme → component/tests/stories → quality gates → ≥90% visual loop. Targets packages/<package> with --package=<name> (default ghost-core). pnpm --filter @v4/tokens sync-icons (icons), then the package build/tests.
extract-figma-tokens Walk the Figma node subtree via the REST API into tokens/states/*.json + manifest (primary-variant rule). pnpm --filter @v4/tokens build
sync-figma-styles Diff a component against Figma; route contract gaps to tokens.json + regeneration; edit only structural / code-only themes. pnpm --filter @v4/tokens build
review-against-figma Evidence-driven exhaustive diff against the REST API — anti-sampling, recursive child review, severity model, three fix modes. pnpm check-types
convert-css-modules-to-vanilla Port an SCSS-module component from Stadion's previous (v3) platform to vanilla-extract, tracing legacy variables to contract paths. Rarely needed here. pnpm --filter @v4/ghost-core check-types
add-test-ids Add the TEST_ID entry to constants.ts and wire data-testid through the component (BEM child derivation). pnpm check-types
component-accessibility Audit semantics/ARIA/keyboard/contrast against the actual component files; write the .accessibility.mdx. Story a11y gate (a11y: { test: "error" }).
validate-registrations Audit the six registration points (barrel, theme registry, init.css, figma.json, stories, token contract) for drift. pnpm --filter @v4/ghost-core build
write-e2e-test Author apps/e2e/tests/<package>/<name>.e2e.ts encoding the harness traps (viewport-not-project, tabTo, kebab story ids, per-rung breakpoints). pnpm --filter @v4/e2e test
ticket-new, ticket-review Draft or review a .ticket.ts against the acceptance-criteria and tickets-as-code rules (and, for review, against its Jira issue). pnpm --filter @v4/tickets lint-tickets; verify-ticket -- --only=<slug>
ticket-update, ticket-update-epic Read the Jira ticket with the client's Figma, Contentful and the code; propose panel rewrites for approval. Never rewrites a .ticket.ts. pnpm --filter @v4/tickets write-panels -- --key=<KEY> --proposal=<file> [--apply]
ticket-work Read the Jira ticket (Jira-first; it stops without a Jira connection here), build it on a ticket-ID branch, run the skills it names, open a PR. pnpm verify
ticket-status Read-only standup view of the board's live statuses, grouped by epic. —

Rule of thumb

Reach for the command when you already know the single step you need — a fragment regen, a drift check, a compose — or when you're in CI. Reach for the skill when you want the guided flow (interview, ephemeral sandbox, regen + tests as one reviewed change) or when the work is judgment the command can't make for you. Either way the SKILL.md is the definition of record — this page just says which half of it does the work.