@12ui/design 0.2.80 → 0.2.82

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 (324) hide show
  1. package/README.md +8 -9
  2. package/SKILL.md +2 -8
  3. package/dist/cli-capabilities.d.ts +2 -2
  4. package/dist/cli-capabilities.js +2 -2
  5. package/dist/cli-capabilities.js.map +1 -1
  6. package/dist/cli-help/design.d.ts +1 -1
  7. package/dist/cli-help/design.d.ts.map +1 -1
  8. package/dist/cli-help/design.js +0 -1
  9. package/dist/cli-help/design.js.map +1 -1
  10. package/dist/cli-help/index.d.ts +3 -3
  11. package/dist/cli-help/workflow.d.ts +2 -2
  12. package/dist/cli-help/workflow.js +4 -4
  13. package/dist/cli-help/workflow.js.map +1 -1
  14. package/dist/cli-usage.d.ts.map +1 -1
  15. package/dist/cli-usage.js +5 -4
  16. package/dist/cli-usage.js.map +1 -1
  17. package/dist/cli-workspace-draw.d.ts.map +1 -1
  18. package/dist/cli-workspace-draw.js +2 -0
  19. package/dist/cli-workspace-draw.js.map +1 -1
  20. package/dist/cli-workspace-runner.d.ts.map +1 -1
  21. package/dist/cli-workspace-runner.js +2 -1
  22. package/dist/cli-workspace-runner.js.map +1 -1
  23. package/dist/corpus-client.d.ts +3 -0
  24. package/dist/corpus-client.d.ts.map +1 -1
  25. package/dist/corpus-client.js +2 -0
  26. package/dist/corpus-client.js.map +1 -1
  27. package/dist/corpus-public-renditions.d.ts +33 -0
  28. package/dist/corpus-public-renditions.d.ts.map +1 -0
  29. package/dist/corpus-public-renditions.js +55 -0
  30. package/dist/corpus-public-renditions.js.map +1 -0
  31. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  32. package/dist/legacy-skill-catalog.js +11 -0
  33. package/dist/legacy-skill-catalog.js.map +1 -1
  34. package/dist/mcp-slate-command.d.ts +0 -2
  35. package/dist/mcp-slate-command.d.ts.map +1 -1
  36. package/dist/mcp-slate-command.js +0 -4
  37. package/dist/mcp-slate-command.js.map +1 -1
  38. package/dist/mcp-slate-resource.d.ts.map +1 -1
  39. package/dist/mcp-slate-resource.js +6 -4
  40. package/dist/mcp-slate-resource.js.map +1 -1
  41. package/dist/mcp-slate-tool-defs.d.ts.map +1 -1
  42. package/dist/mcp-slate-tool-defs.js +8 -6
  43. package/dist/mcp-slate-tool-defs.js.map +1 -1
  44. package/dist/mcp-slate-tools.d.ts.map +1 -1
  45. package/dist/mcp-slate-tools.js +8 -1
  46. package/dist/mcp-slate-tools.js.map +1 -1
  47. package/dist/mcp-slate-ui-copy.d.ts +88 -208
  48. package/dist/mcp-slate-ui-copy.d.ts.map +1 -1
  49. package/dist/mcp-slate-ui-copy.js +58 -159
  50. package/dist/mcp-slate-ui-copy.js.map +1 -1
  51. package/dist/mcp-slate-ui-locales/de-DE.d.ts.map +1 -1
  52. package/dist/mcp-slate-ui-locales/de-DE.js +44 -83
  53. package/dist/mcp-slate-ui-locales/de-DE.js.map +1 -1
  54. package/dist/mcp-slate-ui-locales/es-419.d.ts.map +1 -1
  55. package/dist/mcp-slate-ui-locales/es-419.js +44 -83
  56. package/dist/mcp-slate-ui-locales/es-419.js.map +1 -1
  57. package/dist/mcp-slate-ui-locales/es-ES.d.ts.map +1 -1
  58. package/dist/mcp-slate-ui-locales/es-ES.js +44 -83
  59. package/dist/mcp-slate-ui-locales/es-ES.js.map +1 -1
  60. package/dist/mcp-slate-ui-locales/fr-FR.d.ts.map +1 -1
  61. package/dist/mcp-slate-ui-locales/fr-FR.js +44 -83
  62. package/dist/mcp-slate-ui-locales/fr-FR.js.map +1 -1
  63. package/dist/mcp-slate-ui-locales/hi-IN.d.ts.map +1 -1
  64. package/dist/mcp-slate-ui-locales/hi-IN.js +44 -83
  65. package/dist/mcp-slate-ui-locales/hi-IN.js.map +1 -1
  66. package/dist/mcp-slate-ui-locales/it-IT.d.ts.map +1 -1
  67. package/dist/mcp-slate-ui-locales/it-IT.js +44 -83
  68. package/dist/mcp-slate-ui-locales/it-IT.js.map +1 -1
  69. package/dist/mcp-slate-ui-locales/ja-JP.d.ts.map +1 -1
  70. package/dist/mcp-slate-ui-locales/ja-JP.js +44 -83
  71. package/dist/mcp-slate-ui-locales/ja-JP.js.map +1 -1
  72. package/dist/mcp-slate-ui-locales/ko-KR.d.ts.map +1 -1
  73. package/dist/mcp-slate-ui-locales/ko-KR.js +44 -83
  74. package/dist/mcp-slate-ui-locales/ko-KR.js.map +1 -1
  75. package/dist/mcp-slate-ui-locales/pt-BR.d.ts.map +1 -1
  76. package/dist/mcp-slate-ui-locales/pt-BR.js +44 -83
  77. package/dist/mcp-slate-ui-locales/pt-BR.js.map +1 -1
  78. package/dist/mcp-slate-ui-locales/zh-CN.d.ts.map +1 -1
  79. package/dist/mcp-slate-ui-locales/zh-CN.js +44 -83
  80. package/dist/mcp-slate-ui-locales/zh-CN.js.map +1 -1
  81. package/dist/mcp-slate-ui-locales/zh-TW.d.ts.map +1 -1
  82. package/dist/mcp-slate-ui-locales/zh-TW.js +44 -83
  83. package/dist/mcp-slate-ui-locales/zh-TW.js.map +1 -1
  84. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -1
  85. package/dist/mcp-slate-ui-script-bridge.js +19 -7
  86. package/dist/mcp-slate-ui-script-bridge.js.map +1 -1
  87. package/dist/mcp-slate-ui-script-browser.d.ts.map +1 -1
  88. package/dist/mcp-slate-ui-script-browser.js +0 -3
  89. package/dist/mcp-slate-ui-script-browser.js.map +1 -1
  90. package/dist/mcp-slate-ui-script-designs.d.ts +17 -0
  91. package/dist/mcp-slate-ui-script-designs.d.ts.map +1 -0
  92. package/dist/mcp-slate-ui-script-designs.js +365 -0
  93. package/dist/mcp-slate-ui-script-designs.js.map +1 -0
  94. package/dist/mcp-slate-ui-script-edit.d.ts +9 -0
  95. package/dist/mcp-slate-ui-script-edit.d.ts.map +1 -0
  96. package/dist/mcp-slate-ui-script-edit.js +71 -0
  97. package/dist/mcp-slate-ui-script-edit.js.map +1 -0
  98. package/dist/mcp-slate-ui-script-inline.d.ts +3 -9
  99. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -1
  100. package/dist/mcp-slate-ui-script-inline.js +28 -155
  101. package/dist/mcp-slate-ui-script-inline.js.map +1 -1
  102. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts +13 -12
  103. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts.map +1 -1
  104. package/dist/mcp-slate-ui-script-inspiration-collage.js +24 -24
  105. package/dist/mcp-slate-ui-script-inspiration-collage.js.map +1 -1
  106. package/dist/mcp-slate-ui-script-inspiration-gallery.d.ts +23 -0
  107. package/dist/mcp-slate-ui-script-inspiration-gallery.d.ts.map +1 -0
  108. package/dist/mcp-slate-ui-script-inspiration-gallery.js +221 -0
  109. package/dist/mcp-slate-ui-script-inspiration-gallery.js.map +1 -0
  110. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts +14 -21
  111. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts.map +1 -1
  112. package/dist/mcp-slate-ui-script-inspiration-grid.js +124 -196
  113. package/dist/mcp-slate-ui-script-inspiration-grid.js.map +1 -1
  114. package/dist/mcp-slate-ui-script-inspiration.d.ts +8 -9
  115. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -1
  116. package/dist/mcp-slate-ui-script-inspiration.js +213 -130
  117. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -1
  118. package/dist/mcp-slate-ui-script-l10n.d.ts.map +1 -1
  119. package/dist/mcp-slate-ui-script-l10n.js +2 -0
  120. package/dist/mcp-slate-ui-script-l10n.js.map +1 -1
  121. package/dist/mcp-slate-ui-script-more.d.ts +4 -33
  122. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -1
  123. package/dist/mcp-slate-ui-script-more.js +6 -279
  124. package/dist/mcp-slate-ui-script-more.js.map +1 -1
  125. package/dist/mcp-slate-ui-script-pause.d.ts +10 -6
  126. package/dist/mcp-slate-ui-script-pause.d.ts.map +1 -1
  127. package/dist/mcp-slate-ui-script-pause.js +45 -30
  128. package/dist/mcp-slate-ui-script-pause.js.map +1 -1
  129. package/dist/mcp-slate-ui-script-references.d.ts +19 -0
  130. package/dist/mcp-slate-ui-script-references.d.ts.map +1 -0
  131. package/dist/mcp-slate-ui-script-references.js +102 -0
  132. package/dist/mcp-slate-ui-script-references.js.map +1 -0
  133. package/dist/mcp-slate-ui-script-remote.d.ts +13 -12
  134. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -1
  135. package/dist/mcp-slate-ui-script-remote.js +46 -27
  136. package/dist/mcp-slate-ui-script-remote.js.map +1 -1
  137. package/dist/mcp-slate-ui-script-scribble.d.ts +2 -2
  138. package/dist/mcp-slate-ui-script-scribble.js +7 -7
  139. package/dist/mcp-slate-ui-script-select.d.ts +4 -9
  140. package/dist/mcp-slate-ui-script-select.d.ts.map +1 -1
  141. package/dist/mcp-slate-ui-script-select.js +13 -37
  142. package/dist/mcp-slate-ui-script-select.js.map +1 -1
  143. package/dist/mcp-slate-ui-script-stage.d.ts +4 -10
  144. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -1
  145. package/dist/mcp-slate-ui-script-stage.js +28 -141
  146. package/dist/mcp-slate-ui-script-stage.js.map +1 -1
  147. package/dist/mcp-slate-ui-script-state.d.ts +1 -1
  148. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -1
  149. package/dist/mcp-slate-ui-script-state.js +9 -4
  150. package/dist/mcp-slate-ui-script-state.js.map +1 -1
  151. package/dist/mcp-slate-ui-script-viewer.d.ts +18 -0
  152. package/dist/mcp-slate-ui-script-viewer.d.ts.map +1 -0
  153. package/dist/mcp-slate-ui-script-viewer.js +405 -0
  154. package/dist/mcp-slate-ui-script-viewer.js.map +1 -0
  155. package/dist/mcp-slate-ui-script.d.ts +4 -5
  156. package/dist/mcp-slate-ui-script.d.ts.map +1 -1
  157. package/dist/mcp-slate-ui-script.js +12 -13
  158. package/dist/mcp-slate-ui-script.js.map +1 -1
  159. package/dist/mcp-slate-ui-styles-designs.d.ts +10 -0
  160. package/dist/mcp-slate-ui-styles-designs.d.ts.map +1 -0
  161. package/dist/mcp-slate-ui-styles-designs.js +121 -0
  162. package/dist/mcp-slate-ui-styles-designs.js.map +1 -0
  163. package/dist/mcp-slate-ui-styles-inspiration.d.ts +13 -13
  164. package/dist/mcp-slate-ui-styles-inspiration.d.ts.map +1 -1
  165. package/dist/mcp-slate-ui-styles-inspiration.js +67 -33
  166. package/dist/mcp-slate-ui-styles-inspiration.js.map +1 -1
  167. package/dist/mcp-slate-ui-styles-pause.d.ts +2 -2
  168. package/dist/mcp-slate-ui-styles-pause.d.ts.map +1 -1
  169. package/dist/mcp-slate-ui-styles-pause.js +4 -8
  170. package/dist/mcp-slate-ui-styles-pause.js.map +1 -1
  171. package/dist/mcp-slate-ui-styles-stage.d.ts +3 -22
  172. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -1
  173. package/dist/mcp-slate-ui-styles-stage.js +6 -74
  174. package/dist/mcp-slate-ui-styles-stage.js.map +1 -1
  175. package/dist/mcp-slate-ui-styles.d.ts +12 -19
  176. package/dist/mcp-slate-ui-styles.d.ts.map +1 -1
  177. package/dist/mcp-slate-ui-styles.js +97 -100
  178. package/dist/mcp-slate-ui-styles.js.map +1 -1
  179. package/dist/mcp-slate-ui.d.ts +12 -12
  180. package/dist/mcp-slate-ui.d.ts.map +1 -1
  181. package/dist/mcp-slate-ui.js +24 -23
  182. package/dist/mcp-slate-ui.js.map +1 -1
  183. package/dist/mcp-workflow-tools.js +2 -2
  184. package/dist/mcp-workflow-tools.js.map +1 -1
  185. package/dist/review-files-server.d.ts +8 -0
  186. package/dist/review-files-server.d.ts.map +1 -0
  187. package/dist/review-files-server.js +133 -0
  188. package/dist/review-files-server.js.map +1 -0
  189. package/dist/review-page-assets.d.ts +1 -1
  190. package/dist/review-page-assets.d.ts.map +1 -1
  191. package/dist/review-page-assets.js +3 -1
  192. package/dist/review-page-assets.js.map +1 -1
  193. package/dist/review-page.d.ts +8 -1
  194. package/dist/review-page.d.ts.map +1 -1
  195. package/dist/review-page.js +32 -21
  196. package/dist/review-page.js.map +1 -1
  197. package/dist/review-server-guard.d.ts +33 -0
  198. package/dist/review-server-guard.d.ts.map +1 -0
  199. package/dist/review-server-guard.js +65 -0
  200. package/dist/review-server-guard.js.map +1 -0
  201. package/dist/review-server.d.ts +2 -0
  202. package/dist/review-server.d.ts.map +1 -1
  203. package/dist/review-server.js +45 -74
  204. package/dist/review-server.js.map +1 -1
  205. package/dist/server.d.ts.map +1 -1
  206. package/dist/server.js +2 -0
  207. package/dist/server.js.map +1 -1
  208. package/dist/slate-actions.d.ts +22 -1
  209. package/dist/slate-actions.d.ts.map +1 -1
  210. package/dist/slate-actions.js +46 -2
  211. package/dist/slate-actions.js.map +1 -1
  212. package/dist/slate-browser-host.d.ts +8 -7
  213. package/dist/slate-browser-host.d.ts.map +1 -1
  214. package/dist/slate-browser-host.js +13 -10
  215. package/dist/slate-browser-host.js.map +1 -1
  216. package/dist/slate-browser-server.d.ts.map +1 -1
  217. package/dist/slate-browser-server.js +10 -4
  218. package/dist/slate-browser-server.js.map +1 -1
  219. package/dist/slate-commit.d.ts.map +1 -1
  220. package/dist/slate-commit.js +12 -5
  221. package/dist/slate-commit.js.map +1 -1
  222. package/dist/slate-handoff.d.ts.map +1 -1
  223. package/dist/slate-handoff.js +2 -3
  224. package/dist/slate-handoff.js.map +1 -1
  225. package/dist/slate-ids.d.ts +2 -1
  226. package/dist/slate-ids.d.ts.map +1 -1
  227. package/dist/slate-ids.js +3 -2
  228. package/dist/slate-ids.js.map +1 -1
  229. package/dist/slate-reference-ids.d.ts.map +1 -1
  230. package/dist/slate-reference-ids.js +1 -0
  231. package/dist/slate-reference-ids.js.map +1 -1
  232. package/dist/slate-round-prompt.d.ts +19 -0
  233. package/dist/slate-round-prompt.d.ts.map +1 -1
  234. package/dist/slate-round-prompt.js +22 -0
  235. package/dist/slate-round-prompt.js.map +1 -1
  236. package/dist/slate-round-runner.d.ts.map +1 -1
  237. package/dist/slate-round-runner.js +16 -12
  238. package/dist/slate-round-runner.js.map +1 -1
  239. package/dist/slate-round-search.d.ts.map +1 -1
  240. package/dist/slate-round-search.js +2 -0
  241. package/dist/slate-round-search.js.map +1 -1
  242. package/dist/slate-runtime.d.ts +3 -0
  243. package/dist/slate-runtime.d.ts.map +1 -1
  244. package/dist/slate-runtime.js +1 -0
  245. package/dist/slate-runtime.js.map +1 -1
  246. package/dist/slate-site-references-capture.d.ts +20 -0
  247. package/dist/slate-site-references-capture.d.ts.map +1 -0
  248. package/dist/slate-site-references-capture.js +119 -0
  249. package/dist/slate-site-references-capture.js.map +1 -0
  250. package/dist/slate-site-references-client.d.ts +35 -0
  251. package/dist/slate-site-references-client.d.ts.map +1 -0
  252. package/dist/slate-site-references-client.js +36 -0
  253. package/dist/slate-site-references-client.js.map +1 -0
  254. package/dist/slate-site-references-local.d.ts +6 -0
  255. package/dist/slate-site-references-local.d.ts.map +1 -0
  256. package/dist/slate-site-references-local.js +63 -0
  257. package/dist/slate-site-references-local.js.map +1 -0
  258. package/dist/slate-site-references-suggest.d.ts +36 -0
  259. package/dist/slate-site-references-suggest.d.ts.map +1 -0
  260. package/dist/slate-site-references-suggest.js +144 -0
  261. package/dist/slate-site-references-suggest.js.map +1 -0
  262. package/dist/slate-site-references.d.ts +57 -0
  263. package/dist/slate-site-references.d.ts.map +1 -0
  264. package/dist/slate-site-references.js +129 -0
  265. package/dist/slate-site-references.js.map +1 -0
  266. package/dist/slate-view-contract.d.ts +29 -1
  267. package/dist/slate-view-contract.d.ts.map +1 -1
  268. package/dist/slate-view.d.ts.map +1 -1
  269. package/dist/slate-view.js +5 -0
  270. package/dist/slate-view.js.map +1 -1
  271. package/dist/slate-workspace-parse.d.ts +2 -0
  272. package/dist/slate-workspace-parse.d.ts.map +1 -1
  273. package/dist/slate-workspace-parse.js +20 -3
  274. package/dist/slate-workspace-parse.js.map +1 -1
  275. package/dist/slate-workspace-types.d.ts +17 -2
  276. package/dist/slate-workspace-types.d.ts.map +1 -1
  277. package/dist/workflow/adapter-12ui.js +1 -1
  278. package/dist/workflow/adapter-12ui.js.map +1 -1
  279. package/dist/workflow/adapters.d.ts.map +1 -1
  280. package/dist/workflow/adapters.js +3 -3
  281. package/dist/workflow/adapters.js.map +1 -1
  282. package/dist/workflow/providers.js +2 -2
  283. package/dist/workflow/providers.js.map +1 -1
  284. package/dist/workflow/routing.d.ts +8 -1
  285. package/dist/workflow/routing.d.ts.map +1 -1
  286. package/dist/workflow/routing.js +9 -2
  287. package/dist/workflow/routing.js.map +1 -1
  288. package/dist/workflow/types.d.ts +5 -2
  289. package/dist/workflow/types.d.ts.map +1 -1
  290. package/dist/workflow/types.js.map +1 -1
  291. package/dist/workflow-transport.d.ts.map +1 -1
  292. package/dist/workflow-transport.js +4 -2
  293. package/dist/workflow-transport.js.map +1 -1
  294. package/dist/workspace-draw-messages.d.ts +27 -5
  295. package/dist/workspace-draw-messages.d.ts.map +1 -1
  296. package/dist/workspace-draw-messages.js +29 -3
  297. package/dist/workspace-draw-messages.js.map +1 -1
  298. package/dist/workspace-draw-run.d.ts +12 -0
  299. package/dist/workspace-draw-run.d.ts.map +1 -1
  300. package/dist/workspace-draw-run.js +47 -18
  301. package/dist/workspace-draw-run.js.map +1 -1
  302. package/dist/workspace-draw-types.d.ts +2 -1
  303. package/dist/workspace-draw-types.d.ts.map +1 -1
  304. package/dist/workspace-draw-types.js +1 -0
  305. package/dist/workspace-draw-types.js.map +1 -1
  306. package/dist/workspace-runner-main.d.ts +5 -0
  307. package/dist/workspace-runner-main.d.ts.map +1 -1
  308. package/dist/workspace-runner-main.js +15 -3
  309. package/dist/workspace-runner-main.js.map +1 -1
  310. package/open-design.json +2 -13
  311. package/package.json +1 -1
  312. package/skills/12ui-design/SKILL.md +7 -8
  313. package/dist/mcp-slate-ui-script-dialog.d.ts +0 -21
  314. package/dist/mcp-slate-ui-script-dialog.d.ts.map +0 -1
  315. package/dist/mcp-slate-ui-script-dialog.js +0 -351
  316. package/dist/mcp-slate-ui-script-dialog.js.map +0 -1
  317. package/dist/mcp-slate-ui-script-progress.d.ts +0 -7
  318. package/dist/mcp-slate-ui-script-progress.d.ts.map +0 -1
  319. package/dist/mcp-slate-ui-script-progress.js +0 -9
  320. package/dist/mcp-slate-ui-script-progress.js.map +0 -1
  321. package/dist/mcp-slate-ui-styles-dialog.d.ts +0 -20
  322. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +0 -1
  323. package/dist/mcp-slate-ui-styles-dialog.js +0 -87
  324. 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"}
@@ -34,11 +34,11 @@ export const MCP_WORKFLOW_TOOL_DEFINITIONS = [
34
34
  },
35
35
  {
36
36
  name: 'design.workflow.execute',
37
- description: 'Route a prepared operation. Image, image-edit and convert work runs only through the 12ui CLI\'s own providers (the 12ui API, or the OpenAI API for images, each with explicit allowPaid), never a host session. Text and code may go to a declared session (a handoff to complete with host tools, then register), a local CLI, or an explicitly authorized paid provider. Ambiguous dispatched work is not retried on another provider.',
37
+ description: 'Route a prepared operation. Image, image-edit and convert work runs only through the 12ui CLI\'s own providers (the 12ui API on the 12ui sign-in, or the OpenAI API for images when the user opts in with allowPaid), never a host session. Text and code may go to a declared session (a handoff to complete with host tools, then register), a local CLI, the 12ui API, or the OpenAI API under allowPaid. Ambiguous dispatched work is not retried on another provider.',
38
38
  inputSchema: object({
39
39
  workspace, operationId: string,
40
40
  providers: { type: 'array', minItems: 1, uniqueItems: true, items: { enum: [...PROVIDERS] }, description: 'Provider preference order. A session is eligible only for explicitly declared capabilities.' },
41
- allowPaid: { type: 'array', uniqueItems: true, items: { enum: ['openai', '12ui'] }, description: 'Explicit permission for providers funded by API keys or 12ui credits. Key presence is not permission.' },
41
+ allowPaid: { type: 'array', uniqueItems: true, items: { enum: ['openai', '12ui'] }, description: 'The user\'s opt-in to spend on their own OpenAI API key ("openai"). Key presence is not that opt-in. 12ui credit use needs no permission; a "12ui" entry changes nothing.' },
42
42
  sessionCapabilities: capabilityList,
43
43
  trustCodexConfig,
44
44
  }, ['workspace', 'operationId']),
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-workflow-tools.js","sourceRoot":"","sources":["../src/mcp-workflow-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,qBAAqB,EAAsD,MAAM,yBAAyB,CAAC;AAE9J,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,QAAiB,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AACzD,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,gDAAgD,EAAE,CAAC;AAC/F,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,OAAgB,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,4IAA4I,EAAE,CAAC;AAC5Q,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,SAAkB,EAAE,WAAW,EAAE,wKAAwK,EAAE,CAAC;AAC7O,MAAM,MAAM,GAAG,CAAC,UAAkC,EAAE,WAAqB,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;AACjK,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,mDAAmD,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAC7L,MAAM,QAAQ,GAAG,MAAM,CAAC;IACtB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,SAAS,EAAE,MAAM;IAClG,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAC5J,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,6BAA6B,GAAW;IACnD;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,+LAA+L;QAC5M,WAAW,EAAE;YACX,GAAG,MAAM,CAAC;gBACR,SAAS,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,gFAAgF,EAAE;gBAC5H,OAAO,EAAE,MAAM,CAAC;oBACd,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM;oBACvD,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;oBAC1C,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;oBAC9G,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC/B,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAChD,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,qBAAqB,CAAC,EAAE;gBAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;aACxG,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACxB,KAAK,EAAE;gBACL,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC9F,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE;aAClE;SACF;KACF;IACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,2aAA2a;QACxb,WAAW,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,WAAW,EAAE,MAAM;YAC9B,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,6FAA6F,EAAE;YACzM,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,uGAAuG,EAAE;YAC1M,mBAAmB,EAAE,cAAc;YACnC,gBAAgB;SACjB,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;KACjC;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,wJAAwJ;QACrK,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,gDAAgD,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC;gBAClL,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aACvG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;KAC/D;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,uKAAuK;QACpL,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;KACtF;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,0OAA0O;QACvP,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,gEAAgE,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC;gBACnM,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE;aAC7H,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;KACpG;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,sHAAsH;QACnI,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;QACtE,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,yHAAyH;QACtI,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;KACzG;IACD;QACE,IAAI,EAAE,8BAA8B;QACpC,WAAW,EAAE,oLAAoL;QACjM,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;QACzF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,qNAAqN;QAClO,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;KAC1H;IACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,iMAAiM;QAC9M,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YACzF,QAAQ,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;SAC3H,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;KACzB;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,0RAA0R;QACvS,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACrF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC;OACvF,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAmB,CAAC,CAAC;AAExF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,IAAa,EAAE,OAAkC;IACpG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;IAC7E,OAAO,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAmB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACxG,CAAC"}
1
+ {"version":3,"file":"mcp-workflow-tools.js","sourceRoot":"","sources":["../src/mcp-workflow-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ReviewModel } from './review-types.js';
2
+ export type ReviewFilesServer = {
3
+ port: number;
4
+ close: () => Promise<void>;
5
+ };
6
+ /** Serves `/files/<run>/<path>` for the runs `model()` currently lists, read-only, on its own loopback port. */
7
+ export declare const startReviewFilesServer: (model: () => ReviewModel) => Promise<ReviewFilesServer>;
8
+ //# sourceMappingURL=review-files-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-files-server.d.ts","sourceRoot":"","sources":["../src/review-files-server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkFrD,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAE7E,gHAAgH;AAChH,eAAO,MAAM,sBAAsB,GAAU,OAAO,MAAM,WAAW,KAAG,OAAO,CAAC,iBAAiB,CA6ChG,CAAC"}
@@ -0,0 +1,133 @@
1
+ import { createReadStream } from 'node:fs';
2
+ import { realpath, stat } from 'node:fs/promises';
3
+ import http from 'node:http';
4
+ import path from 'node:path';
5
+ import { assertReviewFileAccess } from './review-server-guard.js';
6
+ /**
7
+ * THE RUN FILES' OWN ORIGIN. `12ui review` serves a run's files (its HTML, scripts, fonts, images) from a second
8
+ * loopback port, not the review page's: a run's HTML opened from the page, or framed in it, is then a normal page at
9
+ * an origin that holds no session token and takes no request that changes anything (`assertReviewFileAccess`). It
10
+ * runs as it would anywhere (module scripts, fetches of its own files, local `@font-face`, storage), and the browser's
11
+ * same-origin policy keeps it from reading the review page, whose server refuses its requests by Origin
12
+ * (`assertReviewAccess`).
13
+ */
14
+ const CONTENT_TYPES = {
15
+ '.avif': 'image/avif',
16
+ '.css': 'text/css; charset=utf-8',
17
+ '.gif': 'image/gif',
18
+ '.htm': 'text/html; charset=utf-8',
19
+ '.html': 'text/html; charset=utf-8',
20
+ '.ico': 'image/x-icon',
21
+ '.jpeg': 'image/jpeg',
22
+ '.jpg': 'image/jpeg',
23
+ '.js': 'text/javascript; charset=utf-8',
24
+ '.json': 'application/json; charset=utf-8',
25
+ '.map': 'application/json; charset=utf-8',
26
+ '.mjs': 'text/javascript; charset=utf-8',
27
+ '.otf': 'font/otf',
28
+ '.png': 'image/png',
29
+ '.svg': 'image/svg+xml',
30
+ '.ttf': 'font/ttf',
31
+ '.txt': 'text/plain; charset=utf-8',
32
+ '.wasm': 'application/wasm',
33
+ '.webmanifest': 'application/manifest+json',
34
+ '.webp': 'image/webp',
35
+ '.woff': 'font/woff',
36
+ '.woff2': 'font/woff2',
37
+ };
38
+ const serveRunFile = async (args) => {
39
+ const segments = args.pathname.split('/').slice(2).map((segment) => decodeURIComponent(segment));
40
+ const runId = segments.shift();
41
+ const run = args.model.runs.find((candidate) => candidate.id === runId);
42
+ if (!run || segments.length === 0 || segments.some((segment) => (!segment
43
+ || segment === '.'
44
+ || segment === '..'
45
+ || segment.startsWith('.')
46
+ || segment.includes('/')
47
+ || segment.includes('\\')))) {
48
+ args.response.writeHead(404).end('not found');
49
+ return;
50
+ }
51
+ const root = await realpath(run.root).catch(() => null);
52
+ const candidate = path.resolve(run.root, ...segments);
53
+ const file = await realpath(candidate).catch(() => null);
54
+ if (!root || !file || (file !== root && !file.startsWith(`${root}${path.sep}`))) {
55
+ args.response.writeHead(403).end('forbidden');
56
+ return;
57
+ }
58
+ if (path.relative(root, file).split(path.sep).some((segment) => segment.startsWith('.'))) {
59
+ args.response.writeHead(404).end('not found');
60
+ return;
61
+ }
62
+ const details = await stat(file).catch(() => null);
63
+ if (!details?.isFile()) {
64
+ args.response.writeHead(404).end('not found');
65
+ return;
66
+ }
67
+ args.response.writeHead(200, {
68
+ 'content-type': CONTENT_TYPES[path.extname(file).toLowerCase()] ?? 'application/octet-stream',
69
+ 'content-length': details.size,
70
+ 'cache-control': 'no-store',
71
+ 'x-content-type-options': 'nosniff',
72
+ });
73
+ if (args.method === 'HEAD')
74
+ args.response.end();
75
+ else
76
+ createReadStream(file).pipe(args.response);
77
+ };
78
+ /** Serves `/files/<run>/<path>` for the runs `model()` currently lists, read-only, on its own loopback port. */
79
+ export const startReviewFilesServer = async (model) => {
80
+ let port = 0;
81
+ const server = http.createServer(async (request, response) => {
82
+ const method = request.method ?? 'GET';
83
+ try {
84
+ assertReviewFileAccess(request, { port });
85
+ }
86
+ catch (error) {
87
+ const refused = error;
88
+ response.writeHead(refused.status, { 'content-type': 'text/plain; charset=utf-8', allow: 'GET, HEAD' }).end(refused.message);
89
+ return;
90
+ }
91
+ let pathname;
92
+ try {
93
+ pathname = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;
94
+ }
95
+ catch {
96
+ response.writeHead(400).end('bad request');
97
+ return;
98
+ }
99
+ if (!pathname.startsWith('/files/')) {
100
+ response.writeHead(404).end('not found');
101
+ return;
102
+ }
103
+ try {
104
+ await serveRunFile({ model: model(), pathname, method, response });
105
+ }
106
+ catch {
107
+ if (!response.headersSent)
108
+ response.writeHead(400).end('bad request');
109
+ else
110
+ response.destroy();
111
+ }
112
+ });
113
+ await new Promise((resolve, reject) => {
114
+ server.once('error', reject);
115
+ server.listen(0, '127.0.0.1', () => resolve());
116
+ });
117
+ const address = server.address();
118
+ if (!address || typeof address === 'string') {
119
+ await new Promise((resolve) => server.close(() => resolve()));
120
+ throw new Error('Review file server did not bind a local TCP port');
121
+ }
122
+ port = address.port;
123
+ return {
124
+ port,
125
+ close: () => new Promise((resolve, reject) => {
126
+ server.close((error) => { if (error)
127
+ reject(error);
128
+ else
129
+ resolve(); });
130
+ }),
131
+ };
132
+ };
133
+ //# sourceMappingURL=review-files-server.js.map