# Package source shape No Storybook — the component list comes from the package's shipped `.d.ts` exports, and there is **no reference render to verify against**. Preview quality therefore comes from two layers: the converter ships every component fully functional (bundle + `.d.ts` + `.prompt.md`) with an honest **floor card**, and rich previews are **authored** — by you, from the repo's own usage examples — for the components the user scopes in (§4). Authored previews are graded on an absolute rubric (§4.3) and reviewed by the user (§4.4); the floor card is never a failure, just an unauthored component. ## 2. Explore, then write config (continued) 3. The converter needs the built `dist/` entry + its `.d.ts` tree. Check whether the entry (from `package.json` `module`/`main`/`exports['.']`) already exists — install may have built it via `prepare`. If missing: - Run ` run build`. No `build` script → try `prepare`/`prepack`. In a monorepo, build the package *and its workspace dependencies* from the repo root: `turbo build --filter=` or `pnpm -F "..." build` (the trailing `...` is required — bare `-F ` skips dependencies and you'll see `Cannot find module '@scope/tokens'`). **Some build scripts fork a watcher and exit 0 early — after the command returns, `ls` the expected output (dist/, build/esm/, or whatever `package.json` `module`/`main` points at) and confirm it's populated before continuing.** If it's empty, check for a `--watch` flag in the script and use the one-shot variant, or poll the output dir. - Still missing → `AskUserQuestion`("What command builds this package?", options = any `scripts.*` containing `tsc|tsup|rollup|vite build|esbuild|swc`, plus freeform). Record the answer as `buildCmd` in the config. - User says there's no build → the converter will synthesize an entry from `src/` (last resort — `.d.ts` contracts will be weaker; recommend adding a build). 4. **Check what's already in the project.** `DesignSync(list_files)` on the target (the base skill §1 already picked the upload path: pinned-at-run-start → atomic; otherwise empty → incremental, non-empty → atomic). If it has files, fetch the small verification anchor: `DesignSync(get_file, path: "_ds_sync.json")` and save it locally (`.design-sync/.cache/remote-sync.json`) — never download `_ds_bundle.js` for this. The driver run (the "Re-syncs are one command" block, `--remote` pointing at the saved anchor) diffs it into `.sync-diff.json` with TWO partitions answering different questions. **Verification** (`unchanged`/`changed`/`added`): which components need capture + grading — `unchanged` were verified at the last upload and skip §4 entirely. **Upload** (`upload.components`/`upload.deletePaths`/`upload.bundle`/`upload.styling`): which files the project is missing — sourceHashes-based, so `.d.ts`/`.prompt.md`-only edits, regroups (old paths land in `deletePaths`), and bundle-only changes still ship even when no render changed. Never scope uploads by the verification partition. No sidecar in the project (never synced, or shape change) → no anchor → full first-sync scope; if `list_files` showed the project NON-empty, deletes can't be derived — review its file list once for files this build doesn't produce; those reviewed paths go into the upload plan's `deletes` at §5. 5. **Confirm the plan AND the preview scope with the user before building.** `AskUserQuestion` with: the component list you found (or a count + a few names if it's long), which files the tokens/CSS are coming from, and which build command you'll run. The build can take minutes and burn tokens — aligning now avoids re-running because it was pointed at the wrong package or missed half the components. - **Preview scope** (this shape's cost slider — all N components import fully functional either way; this only decides which get authored preview cards): **(a)** author rich previews for the core components — the user picks them, or you propose ~20–40 from docs prominence; **(b)** author everything (significantly longer — state the estimate from N × a few minutes each); **(c)** floor cards everywhere for now (fastest; previews can be authored incrementally on any later re-sync — authored files and grades carry forward). - If the project already has components from a prior sync (step 4), also offer: full re-verify + re-upload (`--force`-equivalent) or changed-components-only (the verdict's worklist; default). The precise partition exists only after the driver runs — state it then ("N verified-by-upload, M to verify: [names]") before starting §4 work, and check in with the user if it's surprisingly large. 6. **Write `.design-sync/config.json` and commit it** — re-sync reuses it so output is reproducible. Only `pkg` and `globalName` are required. **If the file already exists, read it first and preserve `dtsPropsFor`, `libOverrides`, and `overrides` — only add to those fields, never replace them.** They accumulate fixes from prior verify-loop iterations. **Also Read `.design-sync/NOTES.md` before anything else** — it holds repo-specific gotchas a prior sync recorded. | Field | Value | |---|---| | `pkg` / `globalName` | package name (required) and the `window.*` global to assign (auto-derived from `pkg` when omitted) | | `projectId` | the claude.ai/design project this repo syncs to — recorded automatically in §1, the moment the target is settled (the atomic upload's post-verify record is a backstop); re-syncs fetch their verification anchor (`_ds_sync.json`) from it without asking | | `shape` | `'storybook'` or `'package'` — pins the source shape (overrides auto-detection). Written on first run. | | `buildCmd` | the discovered build command — tells Claude what to re-run before the converter on re-sync | | `srcDir` | source root when not `src/`/`lib/`/`components/` | | `tsconfig` | path to `tsconfig.json` — esbuild reads `compilerOptions.paths` so `@/…` path aliases resolve in synth-entry mode | | `extraEntries` | package names to merge into `window.` alongside the DS entry (e.g. the DS's separate icon package). Sibling icon packages under the same scope are auto-detected (`[ICON_PKG]`). | | `componentSrcMap` | **sparse** `{Name: path}` — non-null pins/adds a component's src path; `null` excludes a `.d.ts`-exported internal | | `dtsPropsFor` | `{Name: "prop?: Type; …"}` — hand-written `Props` body when auto-extraction fails (complex generics, cross-package types) | | `cssEntry` / `tokensPkg` / `tokensGlob` | stylesheet + token files | | `docsDir` | directory (package-relative; may point outside, e.g. `../../apps/docs`) holding per-component `.md`/`.mdx` docs. Auto-detected as `docs/` or `documentation/` under the package. | | `docsMap` | sparse `{Name: path \| null}` — explicit doc path per component (overrides discovery); `null` excludes. **Exceptions only, never an enumeration**: set `docsDir` and let discovery bind docs; add entries only for misses, exclusions, regroup stubs, or `[DOCS_AMBIGUOUS]` pins. A map that names every component duplicates what discovery already does and rots on every component add. | | `guidelinesGlob` | string or string[] (package-relative) of design-guideline `.md` files to copy into `guidelines/`. Default `['docs/guides/**/*.md', 'docs/*.md', 'guides/**/*.md']`. | | `extraFonts` | paths (package-relative; may point outside the package, e.g. a sibling typography package) to `@font-face` `.css` files or bare `.woff2`/`.ttf`/`.otf` for brand families the DS expects its host app to provide. CSS entries are parsed and their local font files copied to `fonts/`; bare font files are copied as-is. Use when validate prints `[FONT_MISSING]`. | | `runtimeFontPrefixes` | string[] — family-name prefixes for fonts the host app serves at runtime from a font service (via a `