design-pact 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/SKILL.md +253 -0
- package/dist/cli.js +2540 -0
- package/package.json +44 -0
- package/web/404.html +1 -0
- package/web/__next.__PAGE__.txt +9 -0
- package/web/__next._full.txt +20 -0
- package/web/__next._head.txt +6 -0
- package/web/__next._index.txt +5 -0
- package/web/__next._tree.txt +4 -0
- package/web/_next/static/PuB4TNuzsXn-CMEz1oKNJ/_buildManifest.js +11 -0
- package/web/_next/static/PuB4TNuzsXn-CMEz1oKNJ/_clientMiddlewareManifest.js +1 -0
- package/web/_next/static/PuB4TNuzsXn-CMEz1oKNJ/_ssgManifest.js +1 -0
- package/web/_next/static/chunks/0-l9p_pd2v836.js +5 -0
- package/web/_next/static/chunks/012lv2-viu5_..js +187 -0
- package/web/_next/static/chunks/03~yq9q893hmn.js +1 -0
- package/web/_next/static/chunks/0rp7qr3afex.u.js +31 -0
- package/web/_next/static/chunks/0uyeui9y_zv_0.css +3 -0
- package/web/_next/static/chunks/0x72peuimhbw-.js +1 -0
- package/web/_next/static/chunks/15356_01bt_3u.js +1 -0
- package/web/_next/static/chunks/turbopack-0y3s-y83i3.06.js +1 -0
- package/web/_next/static/media/4fa387ec64143e14-s.0wkzw~je483f-.woff2 +0 -0
- package/web/_next/static/media/53b9e256198e5412-s.0-wfv7uh4i7h9.woff2 +0 -0
- package/web/_next/static/media/5ce348bf30bf5439-s.0zgw-jeven.3w.woff2 +0 -0
- package/web/_next/static/media/6306c77e7c8268e4-s.0rhz0arwfsn~5.woff2 +0 -0
- package/web/_next/static/media/7178b3e590c64307-s.0nx0ww8fni_q3.woff2 +0 -0
- package/web/_next/static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2 +0 -0
- package/web/_next/static/media/7d817b4c03b0c5f1-s.0l76wvqk9d84w.woff2 +0 -0
- package/web/_next/static/media/8a480f0b521d4e75-s.0jzbimsg8vl84.woff2 +0 -0
- package/web/_next/static/media/bbc41e54d2fcbd21-s.0k4k9394f2q-k.woff2 +0 -0
- package/web/_next/static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2 +0 -0
- package/web/_next/static/media/favicon.0x3dzn~oxb6tn.ico +0 -0
- package/web/_next/static/media/fef07dbb0973bf53-s.12tyk43_3sh9u.woff2 +0 -0
- package/web/_not-found/__next._full.txt +16 -0
- package/web/_not-found/__next._head.txt +6 -0
- package/web/_not-found/__next._index.txt +5 -0
- package/web/_not-found/__next._not-found.__PAGE__.txt +5 -0
- package/web/_not-found/__next._not-found.txt +5 -0
- package/web/_not-found/__next._tree.txt +2 -0
- package/web/_not-found.html +1 -0
- package/web/_not-found.txt +16 -0
- package/web/favicon.ico +0 -0
- package/web/file.svg +1 -0
- package/web/globe.svg +1 -0
- package/web/index.html +1 -0
- package/web/index.txt +20 -0
- package/web/next.svg +1 -0
- package/web/templates.json +3168 -0
- package/web/vercel.svg +1 -0
- package/web/window.svg +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# design-pact
|
|
2
|
+
|
|
3
|
+
Turn a `design.md` — exported from the [design-pact](../../README.md)
|
|
4
|
+
web app — into project token files. **No AI, no network, fully deterministic.**
|
|
5
|
+
|
|
6
|
+
The `design.md` file is self-contained: it holds the verbatim `:root`
|
|
7
|
+
CSS contract (what humans and AI agents read) plus a W3C Design Tokens JSON
|
|
8
|
+
block (what this CLI parses). An agent can use the file directly; this CLI is
|
|
9
|
+
for when you want the tokens as committed project files.
|
|
10
|
+
|
|
11
|
+
## Install the skill (recommended)
|
|
12
|
+
|
|
13
|
+
Get the `design-system` skill into your agent with the open
|
|
14
|
+
[`skills`](https://github.com/vercel-labs/skills) CLI — one command, works
|
|
15
|
+
across Claude Code / Cursor / Codex:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx skills add no7z/design-pact -g # global: install once, available in every project
|
|
19
|
+
npx skills add no7z/design-pact # or: current project only (.claude/skills/)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The skill then opens the studio on demand via `npx design-pact open`,
|
|
23
|
+
so you never install the studio separately. (This package also ships its own
|
|
24
|
+
installer if you prefer a single, offline, version-locked bundle:
|
|
25
|
+
`npx design-pact init [--global]`.)
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Generate token files in the current directory
|
|
31
|
+
npx design-pact add design.md
|
|
32
|
+
|
|
33
|
+
# Pick formats and an output directory
|
|
34
|
+
npx design-pact add design.md --format css|tailwind|w3c|all --out ./design
|
|
35
|
+
|
|
36
|
+
# Print a summary without writing anything
|
|
37
|
+
npx design-pact inspect design.md
|
|
38
|
+
|
|
39
|
+
# Audit source files: find color literals outside the contract
|
|
40
|
+
npx design-pact check design.md src/ app/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `check` — enforce the contract
|
|
44
|
+
|
|
45
|
+
`check` scans your source files (css/scss/tsx/vue/svelte/…) for hex and
|
|
46
|
+
`rgb()`/`rgba()` color literals that aren't declared in `design.md` and reports
|
|
47
|
+
each with its file and line. It exits `1` when violations exist, so it slots
|
|
48
|
+
into CI or an agent loop: the agent generates UI against `design.md`, runs
|
|
49
|
+
`check`, and fixes anything flagged. `node_modules` / build output are skipped
|
|
50
|
+
automatically; whitelist intentional exceptions with `--allow "#hex,#hex"`.
|
|
51
|
+
|
|
52
|
+
Outputs:
|
|
53
|
+
|
|
54
|
+
| Format | File | Source |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `css` | `tokens.css` | the verbatim `:root` block (byte-identical to the web export) |
|
|
57
|
+
| `w3c` | `design-tokens.json` | the W3C Design Tokens block |
|
|
58
|
+
| `tailwind` | `tailwind.config.js` | regenerated via the web app's own `tailwindConfig` (no drift) |
|
|
59
|
+
|
|
60
|
+
`css` and `w3c` are extracted verbatim from the file; `tailwind` is the one
|
|
61
|
+
format not embedded in the markdown, so it's regenerated from the JSON block
|
|
62
|
+
using the same code path the web app uses — it can't drift from the source.
|
|
63
|
+
|
|
64
|
+
## How to get a `design.md`
|
|
65
|
+
|
|
66
|
+
Open the design-system web app, build your design system, and click
|
|
67
|
+
**Download design.md** in the export step.
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-system
|
|
3
|
+
description: >-
|
|
4
|
+
Establish and apply the project's design system. Invoke at the start of UI
|
|
5
|
+
work, or whenever the user says "use my design system", "apply my tokens",
|
|
6
|
+
"set up our design system", "build this to our design system", or asks to
|
|
7
|
+
build/restyle UI. The skill first looks for a design.md in the repo:
|
|
8
|
+
if present it generates UI against it; if absent it clarifies the product
|
|
9
|
+
direction, YOU (the agent) propose 2–3 palettes, and it opens the
|
|
10
|
+
design-system web app where the user picks one visually and tunes it into a full
|
|
11
|
+
design system to export. All AI runs on the agent's own compute — the web app has no AI and
|
|
12
|
+
no backend.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Design system
|
|
16
|
+
|
|
17
|
+
The project's design system lives in a single file — `design.md` at the
|
|
18
|
+
repo root — exported from the design-system web app. It carries the canonical
|
|
19
|
+
color / type / spacing / radius / shadow / motion tokens plus a copy-verbatim
|
|
20
|
+
`:root` contract. That one file is the source of truth; you do not need the web
|
|
21
|
+
app or network access once it exists.
|
|
22
|
+
|
|
23
|
+
**Always start with Step 0.** It decides whether to apply an existing system or
|
|
24
|
+
help the user create one (you propose 2–3 palettes; they pick one visually).
|
|
25
|
+
|
|
26
|
+
## Step 0 — find or create the design system
|
|
27
|
+
|
|
28
|
+
Look for `design.md`, in order:
|
|
29
|
+
|
|
30
|
+
1. A path the user gave you.
|
|
31
|
+
2. `design.md` at the repo root.
|
|
32
|
+
3. Search the repo for the file's frontmatter marker:
|
|
33
|
+
`rg -l "^design-system:" --type md`.
|
|
34
|
+
|
|
35
|
+
Then branch:
|
|
36
|
+
|
|
37
|
+
- **Found** → go to **Apply** below. (If you found more than one, ask the user
|
|
38
|
+
which to use.)
|
|
39
|
+
- **Not found** → go to **Create** below. Do **not** invent tokens or guess a
|
|
40
|
+
palette — get a real `design.md` first.
|
|
41
|
+
|
|
42
|
+
## Create — no design.md yet
|
|
43
|
+
|
|
44
|
+
There's no design system yet. The division of labor: **you (the agent) do the
|
|
45
|
+
creative part — clarify direction and propose 2–3 palettes; the web app does
|
|
46
|
+
the deterministic part — render each palette so the user picks one visually,
|
|
47
|
+
then derive the full token system (scales, shadows, dark pairs, the `:root`
|
|
48
|
+
contract, contrast audit) from it and let them tune it, then export
|
|
49
|
+
`design.md`.** The web app has no AI; it only needs your palettes as
|
|
50
|
+
input.
|
|
51
|
+
|
|
52
|
+
### 1. Clarify direction
|
|
53
|
+
|
|
54
|
+
If the product's visual direction isn't already clear from the conversation,
|
|
55
|
+
ask the user **one or two** quick questions — only what changes the palette,
|
|
56
|
+
e.g. light vs dark / mood (calm-professional, bold-energetic, warm-friendly),
|
|
57
|
+
and the rough industry/vibe. Don't over-interview; the user tunes everything
|
|
58
|
+
later in the web app.
|
|
59
|
+
|
|
60
|
+
### 2. Propose 2–3 palettes
|
|
61
|
+
|
|
62
|
+
Design **2–3 distinct palettes** (not one) so the user can choose visually in
|
|
63
|
+
the web app — hex codes in chat aren't something a person can judge at a
|
|
64
|
+
glance. Make them genuinely different takes on the brief (e.g. a calm/neutral
|
|
65
|
+
one, a bolder one, a warm or dark one), not minor variations.
|
|
66
|
+
|
|
67
|
+
Each palette is **6 colors** in this exact role order — background, foreground,
|
|
68
|
+
primary, accent, muted, border. Ensure foreground reads on background (aim for
|
|
69
|
+
≥ 4.5:1) and primary stands out. Don't hand-author a full `design.md` —
|
|
70
|
+
let the web app derive the scales/shadows/dark/contract so they're correct; you
|
|
71
|
+
only supply the 6 base colors per palette.
|
|
72
|
+
|
|
73
|
+
Give each palette a short **name** and a one-line **description** (what it's for
|
|
74
|
+
/ the mood), so the user can tell the options apart on the picker — they're
|
|
75
|
+
shown on each card. e.g. name「海洋蓝」, description「冷静专业,适合 B2B SaaS」.
|
|
76
|
+
|
|
77
|
+
You can briefly describe the directions in chat, but **don't ask the user to
|
|
78
|
+
pick in chat** — the point is to let them see the palettes rendered on a real
|
|
79
|
+
UI and pick there.
|
|
80
|
+
|
|
81
|
+
### 2.5 Match same-category real products
|
|
82
|
+
|
|
83
|
+
The web app ships a library of ~70 real brand design templates. List the ones in
|
|
84
|
+
the **same product category** as what's being built, so the user can start from
|
|
85
|
+
a proven real-world design. They appear as a "同类真实产品" row on the first
|
|
86
|
+
screen and are passed via `?m=` in step 3.
|
|
87
|
+
|
|
88
|
+
**Match by PRODUCT CATEGORY, not by color or vibe.** To keep this accurate
|
|
89
|
+
(don't rely on recognizing every slug from memory — some are obscure), the
|
|
90
|
+
brands are pre-grouped below. Steps:
|
|
91
|
+
|
|
92
|
+
1. Classify the product being built into ONE of the categories below.
|
|
93
|
+
2. Take the slugs from that category. If an adjacent category clearly also fits
|
|
94
|
+
the product (e.g. an "AI devtool" spans **AI** and **开发者工具**), you may
|
|
95
|
+
include those too.
|
|
96
|
+
3. **宁缺毋滥** — if no category genuinely fits, send no `m=` at all (the row
|
|
97
|
+
just won't appear). Never pad with off-category brands.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
AI(大模型 / 生成式 AI 产品): claude cohere mistral.ai minimax x.ai elevenlabs runwayml together.ai replicate ollama lovable
|
|
101
|
+
开发者工具 / 基础设施 / 后端: cursor warp vercel supabase mongodb clickhouse hashicorp sentry posthog mintlify sanity resend expo composio opencode.ai voltagent
|
|
102
|
+
生产力 / 协作 / 工作流 SaaS: notion airtable miro slack linear.app cal superhuman zapier raycast intercom clay
|
|
103
|
+
设计 / 建站 / 无代码: figma framer webflow
|
|
104
|
+
金融科技 / 支付: stripe mastercard revolut wise
|
|
105
|
+
加密货币 / 交易所: coinbase binance kraken
|
|
106
|
+
汽车: tesla bmw bmw-m ferrari lamborghini bugatti renault
|
|
107
|
+
消费电子 / 科技巨头 / 游戏主机: apple nvidia meta ibm playstation
|
|
108
|
+
电商 / 零售 / 消费品牌: shopify nike starbucks
|
|
109
|
+
出行 / 市场 / 流媒体(消费平台): airbnb uber pinterest spotify
|
|
110
|
+
媒体 / 出版: theverge wired
|
|
111
|
+
电信: vodafone
|
|
112
|
+
航天: spacex
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
e.g. a payments dashboard → category 金融科技 → `stripe,mastercard,revolut,wise`;
|
|
116
|
+
an EV brand site → 汽车 → `tesla,bmw,lamborghini`; an AI chat product → AI →
|
|
117
|
+
`claude,x.ai,mistral.ai,cohere`; a project-tracking SaaS → 生产力 →
|
|
118
|
+
`linear.app,notion,airtable,slack`.
|
|
119
|
+
|
|
120
|
+
### 3. Open the web app with the palettes baked into the URL
|
|
121
|
+
|
|
122
|
+
The web app loads palettes straight from `?p=` query params. Pass **one `?p=`
|
|
123
|
+
per palette**: with several, the user lands on a "选一套配色" screen showing each
|
|
124
|
+
palette rendered on a mockup with its name + description, and picks one into the
|
|
125
|
+
editor. (A single `?p=` loads directly into the editor instead.)
|
|
126
|
+
|
|
127
|
+
Each set is the 6 hex values (no `#`, role order, `-` separated), optionally
|
|
128
|
+
followed by the **name** and **description**, appended with `~` and
|
|
129
|
+
**URL-encoded** (they usually contain CJK/spaces):
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
p=<bg>-<fg>-<primary>-<accent>-<muted>-<border>~<name>~<description>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Join multiple sets with `&`:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
# several palettes → visual picker (with names + descriptions)
|
|
139
|
+
http://localhost:3000/?p=ffffff-1a1a1a-2f6df6-7c3aed-6b7280-e5e7eb~%E6%B5%B7%E6%B4%8B%E8%93%9D~%E5%86%B7%E9%9D%99%E4%B8%93%E4%B8%9A%EF%BC%8C%E9%80%82%E5%90%88%20B2B%20SaaS&p=0f1115-e6e8ec-5b8cff-ff8a3d-8a90a0-23262e~%E6%9A%97%E5%A4%9C~%E7%A7%91%E6%8A%80%E6%84%9F%E5%8D%81%E8%B6%B3
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
(Names/descriptions are optional — a bare `p=<hexes>` still works. Build the URL
|
|
143
|
+
programmatically with `encodeURIComponent` for each name/description so the `~`
|
|
144
|
+
delimiters stay intact.)
|
|
145
|
+
|
|
146
|
+
Append the same-category brands from step 2.5 as a single comma-separated `m=`
|
|
147
|
+
(slugs only, no encoding needed). Unknown slugs are dropped; omit `m=` entirely
|
|
148
|
+
when nothing matched:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
…&m=stripe,linear.app,vercel,supabase
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Append `&lang=zh` if you're talking to the user in Chinese, or `&lang=en` for
|
|
155
|
+
English — this sets the studio's default UI language on first open (the user
|
|
156
|
+
can still switch in the top-right). Omit it and the app falls back to the
|
|
157
|
+
browser language. Only matters on the user's first visit; after that their
|
|
158
|
+
own choice is remembered.
|
|
159
|
+
|
|
160
|
+
Full URL: `http://localhost:3000/?<query>` (`DESIGN_SYSTEM_URL` defaults to
|
|
161
|
+
`http://localhost:3000`; use a hosted URL if the user has one and skip the CLI).
|
|
162
|
+
|
|
163
|
+
**Do these IN ORDER. Step 1 always happens — even if 2 fails, the printed URL is
|
|
164
|
+
all the user needs.**
|
|
165
|
+
|
|
166
|
+
1. **Print the full URL on its own line and tell the user to open it.** Do this
|
|
167
|
+
first, unconditionally. Opening it manually loads the palettes just the same.
|
|
168
|
+
|
|
169
|
+
> 打开(已带 N 套配色): http://localhost:3000/?p=…&p=…
|
|
170
|
+
|
|
171
|
+
2. **Open the studio with the CLI** — it serves the bundled app locally (no
|
|
172
|
+
clone, no dev server, no account) and opens the browser:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx design-pact open "<query>"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`<query>` is everything after `?` (the `p=…&p=…&m=…` you assembled). It
|
|
179
|
+
returns immediately (studio runs in the background on `http://localhost:3000`),
|
|
180
|
+
reuses a running instance on repeat calls, and prints the URL too. Headless
|
|
181
|
+
is fine.
|
|
182
|
+
|
|
183
|
+
Fallbacks if `npx` can't fetch the package (offline / not yet published): if
|
|
184
|
+
`curl -sf http://localhost:3000` already answers, just open the step-1 URL; or
|
|
185
|
+
from a local clone `npm --prefix "$DESIGN_SYSTEM_DIR" run dev &`. Either way
|
|
186
|
+
the step-1 URL is the instruction.
|
|
187
|
+
|
|
188
|
+
### 4. Tell the user what to do there
|
|
189
|
+
|
|
190
|
+
> 网页第一屏「选一套配色」会把这几套方案分别渲染在真实 UI 上,点你喜欢的那套进入
|
|
191
|
+
> 「调色」区。再用色轮 / 字体 / 间距 / 暗色微调(右侧实时预览 + 对比度审计)→ 在
|
|
192
|
+
> 「导出」区点 **「下载 design.md」** → 把文件放到这个项目的根目录。
|
|
193
|
+
|
|
194
|
+
(If they'd rather start from a different base, they can also pick a brand
|
|
195
|
+
template or extract from an image on the first screen.)
|
|
196
|
+
|
|
197
|
+
### 5. Resume
|
|
198
|
+
|
|
199
|
+
Wait for the user to confirm `design.md` is in the repo, then re-run the
|
|
200
|
+
Step 0 search and continue to **Apply**.
|
|
201
|
+
|
|
202
|
+
## Apply — design.md is present
|
|
203
|
+
|
|
204
|
+
`read` the whole file. It has two parts:
|
|
205
|
+
|
|
206
|
+
- **Prose + a `:root { … }` CSS block** — the contract. Every color, font size,
|
|
207
|
+
spacing step, radius, shadow, duration, and easing as a CSS custom property,
|
|
208
|
+
with usage guidance. This block is authoritative.
|
|
209
|
+
- **A fenced ` ```json ` block at the bottom** (W3C Design Tokens) — the same
|
|
210
|
+
values, machine-readable. Read this only if deriving a config file (see
|
|
211
|
+
"Config files" below); for generating UI the `:root` block is enough.
|
|
212
|
+
|
|
213
|
+
Generate UI strictly against the contract (the file restates these — follow
|
|
214
|
+
exactly):
|
|
215
|
+
|
|
216
|
+
- Paste the `:root` block into your `<style>` **verbatim**. Do not round,
|
|
217
|
+
rescale, rename, or re-derive any value.
|
|
218
|
+
- Reference every value through `var(--…)`. Every length must be a token
|
|
219
|
+
reference — never convert a `px` token to `rem` or vice-versa.
|
|
220
|
+
- Introduce **no** colors, fonts, sizes, spacing, radii, or shadows that aren't
|
|
221
|
+
declared. Need a lighter/darker shade? Derive it in OKLCH by changing
|
|
222
|
+
lightness only — keep hue and chroma fixed.
|
|
223
|
+
- If a `@media (prefers-color-scheme: dark)` block is present, it overrides
|
|
224
|
+
color variables only; every other token is identical in dark mode.
|
|
225
|
+
- Wire interactive states (hover / pressed / focus / disabled) with the opacity
|
|
226
|
+
tokens, and transitions with the motion tokens.
|
|
227
|
+
|
|
228
|
+
Reasoning and generation run on **your** model — no server dependency. After
|
|
229
|
+
generating, verify the output uses the tokens (no stray hex values, no
|
|
230
|
+
off-scale sizes). The companion CLI automates the color half of that audit:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npx design-pact check design.md <dirs-or-files-you-touched>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
It flags every hex / `rgb()` literal that isn't in the contract (exit 1 when
|
|
237
|
+
violations exist) with file:line locations — fix them by switching to
|
|
238
|
+
`var(--color-…)` references, then re-run until clean. If the CLI isn't
|
|
239
|
+
available, do the same audit by hand.
|
|
240
|
+
|
|
241
|
+
## Config files (optional)
|
|
242
|
+
|
|
243
|
+
If the user wants the tokens as project files rather than (or in addition to)
|
|
244
|
+
generated UI, the companion CLI converts the file's `json` block into
|
|
245
|
+
`tokens.css` / `tailwind.config.js` / `design-tokens.json`:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
npx design-pact add design.md --format css|tailwind|w3c|all --out ./design
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
If the CLI isn't installed you can produce the same output by reading the
|
|
252
|
+
` ```json ` block (W3C Design Tokens) and writing the requested format — but
|
|
253
|
+
prefer the CLI when available so the conversion stays canonical.
|