@12ui/design 0.2.76 → 0.2.78

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 (337) hide show
  1. package/SKILL.md +1 -1
  2. package/dist/cli-codex-readiness.d.ts +6 -0
  3. package/dist/cli-codex-readiness.d.ts.map +1 -1
  4. package/dist/cli-codex-readiness.js +12 -12
  5. package/dist/cli-codex-readiness.js.map +1 -1
  6. package/dist/cli-help/design.d.ts +2 -2
  7. package/dist/cli-help/design.d.ts.map +1 -1
  8. package/dist/cli-help/design.js +2 -0
  9. package/dist/cli-help/design.js.map +1 -1
  10. package/dist/cli-help/index.d.ts +2 -2
  11. package/dist/cli-review-command.d.ts.map +1 -1
  12. package/dist/cli-review-command.js +2 -0
  13. package/dist/cli-review-command.js.map +1 -1
  14. package/dist/cli-run.d.ts.map +1 -1
  15. package/dist/cli-run.js +6 -0
  16. package/dist/cli-run.js.map +1 -1
  17. package/dist/cli-workspace-draw.d.ts +1 -11
  18. package/dist/cli-workspace-draw.d.ts.map +1 -1
  19. package/dist/cli-workspace-draw.js +18 -18
  20. package/dist/cli-workspace-draw.js.map +1 -1
  21. package/dist/cli-workspace-runner.d.ts +30 -0
  22. package/dist/cli-workspace-runner.d.ts.map +1 -0
  23. package/dist/cli-workspace-runner.js +105 -0
  24. package/dist/cli-workspace-runner.js.map +1 -0
  25. package/dist/mcp-slate-image.js +1 -1
  26. package/dist/mcp-slate-image.js.map +1 -1
  27. package/dist/mcp-slate-tool-defs.js +1 -1
  28. package/dist/mcp-slate-tool-defs.js.map +1 -1
  29. package/dist/mcp-slate-ui-copy.d.ts +403 -33
  30. package/dist/mcp-slate-ui-copy.d.ts.map +1 -1
  31. package/dist/mcp-slate-ui-copy.js +247 -57
  32. package/dist/mcp-slate-ui-copy.js.map +1 -1
  33. package/dist/mcp-slate-ui-icu.d.ts +47 -0
  34. package/dist/mcp-slate-ui-icu.d.ts.map +1 -0
  35. package/dist/mcp-slate-ui-icu.js +229 -0
  36. package/dist/mcp-slate-ui-icu.js.map +1 -0
  37. package/dist/mcp-slate-ui-locale-match.d.ts +12 -0
  38. package/dist/mcp-slate-ui-locale-match.d.ts.map +1 -0
  39. package/dist/mcp-slate-ui-locale-match.js +34 -0
  40. package/dist/mcp-slate-ui-locale-match.js.map +1 -0
  41. package/dist/mcp-slate-ui-locales/de-DE.d.ts +9 -0
  42. package/dist/mcp-slate-ui-locales/de-DE.d.ts.map +1 -0
  43. package/dist/mcp-slate-ui-locales/de-DE.js +217 -0
  44. package/dist/mcp-slate-ui-locales/de-DE.js.map +1 -0
  45. package/dist/mcp-slate-ui-locales/es-419.d.ts +9 -0
  46. package/dist/mcp-slate-ui-locales/es-419.d.ts.map +1 -0
  47. package/dist/mcp-slate-ui-locales/es-419.js +217 -0
  48. package/dist/mcp-slate-ui-locales/es-419.js.map +1 -0
  49. package/dist/mcp-slate-ui-locales/es-ES.d.ts +9 -0
  50. package/dist/mcp-slate-ui-locales/es-ES.d.ts.map +1 -0
  51. package/dist/mcp-slate-ui-locales/es-ES.js +217 -0
  52. package/dist/mcp-slate-ui-locales/es-ES.js.map +1 -0
  53. package/dist/mcp-slate-ui-locales/fr-FR.d.ts +9 -0
  54. package/dist/mcp-slate-ui-locales/fr-FR.d.ts.map +1 -0
  55. package/dist/mcp-slate-ui-locales/fr-FR.js +217 -0
  56. package/dist/mcp-slate-ui-locales/fr-FR.js.map +1 -0
  57. package/dist/mcp-slate-ui-locales/hi-IN.d.ts +9 -0
  58. package/dist/mcp-slate-ui-locales/hi-IN.d.ts.map +1 -0
  59. package/dist/mcp-slate-ui-locales/hi-IN.js +217 -0
  60. package/dist/mcp-slate-ui-locales/hi-IN.js.map +1 -0
  61. package/dist/mcp-slate-ui-locales/index.d.ts +11 -0
  62. package/dist/mcp-slate-ui-locales/index.d.ts.map +1 -0
  63. package/dist/mcp-slate-ui-locales/index.js +34 -0
  64. package/dist/mcp-slate-ui-locales/index.js.map +1 -0
  65. package/dist/mcp-slate-ui-locales/it-IT.d.ts +9 -0
  66. package/dist/mcp-slate-ui-locales/it-IT.d.ts.map +1 -0
  67. package/dist/mcp-slate-ui-locales/it-IT.js +217 -0
  68. package/dist/mcp-slate-ui-locales/it-IT.js.map +1 -0
  69. package/dist/mcp-slate-ui-locales/ja-JP.d.ts +9 -0
  70. package/dist/mcp-slate-ui-locales/ja-JP.d.ts.map +1 -0
  71. package/dist/mcp-slate-ui-locales/ja-JP.js +217 -0
  72. package/dist/mcp-slate-ui-locales/ja-JP.js.map +1 -0
  73. package/dist/mcp-slate-ui-locales/ko-KR.d.ts +9 -0
  74. package/dist/mcp-slate-ui-locales/ko-KR.d.ts.map +1 -0
  75. package/dist/mcp-slate-ui-locales/ko-KR.js +217 -0
  76. package/dist/mcp-slate-ui-locales/ko-KR.js.map +1 -0
  77. package/dist/mcp-slate-ui-locales/pt-BR.d.ts +9 -0
  78. package/dist/mcp-slate-ui-locales/pt-BR.d.ts.map +1 -0
  79. package/dist/mcp-slate-ui-locales/pt-BR.js +217 -0
  80. package/dist/mcp-slate-ui-locales/pt-BR.js.map +1 -0
  81. package/dist/mcp-slate-ui-locales/zh-CN.d.ts +9 -0
  82. package/dist/mcp-slate-ui-locales/zh-CN.d.ts.map +1 -0
  83. package/dist/mcp-slate-ui-locales/zh-CN.js +217 -0
  84. package/dist/mcp-slate-ui-locales/zh-CN.js.map +1 -0
  85. package/dist/mcp-slate-ui-locales/zh-TW.d.ts +9 -0
  86. package/dist/mcp-slate-ui-locales/zh-TW.d.ts.map +1 -0
  87. package/dist/mcp-slate-ui-locales/zh-TW.js +217 -0
  88. package/dist/mcp-slate-ui-locales/zh-TW.js.map +1 -0
  89. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -1
  90. package/dist/mcp-slate-ui-script-bridge.js +8 -9
  91. package/dist/mcp-slate-ui-script-bridge.js.map +1 -1
  92. package/dist/mcp-slate-ui-script-dialog.d.ts.map +1 -1
  93. package/dist/mcp-slate-ui-script-dialog.js +60 -30
  94. package/dist/mcp-slate-ui-script-dialog.js.map +1 -1
  95. package/dist/mcp-slate-ui-script-inline.d.ts +9 -6
  96. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -1
  97. package/dist/mcp-slate-ui-script-inline.js +91 -46
  98. package/dist/mcp-slate-ui-script-inline.js.map +1 -1
  99. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts +20 -0
  100. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts.map +1 -0
  101. package/dist/mcp-slate-ui-script-inspiration-collage.js +68 -0
  102. package/dist/mcp-slate-ui-script-inspiration-collage.js.map +1 -0
  103. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts +26 -0
  104. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts.map +1 -0
  105. package/dist/mcp-slate-ui-script-inspiration-grid.js +246 -0
  106. package/dist/mcp-slate-ui-script-inspiration-grid.js.map +1 -0
  107. package/dist/mcp-slate-ui-script-inspiration.d.ts +10 -9
  108. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -1
  109. package/dist/mcp-slate-ui-script-inspiration.js +161 -120
  110. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -1
  111. package/dist/mcp-slate-ui-script-l10n.d.ts +29 -0
  112. package/dist/mcp-slate-ui-script-l10n.d.ts.map +1 -0
  113. package/dist/mcp-slate-ui-script-l10n.js +135 -0
  114. package/dist/mcp-slate-ui-script-l10n.js.map +1 -0
  115. package/dist/mcp-slate-ui-script-more.d.ts +3 -2
  116. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -1
  117. package/dist/mcp-slate-ui-script-more.js +19 -18
  118. package/dist/mcp-slate-ui-script-more.js.map +1 -1
  119. package/dist/mcp-slate-ui-script-pause.d.ts +33 -0
  120. package/dist/mcp-slate-ui-script-pause.d.ts.map +1 -0
  121. package/dist/mcp-slate-ui-script-pause.js +217 -0
  122. package/dist/mcp-slate-ui-script-pause.js.map +1 -0
  123. package/dist/mcp-slate-ui-script-remote.d.ts +2 -0
  124. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -1
  125. package/dist/mcp-slate-ui-script-remote.js +47 -6
  126. package/dist/mcp-slate-ui-script-remote.js.map +1 -1
  127. package/dist/mcp-slate-ui-script-scribble.js +1 -1
  128. package/dist/mcp-slate-ui-script-select.js +6 -6
  129. package/dist/mcp-slate-ui-script-stage.d.ts +3 -2
  130. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -1
  131. package/dist/mcp-slate-ui-script-stage.js +31 -19
  132. package/dist/mcp-slate-ui-script-stage.js.map +1 -1
  133. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -1
  134. package/dist/mcp-slate-ui-script-state.js +77 -57
  135. package/dist/mcp-slate-ui-script-state.js.map +1 -1
  136. package/dist/mcp-slate-ui-script.d.ts +2 -2
  137. package/dist/mcp-slate-ui-script.d.ts.map +1 -1
  138. package/dist/mcp-slate-ui-script.js +21 -7
  139. package/dist/mcp-slate-ui-script.js.map +1 -1
  140. package/dist/mcp-slate-ui-styles-dialog.d.ts +6 -7
  141. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +1 -1
  142. package/dist/mcp-slate-ui-styles-dialog.js +13 -29
  143. package/dist/mcp-slate-ui-styles-dialog.js.map +1 -1
  144. package/dist/mcp-slate-ui-styles-inspiration.d.ts +18 -0
  145. package/dist/mcp-slate-ui-styles-inspiration.d.ts.map +1 -0
  146. package/dist/mcp-slate-ui-styles-inspiration.js +43 -0
  147. package/dist/mcp-slate-ui-styles-inspiration.js.map +1 -0
  148. package/dist/mcp-slate-ui-styles-pause.d.ts +10 -0
  149. package/dist/mcp-slate-ui-styles-pause.d.ts.map +1 -0
  150. package/dist/mcp-slate-ui-styles-pause.js +25 -0
  151. package/dist/mcp-slate-ui-styles-pause.js.map +1 -0
  152. package/dist/mcp-slate-ui-styles-stage.d.ts +10 -6
  153. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -1
  154. package/dist/mcp-slate-ui-styles-stage.js +24 -16
  155. package/dist/mcp-slate-ui-styles-stage.js.map +1 -1
  156. package/dist/mcp-slate-ui-styles.d.ts +12 -5
  157. package/dist/mcp-slate-ui-styles.d.ts.map +1 -1
  158. package/dist/mcp-slate-ui-styles.js +38 -21
  159. package/dist/mcp-slate-ui-styles.js.map +1 -1
  160. package/dist/mcp-slate-ui.d.ts +11 -3
  161. package/dist/mcp-slate-ui.d.ts.map +1 -1
  162. package/dist/mcp-slate-ui.js +24 -16
  163. package/dist/mcp-slate-ui.js.map +1 -1
  164. package/dist/mosaic-bands.d.ts +44 -0
  165. package/dist/mosaic-bands.d.ts.map +1 -0
  166. package/dist/mosaic-bands.js +153 -0
  167. package/dist/mosaic-bands.js.map +1 -0
  168. package/dist/review-discovery.d.ts.map +1 -1
  169. package/dist/review-discovery.js +36 -54
  170. package/dist/review-discovery.js.map +1 -1
  171. package/dist/review-page.d.ts.map +1 -1
  172. package/dist/review-page.js +2 -1
  173. package/dist/review-page.js.map +1 -1
  174. package/dist/review-run-roots.d.ts +40 -0
  175. package/dist/review-run-roots.d.ts.map +1 -0
  176. package/dist/review-run-roots.js +94 -0
  177. package/dist/review-run-roots.js.map +1 -0
  178. package/dist/review-server.d.ts +2 -0
  179. package/dist/review-server.d.ts.map +1 -1
  180. package/dist/review-server.js +2 -0
  181. package/dist/review-server.js.map +1 -1
  182. package/dist/review-types.d.ts +10 -0
  183. package/dist/review-types.d.ts.map +1 -1
  184. package/dist/slate-actions.d.ts +3 -3
  185. package/dist/slate-actions.d.ts.map +1 -1
  186. package/dist/slate-actions.js +9 -8
  187. package/dist/slate-actions.js.map +1 -1
  188. package/dist/slate-browser-host-script.d.ts +4 -0
  189. package/dist/slate-browser-host-script.d.ts.map +1 -1
  190. package/dist/slate-browser-host-script.js +25 -6
  191. package/dist/slate-browser-host-script.js.map +1 -1
  192. package/dist/slate-browser-host.d.ts +2 -1
  193. package/dist/slate-browser-host.d.ts.map +1 -1
  194. package/dist/slate-browser-host.js +18 -5
  195. package/dist/slate-browser-host.js.map +1 -1
  196. package/dist/slate-commit.js +7 -7
  197. package/dist/slate-commit.js.map +1 -1
  198. package/dist/slate-corpus.d.ts.map +1 -1
  199. package/dist/slate-corpus.js +3 -2
  200. package/dist/slate-corpus.js.map +1 -1
  201. package/dist/slate-edit-runner.d.ts.map +1 -1
  202. package/dist/slate-edit-runner.js +5 -4
  203. package/dist/slate-edit-runner.js.map +1 -1
  204. package/dist/slate-editability.d.ts +2 -0
  205. package/dist/slate-editability.d.ts.map +1 -1
  206. package/dist/slate-editability.js +1 -1
  207. package/dist/slate-editability.js.map +1 -1
  208. package/dist/slate-errors.d.ts +7 -1
  209. package/dist/slate-errors.d.ts.map +1 -1
  210. package/dist/slate-errors.js +3 -2
  211. package/dist/slate-errors.js.map +1 -1
  212. package/dist/slate-handoff-options.d.ts +2 -1
  213. package/dist/slate-handoff-options.d.ts.map +1 -1
  214. package/dist/slate-handoff-options.js +2 -2
  215. package/dist/slate-handoff-options.js.map +1 -1
  216. package/dist/slate-handoff.js +1 -1
  217. package/dist/slate-handoff.js.map +1 -1
  218. package/dist/slate-image-executor.d.ts +28 -3
  219. package/dist/slate-image-executor.d.ts.map +1 -1
  220. package/dist/slate-image-executor.js +55 -11
  221. package/dist/slate-image-executor.js.map +1 -1
  222. package/dist/slate-inspiration.js +2 -2
  223. package/dist/slate-inspiration.js.map +1 -1
  224. package/dist/slate-local-image.d.ts.map +1 -1
  225. package/dist/slate-local-image.js +4 -1
  226. package/dist/slate-local-image.js.map +1 -1
  227. package/dist/slate-lock.js +1 -1
  228. package/dist/slate-lock.js.map +1 -1
  229. package/dist/slate-resume.js +6 -6
  230. package/dist/slate-resume.js.map +1 -1
  231. package/dist/slate-round-params.d.ts +3 -0
  232. package/dist/slate-round-params.d.ts.map +1 -1
  233. package/dist/slate-round-params.js +5 -0
  234. package/dist/slate-round-params.js.map +1 -1
  235. package/dist/slate-round-prompt.d.ts +15 -3
  236. package/dist/slate-round-prompt.d.ts.map +1 -1
  237. package/dist/slate-round-prompt.js +14 -5
  238. package/dist/slate-round-prompt.js.map +1 -1
  239. package/dist/slate-round-queries.d.ts +18 -0
  240. package/dist/slate-round-queries.d.ts.map +1 -0
  241. package/dist/slate-round-queries.js +29 -0
  242. package/dist/slate-round-queries.js.map +1 -0
  243. package/dist/slate-round-runner.d.ts.map +1 -1
  244. package/dist/slate-round-runner.js +12 -9
  245. package/dist/slate-round-runner.js.map +1 -1
  246. package/dist/slate-round-search.js +5 -5
  247. package/dist/slate-round-search.js.map +1 -1
  248. package/dist/slate-run-action.d.ts.map +1 -1
  249. package/dist/slate-run-action.js +2 -1
  250. package/dist/slate-run-action.js.map +1 -1
  251. package/dist/slate-runner-context.d.ts +3 -1
  252. package/dist/slate-runner-context.d.ts.map +1 -1
  253. package/dist/slate-runner-context.js +4 -3
  254. package/dist/slate-runner-context.js.map +1 -1
  255. package/dist/slate-runner-failure.d.ts +7 -1
  256. package/dist/slate-runner-failure.d.ts.map +1 -1
  257. package/dist/slate-runner-failure.js +6 -5
  258. package/dist/slate-runner-failure.js.map +1 -1
  259. package/dist/slate-runtime.d.ts.map +1 -1
  260. package/dist/slate-runtime.js +1 -0
  261. package/dist/slate-runtime.js.map +1 -1
  262. package/dist/slate-versions.js +3 -3
  263. package/dist/slate-versions.js.map +1 -1
  264. package/dist/slate-view-contract.d.ts +62 -1
  265. package/dist/slate-view-contract.d.ts.map +1 -1
  266. package/dist/slate-view-contract.js +30 -0
  267. package/dist/slate-view-contract.js.map +1 -1
  268. package/dist/slate-view.d.ts.map +1 -1
  269. package/dist/slate-view.js +19 -3
  270. package/dist/slate-view.js.map +1 -1
  271. package/dist/slate-workspace-parse.d.ts.map +1 -1
  272. package/dist/slate-workspace-parse.js +22 -0
  273. package/dist/slate-workspace-parse.js.map +1 -1
  274. package/dist/slate-workspace-types.d.ts +3 -1
  275. package/dist/slate-workspace-types.d.ts.map +1 -1
  276. package/dist/workspace-draw-client.d.ts +58 -5
  277. package/dist/workspace-draw-client.d.ts.map +1 -1
  278. package/dist/workspace-draw-client.js +82 -9
  279. package/dist/workspace-draw-client.js.map +1 -1
  280. package/dist/workspace-draw-codex.d.ts +9 -4
  281. package/dist/workspace-draw-codex.d.ts.map +1 -1
  282. package/dist/workspace-draw-codex.js +17 -3
  283. package/dist/workspace-draw-codex.js.map +1 -1
  284. package/dist/workspace-draw-messages.d.ts +31 -0
  285. package/dist/workspace-draw-messages.d.ts.map +1 -1
  286. package/dist/workspace-draw-messages.js +30 -0
  287. package/dist/workspace-draw-messages.js.map +1 -1
  288. package/dist/workspace-draw-run.d.ts +19 -1
  289. package/dist/workspace-draw-run.d.ts.map +1 -1
  290. package/dist/workspace-draw-run.js +98 -5
  291. package/dist/workspace-draw-run.js.map +1 -1
  292. package/dist/workspace-draw-store.d.ts +2 -0
  293. package/dist/workspace-draw-store.d.ts.map +1 -1
  294. package/dist/workspace-draw-store.js +3 -1
  295. package/dist/workspace-draw-store.js.map +1 -1
  296. package/dist/workspace-draw-types.d.ts +2 -0
  297. package/dist/workspace-draw-types.d.ts.map +1 -1
  298. package/dist/workspace-draw-types.js +2 -0
  299. package/dist/workspace-draw-types.js.map +1 -1
  300. package/dist/workspace-origin.d.ts +15 -0
  301. package/dist/workspace-origin.d.ts.map +1 -0
  302. package/dist/workspace-origin.js +36 -0
  303. package/dist/workspace-origin.js.map +1 -0
  304. package/dist/workspace-runner-children.d.ts +39 -0
  305. package/dist/workspace-runner-children.d.ts.map +1 -0
  306. package/dist/workspace-runner-children.js +139 -0
  307. package/dist/workspace-runner-children.js.map +1 -0
  308. package/dist/workspace-runner-client.d.ts +43 -0
  309. package/dist/workspace-runner-client.d.ts.map +1 -0
  310. package/dist/workspace-runner-client.js +72 -0
  311. package/dist/workspace-runner-client.js.map +1 -0
  312. package/dist/workspace-runner-main.d.ts +56 -0
  313. package/dist/workspace-runner-main.d.ts.map +1 -0
  314. package/dist/workspace-runner-main.js +378 -0
  315. package/dist/workspace-runner-main.js.map +1 -0
  316. package/dist/workspace-runner-policy.d.ts +40 -0
  317. package/dist/workspace-runner-policy.d.ts.map +1 -0
  318. package/dist/workspace-runner-policy.js +47 -0
  319. package/dist/workspace-runner-policy.js.map +1 -0
  320. package/dist/workspace-runner-spawn.d.ts +42 -0
  321. package/dist/workspace-runner-spawn.d.ts.map +1 -0
  322. package/dist/workspace-runner-spawn.js +60 -0
  323. package/dist/workspace-runner-spawn.js.map +1 -0
  324. package/dist/workspace-runner-stop.d.ts +25 -0
  325. package/dist/workspace-runner-stop.d.ts.map +1 -0
  326. package/dist/workspace-runner-stop.js +44 -0
  327. package/dist/workspace-runner-stop.js.map +1 -0
  328. package/dist/workspace-runner-store.d.ts +26 -0
  329. package/dist/workspace-runner-store.d.ts.map +1 -0
  330. package/dist/workspace-runner-store.js +114 -0
  331. package/dist/workspace-runner-store.js.map +1 -0
  332. package/open-design.json +2 -2
  333. package/package.json +1 -1
  334. package/runtime/codex-conversion/src/images/native-frame.mjs +103 -0
  335. package/runtime/codex-conversion/src/images/native-invoke.mjs +24 -5
  336. package/runtime/codex-conversion/src/images/native.mjs +14 -5
  337. package/runtime/codex-conversion/src/run-store.mjs +21 -1
@@ -4,6 +4,8 @@
4
4
  *
5
5
  * The messages. The host wraps every app message as untrusted input, so each one
6
6
  * names what happened and carries no command, flag, path, price or credit word;
7
+ * a Generate more or Edit click that the workspace runner on the person's Mac
8
+ * will draw sends none (remoteAfterRun);
7
9
  * the agent confirms through the model-visible data tool, which returns the
8
10
  * server's own trusted text. Six messages exist, one per click (spec v2 9.2):
9
11
  * Generate more with new options, Generate more based on a design, Edit,
@@ -47,10 +49,49 @@ export const SLATE_UI_REMOTE = String.raw `
47
49
  // is on the server and the person can ask their agent for it.
48
50
  function remoteTellRun(action, opId) {
49
51
  messageAgent(remoteRunMessage(action, opId)).then(function () {}, function (err) {
50
- setStatus(tpl(COPY.sentRefused, { detail: errText(err) }), "err");
52
+ setStatus(t("sentRefused", { detail: errText(err) }), "err");
51
53
  });
52
54
  }
53
55
 
56
+ // ---- the workspace runner: a click it draws is not a message in the thread ----
57
+ // The run result says whether the workspace runner on the person's Mac holds the workspace (runner.alive). Then the
58
+ // agent is not told: the runner claims the request within seconds and the op's phase turns to "drawing". The agent
59
+ // is told after all, with the same message, when the request is still the agent's ("agent") once RUNNER_GRACE_MS
60
+ // has passed, or when a claimed request goes back to the agent because the runner's lease lapsed. Each check reads
61
+ // the status itself, so a card the host hides (no polling) still decides on fresh state. A round that waits on the
62
+ // person (its round carries a pause) is nobody's to draw yet: no runner may claim it, so the screen keeps watching
63
+ // and tells nobody, however long the person takes; once it goes on, the runner gets its grace again from then.
64
+ var RUNNER_GRACE_MS = 20000;
65
+ var RUNNER_RECHECK_MS = 10000;
66
+ var runnerWatch = {};
67
+ function remoteAfterRun(action, opId, runner) {
68
+ if (!(runner && runner.alive === true)) { remoteTellRun(action, opId); return; }
69
+ runnerWatch[opId] = { action: action, waited: false };
70
+ setTimeout(function () { runnerCheck(opId); }, RUNNER_GRACE_MS);
71
+ }
72
+ function opWaitsOnPerson(op) {
73
+ var round = op.kind === "round" ? roundOfOp(op) : null;
74
+ return !!(round && round.pause);
75
+ }
76
+ function runnerCheck(opId) {
77
+ if (!runnerWatch[opId] || !state.view) return;
78
+ callTool(TOOLS.status, { runDir: state.view.runDir, since: state.view.stamp }).then(function (result) {
79
+ var sc = result.structuredContent || {};
80
+ if (sc.schema) applyView(sc, true);
81
+ }).catch(function () {}).then(function () { runnerJudge(opId); });
82
+ }
83
+ function runnerJudge(opId) {
84
+ var watch = runnerWatch[opId];
85
+ if (!watch) return;
86
+ var op = state.view.ops.filter(function (o) { return o.opId === opId; })[0];
87
+ if (!op || op.state !== "running") { delete runnerWatch[opId]; return; }
88
+ if (op.phase === "drawing") { setTimeout(function () { runnerCheck(opId); }, RUNNER_RECHECK_MS); return; }
89
+ if (opWaitsOnPerson(op)) { watch.waited = true; setTimeout(function () { runnerCheck(opId); }, RUNNER_RECHECK_MS); return; }
90
+ if (watch.waited) { watch.waited = false; setTimeout(function () { runnerCheck(opId); }, RUNNER_GRACE_MS); return; }
91
+ delete runnerWatch[opId];
92
+ remoteTellRun(watch.action, opId);
93
+ }
94
+
54
95
  // ---- the marked image ----
55
96
  var MARK_COLORS = [
56
97
  { name: "magenta", hex: "#ff00ff", rgb: [255, 0, 255] },
@@ -68,7 +109,7 @@ export const SLATE_UI_REMOTE = String.raw `
68
109
  return new Promise(function (resolve, reject) {
69
110
  var img = document.createElement("img");
70
111
  img.onload = function () { resolve(img); };
71
- img.onerror = function () { reject(new Error("the image could not be read")); };
112
+ img.onerror = function () { reject(new Error(t("markReadFailed"))); };
72
113
  img.src = src;
73
114
  });
74
115
  }
@@ -77,7 +118,7 @@ export const SLATE_UI_REMOTE = String.raw `
77
118
  canvas.width = w;
78
119
  canvas.height = h;
79
120
  var ctx = canvas.getContext && canvas.getContext("2d");
80
- if (!ctx) throw new Error("no canvas is available");
121
+ if (!ctx) throw new Error(t("markNoCanvas"));
81
122
  return { canvas: canvas, ctx: ctx };
82
123
  }
83
124
  // The colour farthest (in RGB) from the image's mean; the first listed wins a tie.
@@ -122,7 +163,7 @@ export const SLATE_UI_REMOTE = String.raw `
122
163
  return wantImage(version, "full", true).then(markPicture).then(function (img) {
123
164
  var sw = img.naturalWidth || img.width;
124
165
  var sh = img.naturalHeight || img.height;
125
- if (!(sw > 0) || !(sh > 0)) throw new Error("the image has no size");
166
+ if (!(sw > 0) || !(sh > 0)) throw new Error(t("markNoSize"));
126
167
  var color = markColorFor(img);
127
168
  var scale = Math.min(1, MARK_LONG_EDGE / Math.max(sw, sh));
128
169
  for (;;) {
@@ -134,12 +175,12 @@ export const SLATE_UI_REMOTE = String.raw `
134
175
  for (var q = 0; q < MARK_QUALITIES.length; q++) {
135
176
  var url = target.canvas.toDataURL("image/jpeg", MARK_QUALITIES[q]);
136
177
  var comma = url.indexOf(",");
137
- if (url.indexOf("data:image/jpeg") !== 0 || comma < 0) throw new Error("the canvas could not export a JPEG");
178
+ if (url.indexOf("data:image/jpeg") !== 0 || comma < 0) throw new Error(t("markNoJpeg"));
138
179
  var data = url.slice(comma + 1);
139
180
  if (base64Bytes(data) <= MARK_MAX_BYTES) return { mimeType: "image/jpeg", data: data, color: color.name };
140
181
  }
141
182
  scale *= MARK_SHRINK;
142
- if (Math.max(sw, sh) * scale < MARK_MIN_LONG_EDGE) throw new Error("the marked image would be too large");
183
+ if (Math.max(sw, sh) * scale < MARK_MIN_LONG_EDGE) throw new Error(t("markTooLarge"));
143
184
  }
144
185
  });
145
186
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script-remote.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-remote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuHxC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script-remote.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-remote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8JxC,CAAC"}
@@ -69,7 +69,7 @@ export const SLATE_UI_SCRIBBLE = String.raw `
69
69
  function scribbleAttach(wrap, d) {
70
70
  var canvas = document.createElement("canvas");
71
71
  canvas.className = "scribble";
72
- canvas.setAttribute("aria-label", COPY.scribbleHint);
72
+ canvas.setAttribute("aria-label", t("scribbleHint"));
73
73
  d.canvas = canvas;
74
74
  wrap.appendChild(canvas);
75
75
  // The bitmap follows the size the image is shown at; the strokes repaint from their permille points.
@@ -39,19 +39,19 @@ export const SLATE_UI_SELECT = String.raw `
39
39
  if (!version || state.busy || samePick(version) || !pickable(version)) return;
40
40
  state.busy = true;
41
41
  syncControls();
42
- setStatus(COPY.recording);
42
+ setStatus(t("recording"));
43
43
  callTool(TOOLS.pick, { runDir: state.view.runDir, versionId: version.versionId }).then(function (result) {
44
44
  var sc = result.structuredContent || {};
45
45
  if (sc.view) applyView(sc.view, true);
46
46
  var label = sc.pick ? sc.pick.label : version.label;
47
47
  var rev = sc.rev !== undefined ? sc.rev : state.view.rev;
48
48
  return messageAgent(selectMessage(label, rev)).then(function () {
49
- setStatus(tpl(COPY.selectedLine, { label: label }), "ok");
49
+ setStatus(t("selectedLine", { label: label }), "ok");
50
50
  }, function (err) {
51
- setStatus(tpl(COPY.selectedRefused, { label: label, detail: errText(err) }), "err");
51
+ setStatus(t("selectedRefused", { label: label, detail: errText(err) }), "err");
52
52
  });
53
53
  }, function (err) {
54
- setStatus(tpl(COPY.couldNotSelect, { detail: errText(err) }), "err");
54
+ setStatus(t("couldNotSelect", { detail: errText(err) }), "err");
55
55
  }).then(function () { state.busy = false; syncControls(); });
56
56
  }
57
57
 
@@ -63,9 +63,9 @@ export const SLATE_UI_SELECT = String.raw `
63
63
  if (sc.view) applyView(sc.view, true);
64
64
  var rev = sc.rev !== undefined ? sc.rev : state.view.rev;
65
65
  return messageAgent(handoffMessage(kind, version.label, handoffId, rev)).then(function () {
66
- setStatus(COPY.sent, "ok");
66
+ setStatus(t("sent"), "ok");
67
67
  }, function (err) {
68
- setStatus(tpl(COPY.sentRefused, { detail: errText(err) }), "err");
68
+ setStatus(t("sentRefused", { detail: errText(err) }), "err");
69
69
  });
70
70
  });
71
71
  }
@@ -5,8 +5,9 @@
5
5
  * Convert, then Select (primary) at the far right. Nothing else shows until a
6
6
  * button is clicked; the dialogs live
7
7
  * in mcp-slate-ui-script-dialog.ts. One band above the image says what is
8
- * running, stopped or failed, with Resume when the work can resume. Mounted
9
- * only in fullscreen.
8
+ * running (on the local plugin; on the hosted server the person's agent says
9
+ * it), stopped or failed, with Resume when the work can resume. Mounted only
10
+ * in fullscreen.
10
11
  */
11
12
  export declare const SLATE_UI_STAGE: string;
12
13
  //# sourceMappingURL=mcp-slate-ui-script-stage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script-stage.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAwK1B,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script-stage.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QAmL1B,CAAC"}
@@ -5,8 +5,9 @@
5
5
  * Convert, then Select (primary) at the far right. Nothing else shows until a
6
6
  * button is clicked; the dialogs live
7
7
  * in mcp-slate-ui-script-dialog.ts. One band above the image says what is
8
- * running, stopped or failed, with Resume when the work can resume. Mounted
9
- * only in fullscreen.
8
+ * running (on the local plugin; on the hosted server the person's agent says
9
+ * it), stopped or failed, with Resume when the work can resume. Mounted only
10
+ * in fullscreen.
10
11
  */
11
12
  export const SLATE_UI_STAGE = String.raw `
12
13
  var stageBuilt = false;
@@ -25,24 +26,25 @@ export const SLATE_UI_STAGE = String.raw `
25
26
  var stage = $("stage");
26
27
  stage.textContent = "";
27
28
  var head = el("header", "stagehead");
28
- head.appendChild(el("h1", "sr", COPY.title));
29
+ head.appendChild(el("h1", "sr", t("title")));
29
30
  head.appendChild(buildTabs());
30
31
  head.appendChild(el("span", "spacer"));
31
- stageEls.close = iconButton(COPY.closeWorkspace, ICON_CLOSE, closeWorkspace);
32
+ stageEls.close = iconButton(t("closeWorkspace"), ICON_CLOSE, closeWorkspace);
32
33
  head.appendChild(stageEls.close);
33
34
 
34
35
  stageEls.body = el("div", "stagebody");
35
36
  stageEls.rail = el("nav", "rail");
36
- stageEls.rail.setAttribute("aria-label", COPY.tabDesigns);
37
+ stageEls.rail.setAttribute("aria-label", t("tabDesigns"));
37
38
  var main = el("section", "main");
39
+ stageEls.pause = el("div", "pausebar hidden");
38
40
  stageEls.band = el("div", "band hidden");
39
41
  stageEls.band.setAttribute("role", "status");
40
42
  stageEls.hero = el("div", "hero");
41
43
  var row = el("div", "actionrow");
42
- stageEls.edit = button(COPY.edit, "", function () { openDialog("edit", stageEls.edit); });
43
- stageEls.branch = button(COPY.branch, "", function () { openDialog("branch", stageEls.branch); });
44
- stageEls.convert = button(COPY.convert, "", function () { openDialog("convert", stageEls.convert); });
45
- stageEls.select = button(COPY.select, "primary", function () { doSelect(selectedVersion()); });
44
+ stageEls.edit = button(t("edit"), "", function () { openDialog("edit", stageEls.edit); });
45
+ stageEls.branch = button(t("branch"), "", function () { openDialog("branch", stageEls.branch); });
46
+ stageEls.convert = button(t("convert"), "", function () { openDialog("convert", stageEls.convert); });
47
+ stageEls.select = button(t("select"), "primary", function () { doSelect(selectedVersion()); });
46
48
  stageEls.editWhy = el("span", "sr");
47
49
  stageEls.editWhy.id = "edit-why";
48
50
  // Select is last: the row is right-aligned, so it ends at the picture's right edge.
@@ -54,6 +56,7 @@ export const SLATE_UI_STAGE = String.raw `
54
56
  // A line set before the workspace was built (the first view arrives first) still shows.
55
57
  stageEls.status.textContent = state.status.text;
56
58
  if (state.status.kind) stageEls.status.className = "status " + state.status.kind;
59
+ main.appendChild(stageEls.pause);
57
60
  main.appendChild(stageEls.band);
58
61
  main.appendChild(stageEls.hero);
59
62
  main.appendChild(row);
@@ -74,19 +77,25 @@ export const SLATE_UI_STAGE = String.raw `
74
77
  stageBuilt = true;
75
78
  }
76
79
 
77
- // A chip is one version of an option; its title carries the words of the edit that made it.
78
- function chipTitle(v) { return v.prompt ? v.label + ": " + v.prompt : v.label; }
80
+ // A chip is one version of an option; its title carries the words of the edit that made it (the person's own words;
81
+ // an edit made from a drawing alone says so, rather than show the instruction the server wrote for the model).
82
+ function chipTitle(v) {
83
+ if (v.promptFromMarks) return t("versionTitleMarks", { label: v.label });
84
+ return v.prompt ? t("versionTitle", { label: v.label, prompt: v.prompt }) : v.label;
85
+ }
79
86
 
80
87
  function buildRail(rail) {
81
88
  var v = state.view;
82
89
  v.rounds.slice().sort(function (a, b) { return b.index - a.index; }).forEach(function (round) {
83
90
  var section = el("div", "round");
84
- var head = el("h2", "roundhead", COPY.roundPrefix + round.index);
91
+ var head = el("h2", "roundhead", t("roundHeading", { n: round.index }));
85
92
  var title = roundTitle(round);
86
93
  if (title) head.title = title;
87
94
  section.appendChild(head);
88
95
  var list = el("ul", "options");
89
- orderedCandidates().filter(function (c) { return c.roundId === round.roundId; }).sort(byLabel).forEach(function (c) {
96
+ var ofRound = orderedCandidates().filter(function (c) { return c.roundId === round.roundId; }).sort(byLabel);
97
+ if (ofRound.length) setShape(list, ratioOf(ofRound[0]));
98
+ ofRound.forEach(function (c) {
90
99
  var item = el("li", "option");
91
100
  item.appendChild(thumbButton(c, "opt"));
92
101
  var versions = versionsOf(c);
@@ -96,7 +105,7 @@ export const SLATE_UI_STAGE = String.raw `
96
105
  var on = state.sel.versionId === version.versionId;
97
106
  var chip = button(version.label, "chip" + (on ? " selected" : ""), function () { selectCandidate(c.candidateId, version.versionId); });
98
107
  chip.title = chipTitle(version);
99
- chip.setAttribute("aria-label", COPY.versionPrefix + version.label);
108
+ chip.setAttribute("aria-label", t("versionName", { label: version.label }));
100
109
  chip.setAttribute("aria-pressed", on ? "true" : "false");
101
110
  chips.appendChild(chip);
102
111
  });
@@ -107,7 +116,10 @@ export const SLATE_UI_STAGE = String.raw `
107
116
  section.appendChild(list);
108
117
  rail.appendChild(section);
109
118
  });
119
+ // The Generate more tile is one more tile of the newest round's columns and ratio, at the end of the selection.
110
120
  var slot = el("div", "moreslot");
121
+ var newest = orderedCandidates()[0];
122
+ if (newest) setShape(slot, ratioOf(newest));
111
123
  slot.appendChild(moreTile());
112
124
  rail.appendChild(slot);
113
125
  }
@@ -116,7 +128,7 @@ export const SLATE_UI_STAGE = String.raw `
116
128
  function buildBand(node, band) {
117
129
  node.appendChild(el("span", "bandtext" + (band.kind === "failed" ? " err" : ""), band.text));
118
130
  if (band.op.resumable) {
119
- var b = button(COPY.resume, "textbtn", function () { actResume(band.op, b); });
131
+ var b = button(t("resume"), "textbtn", function () { actResume(band.op, b); });
120
132
  node.appendChild(b);
121
133
  }
122
134
  }
@@ -137,7 +149,7 @@ export const SLATE_UI_STAGE = String.raw `
137
149
  // Edit is off when the shown version cannot be edited; the reason is its accessible description, not a tooltip.
138
150
  var blocked = !v || !v.editable;
139
151
  stageEls.edit.disabled = blocked;
140
- stageEls.editWhy.textContent = blocked && v && v.editBlockedReason ? v.editBlockedReason : "";
152
+ stageEls.editWhy.textContent = blocked && v && v.editBlockedReason ? serverText(v.editBlockedL10n, v.editBlockedReason) : "";
141
153
  if (blocked && v && v.editBlockedReason) stageEls.edit.setAttribute("aria-describedby", "edit-why"); else stageEls.edit.removeAttribute("aria-describedby");
142
154
  stageEls.branch.disabled = !v;
143
155
  stageEls.convert.disabled = !v;
@@ -149,7 +161,6 @@ export const SLATE_UI_STAGE = String.raw `
149
161
  if (!stageBuilt) buildStageSkeleton();
150
162
  stageEls.close.classList.toggle("hidden", !canInline());
151
163
  syncTabs();
152
- syncProgressLine(v);
153
164
  var onDesigns = state.tab === "designs";
154
165
  stageEls.body.classList.toggle("hidden", !onDesigns);
155
166
  stageEls.inspiration.classList.toggle("hidden", onDesigns);
@@ -163,13 +174,14 @@ export const SLATE_UI_STAGE = String.raw `
163
174
  stageEls.hero.__sig = "";
164
175
  stageEls.hero.textContent = "";
165
176
  stageEls.hero.classList.add("note");
166
- stageEls.hero.appendChild(el("div", "heronote", COPY.empty));
167
- syncStageControls(COPY.select, true);
177
+ stageEls.hero.appendChild(el("div", "heronote", t("empty")));
178
+ syncStageControls(t("select"), true);
168
179
  return;
169
180
  }
170
181
  var railSig = JSON.stringify([state.sel, v.rounds.map(function (r) { return [r.roundId, r.index, r.kind, r.fromVersionId]; }),
171
182
  orderedCandidates().map(function (x) { return thumbSignature(x).concat([x.versionIds]); })]);
172
183
  setIfChanged(stageEls.rail, railSig, buildRail);
184
+ syncPauseHost(stageEls.pause, true);
173
185
  var band = activeBand(v);
174
186
  stageEls.band.classList.toggle("hidden", !band);
175
187
  setIfChanged(stageEls.band, band ? JSON.stringify([band.kind, band.text, band.op.opId, band.op.resumable]) : "", function (node) { if (band) buildBand(node, band); });
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script-stage.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwKvC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script-stage.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmLvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script-state.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QAqS1B,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script-state.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QAyT1B,CAAC"}
@@ -14,7 +14,7 @@ export const SLATE_UI_STATE = String.raw `
14
14
  host: {}, view: null,
15
15
  sel: { candidateId: null, versionId: null, followLatest: true },
16
16
  tab: "designs", query: "", dialog: null, more: null,
17
- busy: false, status: { text: "", kind: "", source: "", phase: "" }, lastOpText: "", lastBandOp: "",
17
+ busy: false, status: { text: "", kind: "" }, lastRunOp: "",
18
18
  thumbs: {}, fulls: {}, refs: {}, lastOpStates: {}, opBusy: {}, awaitEdit: null,
19
19
  insp: { local: null, writing: false, dirty: false, searching: false, noMatch: "", waiters: [] }
20
20
  };
@@ -42,15 +42,24 @@ export const SLATE_UI_STATE = String.raw `
42
42
  return h.slice(0, 8) + "-" + h.slice(8, 12) + "-" + h.slice(12, 16) + "-" + h.slice(16, 20) + "-" + h.slice(20);
43
43
  }
44
44
  function visible() { return document.visibilityState !== "hidden"; }
45
- function errText(err) { return err && err.message ? err.message : String(err); }
46
- // "source" is "op" for a line the screen derives from the ops' own state, "" for a message about a click.
47
- function setStatus(text, kind, source, phase) {
48
- state.status = { text: text || "", kind: kind || "", source: source || "", phase: phase || "" };
45
+ // What went wrong, in the person's language when the server named it by code, else as it was said.
46
+ function errText(err) {
47
+ var words = err && err.l10n ? said(err.l10n) : "";
48
+ return words || (err && err.message ? err.message : String(err));
49
+ }
50
+ // An op's error, an option's failure, the reason this Mac cannot draw: the screen's words for the code, else the server's.
51
+ function serverText(ref, english) { return said(ref) || english || ""; }
52
+ // What a click did. The workspace's status line says it; the card has no status line, so only an error reaches it,
53
+ // beside Select, and nothing else takes room there.
54
+ function setStatus(text, kind) {
55
+ state.status = { text: text || "", kind: kind || "" };
49
56
  var nodes = document.querySelectorAll("[data-status]");
50
57
  for (var i = 0; i < nodes.length; i++) {
51
58
  nodes[i].textContent = state.status.text;
52
59
  nodes[i].className = "status" + (kind ? " " + kind : "");
53
60
  }
61
+ var alert = $("cardalert");
62
+ if (alert) alert.textContent = state.status.kind === "err" ? state.status.text : "";
54
63
  }
55
64
 
56
65
  // ---- lookups over the current view ----
@@ -80,10 +89,50 @@ export const SLATE_UI_STATE = String.raw `
80
89
  return all.filter(function (c) { return c.roundId === newest || keep[c.candidateId]; });
81
90
  }
82
91
  function versionsOf(c) { return c.versionIds.map(ver).filter(Boolean); }
83
- function runningOps() { return state.view.ops.filter(function (o) { return o.state === "starting" || o.state === "running"; }); }
92
+ function isRunning(op) { return !!op && (op.state === "starting" || op.state === "running"); }
93
+ function runningOps() { return state.view.ops.filter(isRunning); }
94
+ function newestRunning(view) { var running = view.ops.filter(isRunning); return running.length ? running[running.length - 1] : null; }
84
95
  function selectedCandidate() { return cand(state.sel.candidateId); }
85
96
  function selectedVersion() { return ver(state.sel.versionId); }
86
- function optionName(c) { return COPY.optionPrefix + c.label + (c.state === "failed" ? COPY.failedSuffix : ""); }
97
+ function optionName(c) { return t(c.state === "failed" ? "optionNameFailed" : "optionName", { label: c.label }); }
98
+
99
+ // ---- an option without a picture: drawing, or stopped; and the ratio of its tile ----
100
+ // The work an option without a picture belongs to: the op the view names for it, else the newest op of its round.
101
+ function holdingOp(c) {
102
+ var named = c.busyOpId ? state.view.ops.filter(function (o) { return o.opId === c.busyOpId; })[0] : null;
103
+ if (named) return named;
104
+ return state.view.ops.filter(function (o) { var r = o.kind === "round" && roundOfOp(o); return !!r && r.roundId === c.roundId; }).pop() || null;
105
+ }
106
+ // An option is being drawn while it has no picture and its work runs (with no op to read, the view's own busy flag).
107
+ function drawing(c) {
108
+ if (c.state !== "pending") return false;
109
+ // A round that waits for the person's references is not being drawn yet (the inspiration pause).
110
+ if (pausedFor(c)) return false;
111
+ var op = holdingOp(c);
112
+ return op ? isRunning(op) : !!c.busy;
113
+ }
114
+ // Why an option is still without a picture when nothing draws it: what its work said when it stopped (the band's words).
115
+ function stoppedReason(c) {
116
+ var op = holdingOp(c);
117
+ if (op && op.error && op.error.message && (TARGET === "remote" || op.state === "failed")) return serverText(op.error.l10n, op.error.message);
118
+ return t("interrupted");
119
+ }
120
+ // The ratio of an option's tile: its picture's, or for an option still without one what its round draws (a sibling's
121
+ // picture, else the brief's aspect at the sizes the drawing prompt asks for), so the tile keeps its size when it lands.
122
+ var ASPECT_RATIO = { landscape: 1536 / 1024, portrait: 1024 / 1536, square: 1 };
123
+ function sized(v) { return !!v && v.width > 0 && v.height > 0; }
124
+ function ratioOf(c) {
125
+ var v = latestVersion(c);
126
+ if (!sized(v)) v = state.view.candidates.filter(function (x) { return x.roundId === c.roundId; }).map(latestVersion).filter(sized)[0];
127
+ if (sized(v)) return v.width / v.height;
128
+ var aspect = state.view.brief && state.view.brief.aspect;
129
+ return ASPECT_RATIO[aspect] || ASPECT_RATIO.landscape;
130
+ }
131
+ // A grid of tiles takes the ratio of its first option: it is the Generate more tile's ratio and sets the columns' width.
132
+ function setShape(node, ratio) {
133
+ node.style.setProperty("--ar", String(ratio));
134
+ node.style.setProperty("--shape", String(Math.round(Math.sqrt(ratio) * 1000) / 1000));
135
+ }
87
136
 
88
137
  function ensureSelection() {
89
138
  var v = state.view;
@@ -147,7 +196,7 @@ export const SLATE_UI_STATE = String.raw `
147
196
  function run(job) {
148
197
  callTool(job.tool, job.args).then(function (result) {
149
198
  var block = (result.content || []).find(function (b) { return b.type === "image"; });
150
- if (!block) throw new Error("no image block returned");
199
+ if (!block) throw new Error(t("pictureNotReturned"));
151
200
  var src = "data:" + block.mimeType + ";base64," + block.data;
152
201
  job.cache[job.key] = src;
153
202
  job.resolve(src);
@@ -205,27 +254,26 @@ export const SLATE_UI_STATE = String.raw `
205
254
  else clearPoll();
206
255
  });
207
256
 
208
- // ---- what the ops say: the band of the workspace, the status line of the card ----
257
+ // ---- what the ops say: the band of the workspace ----
209
258
  function opLabel(op) {
210
259
  var parent = op.edit && ver(op.edit.parentVersionId);
211
260
  var c = parent && cand(parent.candidateId);
212
261
  return c ? c.label : (op.target || "");
213
262
  }
263
+ // The round an op draws: the one it names by id (both servers send ops[].roundId), else, from a server older than
264
+ // that field, the newest round that runs. Never matched by words: the target text is English, for the agent.
214
265
  function roundOfOp(op) {
215
266
  var rounds = state.view.rounds;
216
- var named = rounds.filter(function (r) { return COPY.roundPrefix + r.index === op.target; })[0];
217
- if (named) return named;
267
+ if (op.roundId) return roundById(op.roundId) || null;
218
268
  var running = rounds.filter(function (r) { return r.state === "running"; });
219
269
  return running.length ? running[running.length - 1] : null;
220
270
  }
221
271
  function progressText(op) {
222
- // The hosted server has no runner of its own: a running op is waiting for the person's agent to draw and upload.
223
- if (TARGET === "remote" && op.phase === "agent") return COPY.waitingForAgent;
224
272
  if (op.kind === "round") {
225
273
  var r = roundOfOp(op);
226
- return r ? tpl(COPY.designingProgress, { n: r.readyCount, m: r.count }) : COPY.designing;
274
+ return r ? t("designingProgress", { n: r.readyCount, m: r.count }) : t("designing");
227
275
  }
228
- return tpl(COPY.editing, { label: opLabel(op) });
276
+ return t("editing", { label: opLabel(op) });
229
277
  }
230
278
  // The newest op. The local plugin stamps every op with a time; the hosted server sends none (data minimization), so
231
279
  // its ops are already oldest first and the last one is the newest.
@@ -233,54 +281,26 @@ export const SLATE_UI_STATE = String.raw `
233
281
  if (TARGET === "remote") return view.ops[view.ops.length - 1];
234
282
  return view.ops.slice().sort(function (a, b) { return Date.parse(a.startedAt) - Date.parse(b.startedAt); }).pop();
235
283
  }
236
- // The one thing worth a band: work that is running, else work that stopped or failed as the newest word.
284
+ // The one thing worth a band: work that is running, else work that stopped or failed as the newest word. On the hosted
285
+ // server the person's own agent does the running work and says what it is doing, and the options it is drawing
286
+ // shimmer, so running work there has no band.
237
287
  function activeBand(view) {
238
- var running = view.ops.filter(function (o) { return o.state === "starting" || o.state === "running"; });
239
- if (running.length) { var op = running[running.length - 1]; return { kind: "run", op: op, text: progressText(op) }; }
288
+ var running = newestRunning(view);
289
+ if (running) return TARGET === "remote" ? null : { kind: "run", op: running, text: progressText(running) };
240
290
  var last = latestOp(view);
241
- if (last && last.state === "interrupted") return { kind: "stopped", op: last, text: TARGET === "remote" && last.error && last.error.message ? last.error.message : COPY.interrupted };
242
- if (last && last.state === "failed" && last.error) return { kind: "failed", op: last, text: last.error.message };
291
+ if (last && last.state === "interrupted") return { kind: "stopped", op: last, text: TARGET === "remote" && last.error && last.error.message ? serverText(last.error.l10n, last.error.message) : t("interrupted") };
292
+ if (last && last.state === "failed" && last.error) return { kind: "failed", op: last, text: serverText(last.error.l10n, last.error.message) };
243
293
  return null;
244
294
  }
245
295
 
246
- // The card has one status line, so it also carries the running, stopped and failed words; the workspace has a band.
247
- function syncProgressLine(view) {
248
- var band = activeBand(view);
249
- // The workspace's band speaks for running work, so a line about an earlier click ("Selected E.") is stale the
250
- // moment a new op starts; a refusal stays, because the person has not read it away.
251
- var bandOp = band && band.kind === "run" ? band.op.opId : "";
252
- if (bandOp && bandOp !== state.lastBandOp && isFullscreen() && state.status.kind !== "err") setStatus("", "");
253
- state.lastBandOp = bandOp;
254
- if (isFullscreen() || !band) {
255
- state.lastOpText = "";
256
- if (state.status.source === "op" && state.status.phase === "progress") setStatus("", "");
257
- return;
258
- }
259
- // A message about a click stays until these words themselves change.
260
- if (band.text !== state.lastOpText) { state.lastOpText = band.text; setStatus(band.text, band.kind === "failed" ? "err" : "", "op", "progress"); }
261
- }
262
- // What a finished op produced. A failure is the band's to say in the workspace.
263
- function syncDoneLine(prev, view) {
264
- var was = {};
265
- if (prev) prev.ops.forEach(function (o) { was[o.opId] = o.state; });
266
- var finished = view.ops.filter(function (o) {
267
- return (was[o.opId] === "starting" || was[o.opId] === "running") && (o.state === "succeeded" || o.state === "failed");
268
- }).pop();
269
- if (!finished) return;
270
- if (finished.state === "failed") return;
271
- var made = view.versions.filter(function (v) { return finished.resultVersionIds.indexOf(v.versionId) >= 0; });
272
- if (finished.kind === "round") {
273
- var n = made.length;
274
- if (n === 0) return;
275
- var round = roundOfOp(finished);
276
- var failedCount = round ? view.candidates.filter(function (c) { return c.roundId === round.roundId && c.state === "failed"; }).length : 0;
277
- var text = (n === 1 ? COPY.roundReadyOne : tpl(COPY.roundReadyMany, { n: n })) + (failedCount ? " " + tpl(COPY.roundFailed, { n: failedCount }) : "");
278
- setStatus(text, failedCount ? "" : "ok", "op", "done");
279
- } else {
280
- setStatus(tpl(COPY.editReady, { label: made.length ? made[made.length - 1].label : opLabel(finished) }), "ok", "op", "done");
281
- }
296
+ // A line about an earlier click ("Selected E.") is stale the moment new work starts; a refusal stays, because the
297
+ // person has not read it away. What the work makes needs no line: its options fill in on the thumbnails.
298
+ function syncStaleLine(view) {
299
+ var running = newestRunning(view);
300
+ var id = running ? running.opId : "";
301
+ if (id && id !== state.lastRunOp && state.status.kind !== "err") setStatus("", "");
302
+ state.lastRunOp = id;
282
303
  }
283
- function syncOpStatus(prev, view) { syncProgressLine(view); syncDoneLine(prev, view); }
284
304
 
285
305
  // ---- tell the agent, best effort, when work that was running has finished ----
286
306
  function announceSettled(prev, next) {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script-state.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqSvC,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script-state.js","sourceRoot":"","sources":["../src/mcp-slate-ui-script-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyTvC,CAAC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * The workspace view's script, assembled from single-purpose fragments that
3
3
  * share one scope: bridge (host protocol), state (view state, picture queue,
4
- * polling, what the ops say), progress, inline (the card), select (Select and
4
+ * polling, what the ops say), l10n (the person's language and every word, `t(key)`), progress, inline (the card), select (Select and
5
5
  * the hand-offs), inspiration (the tabs and the Inspiration tab), stage
6
- * (fullscreen), dialog (Edit, Branch and Convert), more (the Generate more tile and its panel), scribble (the drawing layer of Edit), the hosted and browser targets' words, then the handshake, last, so every function and
6
+ * (fullscreen), pause (the inspiration pause of the hosted server), dialog (Edit, Branch and Convert), more (the Generate more tile and its panel), scribble (the drawing layer of Edit), the hosted and browser targets' words, then the handshake, last, so every function and
7
7
  * variable exists before the first message can arrive. The tool names come
8
8
  * from the view contract (SLATE_UI_TOOLS), not from the server's own module.
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-slate-ui-script.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script.ts"],"names":[],"mappings":"AAeA;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAgB3D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,aAAa,KAAG,MAyB/C,CAAC;AAEb,eAAO,MAAM,eAAe,QAA8B,CAAC"}
1
+ {"version":3,"file":"mcp-slate-ui-script.d.ts","sourceRoot":"","sources":["../src/mcp-slate-ui-script.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AA2B3D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,aAAa,KAAG,MA0B/C,CAAC;AAEb,eAAO,MAAM,eAAe,QAA8B,CAAC"}
@@ -1,28 +1,41 @@
1
- import { SLATE_CONVERT_CHOICES, SLATE_CONVERT_DESCRIPTIONS, SLATE_CONVERT_MAX_WIDTH, SLATE_MORE_COUNTS, SLATE_REMOTE_CONVERT_CHOICES, SLATE_REMOTE_CONVERT_DESCRIPTIONS, SLATE_UI_COPY } from './mcp-slate-ui-copy.js';
2
- import { SLATE_UI_TOOLS } from './slate-view-contract.js';
1
+ import { SLATE_BROWSER_PAGE_KEYS, SLATE_CONVERT_CHOICES, SLATE_CONVERT_DESCRIPTION_KEYS, SLATE_CONVERT_MAX_WIDTH, SLATE_MORE_COUNTS, SLATE_REMOTE_CONVERT_CHOICES, SLATE_REMOTE_CONVERT_DESCRIPTION_KEYS } from './mcp-slate-ui-copy.js';
2
+ import { SLATE_UI_LOCALES } from './mcp-slate-ui-locales/index.js';
3
+ import { SLATE_EDIT_PROMPT_MAX_BYTES, SLATE_UI_TOOLS } from './slate-view-contract.js';
3
4
  import { SLATE_UI_BRIDGE } from './mcp-slate-ui-script-bridge.js';
4
5
  import { SLATE_UI_BROWSER } from './mcp-slate-ui-script-browser.js';
5
6
  import { SLATE_UI_DIALOG } from './mcp-slate-ui-script-dialog.js';
6
7
  import { SLATE_UI_INLINE } from './mcp-slate-ui-script-inline.js';
7
8
  import { SLATE_UI_INSPIRATION } from './mcp-slate-ui-script-inspiration.js';
9
+ import { buildSlateUiL10n } from './mcp-slate-ui-script-l10n.js';
8
10
  import { SLATE_UI_MORE } from './mcp-slate-ui-script-more.js';
11
+ import { SLATE_UI_NO_PAUSE, SLATE_UI_PAUSE } from './mcp-slate-ui-script-pause.js';
9
12
  import { SLATE_UI_PROGRESS } from './mcp-slate-ui-script-progress.js';
10
13
  import { SLATE_UI_REMOTE } from './mcp-slate-ui-script-remote.js';
11
14
  import { SLATE_UI_SCRIBBLE } from './mcp-slate-ui-script-scribble.js';
12
15
  import { SLATE_UI_SELECT } from './mcp-slate-ui-script-select.js';
13
16
  import { SLATE_UI_STAGE } from './mcp-slate-ui-script-stage.js';
14
17
  import { SLATE_UI_STATE } from './mcp-slate-ui-script-state.js';
18
+ /**
19
+ * Every shipped catalogue as the screen carries it: all keys but the words of the browser page around it (that page
20
+ * carries its own, SLATE_BROWSER_PAGE_KEYS; the title is both's).
21
+ */
22
+ const screenMessages = () => {
23
+ const pageOnly = new Set(SLATE_BROWSER_PAGE_KEYS.filter((key) => key !== 'title'));
24
+ return Object.fromEntries(Object.entries(SLATE_UI_LOCALES).map(([tag, messages]) => [
25
+ tag, Object.fromEntries(Object.entries(messages).filter(([key]) => !pageOnly.has(key))),
26
+ ]));
27
+ };
15
28
  const HANDSHAKE = String.raw `
16
29
  // ---- connect: handlers are registered above, before the handshake ----
17
30
  if (window.parent === window) {
18
- fatal(COPY.needsHost);
31
+ fatal(t("needsHost"));
19
32
  } else {
20
33
  request("ui/initialize", { appCapabilities: {}, appInfo: { name: "12ui-slate", version: "3.0.0" }, protocolVersion: PROTOCOL })
21
34
  .then(function (init) {
22
35
  applyHost((init && init.hostContext) || {});
23
36
  notify("ui/notifications/initialized", {});
24
37
  })
25
- .catch(function (err) { fatal(COPY.noConnection + errText(err)); });
38
+ .catch(function (err) { fatal(t("noConnection", { detail: errText(err) })); });
26
39
  }
27
40
  `;
28
41
  /**
@@ -35,20 +48,21 @@ export const buildSlateUiScript = (target) => [
35
48
  '(function () {',
36
49
  SLATE_UI_BRIDGE
37
50
  .replace('__TOOLS__', () => JSON.stringify(SLATE_UI_TOOLS))
38
- .replace('__COPY__', () => JSON.stringify(SLATE_UI_COPY))
39
51
  .replace('__TARGET__', () => JSON.stringify(target))
40
52
  .replace('__CONVERT__', () => JSON.stringify({
41
53
  choices: target === 'remote' ? SLATE_REMOTE_CONVERT_CHOICES : SLATE_CONVERT_CHOICES,
42
- descriptions: target === 'remote' ? SLATE_REMOTE_CONVERT_DESCRIPTIONS : SLATE_CONVERT_DESCRIPTIONS,
54
+ descriptionKeys: target === 'remote' ? SLATE_REMOTE_CONVERT_DESCRIPTION_KEYS : SLATE_CONVERT_DESCRIPTION_KEYS,
43
55
  maxWidth: SLATE_CONVERT_MAX_WIDTH,
44
56
  })),
45
57
  SLATE_UI_STATE,
58
+ buildSlateUiL10n(screenMessages()),
46
59
  SLATE_UI_PROGRESS,
47
60
  SLATE_UI_INLINE,
48
61
  SLATE_UI_SELECT,
49
62
  SLATE_UI_INSPIRATION,
63
+ target === 'remote' ? SLATE_UI_PAUSE : SLATE_UI_NO_PAUSE,
50
64
  SLATE_UI_STAGE,
51
- SLATE_UI_DIALOG,
65
+ SLATE_UI_DIALOG.replace('__EDIT_PROMPT_MAX_BYTES__', () => JSON.stringify(SLATE_EDIT_PROMPT_MAX_BYTES)),
52
66
  SLATE_UI_MORE.replace('__MORE__', () => JSON.stringify(SLATE_MORE_COUNTS)),
53
67
  SLATE_UI_SCRIBBLE,
54
68
  SLATE_UI_REMOTE,