@12ui/design 0.2.80 → 0.2.81

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 (276) hide show
  1. package/README.md +1 -3
  2. package/SKILL.md +2 -8
  3. package/dist/cli-help/design.d.ts +1 -1
  4. package/dist/cli-help/design.d.ts.map +1 -1
  5. package/dist/cli-help/design.js +0 -1
  6. package/dist/cli-help/design.js.map +1 -1
  7. package/dist/cli-help/index.d.ts +1 -1
  8. package/dist/cli-workspace-draw.d.ts.map +1 -1
  9. package/dist/cli-workspace-draw.js +2 -0
  10. package/dist/cli-workspace-draw.js.map +1 -1
  11. package/dist/cli-workspace-runner.d.ts.map +1 -1
  12. package/dist/cli-workspace-runner.js +2 -1
  13. package/dist/cli-workspace-runner.js.map +1 -1
  14. package/dist/corpus-client.d.ts +3 -0
  15. package/dist/corpus-client.d.ts.map +1 -1
  16. package/dist/corpus-client.js +2 -0
  17. package/dist/corpus-client.js.map +1 -1
  18. package/dist/corpus-public-renditions.d.ts +33 -0
  19. package/dist/corpus-public-renditions.d.ts.map +1 -0
  20. package/dist/corpus-public-renditions.js +55 -0
  21. package/dist/corpus-public-renditions.js.map +1 -0
  22. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  23. package/dist/legacy-skill-catalog.js +11 -0
  24. package/dist/legacy-skill-catalog.js.map +1 -1
  25. package/dist/mcp-slate-command.d.ts +0 -2
  26. package/dist/mcp-slate-command.d.ts.map +1 -1
  27. package/dist/mcp-slate-command.js +0 -4
  28. package/dist/mcp-slate-command.js.map +1 -1
  29. package/dist/mcp-slate-resource.d.ts.map +1 -1
  30. package/dist/mcp-slate-resource.js +6 -4
  31. package/dist/mcp-slate-resource.js.map +1 -1
  32. package/dist/mcp-slate-tool-defs.d.ts.map +1 -1
  33. package/dist/mcp-slate-tool-defs.js +8 -6
  34. package/dist/mcp-slate-tool-defs.js.map +1 -1
  35. package/dist/mcp-slate-tools.d.ts.map +1 -1
  36. package/dist/mcp-slate-tools.js +8 -1
  37. package/dist/mcp-slate-tools.js.map +1 -1
  38. package/dist/mcp-slate-ui-copy.d.ts +88 -208
  39. package/dist/mcp-slate-ui-copy.d.ts.map +1 -1
  40. package/dist/mcp-slate-ui-copy.js +58 -159
  41. package/dist/mcp-slate-ui-copy.js.map +1 -1
  42. package/dist/mcp-slate-ui-locales/de-DE.d.ts.map +1 -1
  43. package/dist/mcp-slate-ui-locales/de-DE.js +44 -83
  44. package/dist/mcp-slate-ui-locales/de-DE.js.map +1 -1
  45. package/dist/mcp-slate-ui-locales/es-419.d.ts.map +1 -1
  46. package/dist/mcp-slate-ui-locales/es-419.js +44 -83
  47. package/dist/mcp-slate-ui-locales/es-419.js.map +1 -1
  48. package/dist/mcp-slate-ui-locales/es-ES.d.ts.map +1 -1
  49. package/dist/mcp-slate-ui-locales/es-ES.js +44 -83
  50. package/dist/mcp-slate-ui-locales/es-ES.js.map +1 -1
  51. package/dist/mcp-slate-ui-locales/fr-FR.d.ts.map +1 -1
  52. package/dist/mcp-slate-ui-locales/fr-FR.js +44 -83
  53. package/dist/mcp-slate-ui-locales/fr-FR.js.map +1 -1
  54. package/dist/mcp-slate-ui-locales/hi-IN.d.ts.map +1 -1
  55. package/dist/mcp-slate-ui-locales/hi-IN.js +44 -83
  56. package/dist/mcp-slate-ui-locales/hi-IN.js.map +1 -1
  57. package/dist/mcp-slate-ui-locales/it-IT.d.ts.map +1 -1
  58. package/dist/mcp-slate-ui-locales/it-IT.js +44 -83
  59. package/dist/mcp-slate-ui-locales/it-IT.js.map +1 -1
  60. package/dist/mcp-slate-ui-locales/ja-JP.d.ts.map +1 -1
  61. package/dist/mcp-slate-ui-locales/ja-JP.js +44 -83
  62. package/dist/mcp-slate-ui-locales/ja-JP.js.map +1 -1
  63. package/dist/mcp-slate-ui-locales/ko-KR.d.ts.map +1 -1
  64. package/dist/mcp-slate-ui-locales/ko-KR.js +44 -83
  65. package/dist/mcp-slate-ui-locales/ko-KR.js.map +1 -1
  66. package/dist/mcp-slate-ui-locales/pt-BR.d.ts.map +1 -1
  67. package/dist/mcp-slate-ui-locales/pt-BR.js +44 -83
  68. package/dist/mcp-slate-ui-locales/pt-BR.js.map +1 -1
  69. package/dist/mcp-slate-ui-locales/zh-CN.d.ts.map +1 -1
  70. package/dist/mcp-slate-ui-locales/zh-CN.js +44 -83
  71. package/dist/mcp-slate-ui-locales/zh-CN.js.map +1 -1
  72. package/dist/mcp-slate-ui-locales/zh-TW.d.ts.map +1 -1
  73. package/dist/mcp-slate-ui-locales/zh-TW.js +44 -83
  74. package/dist/mcp-slate-ui-locales/zh-TW.js.map +1 -1
  75. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -1
  76. package/dist/mcp-slate-ui-script-bridge.js +19 -7
  77. package/dist/mcp-slate-ui-script-bridge.js.map +1 -1
  78. package/dist/mcp-slate-ui-script-browser.d.ts.map +1 -1
  79. package/dist/mcp-slate-ui-script-browser.js +0 -3
  80. package/dist/mcp-slate-ui-script-browser.js.map +1 -1
  81. package/dist/mcp-slate-ui-script-designs.d.ts +17 -0
  82. package/dist/mcp-slate-ui-script-designs.d.ts.map +1 -0
  83. package/dist/mcp-slate-ui-script-designs.js +365 -0
  84. package/dist/mcp-slate-ui-script-designs.js.map +1 -0
  85. package/dist/mcp-slate-ui-script-edit.d.ts +9 -0
  86. package/dist/mcp-slate-ui-script-edit.d.ts.map +1 -0
  87. package/dist/mcp-slate-ui-script-edit.js +71 -0
  88. package/dist/mcp-slate-ui-script-edit.js.map +1 -0
  89. package/dist/mcp-slate-ui-script-inline.d.ts +3 -9
  90. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -1
  91. package/dist/mcp-slate-ui-script-inline.js +28 -155
  92. package/dist/mcp-slate-ui-script-inline.js.map +1 -1
  93. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts +13 -12
  94. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts.map +1 -1
  95. package/dist/mcp-slate-ui-script-inspiration-collage.js +24 -24
  96. package/dist/mcp-slate-ui-script-inspiration-collage.js.map +1 -1
  97. package/dist/mcp-slate-ui-script-inspiration-gallery.d.ts +23 -0
  98. package/dist/mcp-slate-ui-script-inspiration-gallery.d.ts.map +1 -0
  99. package/dist/mcp-slate-ui-script-inspiration-gallery.js +221 -0
  100. package/dist/mcp-slate-ui-script-inspiration-gallery.js.map +1 -0
  101. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts +14 -21
  102. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts.map +1 -1
  103. package/dist/mcp-slate-ui-script-inspiration-grid.js +124 -196
  104. package/dist/mcp-slate-ui-script-inspiration-grid.js.map +1 -1
  105. package/dist/mcp-slate-ui-script-inspiration.d.ts +8 -9
  106. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -1
  107. package/dist/mcp-slate-ui-script-inspiration.js +213 -130
  108. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -1
  109. package/dist/mcp-slate-ui-script-l10n.d.ts.map +1 -1
  110. package/dist/mcp-slate-ui-script-l10n.js +2 -0
  111. package/dist/mcp-slate-ui-script-l10n.js.map +1 -1
  112. package/dist/mcp-slate-ui-script-more.d.ts +4 -33
  113. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -1
  114. package/dist/mcp-slate-ui-script-more.js +6 -279
  115. package/dist/mcp-slate-ui-script-more.js.map +1 -1
  116. package/dist/mcp-slate-ui-script-pause.d.ts +10 -6
  117. package/dist/mcp-slate-ui-script-pause.d.ts.map +1 -1
  118. package/dist/mcp-slate-ui-script-pause.js +45 -30
  119. package/dist/mcp-slate-ui-script-pause.js.map +1 -1
  120. package/dist/mcp-slate-ui-script-references.d.ts +19 -0
  121. package/dist/mcp-slate-ui-script-references.d.ts.map +1 -0
  122. package/dist/mcp-slate-ui-script-references.js +102 -0
  123. package/dist/mcp-slate-ui-script-references.js.map +1 -0
  124. package/dist/mcp-slate-ui-script-remote.d.ts +13 -12
  125. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -1
  126. package/dist/mcp-slate-ui-script-remote.js +46 -27
  127. package/dist/mcp-slate-ui-script-remote.js.map +1 -1
  128. package/dist/mcp-slate-ui-script-scribble.d.ts +2 -2
  129. package/dist/mcp-slate-ui-script-scribble.js +7 -7
  130. package/dist/mcp-slate-ui-script-select.d.ts +4 -9
  131. package/dist/mcp-slate-ui-script-select.d.ts.map +1 -1
  132. package/dist/mcp-slate-ui-script-select.js +13 -37
  133. package/dist/mcp-slate-ui-script-select.js.map +1 -1
  134. package/dist/mcp-slate-ui-script-stage.d.ts +4 -10
  135. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -1
  136. package/dist/mcp-slate-ui-script-stage.js +28 -141
  137. package/dist/mcp-slate-ui-script-stage.js.map +1 -1
  138. package/dist/mcp-slate-ui-script-state.d.ts +1 -1
  139. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -1
  140. package/dist/mcp-slate-ui-script-state.js +9 -4
  141. package/dist/mcp-slate-ui-script-state.js.map +1 -1
  142. package/dist/mcp-slate-ui-script-viewer.d.ts +18 -0
  143. package/dist/mcp-slate-ui-script-viewer.d.ts.map +1 -0
  144. package/dist/mcp-slate-ui-script-viewer.js +405 -0
  145. package/dist/mcp-slate-ui-script-viewer.js.map +1 -0
  146. package/dist/mcp-slate-ui-script.d.ts +4 -5
  147. package/dist/mcp-slate-ui-script.d.ts.map +1 -1
  148. package/dist/mcp-slate-ui-script.js +12 -13
  149. package/dist/mcp-slate-ui-script.js.map +1 -1
  150. package/dist/mcp-slate-ui-styles-designs.d.ts +10 -0
  151. package/dist/mcp-slate-ui-styles-designs.d.ts.map +1 -0
  152. package/dist/mcp-slate-ui-styles-designs.js +121 -0
  153. package/dist/mcp-slate-ui-styles-designs.js.map +1 -0
  154. package/dist/mcp-slate-ui-styles-inspiration.d.ts +13 -13
  155. package/dist/mcp-slate-ui-styles-inspiration.d.ts.map +1 -1
  156. package/dist/mcp-slate-ui-styles-inspiration.js +67 -33
  157. package/dist/mcp-slate-ui-styles-inspiration.js.map +1 -1
  158. package/dist/mcp-slate-ui-styles-pause.d.ts +2 -2
  159. package/dist/mcp-slate-ui-styles-pause.d.ts.map +1 -1
  160. package/dist/mcp-slate-ui-styles-pause.js +4 -8
  161. package/dist/mcp-slate-ui-styles-pause.js.map +1 -1
  162. package/dist/mcp-slate-ui-styles-stage.d.ts +3 -22
  163. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -1
  164. package/dist/mcp-slate-ui-styles-stage.js +6 -74
  165. package/dist/mcp-slate-ui-styles-stage.js.map +1 -1
  166. package/dist/mcp-slate-ui-styles.d.ts +12 -19
  167. package/dist/mcp-slate-ui-styles.d.ts.map +1 -1
  168. package/dist/mcp-slate-ui-styles.js +97 -100
  169. package/dist/mcp-slate-ui-styles.js.map +1 -1
  170. package/dist/mcp-slate-ui.d.ts +12 -12
  171. package/dist/mcp-slate-ui.d.ts.map +1 -1
  172. package/dist/mcp-slate-ui.js +24 -23
  173. package/dist/mcp-slate-ui.js.map +1 -1
  174. package/dist/server.d.ts.map +1 -1
  175. package/dist/server.js +2 -0
  176. package/dist/server.js.map +1 -1
  177. package/dist/slate-actions.d.ts +22 -1
  178. package/dist/slate-actions.d.ts.map +1 -1
  179. package/dist/slate-actions.js +46 -2
  180. package/dist/slate-actions.js.map +1 -1
  181. package/dist/slate-browser-host.d.ts +8 -7
  182. package/dist/slate-browser-host.d.ts.map +1 -1
  183. package/dist/slate-browser-host.js +13 -10
  184. package/dist/slate-browser-host.js.map +1 -1
  185. package/dist/slate-browser-server.d.ts.map +1 -1
  186. package/dist/slate-browser-server.js +10 -4
  187. package/dist/slate-browser-server.js.map +1 -1
  188. package/dist/slate-commit.d.ts.map +1 -1
  189. package/dist/slate-commit.js +12 -5
  190. package/dist/slate-commit.js.map +1 -1
  191. package/dist/slate-handoff.d.ts.map +1 -1
  192. package/dist/slate-handoff.js +2 -3
  193. package/dist/slate-handoff.js.map +1 -1
  194. package/dist/slate-ids.d.ts +2 -1
  195. package/dist/slate-ids.d.ts.map +1 -1
  196. package/dist/slate-ids.js +3 -2
  197. package/dist/slate-ids.js.map +1 -1
  198. package/dist/slate-reference-ids.d.ts.map +1 -1
  199. package/dist/slate-reference-ids.js +1 -0
  200. package/dist/slate-reference-ids.js.map +1 -1
  201. package/dist/slate-round-prompt.d.ts +19 -0
  202. package/dist/slate-round-prompt.d.ts.map +1 -1
  203. package/dist/slate-round-prompt.js +22 -0
  204. package/dist/slate-round-prompt.js.map +1 -1
  205. package/dist/slate-round-runner.d.ts.map +1 -1
  206. package/dist/slate-round-runner.js +16 -12
  207. package/dist/slate-round-runner.js.map +1 -1
  208. package/dist/slate-round-search.d.ts.map +1 -1
  209. package/dist/slate-round-search.js +2 -0
  210. package/dist/slate-round-search.js.map +1 -1
  211. package/dist/slate-runtime.d.ts +3 -0
  212. package/dist/slate-runtime.d.ts.map +1 -1
  213. package/dist/slate-runtime.js +1 -0
  214. package/dist/slate-runtime.js.map +1 -1
  215. package/dist/slate-site-references-capture.d.ts +20 -0
  216. package/dist/slate-site-references-capture.d.ts.map +1 -0
  217. package/dist/slate-site-references-capture.js +119 -0
  218. package/dist/slate-site-references-capture.js.map +1 -0
  219. package/dist/slate-site-references-client.d.ts +35 -0
  220. package/dist/slate-site-references-client.d.ts.map +1 -0
  221. package/dist/slate-site-references-client.js +36 -0
  222. package/dist/slate-site-references-client.js.map +1 -0
  223. package/dist/slate-site-references-local.d.ts +6 -0
  224. package/dist/slate-site-references-local.d.ts.map +1 -0
  225. package/dist/slate-site-references-local.js +63 -0
  226. package/dist/slate-site-references-local.js.map +1 -0
  227. package/dist/slate-site-references-suggest.d.ts +36 -0
  228. package/dist/slate-site-references-suggest.d.ts.map +1 -0
  229. package/dist/slate-site-references-suggest.js +144 -0
  230. package/dist/slate-site-references-suggest.js.map +1 -0
  231. package/dist/slate-site-references.d.ts +57 -0
  232. package/dist/slate-site-references.d.ts.map +1 -0
  233. package/dist/slate-site-references.js +129 -0
  234. package/dist/slate-site-references.js.map +1 -0
  235. package/dist/slate-view-contract.d.ts +29 -1
  236. package/dist/slate-view-contract.d.ts.map +1 -1
  237. package/dist/slate-view.d.ts.map +1 -1
  238. package/dist/slate-view.js +5 -0
  239. package/dist/slate-view.js.map +1 -1
  240. package/dist/slate-workspace-parse.d.ts +2 -0
  241. package/dist/slate-workspace-parse.d.ts.map +1 -1
  242. package/dist/slate-workspace-parse.js +20 -3
  243. package/dist/slate-workspace-parse.js.map +1 -1
  244. package/dist/slate-workspace-types.d.ts +17 -2
  245. package/dist/slate-workspace-types.d.ts.map +1 -1
  246. package/dist/workspace-draw-messages.d.ts +27 -5
  247. package/dist/workspace-draw-messages.d.ts.map +1 -1
  248. package/dist/workspace-draw-messages.js +29 -3
  249. package/dist/workspace-draw-messages.js.map +1 -1
  250. package/dist/workspace-draw-run.d.ts +12 -0
  251. package/dist/workspace-draw-run.d.ts.map +1 -1
  252. package/dist/workspace-draw-run.js +47 -18
  253. package/dist/workspace-draw-run.js.map +1 -1
  254. package/dist/workspace-draw-types.d.ts +2 -1
  255. package/dist/workspace-draw-types.d.ts.map +1 -1
  256. package/dist/workspace-draw-types.js +1 -0
  257. package/dist/workspace-draw-types.js.map +1 -1
  258. package/dist/workspace-runner-main.d.ts +5 -0
  259. package/dist/workspace-runner-main.d.ts.map +1 -1
  260. package/dist/workspace-runner-main.js +15 -3
  261. package/dist/workspace-runner-main.js.map +1 -1
  262. package/open-design.json +2 -13
  263. package/package.json +1 -1
  264. package/skills/12ui-design/SKILL.md +7 -8
  265. package/dist/mcp-slate-ui-script-dialog.d.ts +0 -21
  266. package/dist/mcp-slate-ui-script-dialog.d.ts.map +0 -1
  267. package/dist/mcp-slate-ui-script-dialog.js +0 -351
  268. package/dist/mcp-slate-ui-script-dialog.js.map +0 -1
  269. package/dist/mcp-slate-ui-script-progress.d.ts +0 -7
  270. package/dist/mcp-slate-ui-script-progress.d.ts.map +0 -1
  271. package/dist/mcp-slate-ui-script-progress.js +0 -9
  272. package/dist/mcp-slate-ui-script-progress.js.map +0 -1
  273. package/dist/mcp-slate-ui-styles-dialog.d.ts +0 -20
  274. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +0 -1
  275. package/dist/mcp-slate-ui-styles-dialog.js +0 -87
  276. package/dist/mcp-slate-ui-styles-dialog.js.map +0 -1
@@ -1,146 +1,143 @@
1
1
  /**
2
- * The workspace view's stylesheet: base and inline card (the fullscreen stage
3
- * is in mcp-slate-ui-styles-stage.ts, the dialogs in
4
- * mcp-slate-ui-styles-dialog.ts). Host variables win; the fallbacks keep the
5
- * view usable when a host passes none. System fonts only, no external
6
- * requests.
2
+ * The workspace view's stylesheet: tokens, base and the shell (the prompt card and the tab row), shared by the inline
3
+ * card and the fullscreen workspace (the stage is in mcp-slate-ui-styles-stage.ts, the Designs tab and its large view in
4
+ * mcp-slate-ui-styles-designs.ts).
7
5
  *
8
- * The layout is fluid by construction: the view never asks the host for a
9
- * width. Every flex/grid parent sets `min-width: 0` so no child can push the
10
- * frame wider than its pane, and the thumbnails wrap onto as many rows as
11
- * they need: nothing scrolls sideways.
6
+ * Every colour, border, radius and font comes from the MCP Apps standard variables the host sends
7
+ * (`hostContext.styles.variables`, which Codex sends whole, resolved for its current theme and the person's accent),
8
+ * with a neutral light and dark fallback each, keyed on `color-scheme` through `light-dark()`: the theme is
9
+ * `[data-theme]` (set by the host's shell and by `hostContext.theme`), else `window.openai.theme` (the bridge sets the
10
+ * same attribute), else `prefers-color-scheme` (a plain browser: the `12ui workspace open` page). The accent is the host's
11
+ * ring colour (selection rings), a solid accent fills the check badges, and the primary button is ink, as Codex draws
12
+ * its own. No brand colour is written here; system fonts only, no external requests.
12
13
  *
13
- * A design's thumbnail has the design's own aspect ratio (`--ar`, set by the script on each tile from its picture, or
14
- * for an option still without one from what its round draws). The strip and each round of the selection are grids of
15
- * equal columns; a column is no narrower than a size token times the square root of the row's ratio (`--shape`, also
16
- * set by the script), so tiles of any ratio have about the same area, and the columns share out what is left. The
17
- * tokens, one place each: --thumb-card (the card's strip, 124 px under a 480 px card and 170 px from it, so a 3:2
18
- * design is at least 152 or 208 px wide, a 2:3 one 101 or 139, a square one 124 or 170; at least double the picture
19
- * a 144 px square tile used to show from 480 px) and --thumb-rail (the workspace's selection, 170 px, 124 px under a
20
- * 640 px window). The container queries read the card's own width
21
- * (`main`). Every thumbnail picture (designs, inspiration, the Based on picture and the reference chips) is
22
- * `object-fit: contain`, so the whole design shows and nothing is cropped or stretched.
14
+ * The layout is fluid by construction: the view never asks the host for a width. Every flex/grid parent sets
15
+ * `min-width: 0` so no child can push the frame wider than its pane, and nothing scrolls sideways.
23
16
  */
24
17
  export const SLATE_UI_STYLES = String.raw `
25
- /* Host variables win; these fallbacks keep the view usable when a host passes none. System fonts only. */
26
18
  :root {
27
19
  color-scheme: light dark;
28
- --f-bg: light-dark(#ffffff, #1c1c1c);
29
- --f-bg2: light-dark(#f4f4f2, #2a2a2a);
30
- --f-bg3: light-dark(#e8e8e4, #3a3a3a);
31
- --f-text: light-dark(#1a1a1a, #f2f2f2);
32
- --f-text2: light-dark(#5f5f5b, #a8a8a3);
33
- --f-border: light-dark(#d9d9d3, #444440);
34
- --f-inverse: light-dark(#1a1a1a, #f2f2f2);
35
- --f-inverse-text: light-dark(#ffffff, #1a1a1a);
36
- --f-ring: light-dark(#2f6fed, #7aa2ff);
37
- --f-danger: light-dark(#b3261e, #ff8a80);
38
- --f-ok: light-dark(#1d6b3a, #6fd08c);
20
+ /* Neutral fallbacks, used only when the host omits a variable; close to Codex's own, so the first paint never jumps. */
21
+ --f-bg: light-dark(#ffffff, #181818);
22
+ --f-bg2: light-dark(#ffffff, #363636);
23
+ --f-bg3: light-dark(#f6f6f6, #141414);
24
+ --f-text: light-dark(#1a1c1f, #ffffff);
25
+ --f-text2: light-dark(rgb(26 28 31 / .5), rgb(255 255 255 / .5));
26
+ --f-border: light-dark(rgb(26 28 31 / .12), rgb(255 255 255 / .16));
27
+ --f-border2: light-dark(rgb(26 28 31 / .08), rgb(255 255 255 / .08));
28
+ --f-inverse: light-dark(#1a1c1f, #ffffff);
29
+ --f-inverse-text: light-dark(#ffffff, #0d0d0d);
30
+ --f-accent: light-dark(#2f6fed, #7aa2ff);
31
+ --f-accent-tint: light-dark(#e5f2ff, #0d273f);
32
+ --f-danger: light-dark(#e02e2a, #ff6764);
33
+ --f-ok: light-dark(#00a240, #40c977);
34
+ /* The host's variables first, the neutral fallback second. */
39
35
  --bg: var(--color-background-primary, var(--f-bg));
40
36
  --bg2: var(--color-background-secondary, var(--f-bg2));
41
37
  --bg3: var(--color-background-tertiary, var(--f-bg3));
42
38
  --text: var(--color-text-primary, var(--f-text));
43
39
  --text2: var(--color-text-secondary, var(--f-text2));
44
40
  --border: var(--color-border-primary, var(--f-border));
41
+ --border2: var(--color-border-secondary, var(--f-border2));
45
42
  --inverse: var(--color-background-inverse, var(--f-inverse));
46
43
  --inverse-text: var(--color-text-inverse, var(--f-inverse-text));
47
- --ring: var(--color-ring-primary, var(--f-ring));
48
44
  --danger: var(--color-text-danger, var(--f-danger));
49
45
  --ok: var(--color-text-success, var(--f-ok));
50
- --radius: var(--border-radius-md, 8px);
51
- --font: var(--font-sans, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
52
- --thumb-rail: 170px;
46
+ /* The accent is the host's ring colour (the person's own accent in Codex); a solid accent fills a badge. */
47
+ --ring: var(--color-ring-primary, var(--f-accent));
48
+ --accent-solid: var(--color-text-info, var(--f-accent));
49
+ --accent-tint: var(--color-background-info, var(--f-accent-tint));
50
+ /* Fills derived from the host's ink and ground, so they read in either theme whatever the host sends
51
+ (--color-background-secondary is translucent and equals the page in Codex's light theme). */
52
+ --fill: color-mix(in srgb, var(--text) 5%, var(--bg));
53
+ --fill-hover: color-mix(in srgb, var(--text) 9%, var(--bg));
54
+ --radius: var(--border-radius-md, 10px);
55
+ --radius-lg: var(--border-radius-lg, 12.5px);
56
+ --radius-xl: var(--border-radius-xl, 15px);
57
+ --font: var(--font-sans, -apple-system, "system-ui", "Segoe UI", sans-serif);
58
+ --fs-sm: var(--font-text-sm-size, 12px);
59
+ --fs-md: var(--font-text-md-size, 14px);
60
+ --fs-lg: var(--font-text-lg-size, 16px);
61
+ --elev-sm: var(--shadow-sm, 0 1px 2px -1px rgb(0 0 0 / .08));
62
+ --elev: var(--shadow-md, 0 2px 4px -1px rgb(0 0 0 / .08));
63
+ --elev-lg: var(--shadow-lg, 0 4px 8px -2px rgb(0 0 0 / .1));
53
64
  }
54
- @media (max-width: 639px) { :root { --thumb-rail: 124px; } }
55
- #card { --thumb-card: 124px; }
56
- @container (min-width: 480px) { #card { --thumb-card: 170px; } }
65
+ /* The host's shell sets data-theme before this script runs, and hostContext.theme keeps it current. */
57
66
  :root[data-theme="light"] { color-scheme: light; }
58
67
  :root[data-theme="dark"] { color-scheme: dark; }
59
68
  * { box-sizing: border-box; }
60
69
  html, body { margin: 0; }
61
- /* Fluid by construction: the app never asks the host for a width. The layout width is whatever the host gives
62
- the view (fixed width or flexible maxWidth alike), so a host can never grow the frame past its pane. */
63
70
  body {
64
71
  background: var(--bg);
65
72
  color: var(--text);
66
- font: 14px/1.45 var(--font);
73
+ font: var(--fs-md)/1.45 var(--font);
67
74
  padding: 16px;
68
75
  min-width: 0;
69
76
  }
70
77
  main { max-width: 960px; margin: 0 auto; min-width: 0; container-type: inline-size; }
71
78
  .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
72
79
  h1 { font-size: 15px; font-weight: 600; margin: 0; }
73
- .meta { color: var(--text2); font-size: 12px; }
74
- .topbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; min-width: 0; }
75
- .tabs { display: flex; gap: 4px; min-width: 0; }
76
- .tab { padding: 6px 12px; border-radius: 999px; border-color: transparent; background: transparent; color: var(--text2); font-weight: 500; }
77
- .tab[aria-selected="true"] { background: var(--bg2); color: var(--text); border-color: var(--border); }
78
- .iconbtn { display: inline-grid; place-items: center; flex: none; width: 34px; height: 34px; padding: 0; }
79
- /* The large image. Its box has the image's own aspect ratio and a capped height, so the card never jumps when the
80
- picture lands and the badge and hairline sit on the picture itself. The card caps the height at 60 percent of
81
- its own width (a container unit, so the frame's height never feeds back into it); the workspace uses the window. */
82
- .hero { position: relative; width: min(100%, calc(var(--cap, 60cqw) * var(--ar, 1.5))); aspect-ratio: var(--ar, 1.5); margin: 0 auto; min-width: 0; border-radius: var(--radius); background: var(--bg3); overflow: hidden; }
83
- #card .hero { --cap: 60cqw; }
84
- .hero.note { width: 100%; aspect-ratio: auto; background: var(--bg2); }
85
- .heroimg { display: block; width: 100%; height: 100%; object-fit: fill; user-select: none; -webkit-user-drag: none; }
86
- .heroimg.empty { background: var(--bg3); }
87
- /* An image with no source yet paints nothing. Chromium draws a 1 px silver placeholder frame inside an <img> that has
88
- no source, square-cornered, and the rounded tile around it then cuts that frame off at its corners: the clipped
89
- corners of the thumbnails that were still loading or drawing. The tile's own surface stands in until the picture
90
- arrives, and an option with no picture at all (drawing, failed, stopped) has no <img>. */
91
- .thumbbtn .thumb:not([src]), .opt .thumb:not([src]), .heroimg:not([src]) { visibility: hidden; }
92
- .heronote { padding: 32px 16px; color: var(--text2); text-align: center; overflow-wrap: anywhere; }
93
- .hero .badge, .thumbbtn .code, .opt .code { position: absolute; left: 8px; bottom: 8px; padding: 0 8px; border-radius: 999px; background: var(--inverse); color: var(--inverse-text); font-size: 12px; font-weight: 600; line-height: 20px; }
94
- .hero .hair { position: absolute; left: 0; right: 0; bottom: 0; }
95
- /* Select sits under the large image at the right, in line with the right edge of the thumbnails below; an error about
96
- a click (Select could not be recorded, the host refused the message) shows beside it and takes no room otherwise. */
97
- .pickrow { display: flex; align-items: center; gap: 12px; margin-top: 10px; min-width: 0; }
98
- .pickrow > button { flex: none; margin-left: auto; }
99
- .cardalert { flex: 1 1 0; min-width: 0; margin: 0; font-size: 12px; color: var(--danger); overflow-wrap: anywhere; }
100
- /* Every option of the strip in view, on as many rows as it takes, and the Generate more tile last; nothing scrolls. */
101
- .strip { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--thumb-card) * var(--shape, 1))), 1fr)); gap: 8px; align-items: start; margin-top: 12px; min-width: 0; }
102
- .thumbbtn, .opt, .refbtn { position: relative; padding: 0; border: 0; border-radius: 6px; background: var(--bg2); overflow: hidden; }
103
- /* A design's tile is as wide as its column and as tall as its picture's ratio makes it. */
104
- .thumbbtn, .opt { display: block; width: 100%; aspect-ratio: var(--ar, 1.5); align-self: start; }
105
- /* The tile has the picture's ratio, so the picture fills it; contain keeps the whole design if the two ever differ. */
106
- .thumb { display: block; width: 100%; height: 100%; background: var(--bg3); object-fit: contain; object-position: center; }
107
- .thumbbtn .code, .opt .code { left: 6px; bottom: 6px; padding: 0 7px; font-size: 11px; line-height: 18px; }
108
- .thumbbtn.selected, .opt.selected { box-shadow: 0 0 0 2px var(--text); }
109
- /* An option with no picture says why on its own tile, above its code: failed (the reason, recessed tile), or stopped
110
- before it was drawn (what the work said). A drawing option shimmers instead. */
111
- .tilenote { position: absolute; left: 8px; right: 8px; top: 6px; bottom: 30px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 500; line-height: 1.35; text-align: center; color: var(--text2); }
80
+
81
+ /* The prompt card: the one input of the screen, an expanding field with its button inside the card's right edge. */
82
+ .briefwrap { display: flex; align-items: center; gap: 10px; min-width: 0; margin-bottom: 14px; padding: 8px 8px 8px 16px; border: 1px solid var(--border); border-radius: var(--radius-xl); background: var(--bg); box-shadow: var(--elev-sm); }
83
+ .briefwrap:focus-within { border-color: var(--ring); }
84
+ textarea.brief {
85
+ display: block; flex: 1 1 auto; width: 100%; min-width: 0; margin: 0; padding: 6px 0; resize: none; overflow-y: hidden;
86
+ font: inherit; font-size: var(--fs-lg); line-height: 1.45; color: var(--text); background: transparent; border: 0;
87
+ max-height: calc(7 * 1.45em + 12px);
88
+ }
89
+ /* Folded to two lines until it has focus: the last line fades out. */
90
+ textarea.brief.folded { -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 1.3em), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 1.3em), transparent); cursor: text; }
91
+ textarea.brief::placeholder { color: var(--text2); }
92
+ textarea.brief:focus-visible { outline: none; }
93
+ button.promptgo { flex: none; align-self: flex-end; padding: 8px 18px; border-radius: 999px; }
94
+ #stage > .briefwrap { margin-bottom: 0; }
95
+
96
+ /* The tab row: slim underlined tabs, and at its right the quiet count and the full-screen control. */
97
+ .topbar, .stagehead { display: flex; align-items: center; gap: 12px; min-width: 0; border-bottom: 1px solid var(--border2); }
98
+ .topbar { margin-bottom: 16px; }
99
+ .tabs { display: flex; gap: 24px; min-width: 0; align-self: stretch; }
100
+ button.tab { margin-bottom: -1px; padding: 10px 0 9px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--text2); font-weight: 500; white-space: nowrap; }
101
+ button.tab:hover:not(:disabled) { background: transparent; color: var(--text); }
102
+ button.tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--text); }
103
+ button.tab:focus-visible { outline-offset: -2px; }
104
+ .selcount { margin-left: auto; font-size: var(--fs-sm); color: var(--text2); font-variant-numeric: tabular-nums; white-space: nowrap; }
105
+ .selcount:empty { display: none; }
106
+ .topbar > .iconbtn, .stagehead > .iconbtn { margin-left: auto; }
107
+ .selcount:not(:empty) + .iconbtn { margin-left: 0; }
108
+ button.iconbtn { display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--text2); }
109
+ button.iconbtn:hover:not(:disabled) { background: var(--fill); color: var(--text); }
110
+ @container (max-width: 440px) { .selcount { display: none; } .tabs { gap: 18px; } }
111
+ @media (max-width: 480px) { .selcount { display: none; } .tabs { gap: 18px; } }
112
+
113
+ .cardalert { flex: 1 1 0; min-width: 0; margin: 0; font-size: var(--fs-sm); color: var(--danger); overflow-wrap: anywhere; }
114
+ .cardalert:empty { display: none; }
115
+ /* A picture with no source yet paints nothing (Chromium draws a silver placeholder frame the rounded tile would cut). */
116
+ .thumb:not([src]) { visibility: hidden; }
117
+ .thumb { display: block; width: 100%; height: 100%; background: var(--fill); object-fit: contain; object-position: center; }
118
+ .tilenote { position: absolute; left: 8px; right: 8px; top: 6px; bottom: 6px; display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm); font-weight: 500; line-height: 1.35; text-align: center; color: var(--text2); }
112
119
  .tilenote > span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; overflow-wrap: anywhere; }
113
- .thumbbtn.failed, .opt.failed { background: var(--bg); box-shadow: inset 0 0 0 1px var(--border); }
114
- .thumbbtn.failed.selected, .opt.failed.selected { box-shadow: inset 0 0 0 1px var(--border), 0 0 0 2px var(--text); }
115
- .failed .tilenote { color: var(--danger); }
116
- .failed .code { opacity: .6; }
117
- .shimmer { background: linear-gradient(100deg, var(--bg2) 30%, var(--bg3) 50%, var(--bg2) 70%); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; }
120
+ .shimmer { background: linear-gradient(100deg, var(--fill) 30%, var(--fill-hover) 50%, var(--fill) 70%); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; }
118
121
  @keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
119
- .field { margin-top: 0; }
120
- label.lbl, span.lbl { display: block; font-size: 12px; color: var(--text2); margin-bottom: 4px; }
121
- input[type="text"], input[type="number"], select {
122
+ input[type="text"] {
122
123
  width: 100%; padding: 8px 10px; font: inherit; color: var(--text); background: var(--bg);
123
124
  border: 1px solid var(--border); border-radius: var(--radius);
124
125
  }
125
- input[type="text"]:focus-visible, input[type="number"]:focus-visible, select:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
126
+ input[type="text"]:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
126
127
  .spacer { flex: 1 1 0; min-width: 0; }
127
128
  button {
128
129
  font: inherit; font-weight: 600; padding: 8px 16px; border-radius: var(--radius);
129
- border: 1px solid var(--border); background: var(--bg2); color: var(--text); cursor: pointer;
130
+ border: 1px solid var(--border); background: var(--bg); color: var(--text); cursor: pointer;
130
131
  }
131
- button.thumbbtn, button.opt, button.refbtn { padding: 0; border: 0; }
132
+ button:hover:not(:disabled) { background: var(--fill); }
132
133
  button.primary { background: var(--inverse); color: var(--inverse-text); border-color: var(--inverse); }
134
+ button.primary:hover:not(:disabled) { background: var(--inverse); opacity: .86; }
133
135
  button:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
134
136
  button:disabled { opacity: .45; cursor: default; }
135
- .note { margin: 10px 0 0; font-size: 12px; color: var(--text2); }
136
- .hair { display: block; height: 2px; background: var(--bg3); overflow: hidden; position: relative; min-width: 0; }
137
- .hair.indeterminate::after { content: ""; position: absolute; inset: 0 auto 0 -30%; width: 30%; background: var(--text); animation: slide 1.4s ease-in-out infinite; }
138
- @keyframes slide { from { left: -30%; } to { left: 100%; } }
139
- @media (prefers-reduced-motion: reduce) {
140
- .hair.indeterminate::after { animation: none; width: 100%; left: 0; opacity: .3; }
141
- .shimmer { animation: none; }
142
- }
143
- .status { min-height: 18px; margin: 8px 0 0; font-size: 12px; overflow-wrap: anywhere; }
137
+ .note { margin: 10px 0 0; font-size: var(--fs-sm); color: var(--text2); }
138
+ @media (prefers-reduced-motion: reduce) { .shimmer { animation: none; } }
139
+ .status { min-height: 18px; margin: 8px 0 0; font-size: var(--fs-sm); overflow-wrap: anywhere; }
140
+ .status:empty { display: none; }
144
141
  .status.ok { color: var(--ok); }
145
142
  .status.err, .err { color: var(--danger); }
146
143
  #fatal { padding: 16px; color: var(--danger); }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-styles.js","sourceRoot":"","sources":["../src/mcp-slate-ui-styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4HxC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-styles.js","sourceRoot":"","sources":["../src/mcp-slate-ui-styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgIxC,CAAC"}
@@ -1,20 +1,20 @@
1
1
  import { type SlateUiTarget } from './mcp-slate-ui-script.js';
2
2
  /**
3
- * The workspace view for one target, as one self-contained HTML document: no external script,
4
- * stylesheet, font, or URL, so it renders under the strictest host sandbox.
3
+ * The workspace view for one target, as one self-contained HTML document: no external script, stylesheet or font, so
4
+ * it renders under the strictest host sandbox. Reference pictures with a public rendition load from the rendition
5
+ * origin the resource declares; everything else arrives through the app's tools.
5
6
  *
6
- * The static markup is the inline card and nothing else: the tabs, one large
7
- * image, Select under it (with the place an error about a click shows), the
8
- * strip of options on as many rows as it takes, and an icon-only control that
9
- * opens the workspace. The card has no status line: drawing shows on the
10
- * thumbnails themselves, and an option that failed says why on its own tile.
11
- * The fullscreen stage and its dialogs are built by the script into `#stage`
12
- * only when the host puts the view in fullscreen.
7
+ * The static markup is the inline card: the prompt card (the screen's one input, an expanding field the person can edit,
8
+ * with its Search button inside), then the tabs Inspiration, References and Designs with the quiet selected count and the
9
+ * icon-only control that opens the workspace, then one pane per tab and
10
+ * the host of the large view (used in the card only when the host has no fullscreen). The Designs pane is built by
11
+ * mcp-slate-ui-script-designs.ts; the Inspiration and References panes by their scripts. The fullscreen stage is
12
+ * built by the script into `#stage` only when the host puts the view in fullscreen.
13
13
  *
14
14
  * The markup's words are English, so the first paint is never blank, and each carries its catalogue key
15
- * (`data-l10n`, `data-l10n-aria`, `data-l10n-label`), so the script re-words it in the person's language before the
16
- * view shows. The document has no `lang` of its own: a host may set one before the screen is written into its
17
- * document (Codex does), and the script reads it, then sets the language it speaks.
15
+ * (`data-l10n`, `data-l10n-aria`, `data-l10n-label`, `data-l10n-placeholder`), so the script re-words it in the
16
+ * person's language before the view shows. The document has no `lang` of its own: a host may set one before the
17
+ * screen is written into its document (Codex does), and the script reads it, then sets the language it speaks.
18
18
  */
19
19
  export declare const buildSlateUiHtml: ({ target }: {
20
20
  target: SlateUiTarget;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAMlF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,GAAI,YAAY;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,KAAG,MAwCxE,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,aAAa,QAAwC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOlF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,GAAI,YAAY;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,KAAG,MAwCxE,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,aAAa,QAAwC,CAAC"}
@@ -1,25 +1,26 @@
1
1
  import { SLATE_UI_COPY as COPY } from './mcp-slate-ui-copy.js';
2
2
  import { buildSlateUiScript } from './mcp-slate-ui-script.js';
3
3
  import { SLATE_UI_STYLES } from './mcp-slate-ui-styles.js';
4
- import { SLATE_UI_DIALOG_STYLES, SLATE_UI_MORE_STYLES } from './mcp-slate-ui-styles-dialog.js';
4
+ import { SLATE_UI_INSPIRATION_STYLES } from './mcp-slate-ui-styles-inspiration.js';
5
5
  import { SLATE_UI_PAUSE_STYLES } from './mcp-slate-ui-styles-pause.js';
6
6
  import { SLATE_UI_STAGE_STYLES } from './mcp-slate-ui-styles-stage.js';
7
+ import { SLATE_UI_DESIGNS_STYLES } from './mcp-slate-ui-styles-designs.js';
7
8
  /**
8
- * The workspace view for one target, as one self-contained HTML document: no external script,
9
- * stylesheet, font, or URL, so it renders under the strictest host sandbox.
9
+ * The workspace view for one target, as one self-contained HTML document: no external script, stylesheet or font, so
10
+ * it renders under the strictest host sandbox. Reference pictures with a public rendition load from the rendition
11
+ * origin the resource declares; everything else arrives through the app's tools.
10
12
  *
11
- * The static markup is the inline card and nothing else: the tabs, one large
12
- * image, Select under it (with the place an error about a click shows), the
13
- * strip of options on as many rows as it takes, and an icon-only control that
14
- * opens the workspace. The card has no status line: drawing shows on the
15
- * thumbnails themselves, and an option that failed says why on its own tile.
16
- * The fullscreen stage and its dialogs are built by the script into `#stage`
17
- * only when the host puts the view in fullscreen.
13
+ * The static markup is the inline card: the prompt card (the screen's one input, an expanding field the person can edit,
14
+ * with its Search button inside), then the tabs Inspiration, References and Designs with the quiet selected count and the
15
+ * icon-only control that opens the workspace, then one pane per tab and
16
+ * the host of the large view (used in the card only when the host has no fullscreen). The Designs pane is built by
17
+ * mcp-slate-ui-script-designs.ts; the Inspiration and References panes by their scripts. The fullscreen stage is
18
+ * built by the script into `#stage` only when the host puts the view in fullscreen.
18
19
  *
19
20
  * The markup's words are English, so the first paint is never blank, and each carries its catalogue key
20
- * (`data-l10n`, `data-l10n-aria`, `data-l10n-label`), so the script re-words it in the person's language before the
21
- * view shows. The document has no `lang` of its own: a host may set one before the screen is written into its
22
- * document (Codex does), and the script reads it, then sets the language it speaks.
21
+ * (`data-l10n`, `data-l10n-aria`, `data-l10n-label`, `data-l10n-placeholder`), so the script re-words it in the
22
+ * person's language before the view shows. The document has no `lang` of its own: a host may set one before the
23
+ * screen is written into its document (Codex does), and the script reads it, then sets the language it speaks.
23
24
  */
24
25
  export const buildSlateUiHtml = ({ target }) => `<!doctype html>
25
26
  <html>
@@ -27,7 +28,7 @@ export const buildSlateUiHtml = ({ target }) => `<!doctype html>
27
28
  <meta charset="utf-8">
28
29
  <meta name="viewport" content="width=device-width, initial-scale=1">${target === 'local' ? '' : `\n<meta name="slate-target" content="${target}">`}
29
30
  <title>${COPY.title}</title>
30
- <style>${SLATE_UI_STYLES}${SLATE_UI_STAGE_STYLES}${SLATE_UI_DIALOG_STYLES}${SLATE_UI_MORE_STYLES}${SLATE_UI_PAUSE_STYLES}</style>
31
+ <style>${SLATE_UI_STYLES}${SLATE_UI_STAGE_STYLES}${SLATE_UI_DESIGNS_STYLES}${SLATE_UI_INSPIRATION_STYLES}${SLATE_UI_PAUSE_STYLES}</style>
31
32
  </head>
32
33
  <body>
33
34
  <div id="fatal" class="hidden" role="alert"></div>
@@ -35,26 +36,26 @@ export const buildSlateUiHtml = ({ target }) => `<!doctype html>
35
36
  <h1 class="sr" data-l10n="title">${COPY.title}</h1>
36
37
  <p class="note hidden" id="empty" data-l10n="empty">${COPY.empty}</p>
37
38
  <div id="card">
39
+ <div class="briefwrap"><textarea id="brief" class="brief" rows="1" spellcheck="false" aria-label="${COPY.briefLabel}" placeholder="${COPY.briefPlaceholder}" data-l10n-aria="briefLabel" data-l10n-placeholder="briefPlaceholder"></textarea><button id="briefgo" type="button" class="primary promptgo" data-l10n="search">${COPY.search}</button></div>
38
40
  <div class="topbar">
39
41
  <div class="tabs" role="tablist" aria-label="${COPY.title}" data-l10n-aria="title">
40
- <button type="button" role="tab" class="tab" data-tab="designs" aria-selected="true" data-l10n="tabDesigns">${COPY.tabDesigns}</button>
41
42
  <button type="button" role="tab" class="tab" data-tab="inspiration" aria-selected="false" data-l10n="tabInspiration">${COPY.tabInspiration}</button>
43
+ <button type="button" role="tab" class="tab" data-tab="references" aria-selected="false" data-l10n="tabReferences">${COPY.tabReferences}</button>
44
+ <button type="button" role="tab" class="tab" data-tab="designs" aria-selected="true" data-l10n="tabDesigns">${COPY.tabDesigns}</button>
42
45
  </div>
46
+ <span class="selcount" data-selcount aria-live="polite"></span>
43
47
  <button id="expand" type="button" class="iconbtn" aria-label="${COPY.openWorkspace}" title="${COPY.openWorkspace}" data-l10n-label="openWorkspace" disabled>
44
48
  <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/></svg>
45
49
  </button>
46
50
  </div>
51
+ <div id="pane-inspiration" class="hidden"></div>
52
+ <div id="pane-references" class="hidden"></div>
47
53
  <div id="pane-designs">
48
54
  <div id="pausebar" class="pausebar hidden"></div>
49
- <div id="hero" class="hero"></div>
50
- <div class="pickrow">
51
- <p class="cardalert" id="cardalert" role="alert"></p>
52
- <button id="select" type="button" class="primary" data-l10n="select" disabled>${COPY.select}</button>
53
- </div>
54
- <div class="strip" id="strip" role="group" aria-label="${COPY.optionsGroup}" data-l10n-aria="optionsGroup"></div>
55
- <div id="more"></div>
55
+ <p class="cardalert" id="cardalert" role="alert"></p>
56
+ <div id="designs" class="designs"></div>
56
57
  </div>
57
- <div id="pane-inspiration" class="hidden"></div>
58
+ <div id="viewer" class="hidden"></div>
58
59
  </div>
59
60
  </main>
60
61
  <div id="stage" class="hidden"></div>
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui.js","sourceRoot":"","sources":["../src/mcp-slate-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAsB,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,MAAM,EAA6B,EAAU,EAAE,CAAC;;;;sEAIb,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wCAAwC,MAAM,IAAI;SACzI,IAAI,CAAC,KAAK;SACV,eAAe,GAAG,qBAAqB,GAAG,sBAAsB,GAAG,oBAAoB,GAAG,qBAAqB;;;;;qCAKnF,IAAI,CAAC,KAAK;wDACS,IAAI,CAAC,KAAK;;;qDAGb,IAAI,CAAC,KAAK;sHACuD,IAAI,CAAC,UAAU;+HACN,IAAI,CAAC,cAAc;;sEAE5E,IAAI,CAAC,aAAa,YAAY,IAAI,CAAC,aAAa;;;;;;;;;wFAS9B,IAAI,CAAC,MAAM;;+DAEpC,IAAI,CAAC,YAAY;;;;;;;UAOtE,kBAAkB,CAAC,MAAM,CAAC;;;CAGnC,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui.js","sourceRoot":"","sources":["../src/mcp-slate-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAsB,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,MAAM,EAA6B,EAAU,EAAE,CAAC;;;;sEAIb,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wCAAwC,MAAM,IAAI;SACzI,IAAI,CAAC,KAAK;SACV,eAAe,GAAG,qBAAqB,GAAG,uBAAuB,GAAG,2BAA2B,GAAG,qBAAqB;;;;;qCAK3F,IAAI,CAAC,KAAK;wDACS,IAAI,CAAC,KAAK;;wGAEsC,IAAI,CAAC,UAAU,kBAAkB,IAAI,CAAC,gBAAgB,oKAAoK,IAAI,CAAC,MAAM;;qDAExR,IAAI,CAAC,KAAK;+HACgE,IAAI,CAAC,cAAc;6HACrB,IAAI,CAAC,aAAa;sHACzB,IAAI,CAAC,UAAU;;;sEAG/D,IAAI,CAAC,aAAa,YAAY,IAAI,CAAC,aAAa;;;;;;;;;;;;;;;UAe5G,kBAAkB,CAAC,MAAM,CAAC;;;CAGnC,CAAC;AAEF,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAWnE,OAAO,EAAoB,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAWzF,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;OAOG;IACH,MAAM,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACpD,sFAAsF;IACtF,YAAY,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,CAAC,CAAC;IACnD;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,qGAAqG;AACrG,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,MA4C3D,CAAC;AAEF,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAWnE,OAAO,EAAoB,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAYzF,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;OAOG;IACH,MAAM,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACpD,sFAAsF;IACtF,YAAY,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,CAAC,CAAC;IACnD;;;;OAIG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,qGAAqG;AACrG,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,MA6C3D,CAAC;AAEF,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E"}
package/dist/server.js CHANGED
@@ -6,6 +6,7 @@ import { readCorpusConfig } from './config.js';
6
6
  import { MCP_TOOL_DEFINITIONS } from './mcp-tool-definitions.js';
7
7
  import { callMcpTool, createMcpCorpusDependencies, createMcpToolDependencies, } from './mcp-tool-handler.js';
8
8
  import { lazyCorpus } from './slate-corpus.js';
9
+ import { startLocalReferences } from './slate-site-references-local.js';
9
10
  import { listSlateResources, readSlateResource } from './mcp-slate-resource.js';
10
11
  import { SLATE_TOOL_DEFINITIONS, createSlateToolHandler, isSlateTool, } from './mcp-slate-tools.js';
11
12
  /** Construct the transport without reading credentials; local workflow and slate tools need none. */
@@ -28,6 +29,7 @@ export const createMcpServer = (options) => {
28
29
  const slateTools = createSlateToolHandler({
29
30
  // The workspace's free reference search reads the same optional-auth corpus configuration, lazily.
30
31
  corpus: lazyCorpus(resolveCorpusConfig),
32
+ gatherReferences: (root) => { startLocalReferences(root); },
31
33
  ...options.slate,
32
34
  });
33
35
  const server = new Server({ name: PACKAGE_NAME, version: packageIdentity().version }, { capabilities: { tools: {}, resources: {} } });
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,20 @@ export type RoundAction = {
25
25
  note: string | null;
26
26
  fromVersionId: string | null;
27
27
  count: RoundOptionCount;
28
+ /** The design prompt as the person edited it on the screen; it becomes the workspace's brief. Absent: unchanged. */
29
+ brief?: string;
30
+ };
31
+ /**
32
+ * Branch: grow the other pages of the product from one design, the design attached as the identity reference. The
33
+ * pages are the person's names (one option each), or, with none, `count` pages the drawing model chooses.
34
+ */
35
+ export type BranchAction = {
36
+ kind: 'round';
37
+ mode: 'branch';
38
+ note: null;
39
+ fromVersionId: string;
40
+ count: number;
41
+ pages: string[];
28
42
  };
29
43
  export type EditAction = {
30
44
  kind: 'edit';
@@ -32,12 +46,19 @@ export type EditAction = {
32
46
  prompt: string;
33
47
  strokes: SlateStroke[];
34
48
  };
35
- export type SlateWorkAction = RoundAction | EditAction;
49
+ export type SlateWorkAction = RoundAction | BranchAction | EditAction;
50
+ export declare const BRANCH_DEFAULT_PAGES = 4;
51
+ export declare const BRANCH_MAX_PAGES = 8;
52
+ export declare const PAGE_NAME_MAX_CHARACTERS = 60;
53
+ /** The pages a branch draws when the person names none, in this order (a product without one draws its closest equivalent). */
54
+ export declare const BRANCH_DEFAULT_PAGE_NAMES: readonly ["Detail", "Sign in", "Pricing", "Settings", "Dashboard", "Search", "Profile", "Checkout"];
36
55
  /** Control characters are stripped except tab and newline; the rest is the user's text. */
37
56
  export declare const cleanUserText: (value: string) => string;
38
57
  /** Freehand strokes as integer permille points; anything outside the limits is refused, never trimmed. */
39
58
  export declare const normalizeStrokes: (value: unknown) => SlateStroke[];
40
59
  /** A missing count is the default; anything but 1, 2, 4, 6, 8 or 12 is refused, never rounded. */
41
60
  export declare const normalizeRoundCount: (value: unknown) => RoundOptionCount;
61
+ /** Page names: trimmed, inner whitespace collapsed, empty ones dropped; more than eight, or a name over 60 characters, is refused. */
62
+ export declare const normalizePages: (value: unknown) => string[];
42
63
  export declare const normalizeAction: (input: unknown) => SlateWorkAction;
43
64
  //# sourceMappingURL=slate-actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slate-actions.d.ts","sourceRoot":"","sources":["../src/slate-actions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkD,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5G;;;GAGG;AAEH,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,8BAA+B,CAAC;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,eAAO,MAAM,0BAA0B,EAAE,gBAAoB,CAAC;AAC9D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,qBAAqB,OAA8B,CAAC;AACjE;;;GAGG;AACH,eAAO,MAAM,sBAAsB,6KAA6K,CAAC;AACjN,eAAO,MAAM,aAAa;;;;CAAqE,CAAC;AAEhG,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AACrG,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,UAAU,CAAC;AAQvD,2FAA2F;AAC3F,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAG7C,CAAC;AAEF,0GAA0G;AAC1G,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,WAAW,EAsB5D,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG,gBAKpD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,eA+BhD,CAAC"}
1
+ {"version":3,"file":"slate-actions.d.ts","sourceRoot":"","sources":["../src/slate-actions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkD,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5G;;;GAGG;AAEH,4FAA4F;AAC5F,eAAO,MAAM,mBAAmB,8BAA+B,CAAC;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,eAAO,MAAM,0BAA0B,EAAE,gBAAoB,CAAC;AAC9D,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,qBAAqB,OAA8B,CAAC;AACjE;;;GAGG;AACH,eAAO,MAAM,sBAAsB,6KAA6K,CAAC;AACjN,eAAO,MAAM,aAAa;;;;CAAqE,CAAC;AAGhG,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,gBAAgB,CAAC;IACxB,oHAAoH;IACpH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAChI,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AACrG,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;AAEtE,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,+HAA+H;AAC/H,eAAO,MAAM,yBAAyB,qGAAsG,CAAC;AAQ7I,2FAA2F;AAC3F,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAG7C,CAAC;AAEF,0GAA0G;AAC1G,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,WAAW,EAsB5D,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG,gBAKpD,CAAC;AAEF,sIAAsI;AACtI,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,MAAM,EAWrD,CAAC;AAWF,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,eAsChD,CAAC"}
@@ -16,6 +16,12 @@ export const EDIT_PROMPT_MAX_BYTES = SLATE_EDIT_PROMPT_MAX_BYTES;
16
16
  */
17
17
  export const EDIT_MARKS_ONLY_PROMPT = 'Infer the change from the marks: an X or a cross-out means remove that element, a circle or a scribble means adjust it, and any words written there are the instruction.';
18
18
  export const STROKE_LIMITS = { strokes: 24, pointsPerStroke: 400, pointsTotal: 3_000 };
19
+ const ROUND_BRIEF_MAX_CHARACTERS = 2_000;
20
+ export const BRANCH_DEFAULT_PAGES = 4;
21
+ export const BRANCH_MAX_PAGES = 8;
22
+ export const PAGE_NAME_MAX_CHARACTERS = 60;
23
+ /** The pages a branch draws when the person names none, in this order (a product without one draws its closest equivalent). */
24
+ export const BRANCH_DEFAULT_PAGE_NAMES = ['Detail', 'Sign in', 'Pricing', 'Settings', 'Dashboard', 'Search', 'Profile', 'Checkout'];
19
25
  const isRecord = (value) => (!!value && typeof value === 'object' && !Array.isArray(value));
20
26
  const invalid = (message, l10n) => { throw new SlateError('invalid_input', message, l10n ? { l10n } : {}); };
21
27
  /** Control characters are stripped except tab and newline; the rest is the user's text. */
@@ -63,12 +69,42 @@ export const normalizeRoundCount = (value) => {
63
69
  return invalid(`count must be one of ${ROUND_OPTION_COUNTS.join(', ')}`);
64
70
  return allowed;
65
71
  };
72
+ /** Page names: trimmed, inner whitespace collapsed, empty ones dropped; more than eight, or a name over 60 characters, is refused. */
73
+ export const normalizePages = (value) => {
74
+ if (value === undefined || value === null)
75
+ return [];
76
+ if (!Array.isArray(value))
77
+ return invalid('pages must be a list of page names');
78
+ const pages = value.map((page) => {
79
+ if (typeof page !== 'string')
80
+ return invalid('a page name must be text');
81
+ const cleaned = cleanUserText(page).replace(/\s+/gu, ' ');
82
+ if ([...cleaned].length > PAGE_NAME_MAX_CHARACTERS)
83
+ return invalid(`A page name can be at most ${PAGE_NAME_MAX_CHARACTERS} characters.`);
84
+ return cleaned;
85
+ }).filter(Boolean);
86
+ if (pages.length > BRANCH_MAX_PAGES)
87
+ return invalid(`A branch draws at most ${BRANCH_MAX_PAGES} pages.`);
88
+ return pages;
89
+ };
90
+ const normalizeBranch = (input) => {
91
+ const fromVersionId = input.fromVersionId;
92
+ if (typeof fromVersionId !== 'string' || !VERSION_ID_PATTERN.test(fromVersionId))
93
+ return invalid('A branch needs the version it grows from (fromVersionId).');
94
+ const pages = normalizePages(input.pages);
95
+ const count = pages.length > 0 ? pages.length : (input.count ?? BRANCH_DEFAULT_PAGES);
96
+ if (typeof count !== 'number' || !Number.isInteger(count) || count < 1 || count > BRANCH_MAX_PAGES)
97
+ return invalid(`A branch draws 1 to ${BRANCH_MAX_PAGES} pages.`);
98
+ return { kind: 'round', mode: 'branch', note: null, fromVersionId, count, pages: pages.length > 0 ? pages : BRANCH_DEFAULT_PAGE_NAMES.slice(0, count) };
99
+ };
66
100
  export const normalizeAction = (input) => {
67
101
  if (!isRecord(input))
68
102
  return invalid('action must be an object');
103
+ if (input.kind === 'round' && input.mode === 'branch')
104
+ return normalizeBranch(input);
69
105
  if (input.kind === 'round') {
70
106
  if (input.mode !== 'new' && input.mode !== 'like')
71
- return invalid('mode must be new or like');
107
+ return invalid('mode must be new, like or branch');
72
108
  let note = null;
73
109
  if (input.note !== undefined && input.note !== null) {
74
110
  if (typeof input.note !== 'string')
@@ -88,7 +124,15 @@ export const normalizeAction = (input) => {
88
124
  return invalid('More like this needs the version to stay close to (fromVersionId).');
89
125
  if (input.mode === 'new' && fromVersionId !== null)
90
126
  return invalid('New options do not start from a version.');
91
- return { kind: 'round', mode: input.mode, note, fromVersionId, count: normalizeRoundCount(input.count) };
127
+ let brief = null;
128
+ if (input.brief !== undefined && input.brief !== null) {
129
+ if (typeof input.brief !== 'string')
130
+ return invalid('brief must be text');
131
+ brief = cleanUserText(input.brief).replace(/\s+/gu, ' ') || null;
132
+ if (brief !== null && [...brief].length > ROUND_BRIEF_MAX_CHARACTERS)
133
+ return invalid(`The brief can be at most ${ROUND_BRIEF_MAX_CHARACTERS} characters.`);
134
+ }
135
+ return { kind: 'round', mode: input.mode, note, fromVersionId, count: normalizeRoundCount(input.count), ...(brief === null ? {} : { brief }) };
92
136
  }
93
137
  if (input.kind === 'edit') {
94
138
  const versionId = input.versionId;