# Storybook source shape Storybook is the **fidelity oracle, not the runtime**. The converter bundles the package's compiled `dist/` into `_ds_bundle.js` — the same bundle the claude.ai/design agent builds with — and generates each preview by **compiling the story source module itself** (hooks, fixtures, local helpers — the whole closure comes along), with every component import resolved to that shipped bundle (`lib/story-imports.mjs` redirects package *and* relative component imports to `window.`). The repo's own storybook render is the ground truth those previews must match: a compare harness screenshots each story in the reference storybook and the matching preview render side by side, and you iterate until they match. Nothing from storybook-static is uploaded, and no story code is ever evaluated at build time — stories run only in the browser, against the real artifact. Requires React 18+. Playwright + chromium are **required** for this shape (the compare loop is the verification), not optional. **First sync or re-sync?** A re-sync is marked by a config whose `projectId` and `pkg` were both in place before this run started — most of this document then doesn't apply; go to §7, where one driver run routes the work and untouched components cost nothing. Everything else takes the full flow (§2 build → §3 self-heal → §4 match → §6 upload), where every component gets verified and graded once — that includes a partial config left by an aborted run, and a pin this run itself just recorded in the base skill's §1. (Only the old `design-sync.config.json` present? Move it first and commit: `mkdir -p .design-sync && mv -n design-sync.config.json .design-sync/config.json`, then apply the same test.) ## 2. Build, then run the converter 1. **Build the DS package *and its workspace dependencies*.** The converter bundles `dist/` into `window.`. Run ` run build`; in a monorepo use `turbo run build --filter=` or `pnpm -F "..." build` (the trailing `...` is required — bare `-F ` skips dependencies and you'll see `Cannot find module '@scope/tokens'`). If `package.json` `module`/`exports['.']` points at TS source, find the actual built entry and pass it via `--entry`. **Do this before step 2** — storybook often imports sibling packages from their built `dist/`. 2. **Build the reference storybook ONCE into `.design-sync/sb-reference/`** — NOT under `ds-bundle/` (the converter wipes `--out` on every rebuild, and storybook builds take minutes; the reference must survive the fix loop): ```bash npx storybook build -c -o .design-sync/sb-reference ``` Run it from the directory whose `package.json` has the storybook devDependencies — usually the one containing `.storybook/`; monorepos often have several storybooks, so pick the one covering the package you're syncing. **Make `-o` the repo-root path** (e.g. `-o "$(git rev-parse --show-toplevel)/.design-sync/sb-reference"`): the converter and compare resolve `.design-sync/` from the repo root, so a cwd-relative `-o` in a subpackage puts the reference where nothing will find it. Use `npx storybook build` directly, **not** the repo's `npm run build-storybook` script (wrong output dir). Then check `.design-sync/sb-reference/iframe.html` exists and is >10KB — `index.json` alone can exist with a failed build. Long builds: background them **through your shell tool's background mode only** and wait for the completion notification. Never a bare `&` (untracked — the notification never comes), and never a `pgrep -f '