Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions .design-sync/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ restage by hand (or copy from main) in those worktrees.
with **tsup** → `packages/ui/dist/{index.js,index.d.ts,uploads-ui.css}`.
- `cfg.buildCmd` = `pnpm --filter @uploads/ui build`. That needs the package's
devDeps installed. In an isolated worktree with no workspace install, build it
standalone: `cd packages/ui && npm install --no-save --no-package-lock && npx tsup`
standalone: `cd packages/ui && npm install --no-save --no-package-lock && npm run build`
(npm avoids pnpm workspace resolution; approve the esbuild postinstall).
**Use `npm run build`, not `npx tsup`.** `tsup.config.ts` sets `dts: false`, so
tsup alone emits only `index.js` + `uploads-ui.css`; the 12 `.d.ts` files come
from the second half of the build script (`tsc -p tsconfig.build.json
--emitDeclarationOnly --outDir dist`). Skip it and every `<Name>Props` contract
the design agent codes against degrades silently.
- Converter invocation (from repo root):
`node .ds-sync/package-build.mjs --config .design-sync/config.json --node-modules packages/ui/node_modules --entry ./packages/ui/dist/index.js --out ./ds-bundle`
`PKG_DIR` is walked up from `--entry`, so the entry must be the real
Expand Down Expand Up @@ -88,19 +93,36 @@ restage by hand (or copy from main) in those worktrees.
- Playwright + chromium live under `.ds-sync/node_modules` (see restage above —
install with the other converter deps in one `npm i`). On a fresh clone the
`.ds-sync/` tree is gitignored and regenerated, so reinstall before validating.
- 5 components use `cfg.overrides.<Name>.cardMode = "column"` (Button, Divider,
Field, GalleryTile, Panel) to resolve `[GRID_OVERFLOW]` — their previews are wider
than a grid cell. Not a warn once the override is applied.
- 7 components use `cfg.overrides.<Name>.cardMode = "column"` (Button, Divider,
Field, GalleryTile, Panel, Progress, Select) to resolve `[GRID_OVERFLOW]` — their
previews are wider than a grid cell. Not a warn once the override is applied.
- **Progress and Select were added to that list on the 2026-08-14 re-sync.** The
2026-08-14 sync recorded them as fitting the default card width; a later converter
measures grid cells differently and flagged both `[GRID_OVERFLOW]` (`wide`). If a
future converter flags more components the same way, the remedy is the same one
the warn names — merge `cardMode: "column"`, then
`preview-rebuild.mjs --components <them>`; grades carry through it.
- No `[RENDER_THIN]` / `variants-identical` warns to record — all cells graded good.
- **Progress** and **Select** were added to `@uploads/ui` and authored on the
2026-08-14 sync (`previews/Progress.tsx`, `previews/Select.tsx`) — 3 cells each,
all graded good, no grid override needed (default card width fits). Select is a
all graded good (both later needed `cardMode: "column"`, see above). Select is a
new export from `Field.tsx` (`ul-select` / compact `ul-select--sm`); Progress is
its own file (`ul-progress__*`, `data-level` fill bands). Both added to
`conventions.md`. That brought the DS from 12 → 14 components.

## Re-sync risks

- **Sync from an up-to-date `main`, and check before uploading.** A sync uploads
whatever the working tree builds, so a stale base silently *reverts* merged
design-system fixes in the Claude Design project — the anchor diff can't catch
it, because the bundle genuinely changed and looks like a legitimate update.
This bit us on 2026-08-14: a worktree branched at #663 re-synced ~1h after #664
merged and re-uploaded the pre-#664 stylesheet, restoring the exact
`--ul-progress-fill` declaration #664 removed. The design agent kept reporting
the finding and was correct. **Run `git fetch && git log --oneline -3
origin/main` before the build**, and after building grep the bundle for
whatever the most recent DS fix removed
(`grep -c 'ul-progress-fill' ds-bundle/_ds_bundle.css` → expect 0).
- **Harness is not in git** — if `.ds-sync/` is missing, restage before build/
validate (see "Converter harness" above). Worktrees only inherit it when main
already has a staged copy.
Expand All @@ -110,6 +132,12 @@ restage by hand (or copy from main) in those worktrees.
- `.design-sync/conventions.md` enumerates real tokens/props/components validated
against the build. If `packages/ui` renames a token or component, re-validate the
header (the base skill's conventions step does this) and fix drift.
**Drift is usually additive, not renames** — the 2026-08-14 re-sync found
`Button.variant` had gained `"solid"` (a real variant with its own
`ul-btn--solid` CSS) while the header still listed only four. Nothing the header
named was wrong, so a name-existence check alone passes; also diff each
enumerated union against the fresh `<Name>.d.ts` for *added* members, or the
design agent never learns the new option exists.
- The scoped `npm install` in `packages/ui` writes no lockfile (`--no-package-lock`),
so the exact tsup/esbuild versions aren't pinned there — the committed
`package.json` ranges are the source of truth. A real `pnpm install` at repo root
Expand Down
4 changes: 3 additions & 1 deletion .design-sync/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"Divider": { "cardMode": "column" },
"Field": { "cardMode": "column" },
"GalleryTile": { "cardMode": "column" },
"Panel": { "cardMode": "column" }
"Panel": { "cardMode": "column" },
"Progress": { "cardMode": "column" },
"Select": { "cardMode": "column" }
}
}
4 changes: 3 additions & 1 deletion .design-sync/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ Build every screen inside one.
There is **no utility-class vocabulary to author**. Style two ways only:

1. **Component props** carry the design language:
- `Button` — `variant` (`default | primary | ghost | danger`), `size` (`sm | md | lg`), `block`
- `Button` — `variant` (`default | primary | solid | ghost | danger`; `solid`
fills with the accent — at most one per surface), `size` (`sm | md | lg`),
`block`, `icon`
- `Callout` — `tone` (`info | ready | error | muted`), `title`
- `Badge` — `tone` (`neutral | accent | ok | danger`), `dot`
- `Field` — `label`, `hint`, `invalid`
Expand Down
Loading