# Package source shape No Storybook — the component list comes from the package's shipped `.d.ts` exports. Previews are generated from the `.d.ts` prop types plus `cfg.previewArgs`. ## 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, the build may be at the repo root (`turbo build --filter=`, `pnpm -F build`, `nx build `). **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. If it returns files, read `_ds_bundle.js` via `DesignSync(get_file)` and note the component names from its first-line `/* @ds-bundle: {…} */` header — but **always still rebuild** (step 7); the existing bundle is stale the moment source changes. The header's `sourceHashes` diff decides what to *upload* incrementally via `DesignSync`, not what to build. 5. **Confirm the plan 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. - If the project already has N components (step 4), include that in the question and offer the scope: **(a)** full rebuild + re-upload everything, **(b)** update only the changed components (diff from `sourceHashes`), **(c)** tokens + CSS only (no component rebuild). Default to (b) when the diff is small. 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 `previewArgs`, `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` (or whatever `cfg.notes` points at) before anything else** — it holds repo-specific gotchas a prior sync recorded. | Field | Value | |---|---| | `pkg` / `globalName` | package name and the `window.*` global to assign — required | | `shape` | `'storybook'` or `'package'` — pins the source shape (overrides auto-detection). Written on first run. | | `buildCmd` | the discovered build command; re-sync re-runs it | | `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) | | `previewArgs` | `{Name: {prop: value, …}}` — props rendered as a `Preview` export in the auto-generated `.design-sync/previews/.tsx`. Use for simple flat props; for composed JSX children edit the `.tsx` directly. | | `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 | | `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 `