mockpit 2.0.0 → 3.1.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.
Files changed (90) hide show
  1. package/README.md +59 -223
  2. package/bin/demoData.js +2 -2
  3. package/bin/initDesign.js +17 -22
  4. package/bin/mockpit.js +626 -216
  5. package/bin/poster.js +434 -0
  6. package/dist/mcp/server.js +127 -29
  7. package/dist/server/answerAdditions.d.ts +7 -0
  8. package/dist/server/answerAdditions.js +76 -0
  9. package/dist/server/apiViews.d.ts +627 -385
  10. package/dist/server/apiViews.js +198 -81
  11. package/dist/server/app.d.ts +7 -2
  12. package/dist/server/app.js +3514 -984
  13. package/dist/server/appIcon.js +15 -5
  14. package/dist/server/appIconPng.js +3 -3
  15. package/dist/server/askNudges.js +1 -1
  16. package/dist/server/cdnInline.d.ts +8 -0
  17. package/dist/server/cdnInline.js +640 -0
  18. package/dist/server/codeWorker.js +2 -2
  19. package/dist/server/contrast.d.ts +4 -0
  20. package/dist/server/contrast.js +157 -0
  21. package/dist/server/decisionList.d.ts +48 -0
  22. package/dist/server/decisionList.js +340 -0
  23. package/dist/server/decisions.d.ts +4 -4
  24. package/dist/server/decisions.js +9 -9
  25. package/dist/server/designGuide.d.ts +14 -7
  26. package/dist/server/designGuide.js +314 -88
  27. package/dist/server/embeds.d.ts +3 -1
  28. package/dist/server/embeds.js +31 -6
  29. package/dist/server/eventLog.d.ts +2 -2
  30. package/dist/server/eventLog.js +11 -11
  31. package/dist/server/events.d.ts +15 -6
  32. package/dist/server/feedbackBatch.d.ts +39 -13
  33. package/dist/server/feedbackBatch.js +129 -47
  34. package/dist/server/fills.d.ts +4 -0
  35. package/dist/server/fills.js +55 -1
  36. package/dist/server/guidance.d.ts +1 -1
  37. package/dist/server/guidance.js +2 -2
  38. package/dist/server/handoff.d.ts +4 -1
  39. package/dist/server/handoff.js +8 -2
  40. package/dist/server/icons.js +1 -1
  41. package/dist/server/index.js +39 -10
  42. package/dist/server/jump.d.ts +21 -0
  43. package/dist/server/jump.js +175 -0
  44. package/dist/server/kits.d.ts +2 -2
  45. package/dist/server/kits.js +54 -1
  46. package/dist/server/knobs.d.ts +3 -3
  47. package/dist/server/knobs.js +6 -6
  48. package/dist/server/mcpHttp.d.ts +7 -1
  49. package/dist/server/mcpHttp.js +29 -12
  50. package/dist/server/mcpSpec.d.ts +27 -27
  51. package/dist/server/mcpSpec.js +196 -56
  52. package/dist/server/parts.js +9 -1
  53. package/dist/server/run.d.ts +1 -1
  54. package/dist/server/run.js +47 -17
  55. package/dist/server/runApi.d.ts +3 -3
  56. package/dist/server/runApi.js +34 -21
  57. package/dist/server/sqlStore.d.ts +148 -103
  58. package/dist/server/sqlStore.js +1052 -181
  59. package/dist/server/standings.d.ts +25 -0
  60. package/dist/server/standings.js +113 -0
  61. package/dist/server/surfacePage.d.ts +8 -9
  62. package/dist/server/surfacePage.js +423 -100
  63. package/dist/server/system.d.ts +234 -0
  64. package/dist/server/system.js +1508 -0
  65. package/dist/server/systemChecks.d.ts +15 -0
  66. package/dist/server/systemChecks.js +224 -0
  67. package/dist/server/systemSpecimen.d.ts +2 -0
  68. package/dist/server/systemSpecimen.js +49 -0
  69. package/dist/server/themes.d.ts +9 -7
  70. package/dist/server/themes.js +43 -90
  71. package/dist/server/types.d.ts +266 -93
  72. package/dist/server/types.js +76 -79
  73. package/extensions/mockpit.js +89 -72
  74. package/guide/AGENT_SETUP.md +15 -1
  75. package/guide/packs/design-craft.md +2 -3
  76. package/guide/packs/foundations.md +35 -0
  77. package/guide/topics/asks.md +108 -63
  78. package/guide/topics/feedback.md +129 -120
  79. package/guide/topics/html.md +18 -25
  80. package/guide/topics/http.md +43 -41
  81. package/guide/topics/knobs.md +7 -10
  82. package/guide/topics/scripts.md +22 -33
  83. package/guide/topics/surfaces.md +39 -48
  84. package/guide/topics/system.md +157 -0
  85. package/opencode/mockpit.js +120 -0
  86. package/opencode/package.json +8 -0
  87. package/package.json +15 -14
  88. package/skills/launch-video/SKILL.md +11 -11
  89. package/skills/mockpit/SKILL.md +33 -26
  90. package/viewer/dist/index.html +10 -9
package/README.md CHANGED
@@ -1,263 +1,99 @@
1
1
  # mockpit
2
2
 
3
- **A design-decision loop for terminal coding agents.**
3
+ **A design loop for terminal coding agents. Your agent shows designs in your browser and asks
4
+ its questions there. You answer in place and press Send once.**
4
5
 
5
- Your agent publishes a mock (a page or a component) in each of its UI states and
6
- in a few parallel variants. It shows up live in your browser with the agent's
7
- questions beside it: pick a variant from pictures, tune the knobs it exposed, leave
8
- comments on the parts it declared, then press **Send**, at your own pace. Nothing
9
- the agent calls waits for you: it gets the whole batch once and revises.
6
+ The agent publishes a screen in its states and a few variants, then ends its turn. You compare
7
+ them from pictures, tune knobs, comment on parts and keep the runners-up. One Send gives the
8
+ agent the whole reply. Nothing it calls waits for you.
10
9
 
11
- <table>
12
- <tr>
13
- <td width="50%" valign="top">
14
- <picture>
15
- <source media="(prefers-color-scheme: dark)" srcset="docs/mockpit-dark.png">
16
- <img width="100%" alt="The Writer mock on its first question, Which variant?: the Writing state on the stage with a numbered question pin, the row of four UI states below it, and the panel offering three variants (Quiet, Dark, Editorial) as picture options" src="docs/mockpit-light.png">
17
- </picture>
18
- </td>
19
- <td width="50%" valign="top">
20
- <img width="100%" alt="Animated demo: the agent publishes the Writer mock; the user previews the three variants on the stage, picks Quiet, answers where the trim goes, borrows a part from another variant and presses Send; the top bar reads Sent, Not seen yet, then Delivered once the agent reads the feedback; the agent replies and publishes its next version" src="docs/mockpit-demo.gif">
21
- </td>
22
- </tr>
23
- </table>
24
-
25
- ## Fork of sideshow
26
-
27
- mockpit is a fork of [sideshow](https://github.com/modem-dev/sideshow) by
28
- [Ben Vinegar](https://github.com/benvinegar), sponsored by
29
- [Modem](https://modem.dev). The renderer, sandboxing, MCP/CLI/HTTP tiers and
30
- Cloudflare deploy all come from that work. Thank you.
31
-
32
- Upstream is a live visual surface where agents post renders and you comment.
33
- mockpit turns that into a design-decision loop:
34
-
35
- | | sideshow | mockpit |
36
- | ------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
37
- | Structure | A stream of posts per session | **project › mock › state › variant › version**: a repo, a page or component by slug, its UI states, parallel variants, history |
38
- | Questions | Free-text comments | The agent asks; you answer in place, picking from pictures of each option |
39
- | Tuning | — | Knobs the agent declares (sliders, colours, springs…) on [tunekit](https://github.com/fabiogaliano/tunekit), live on the stage |
40
- | Comments | Text on a post | Anchored on a **part** the agent declared with `data-part`, in a given state |
41
- | Feedback | Each comment reaches the agent as it's written | Picks, tuned values, borrowed parts and comments stay drafts until you **Send**, then go out as one reply |
42
- | Design system | Built-in viewer themes | `mockpit init` detects the repo's tokens, fonts and kit so the agent's markup matches your codebase |
43
- | Agent verbs | Post-level: `publish`, `update`, `wait`, `comment` | Mock-level, never blocking: `publish`, `ask`, `read`, `feedback`, `say`, `edit`, `export`, `upload`, `guide`, `run` |
44
-
45
- ## The loop
10
+ <a href="docs/mockpit-demo.gif"><img width="100%" alt="Animated demo: on HALDE, a shop design with three product grids, the pointer hovers Gallery and Editorial, each previewing on the stage, then picks Gallery" src="docs/mockpit-demo.gif"></a>
46
11
 
47
- 1. **Publish.** The agent publishes each state of the mock ("Writing", "Lab
48
- open") in one or more variants ("quiet", "dark"). One stage shows the mock,
49
- one state at a time.
50
- 2. **Ask.** The agent asks what it can't decide alone: which variant, where a
51
- panel goes, which of two layouts. The question lives in the mock, not in
52
- chat; the agent tells you where to look and ends its turn. Options bound to
53
- a variant or to knob values render as pictures; hovering one previews it on
54
- the stage, clicking picks it, and the part it changed is outlined. A
55
- region the agent drew several ways (a part with fills: one `data-part`, a
56
- `data-fill` per alternative) is asked about once; a part inside a fill is
57
- asked only while that fill is chosen. Variants the agent forgot to ask about
58
- get a built-in **Which variant?**.
59
- 3. **Tune.** Parts the agent declared are selectable on the stage. Tune lists
60
- them with the knobs it declared for each, a **Borrow** line for a part
61
- another variant draws differently, plus a comment field. Presets
62
- save a set of tuned values in your browser.
63
- 4. **Send.** Everything above is a draft (it survives a reload) until one
64
- **Send**. A mock with a single variant and no questions gets **Use this /
65
- Revise** instead. The Send lands in the Thread as **Not seen yet**,
66
- then **Delivered** once the agent has it. If it isn't picked up, tell your
67
- agent you've answered.
68
- 5. **Revise.** The agent gets one reply (answers, tuned values, borrowed parts, comments)
69
- on its next write, its next `feedback` call, or from `mockpit watch` under a
70
- background monitor. It publishes the next version. Versions are named by
71
- their variant's own number ("Dark #2"); the version bar walks the history,
72
- and **Use this** puts an older one back in use. Variants that lost are
73
- archived, not deleted.
12
+ ## Quickstart
74
13
 
75
- **Home** lists the project's mocks with a thumbnail, their states and how many
76
- questions are open, with "Answer next ›" to jump to the first one. Dark and
77
- light themes, toggled from the top bar. On a phone or an iPad in portrait the
78
- design is a canvas you pan and pinch, at each width the agent names (or one you
79
- pick: Phone 390, Tablet 744, Desktop 820, Wide 1280) side by side, and the
80
- questions float over it in a card you can snap to a corner, a side or the
81
- bottom, or tuck against an edge. On a desktop, Inspect opens the stage full
82
- screen to pan and pinch-zoom it.
83
-
84
- ## Quick start
85
-
86
- Requires Node 22.18 or newer.
14
+ Needs Node 22.18 or newer.
87
15
 
88
16
  ```sh
89
- git clone https://github.com/fabiogaliano/mockpit && cd mockpit
90
- npm install
91
- npm start # viewer on http://localhost:8228
92
- npm link # puts the `mockpit` CLI on your PATH
17
+ npm i -g mockpit
18
+ mockpit serve --open # http://localhost:8228
19
+ mockpit demo # seeds a sample design to click through
93
20
  ```
94
21
 
95
- Point your agent at it by pasting the setup block into its instructions:
22
+ Point your agent at it, once per repo:
96
23
 
97
24
  ```sh
98
25
  curl -s http://localhost:8228/setup >> AGENTS.md
26
+ mockpit init # reads the repo's tokens, fonts and kit
99
27
  ```
100
28
 
101
- Then run `mockpit init` once per repo and ask the agent to "mock this up on
102
- mockpit". No agent handy? `mockpit demo` seeds the Writer: one mock in four
103
- states and three variants, with questions, knobs and declared parts.
104
-
105
- MCP, the Pi extension and the Claude Code plugin are covered in
106
- **[docs/connecting-agents.md](docs/connecting-agents.md)**.
107
-
108
- ## What a mock can show
109
-
110
- A version is an ordered list of **surfaces**, and one version can carry several.
111
- Html is what design mocks use and the only kind with parts and knobs; the others
112
- render the same way on the stage.
113
-
114
- <table>
115
- <tr>
116
- <td width="50%" valign="top">
117
- <img src="docs/surfaces/01-html.png" width="100%" alt="html surface">
118
- <p><b><code>html</code></b>: markup the agent authors, rendered in a sandbox and themed by your design system.</p>
119
- </td>
120
- <td width="50%" valign="top">
121
- <img src="docs/surfaces/02-markdown.png" width="100%" alt="markdown surface">
122
- <p><b><code>markdown</code></b>: prose, tables and fenced code.</p>
123
- </td>
124
- </tr>
125
- <tr>
126
- <td width="50%" valign="top">
127
- <img src="docs/surfaces/03-diff.png" width="100%" alt="diff surface">
128
- <p><b><code>diff</code></b>: a patch as a syntax-highlighted code review (unified or split).</p>
129
- </td>
130
- <td width="50%" valign="top">
131
- <img src="docs/surfaces/07-mermaid.png" width="100%" alt="mermaid surface">
132
- <p><b><code>mermaid</code></b>: diagram source rendered to SVG in the viewer palette.</p>
133
- </td>
134
- </tr>
135
- </table>
136
-
137
- There are also `terminal` (ANSI output), `image` (uploaded assets), `json`
138
- (collapsible tree) and `code` (shiki-highlighted source with line numbers).
139
-
140
- ## Agent verbs
141
-
142
- Ten verbs, the same on every tier with the same fields: a zero-dependency CLI
143
- for agents with only a shell, MCP over stdio or streamable HTTP at `/mcp`, and
144
- plain HTTP. None of them waits for the user.
145
-
146
- | CLI | MCP | HTTP |
147
- | --------------------- | -------------------- | --------------------------------------------------- |
148
- | `mockpit publish` | `publish` | `POST /api/mocks` |
149
- | `mockpit ask` | `ask` | `POST /api/mocks/:id/asks` |
150
- | `mockpit read [slug]` | `read` | `GET /api/mocks`, `GET /api/mocks/:id` |
151
- | `mockpit feedback` | `feedback` | `GET /api/feedback?session=…` |
152
- | `mockpit say` | `say` | `POST /api/mocks/:id/say` |
153
- | `mockpit edit` | `edit` | `PATCH /api/mocks/:id`, `PATCH /api/projects/:name` |
154
- | `mockpit export` | `export` | `GET /api/mocks/:id/export` |
155
- | `mockpit upload` | `upload` | `POST /api/assets` |
156
- | `mockpit guide` | `guide` | `GET /agent-howto` |
157
- | `mockpit run` | `run` (`?mode=code`) | `POST /api/run` |
29
+ Then ask it to "design this up on mockpit". Claude Code, Codex, OpenCode, Pi and MCP setup:
30
+ [docs/connecting-agents.md](docs/connecting-agents.md).
158
31
 
159
- The CLI adds `mockpit init` (detect the repo's design system, once per repo)
160
- and `mockpit watch` (one line per Send, for a background monitor).
161
-
162
- - **`publish` is the one write.** It creates the mock, state or variant, or the
163
- next version of an existing one. Send `html`, the full ordered `surfaces`
164
- list (an entry that is only `{id}` keeps that surface), or `parts` to replace
165
- just the declared elements.
166
- - **`feedback` returns at once** with what the user sent since the agent last
167
- heard, plus `pending`: whether each mock is open in the viewer and how far the user's
168
- draft has got (`2 of 3 answered`). Every write returns `feedback` too, and
169
- each Send is delivered exactly once across all of them.
170
- - **Questions are nudged.** A publish that leaves several variants with no
171
- question binding them returns a nudge and a ready `suggestedAsk`.
172
-
173
- A typical turn:
32
+ ## A turn
174
33
 
175
34
  ```sh
176
- mockpit publish --mock writer --state "Writing" --variant quiet --html quiet.html
177
- mockpit publish --mock writer --state "Writing" --variant dark --html dark.html
178
- mockpit ask --mock writer "Quiet or dark?" --option Quiet=quiet --option Dark=dark
179
- # the agent says where to look and ends its turn; once you've answered:
35
+ mockpit publish --design shop --state Grid --variant index --html index.html
36
+ mockpit publish --design shop --state Grid --variant gallery --html gallery.html
37
+ mockpit ask --design shop "Which grid?" --option Index=index --option Gallery=gallery
38
+ # the agent says where to look and stops. After your Send:
180
39
  mockpit feedback
181
40
  ```
182
41
 
183
- The running server serves the brief at `/agent-howto`: one short, project-aware
184
- document an agent reads before its first publish. Reference topics (`knobs`,
185
- `asks`, `surfaces`, `html`, `feedback`, `http`, `scripts`) are at
186
- `/agent-howto?topic=<id>`; `/guide` is the `html` topic. `run` executes one
187
- script against the same verbs on the server, so publishing variants and asking
188
- take one call; `/mcp?mode=code` serves it as the only tool, for connectors
189
- without a codemode of their own.
42
+ ## What you can do with an answer
190
43
 
191
- ## Guidance
44
+ - **Pick** from pictures. Hover to preview it on the stage.
45
+ - **Keep** runners-up. After Send they stay beside the design, one click from Use this instead.
46
+ - **Hide** what you don't want, with a reason if you like. The agent won't offer it again.
47
+ - **Ask for more** answers without sending the rest of your draft.
48
+ - **Save a set** of answers across questions, like Warm or Quiet, and switch between sets.
49
+ - **Tune** the knobs the agent declared, **borrow** a part from another variant, and
50
+ **comment** on any part.
192
51
 
193
- Agents read one brief before their first publish, in layers. Higher wins:
52
+ Studio puts every variant side by side. Home groups a project's ideas, screens, flows and
53
+ components, and Needs you lists what's waiting on you.
194
54
 
195
- | Layer | Where | Who gets it |
196
- | ------------- | ------------------------------- | ------------------------------------- |
197
- | Core | built in | everyone: how mockpit works, no taste |
198
- | Packs | built in, off by default | whoever turns one on (`design-craft`) |
199
- | Your rules | `~/.mockpit/rules.md` | you, in every project |
200
- | Project rules | `.mockpit/rules.md` in the repo | anyone designing that repo |
55
+ <table>
56
+ <tr>
57
+ <td width="50%"><a href="docs/mockpit-question.png"><img src="docs/mockpit-question.png" width="100%" alt="The HALDE shop asking Which grid?, with Index, Gallery and Editorial as picture answers beside the stage"></a></td>
58
+ <td width="50%"><a href="docs/mockpit-preview.png"><img src="docs/mockpit-preview.png" width="100%" alt="The product page previewing the Bone answer to What colour behind the products? before it is picked"></a></td>
59
+ </tr>
60
+ </table>
201
61
 
202
- A rules file has `## Rules` (always followed) and `## Suggestions` (aimed for),
203
- and turns packs on with `packs: [design-craft]` in its frontmatter. `mockpit
204
- rules` sends the project's file to the server; `mockpit init` does it too.
205
- [`examples/rules.md`](examples/rules.md) is the maintainer's own, symlinked to
206
- `~/.mockpit/rules.md`.
62
+ ## What it shows
207
63
 
208
- ## Run it anywhere
64
+ Html with parts and knobs, plus markdown, diff, terminal, image, mermaid, json and code. All of
65
+ it renders in a sandboxed frame.
209
66
 
210
- It runs locally as a small Node server (SQLite at `~/.mockpit/mockpit.db`), or on
211
- Cloudflare Workers when your agent and browser are on different machines. See
212
- **[docs/deploying.md](docs/deploying.md)**.
67
+ ## Agent side
213
68
 
214
- The server keeps an event log, one JSON line per agent call, viewer write and
215
- live-feed connection (ids and shapes, never content), at
216
- `~/.mockpit/events.jsonl` next to the database. It rolls over at 10 MB. Set
217
- `MOCKPIT_LOG` to another path, or to `off` to disable it; on Workers it goes to
218
- Workers Logs. `node scripts/inspect.ts` in a checkout reads it alongside the
219
- database and Claude Code transcripts.
69
+ Eleven verbs, the same on the zero-dependency CLI, MCP (stdio, or HTTP at `/mcp`) and plain
70
+ HTTP: `publish`, `ask`, `read`, `feedback`, `say`, `move`, `edit`, `export`, `upload`,
71
+ `guide`, `run`. `mockpit watch` wakes a waiting agent on each Send.
220
72
 
221
- The server app is importable from `mockpit/server` (`createApp`, `SqlStore`,
222
- `createSqliteStorage`). The embeddable viewer engine (`mockpit/viewer-embed`,
223
- `mountViewer`) is gone: the viewer is self-hosted only.
73
+ Agents read a short brief before their first publish (`/agent-howto`). Add your own taste in
74
+ `~/.mockpit/rules.md`, or per repo in `.mockpit/rules.md`.
75
+ [`examples/rules.md`](examples/rules.md) is one.
224
76
 
225
- ## Migrating from 0.x
77
+ ## Where it runs
226
78
 
227
- - **SQLite workspaces migrate in place on first boot.** Each item becomes a
228
- single-state mock with its variants and version history; comments keep their
229
- ids and sequence numbers, so agents' feedback cursors carry over. Comments a
230
- user was still drafting become the mock's draft. Deployed Durable Objects
231
- migrate the same way.
232
- - **The JSON store is gone.** If you run with `MOCKPIT_STORE=json`, start your
233
- current version once without it **before upgrading**:
234
- `env -u MOCKPIT_STORE mockpit serve` (keep `MOCKPIT_DATA`/`MOCKPIT_DB` if you
235
- set them). That first SQLite boot copies `~/.mockpit/mockpit.json` into
236
- `~/.mockpit/mockpit.db`, as long as the database is still empty; then upgrade.
237
- The JSON file is left untouched either way.
238
- - **`--item` is now `--mock`** (`mockpit publish --mock <slug> --state <s>
239
- --variant <v>`), and the MCP tools are named by verb (`publish`, `ask`,
240
- `read`, `feedback`, `say`, `export`, `upload`, `guide`).
241
- - **Removed:** the item, post, snippet and session-page routes
242
- (`/api/projects/:name/items`, `/api/posts`, `/api/surfaces`, `/api/snippets`,
243
- `/session/:id`, `/p/:id`), `?part=`, the item/post MCP tools and their
244
- deprecated aliases (`publish_item`, `publish_post`, `publish_surface`, …), the
245
- CLI's `page`, `list`, `sessions`, `update`, per-kind shortcuts (`markdown`,
246
- `diff`, …), `test-post` and `trace*` commands, the github/gruvbox/one themes
247
- and the embed engine. Agents should re-fetch `/agent-howto`; refresh pasted
248
- setup blocks from `/setup`.
79
+ Locally, a small Node server with SQLite at `~/.mockpit/mockpit.db`. When the agent and browser
80
+ are on different machines, deploy it to Cloudflare Workers: [docs/deploying.md](docs/deploying.md).
249
81
 
250
82
  ## Development
251
83
 
252
84
  ```sh
253
- npm run dev # server with watch + viewer watch build
254
- npm run typecheck # node + workers + viewer
255
- npm run lint # oxlint
256
- npm run format # oxfmt
85
+ git clone https://github.com/fabiogaliano/mockpit && cd mockpit
86
+ npm install
87
+ npm run dev # server + viewer watch build
88
+ npm run typecheck && npm run lint && npm run format:check
257
89
  ```
258
90
 
259
- The architecture and contributor rules are in [AGENTS.md](AGENTS.md).
91
+ Architecture and rules: [AGENTS.md](AGENTS.md).
92
+
93
+ ## Credits
260
94
 
261
- ## License
95
+ A fork of [sideshow](https://github.com/modem-dev/sideshow) by
96
+ [Ben Vinegar](https://github.com/benvinegar), sponsored by [Modem](https://modem.dev). The
97
+ renderer, sandboxing, agent tiers and Cloudflare deploy started there.
262
98
 
263
99
  [MIT](LICENSE). The original sideshow copyright is retained.
package/bin/demoData.js CHANGED
@@ -1,4 +1,4 @@
1
- // Seed content for `mockpit demo`: the Writer mock — four states of one
1
+ // Seed content for `mockpit demo`: the Writer design — four states of one
2
2
  // writing app, each drawn in three variants, with its parts marked so the viewer
3
3
  // can show questions, tuning and part comments. Dependency-free like the CLI.
4
4
 
@@ -103,7 +103,7 @@ export const DEMO = {
103
103
  {
104
104
  id: "tone",
105
105
  text: "Quiet, dark or editorial?",
106
- scope: "mock",
106
+ scope: "design",
107
107
  options: [
108
108
  { label: "Quiet", variant: "quiet" },
109
109
  { label: "Dark", variant: "dark" },
package/bin/initDesign.js CHANGED
@@ -4,7 +4,7 @@
4
4
  //
5
5
  // The point of this file is that the agent never assembles a design set by
6
6
  // hand: init reads what the repo already declares (Tailwind, shadcn, a `:root`
7
- // token block, fonts), turns it into the project's DesignSettings, and writes a
7
+ // token block, fonts), turns it into the project's DesignSystem, and writes a
8
8
  // starter file the agent copies from. Everything here is deterministic — no
9
9
  // model in the loop.
10
10
 
@@ -14,17 +14,6 @@ import { readdirSync, readFileSync, statSync } from "node:fs";
14
14
  import { homedir } from "node:os";
15
15
  import { basename, join, relative } from "node:path";
16
16
 
17
- // The palette mapper lives in server/themes.ts so the server and the CLI can
18
- // never disagree about what a repo's tokens mean. Node type-strips the .ts in a
19
- // checkout; the packed CLI has only the compiled tree, hence the fallback.
20
- async function loadThemes() {
21
- try {
22
- return await import("../server/themes.ts");
23
- } catch {
24
- return await import("../dist/server/themes.js");
25
- }
26
- }
27
-
28
17
  // Where repos actually keep their global stylesheet. Ordered by how likely the
29
18
  // first hit is to be THE token file, because the first file with the most
30
19
  // custom properties wins.
@@ -257,12 +246,11 @@ function hasTailwind(cwd) {
257
246
  }
258
247
 
259
248
  /**
260
- * Inspect a repo and derive the project's DesignSettings inputs.
249
+ * Inspect a repo and derive the project's DesignSystem inputs.
261
250
  * Never throws on a hostile/odd tree — an undetectable repo returns the
262
251
  * builtin kit with no palette, which is a perfectly good starting point.
263
252
  */
264
- export async function detectDesign(cwd) {
265
- const { paletteFromCssVars } = await loadThemes();
253
+ export async function detectDesignSystem(cwd) {
266
254
  const budget = { left: MAX_FILES };
267
255
  const cssFiles = findCssFiles(cwd, budget);
268
256
 
@@ -309,7 +297,6 @@ export async function detectDesign(cwd) {
309
297
  cssVars: best ? best.count : 0,
310
298
  fonts: [...fonts].slice(0, 8),
311
299
  },
312
- palette: cssVars ? paletteFromCssVars(cssVars) : null,
313
300
  cssVars,
314
301
  // Where the tokens came from, relative to the repo — `init` prints it so
315
302
  // the operator can see which file was imported.
@@ -494,6 +481,7 @@ export function readTokenFiles(files) {
494
481
  if (isMap(json)) collectTokens(json, [], undefined, all);
495
482
  }
496
483
  const values = {};
484
+ const types = {};
497
485
  let count = 0;
498
486
  for (const [name, token] of all) {
499
487
  let { type, value } = token;
@@ -508,9 +496,12 @@ export function readTokenFiles(files) {
508
496
  const text = ref ? `{${ref}}` : tokenText(value);
509
497
  if (text === null) continue;
510
498
  count++;
511
- if (count <= TOKENS_MAX) values[name] = text.slice(0, VALUE_MAX);
499
+ if (count <= TOKENS_MAX) {
500
+ values[name] = text.slice(0, VALUE_MAX);
501
+ types[name] = type;
502
+ }
512
503
  }
513
- return count ? { count, values } : null;
504
+ return count ? { count, values, types } : null;
514
505
  }
515
506
 
516
507
  // tsconfig is JSONC: comments and trailing commas, outside strings.
@@ -613,10 +604,14 @@ export function readDesignFiles(cwd, css = "") {
613
604
  cssVars:
614
605
  tokens.count === names.length && names.every((n) => declared.has(n.replace(/\./g, "-"))),
615
606
  values: tokens.values,
607
+ types: tokens.types,
616
608
  };
617
609
  // Tokens are the one unbounded part; shed them until the blob fits.
618
610
  while (JSON.stringify(files).length > DESIGN_FILES_MAX && names.length) {
619
- for (const n of names.splice(Math.floor(names.length / 2))) delete files.tokens.values[n];
611
+ for (const n of names.splice(Math.floor(names.length / 2))) {
612
+ delete files.tokens.values[n];
613
+ delete files.tokens.types[n];
614
+ }
620
615
  }
621
616
  }
622
617
  const shadcn = readShadcn(cwd);
@@ -818,13 +813,13 @@ const STARTER_TOKENS = [
818
813
  * tokens, and one icon in use. `iconSets` are the prefixes the server resolves
819
814
  * for this project.
820
815
  */
821
- export function renderStarter(design, iconSets = ["lucide", "mage"]) {
822
- const kit = design?.kit ?? "builtin";
816
+ export function renderStarter(designSystem, iconSets = ["lucide", "mage"]) {
817
+ const kit = designSystem?.kit ?? "builtin";
823
818
  const bodies = { tailwind: TAILWIND_BODY, basecoat: BASECOAT_BODY };
824
819
  const body = (bodies[kit] ?? BUILTIN_BODY).replace("ICON_SLOT", '<i icon="lucide:check"></i>');
825
820
  // Show the tokens an agent reaches for first. A repo's block is usually led
826
821
  // by sizing/easing tokens, so surface the semantic colors ahead of them.
827
- const props = customProps(design?.cssVars ?? "");
822
+ const props = customProps(designSystem?.cssVars ?? "");
828
823
  const rank = (name) => {
829
824
  const i = STARTER_TOKENS.indexOf(name);
830
825
  return i === -1 ? STARTER_TOKENS.length : i;