@jxsuite/studio 6.1.1 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -17,6 +17,7 @@ import { allCanvasSurfaces, stageContaining, surfaceForPane } from "./surface-re
17
17
  import type { CanvasSurface } from "./surface-registry";
18
18
  import type { PaneDerivation } from "../workspace/workspace";
19
19
  import type { CanvasPanel } from "../types";
20
+ import type { UnboundCanvasPanel } from "./canvas-utils";
20
21
  import type { Tab } from "../tabs/tab";
21
22
 
22
23
  export {
@@ -149,11 +150,12 @@ export function panelHostingCanvas(
149
150
  * answers with the FOCUSED pane's tab, which is a different document the moment the click is in a
150
151
  * pane the keyboard is not in.
151
152
  *
152
- * @param {CanvasPanel} panel
153
+ * @param {UnboundCanvasPanel} panel
153
154
  * @returns {Tab | null}
154
155
  */
155
- export function tabOfMountedPanel(panel: CanvasPanel): Tab | null {
156
- const canvasEl = panel.canvas as HTMLElement | null;
156
+ export function tabOfMountedPanel(panel: UnboundCanvasPanel): Tab | null {
157
+ // An unbound board (no canvas node yet) has no pane mounting it.
158
+ const canvasEl = panel.canvas;
157
159
  const mounted = canvasEl ? panelHostingCanvas(canvasEl) : null;
158
160
  return mounted ? tabOfPane(mounted.surface.paneId) : null;
159
161
  }
@@ -4,7 +4,7 @@
4
4
  * template creation, centering, transform application, zoom indicator, and fit-to-screen.
5
5
  */
6
6
 
7
- import type { CanvasPanel, JsonValue } from "../types";
7
+ import type { CanvasPanel } from "../types";
8
8
 
9
9
  import { renderOnly } from "../store";
10
10
  import {
@@ -39,6 +39,7 @@ import {
39
39
  import type { CanvasStageHandle, CanvasStagePanelItem } from "../surfaces/canvas-stage";
40
40
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
41
41
  import type { CommandArgValues } from "../commands/command-args";
42
+ import { isNumber, isString } from "@jxsuite/schema/guards";
42
43
  import type { Tab } from "../tabs/tab";
43
44
 
44
45
  /*
@@ -106,6 +107,22 @@ function setZoomOf(surface: CanvasSurface, zoom: number): void {
106
107
  }
107
108
  }
108
109
 
110
+ /** The {@link CanvasPanel} fields that hold the board's drawn nodes. */
111
+ type CanvasPanelNodeKey = "canvas" | "element" | "scrollContainer" | "viewport";
112
+
113
+ /**
114
+ * A panel record as it may be before {@link bindCanvasPanels} has run: its DOM fields can still be
115
+ * null, because {@link canvasPanelEntry} builds them that way. A bound {@link CanvasPanel} is
116
+ * assignable to it, so a reader that must tolerate an unbound board takes this type.
117
+ */
118
+ export type UnboundCanvasPanel = Omit<CanvasPanel, CanvasPanelNodeKey> &
119
+ Record<CanvasPanelNodeKey, HTMLElement | null>;
120
+
121
+ /** Whether the stage has wired a board's canvas and viewport nodes into its record yet. */
122
+ export function isPanelBound(panel: UnboundCanvasPanel): boolean {
123
+ return Boolean(panel.canvas && panel.viewport);
124
+ }
125
+
109
126
  /**
110
127
  * One artboard: the record the geometry reads, and the item the stage document draws.
111
128
  *
@@ -139,7 +156,7 @@ export function canvasPanelEntry(
139
156
  fullWidth: boolean,
140
157
  width: number | null = null,
141
158
  ): CanvasPanelEntry {
142
- const panel = {
159
+ const unbound: UnboundCanvasPanel = {
143
160
  _width: width || null,
144
161
  canvas: null,
145
162
  element: null,
@@ -148,7 +165,11 @@ export function canvasPanelEntry(
148
165
  renderScope: null,
149
166
  scrollContainer: null,
150
167
  viewport: null,
151
- } as unknown as CanvasPanel;
168
+ };
169
+ /* SAFETY: the record is handed out unbound and filled in place by `bindCanvasPanels` once the
170
+ stage has drawn it; every reader that can run before that (`tabOfMountedPanel`, `applyEditZoom`,
171
+ `updateActivePanelHeaders`) reads it as an UnboundCanvasPanel and checks the nodes first. */
172
+ const panel = unbound as CanvasPanel;
152
173
  /* The viewport takes the declared width, the canvas takes it too — but a FULL-WIDTH board's
153
174
  viewport does not, because "full width" means "as wide as the box you are in". Carried as two
154
175
  custom properties rather than as `width:` so `applyEditZoom`'s inline write on the canvas still
@@ -186,9 +207,13 @@ export function canvasPanelEntry(
186
207
  */
187
208
  export function bindCanvasPanels(entries: CanvasPanelEntry[], stage: CanvasStageHandle): void {
188
209
  for (const { item, panel } of entries) {
189
- panel.element = stage.panelNode(item.key, "panel") as HTMLElement;
190
- panel.viewport = stage.panelNode(item.key, "panel-viewport") as HTMLElement;
191
- panel.canvas = stage.panelNode(item.key, "panel-canvas") as HTMLElement;
210
+ /* SAFETY: callers bind only after `drawStage` has settled, and the stage document draws the
211
+ `panel`, `panel-viewport` and `panel-canvas` parts for every item it was given, keyed by
212
+ `item.key`, so each lookup finds its node. */
213
+ const node = (part: string) => stage.panelNode(item.key, part) as HTMLElement;
214
+ panel.element = node("panel");
215
+ panel.viewport = node("panel-viewport");
216
+ panel.canvas = node("panel-canvas");
192
217
  }
193
218
  }
194
219
 
@@ -232,8 +257,10 @@ export function centerCanvas(surface: CanvasSurface) {
232
257
  const wrapWidth = surface.wrap.clientWidth;
233
258
  const contentWidth = surface.panzoomWrap.scrollWidth;
234
259
  const zoom = zoomOf(surface);
235
- const scaledWidth = contentWidth * zoom;
236
- surface.panX = Math.max(16, (wrapWidth - scaledWidth) / 2);
260
+ const free = wrapWidth - contentWidth * zoom;
261
+ /* Content that fits is centred, however little room is left over: a 16px floor on a fitted page
262
+ pushed its right edge 16px past the pane. Content wider than the pane starts 16px in. */
263
+ surface.panX = free >= 0 ? free / 2 : 16;
237
264
  surface.panY = 0;
238
265
  }
239
266
 
@@ -349,7 +376,7 @@ export function applyEditZoom(
349
376
  return;
350
377
  }
351
378
  const [panel] = surface.panels;
352
- if (!panel?.canvas || !panel.viewport) {
379
+ if (!panel || !isPanelBound(panel)) {
353
380
  return;
354
381
  }
355
382
  const canvasEl = panel.canvas;
@@ -458,6 +485,14 @@ export function requestEditZoom(
458
485
  );
459
486
  }
460
487
 
488
+ /** The screen pixels a stage reserves above its boards (`--boards-inset`), or 0 for none. */
489
+ export function boardsInset(panzoomWrap: HTMLElement): number {
490
+ // The inset is declared in px (`--boards-inset:40px`); unset reads as "", which is no inset.
491
+ const declared = getComputedStyle(panzoomWrap).getPropertyValue("--boards-inset").trim();
492
+ const inset = Number(declared.replace(/px$/, ""));
493
+ return Number.isFinite(inset) ? inset : 0;
494
+ }
495
+
461
496
  /**
462
497
  * Compute and apply a geometric fit. Pure arithmetic — it declares nothing.
463
498
  *
@@ -470,7 +505,9 @@ function applyGeometricFit(surface: CanvasSurface, axis: "width" | "page", maxZo
470
505
  return;
471
506
  }
472
507
  const wrapWidth = surface.wrap.clientWidth;
473
- const wrapHeight = surface.wrap.clientHeight;
508
+ // The boards' own top clearance (`--boards-inset`, the Project Styles bar) is screen space the
509
+ // Artboards cannot use, so the page is fitted into what is left below it.
510
+ const wrapHeight = surface.wrap.clientHeight - boardsInset(surface.panzoomWrap);
474
511
  const gap = 24;
475
512
  const padding = 32;
476
513
  let totalPanelWidth = 0;
@@ -571,12 +608,12 @@ export const FIT_WORDS: readonly string[] = ["width", "page", "none"];
571
608
  * assistant sees. It stays as the typed read the body needs (`args.fit` is `unknown`) and as the
572
609
  * refusal for a caller that reaches the body directly.
573
610
  */
574
- function fitArg(commandId: string, args: Record<string, unknown>, key: string): FitMode {
611
+ function fitArg(commandId: string, args: CommandArgValues, key: string): FitMode {
575
612
  const value = args[key];
576
- if (typeof value === "string" && FIT_WORDS.includes(value)) {
577
- return value as FitMode;
613
+ if (isFitWord(value)) {
614
+ return value;
578
615
  }
579
- if (typeof value === "number" && value >= PAN_ZOOM_MIN && value <= PAN_ZOOM_MAX) {
616
+ if (isNumber(value) && value >= PAN_ZOOM_MIN && value <= PAN_ZOOM_MAX) {
580
617
  return value;
581
618
  }
582
619
  throw new RangeError(
@@ -585,6 +622,11 @@ function fitArg(commandId: string, args: Record<string, unknown>, key: string):
585
622
  );
586
623
  }
587
624
 
625
+ /** Whether a value is one of {@link FIT_WORDS}, the named (non-scale) fits. */
626
+ function isFitWord(value: unknown): value is Exclude<FitMode, number> {
627
+ return isString(value) && FIT_WORDS.includes(value);
628
+ }
629
+
588
630
  /** Declared fits, keyed per tab + document. */
589
631
  const _fits = new Map<string, FitMode>();
590
632
 
@@ -641,7 +683,7 @@ export function applyFit(fit?: FitMode, surface: CanvasSurface = activeCanvasSur
641
683
  applyTransform(surface);
642
684
  return;
643
685
  }
644
- if (typeof chosen === "number") {
686
+ if (isNumber(chosen)) {
645
687
  setZoomOf(surface, clampPanZoom(chosen));
646
688
  applyTransform(surface);
647
689
  return;
@@ -733,11 +775,12 @@ export function resetZoom(surface: CanvasSurface = activeCanvasSurface()) {
733
775
  * hands a rect back), so one arithmetic serves a rect measured from a parent DOM element and a rect
734
776
  * measured inside a canvas iframe alike.
735
777
  *
736
- * **The viewport is the box that SCROLLS, not the stage.** Edit docks the Document Header card
737
- * above its scroller, inside the same stage cell, so there the stage is the band plus the page and
738
- * its centre is half a band too high: a reveal would land the node that far above the middle of
739
- * what the author can actually see. {@link revealScroller} is that box wherever there is one, and
740
- * where there is none (Design, Stylebook, a comparison) the stage is still the viewport.
778
+ * **The viewport is the box that SCROLLS, not the stage.** Over a collection entry Edit stands the
779
+ * writing banner above its scroller, inside the same stage cell, so there the stage is the banner
780
+ * plus the page and its centre is half a banner too high: a reveal would land the node that far
781
+ * above the middle of what the author can actually see. {@link revealScroller} is that box wherever
782
+ * there is one, and where there is none (Design, Stylebook, a comparison) the stage is still the
783
+ * viewport.
741
784
  */
742
785
  function centeringOffset(surface: CanvasSurface, rect: { top: number; height: number }): number {
743
786
  const viewport = rectOf(revealScroller(surface) ?? surface.wrap);
@@ -810,6 +853,37 @@ export function panToParentRect(
810
853
  revealBy(surface, centeringOffset(surface, rect), false);
811
854
  }
812
855
 
856
+ /**
857
+ * Bring a PARENT-VIEWPORT rect into view on a pan/zoom stage, moving as little as it must: not at
858
+ * all when the rect is already wholly in view, and never so far that the boards' top edge comes
859
+ * down past where it stands now.
860
+ *
861
+ * {@link panToParentRect} always centres, which is right for a jump to a diff change or a node the
862
+ * author asked to see. The stylebook's Outline is a list the author clicks DOWN, and centring its
863
+ * first rows meant the h1 at the very top of a fitted catalogue pulled every board half a pane
864
+ * down, leaving an empty band above them and no specimen that had moved into view.
865
+ */
866
+ export function revealParentRect(
867
+ rect: { top: number; height: number },
868
+ surface: CanvasSurface = activeCanvasSurface(),
869
+ ) {
870
+ const viewport = rectOf(surface.wrap);
871
+ if (rect.top >= viewport.top && rect.top + rect.height <= viewport.top + viewport.height) {
872
+ return;
873
+ }
874
+ const offset = centeringOffset(surface, rect);
875
+ const ceiling = Math.max(surface.panY, 0) - surface.panY;
876
+ const step = Math.min(offset, ceiling);
877
+ if (step !== 0) {
878
+ /* A reveal is a pan somebody asked for, so the entry's centring stands down as a user's pan
879
+ makes it: a frame still growing to its height would otherwise re-centre the stage (top
880
+ aligned) under the card just brought on screen, which is what a reveal on a fresh stylebook
881
+ canvas did. */
882
+ surface.needsCenter = false;
883
+ animatePanBy(surface, step);
884
+ }
885
+ }
886
+
813
887
  /** Animate a stage's `panY` by `offsetY` with the shared 250ms ease-out. */
814
888
  function animatePanBy(surface: CanvasSurface, offsetY: number) {
815
889
  const startY = surface.panY;
@@ -844,6 +918,7 @@ export const CANVAS_MODES = [
844
918
  "preview",
845
919
  "source",
846
920
  "stylebook",
921
+ "tokens",
847
922
  "grid",
848
923
  "git-diff",
849
924
  ] as const;
@@ -853,6 +928,11 @@ export type CanvasMode = (typeof CANVAS_MODES)[number];
853
928
  /** The base modes the preview flag composes with — the two the Canvas view axis shows it beside. */
854
929
  const PREVIEWABLE_BASE_MODES = new Set(["edit", "design"]);
855
930
 
931
+ /** Whether a base mode is one the preview flag composes with: a member of PREVIEWABLE_BASE_MODES. */
932
+ function isPreviewableBase(mode: string): mode is "edit" | "design" {
933
+ return PREVIEWABLE_BASE_MODES.has(mode);
934
+ }
935
+
856
936
  // ─── The Canvas view (§4.2) ──────────────────────────────────────────────────
857
937
  // `Edit │ Design` is a radio and `Preview` is a TOGGLE beside it, because that is what the storage
858
938
  // Has always been: `preview` is not a base mode, it is a flag that composes with one.
@@ -913,7 +993,13 @@ export function canvasBaseViewsFor(tab: ViewableTab): CanvasView[] {
913
993
  /** The base view the tab returns to — what the radio marks while preview is on. */
914
994
  export function canvasBaseViewOf(tab: ViewableTab): CanvasView | null {
915
995
  const base = tab.session.ui.canvasMode;
916
- return PREVIEWABLE_BASE_MODES.has(base) ? (base as CanvasView) : null;
996
+ return isPreviewableBase(base) ? base : null;
997
+ }
998
+
999
+ /** A tab's Preview toggle: whether it is offered, and whether it is pressed. */
1000
+ export interface PreviewState {
1001
+ available: boolean;
1002
+ on: boolean;
917
1003
  }
918
1004
 
919
1005
  /**
@@ -922,7 +1008,7 @@ export function canvasBaseViewOf(tab: ViewableTab): CanvasView | null {
922
1008
  * `available` is a fact about the DOCUMENT (its declared modes) and about the base it is currently
923
1009
  * in — `source` composes with no preview, so the toggle is not offered there.
924
1010
  */
925
- export function previewStateOf(tab: ViewableTab): { available: boolean; on: boolean } {
1011
+ export function previewStateOf(tab: ViewableTab): PreviewState {
926
1012
  return {
927
1013
  available:
928
1014
  tab.capabilities.modes.includes("preview") &&
@@ -1041,7 +1127,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1041
1127
  * than the control it replaced, which is the opposite of the point.
1042
1128
  */
1043
1129
  function contextTab(commandId: string, args: CommandArgValues) {
1044
- const { pane } = args as { pane?: unknown };
1130
+ const { pane } = args;
1045
1131
  if (pane === undefined) {
1046
1132
  return requireTab(commandId);
1047
1133
  }
@@ -1073,8 +1159,8 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1073
1159
 
1074
1160
  /** The pane a rendering-context verb addresses, named or focused. {@link repaint}'s own rule. */
1075
1161
  function paneOfArgs(args: CommandArgValues): string {
1076
- const { pane } = args as { pane?: unknown };
1077
- return typeof pane === "string" ? pane : workspace.activePaneId;
1162
+ const { pane } = args;
1163
+ return isString(pane) ? pane : workspace.activePaneId;
1078
1164
  }
1079
1165
 
1080
1166
  return [
@@ -1103,7 +1189,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1103
1189
  description:
1104
1190
  "Switch the active document's editor mode. edit and design put its element tree on " +
1105
1191
  "the canvas, where the document tools work; preview renders it as a visitor sees it; " +
1106
- "source shows the JSON; stylebook, grid and git-diff open other editors. Use it to " +
1192
+ "source shows the JSON; stylebook, tokens, grid and git-diff open other editors. Use it to " +
1107
1193
  "return a document to edit or design when the tree tools are refused.",
1108
1194
  name: "set_canvas_mode",
1109
1195
  /* `after.editor.kind` rather than the tab's own field: it is the gate's read (`treeEditable`
@@ -1258,9 +1344,9 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1258
1344
  * so it simply renders at the pane's width — which is the same clamp the drag applies, arrived
1259
1345
  * at by CSS instead of by arithmetic. Refusing would make the verb depend on the window size.
1260
1346
  */
1261
- run: (_commandCtx, args) => {
1347
+ run: (_commandCtx, args: CommandArgValues) => {
1262
1348
  const tab = contextTab("canvas.setEditWidth", args);
1263
- const { width } = args as { width?: unknown };
1349
+ const { width } = args;
1264
1350
  if (width === null) {
1265
1351
  clearEditWidth(paneOfArgs(args));
1266
1352
  repaint(args);
@@ -1311,10 +1397,10 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1311
1397
  group: "3_canvas",
1312
1398
  requires: "an open document",
1313
1399
  when: documentOpen,
1314
- run: (_commandCtx, args) => {
1400
+ run: (_commandCtx, args: CommandArgValues) => {
1315
1401
  const tab = contextTab("canvas.setBreakpoint", args);
1316
- const { media } = args as { media?: unknown };
1317
- if (media !== null && typeof media !== "string") {
1402
+ const { media } = args;
1403
+ if (media !== null && !isString(media)) {
1318
1404
  throw new RangeError(
1319
1405
  `command "canvas.setBreakpoint" argument "media": expected a breakpoint key or null`,
1320
1406
  );
@@ -1323,9 +1409,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1323
1409
  that does not exist — the rule `data.expandRow` applies to a state entry's name.
1324
1410
  `getEffectiveMedia` and not `document.$media`: the popover offers the SITE's breakpoints
1325
1411
  too, and a command that refused what the control offers would be worse than no command. */
1326
- const declared = Object.keys(
1327
- getEffectiveMedia(tab.doc.document?.$media as Record<string, string> | undefined),
1328
- );
1412
+ const declared = Object.keys(getEffectiveMedia(tab.doc.document.$media));
1329
1413
  if (media !== null && !declared.includes(media)) {
1330
1414
  throw new RangeError(
1331
1415
  `command "canvas.setBreakpoint" argument "media": "${media}" is not a breakpoint this ` +
@@ -1359,7 +1443,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1359
1443
  args,
1360
1444
  "scheme",
1361
1445
  COLOR_SCHEMES,
1362
- ) as "auto" | "dark" | "light";
1446
+ );
1363
1447
  repaint(args);
1364
1448
  },
1365
1449
  title: "Set Color Scheme",
@@ -1372,9 +1456,9 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1372
1456
  * preset owns it. What is left over is genuinely a rendering context, and it is the half of
1373
1457
  * site-architecture.md §13.4 the canvas can show today: the artboard root's `lang` and `dir`.
1374
1458
  * That is why this is a verb and not a label — an RTL locale mirrors the layout on screen.
1375
- * (That section's other half, `$page.locale` in the rendered state, is injected by the
1376
- * compiler and not by the canvas's `substitutePreviewParams`; previewing it is a separate
1377
- * change to the render path.)
1459
+ * (That section's other half, `$page.locale`, is injected into the canvas render from the
1460
+ * page's route, as the build injects it (studio.md §4.1). This verb leaves it alone: the
1461
+ * pane's language is a rendering context, not the page's (§20.2).)
1378
1462
  *
1379
1463
  * It lives in this file rather than in `i18n/i18n-commands.ts` because `contextTab`, `paneArg`
1380
1464
  * and `repaint` are local closures here, and every rendering-context verb needs all three: the
@@ -1475,16 +1559,18 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1475
1559
  level: "document",
1476
1560
  menus: ["palette"],
1477
1561
  requires: "a popover in the open document",
1478
- run: (_commandCtx, args) => {
1562
+ run: (_commandCtx, args: CommandArgValues) => {
1479
1563
  const tab = contextTab("canvas.setPopoverOpen", args);
1480
- const raw = (args ?? {}) as { open?: unknown; path?: JxPath };
1564
+ /* SAFETY: `registry.run` coerces args against this record's schema before `run`, and the
1565
+ schema declares `path` an array of strings and numbers, which is what a JxPath is. */
1566
+ const explicitPath = args["path"] as JxPath | undefined;
1481
1567
  const open =
1482
- raw.open === undefined ? true : booleanArg("canvas.setPopoverOpen", args, "open");
1483
- if (!open && raw.path === undefined) {
1568
+ args["open"] === undefined ? true : booleanArg("canvas.setPopoverOpen", args, "open");
1569
+ if (!open && explicitPath === undefined) {
1484
1570
  deps.setOpenPopover(tab, null);
1485
1571
  return;
1486
1572
  }
1487
- const path = popoverPathFor(tab, raw.path);
1573
+ const path = popoverPathFor(tab, explicitPath);
1488
1574
  /* REFUSES a path that is not a popover rather than opening nothing — the rule
1489
1575
  `canvas.setBreakpoint` applies to a breakpoint key. A <dialog> is refused with it: its UA
1490
1576
  rules key off `open`, not `popover`, so de-popovering one falls back to a different rule
@@ -1535,16 +1621,18 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1535
1621
  level: "document",
1536
1622
  menus: ["palette"],
1537
1623
  requires: "a dialog in the open document",
1538
- run: (_commandCtx, args) => {
1624
+ run: (_commandCtx, args: CommandArgValues) => {
1539
1625
  const tab = contextTab("canvas.setDialogOpen", args);
1540
- const raw = (args ?? {}) as { open?: unknown; path?: JxPath };
1626
+ /* SAFETY: `registry.run` coerces args against this record's schema before `run`, and the
1627
+ schema declares `path` an array of strings and numbers, which is what a JxPath is. */
1628
+ const explicitPath = args["path"] as JxPath | undefined;
1541
1629
  const open =
1542
- raw.open === undefined ? true : booleanArg("canvas.setDialogOpen", args, "open");
1543
- if (!open && raw.path === undefined) {
1630
+ args["open"] === undefined ? true : booleanArg("canvas.setDialogOpen", args, "open");
1631
+ if (!open && explicitPath === undefined) {
1544
1632
  deps.setOpenDialog(tab, null);
1545
1633
  return;
1546
1634
  }
1547
- const path = dialogPathFor(tab, raw.path);
1635
+ const path = dialogPathFor(tab, explicitPath);
1548
1636
  /* REFUSES a path that is not a dialog, for the same reason its twin refuses a non-popover:
1549
1637
  the canvas would draw it under the wrong rule and with the wrong name. */
1550
1638
  if (path === null) {
@@ -1586,14 +1674,14 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1586
1674
  * (`scripts/screenshots/README.md`) forbids outright. The pointer and the camera use the same
1587
1675
  * door.
1588
1676
  */
1589
- run: (_commandCtx, args) => {
1677
+ run: (_commandCtx, args: CommandArgValues) => {
1590
1678
  // Resolve the tab first, so a pane with no document refuses before anything opens.
1591
1679
  contextTab("canvas.setResolvingOpen", args);
1592
- const { open, pane } = args as { open?: unknown; pane?: unknown };
1680
+ const { open, pane } = args;
1593
1681
  // `open` defaults to true and is never COERCED: `{ open: "no" }` would otherwise read as a
1594
1682
  // Close, the class of silent wrong answer this setter family exists to stop.
1595
1683
  deps.setResolvingOpen(
1596
- typeof pane === "string" ? pane : workspace.activePaneId,
1684
+ isString(pane) ? pane : workspace.activePaneId,
1597
1685
  open === undefined || booleanArg("canvas.setResolvingOpen", args, "open"),
1598
1686
  );
1599
1687
  },
@@ -1636,26 +1724,24 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
1636
1724
  group: "3_canvas",
1637
1725
  requires: "an open component document",
1638
1726
  when: documentOpen,
1639
- run: (_commandCtx, args) => {
1727
+ run: (_commandCtx, args: CommandArgValues) => {
1640
1728
  const tab = contextTab("canvas.setTestProp", args);
1641
1729
  const name = stringArg("canvas.setTestProp", args, "name");
1642
1730
  // REFUSES a prop the component does not declare, rather than seeding a value nothing reads
1643
1731
  // — the rule `data.expandRow` and `canvas.setBreakpoint` both apply to their own names.
1644
- const declared = Object.keys(
1645
- (tab.doc.document?.state as Record<string, unknown> | undefined) ?? {},
1646
- );
1732
+ const declared = Object.keys(tab.doc.document.state ?? {});
1647
1733
  if (!declared.includes(name)) {
1648
1734
  throw new RangeError(
1649
1735
  `command "canvas.setTestProp" argument "name": "${name}" is not a prop this component ` +
1650
1736
  `declares — it declares: ${declared.length > 0 ? declared.join(", ") : "nothing"}`,
1651
1737
  );
1652
1738
  }
1653
- const { value } = args as { value?: unknown };
1739
+ const { value } = args;
1654
1740
  const next = { ...tab.session.ui.previewProps };
1655
1741
  if (value === null || value === undefined) {
1656
1742
  delete next[name];
1657
1743
  } else {
1658
- next[name] = value as JsonValue;
1744
+ next[name] = value;
1659
1745
  }
1660
1746
  tab.session.ui.previewProps = Object.keys(next).length > 0 ? next : null;
1661
1747
  repaint(args);
@@ -1723,13 +1809,13 @@ export function registerCanvasViewCommands(
1723
1809
  */
1724
1810
  export function updateActivePanelHeaders(surface: CanvasSurface = activeCanvasSurface()) {
1725
1811
  const activeMedia = activeMediaOfPane(surface.paneId);
1726
- for (const p of surface.panels) {
1812
+ // A board the stage has not bound yet has no header to mark.
1813
+ const panels: readonly UnboundCanvasPanel[] = surface.panels;
1814
+ for (const p of panels) {
1727
1815
  const header = p.element?.querySelector('[part="panel-header"]');
1728
1816
  if (header) {
1729
1817
  const isActive =
1730
- (activeMedia === null && p.mediaName === "base") ||
1731
- (activeMedia === null && p.mediaName === null) ||
1732
- activeMedia === p.mediaName;
1818
+ (activeMedia === null && p.mediaName === "base") || activeMedia === p.mediaName;
1733
1819
  /* An ATTRIBUTE the document does not bind, written from outside it. Which board is current is
1734
1820
  a fact about the pane's session that changes without the stage being rebuilt — the same
1735
1821
  reason the pan transform is written rather than bound — so a reconcile can never disagree
@@ -12,8 +12,9 @@
12
12
  */
13
13
 
14
14
  import { activeTab } from "../workspace/workspace";
15
- import { getNodeAtPath } from "../state";
15
+ import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
16
16
  import { documentHasDialog, isDialog } from "@jxsuite/schema/dialogs";
17
+ import { isNonNullObject } from "@jxsuite/schema/guards";
17
18
  import { primarySelection } from "../tabs/selection";
18
19
  import type { JxMutableNode } from "@jxsuite/schema/types";
19
20
  import type { JxPath } from "../state";
@@ -39,7 +40,8 @@ export function ancestorDialogPath(
39
40
  for (let end = path.length; end >= 0; end -= 1) {
40
41
  const prefix = path.slice(0, end);
41
42
  const node = getNodeAtPath(doc, prefix);
42
- if (node && typeof node === "object" && isDialog(node)) {
43
+ // A path can end on a text child or a value, so only an element is asked about its tag.
44
+ if (isNonNullObject(node) && isDialog(node)) {
43
45
  return prefix;
44
46
  }
45
47
  }
@@ -58,19 +60,22 @@ export function ancestorDialogPath(
58
60
  * @returns The dialog's path, or null.
59
61
  */
60
62
  export function dialogPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
63
+ /* SAFETY: a widening, so it cannot hide a mismatch: `Tab` declares the document always present,
64
+ but a tab record without one must answer null rather than throw (tests/dialog-path.test.ts,
65
+ "a tab with no document"), and the widened type keeps that guard checked. */
61
66
  const doc = tab.doc.document as JxMutableNode | undefined;
62
67
  if (!doc) {
63
68
  return null;
64
69
  }
65
70
  if (explicit) {
66
71
  const node = getNodeAtPath(doc, explicit);
67
- return node && typeof node === "object" && isDialog(node) ? explicit : null;
72
+ return isNonNullObject(node) && isDialog(node) ? explicit : null;
68
73
  }
69
74
  return ancestorDialogPath(doc, primarySelection(tab.session.selection));
70
75
  }
71
76
 
72
77
  /** Whether the active document holds a `<dialog>` at all — the command's `enablement`. */
73
78
  export function activeDocumentHasDialog(): boolean {
74
- const doc = activeTab.value?.doc.document as JxMutableNode | undefined;
79
+ const doc = activeTab.value?.doc.document;
75
80
  return doc ? documentHasDialog(doc) : false;
76
81
  }
@@ -19,7 +19,6 @@ import { ancestorDialogPath } from "./dialog-path";
19
19
  import { postDialogOpen } from "./iframe-host";
20
20
  import { primarySelection } from "../tabs/selection";
21
21
  import { updateSession } from "../store";
22
- import type { JxMutableNode } from "@jxsuite/schema/types";
23
22
  import type { JxPath } from "../state";
24
23
  import type { Tab } from "../tabs/tab";
25
24
 
@@ -51,7 +50,7 @@ export function setOpenDialog(tab: Tab, path: JxPath | null): void {
51
50
  * @returns Whether anything changed.
52
51
  */
53
52
  export function openDialogFor(tab: Tab, path: JxPath | null): boolean {
54
- const target = ancestorDialogPath(tab.doc.document as JxMutableNode, path);
53
+ const target = ancestorDialogPath(tab.doc.document, path);
55
54
  if (target === null || samePath(tab.session.ui.openDialog, target)) {
56
55
  return false;
57
56
  }
@@ -35,6 +35,7 @@
35
35
  */
36
36
 
37
37
  import { deepEqual, matchChildren } from "@jxsuite/collab/diff-core";
38
+ import { isJsonObject } from "@jxsuite/schema/guards";
38
39
  import type { JxMutableNode, JxPath } from "@jxsuite/schema/types";
39
40
 
40
41
  /** What happened to a node. `modified` means the node survived and its own content changed. */
@@ -84,10 +85,6 @@ export interface ChangeMapOptions {
84
85
 
85
86
  const DEFAULT_MAX_CELLS = 250_000;
86
87
 
87
- function isPlainObject(value: unknown): value is Record<string, unknown> {
88
- return typeof value === "object" && value !== null && !Array.isArray(value);
89
- }
90
-
91
88
  class ChangeWalker {
92
89
  readonly original: ChangeMark[] = [];
93
90
  readonly current: ChangeMark[] = [];
@@ -121,12 +118,7 @@ class ChangeWalker {
121
118
  this.steps.push({ currentPath: bPath, kind, originalPath: aPath });
122
119
  }
123
120
 
124
- diffNode(
125
- aPath: JxPath,
126
- bPath: JxPath,
127
- a: Record<string, unknown>,
128
- b: Record<string, unknown>,
129
- ): void {
121
+ diffNode(aPath: JxPath, bPath: JxPath, a: JxMutableNode, b: JxMutableNode): void {
130
122
  const isRoot = aPath.length === 0 && bPath.length === 0;
131
123
  let ownChanged = false;
132
124
  for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) {
@@ -161,8 +153,8 @@ class ChangeWalker {
161
153
  private diffChildren(
162
154
  aPath: JxPath,
163
155
  bPath: JxPath,
164
- ca: readonly unknown[],
165
- cb: readonly unknown[],
156
+ ca: readonly (JxMutableNode | string)[],
157
+ cb: readonly (JxMutableNode | string)[],
166
158
  ): void {
167
159
  if (ca.length * cb.length > this.maxCells) {
168
160
  this.degraded = true;
@@ -183,7 +175,7 @@ class ChangeWalker {
183
175
  if (!match.identical) {
184
176
  const aItem = ca[match.aIndex];
185
177
  const bItem = cb[match.bIndex];
186
- if (isPlainObject(aItem) && isPlainObject(bItem)) {
178
+ if (isJsonObject(aItem) && isJsonObject(bItem)) {
187
179
  this.diffNode(
188
180
  [...aPath, "children", match.aIndex],
189
181
  [...bPath, "children", match.bIndex],
@@ -211,11 +203,12 @@ class ChangeWalker {
211
203
  kind: "added" | "removed",
212
204
  aPath: JxPath,
213
205
  bPath: JxPath,
214
- item: unknown,
206
+ // Every caller reads in bounds, but an indexed read is typed possibly undefined; it is no element.
207
+ item: JxMutableNode | string | undefined,
215
208
  aIndex: number | null,
216
209
  bIndex: number | null,
217
210
  ): void {
218
- if (!isPlainObject(item)) {
211
+ if (!isJsonObject(item)) {
219
212
  this.emit("modified", aPath, bPath);
220
213
  return;
221
214
  }
@@ -241,7 +234,7 @@ export function buildChangeMap(
241
234
  opts: ChangeMapOptions = {},
242
235
  ): ChangeMap {
243
236
  const walker = new ChangeWalker(opts.maxCells ?? DEFAULT_MAX_CELLS);
244
- walker.diffNode([], [], a as Record<string, unknown>, b as Record<string, unknown>);
237
+ walker.diffNode([], [], a, b);
245
238
  return {
246
239
  current: walker.current,
247
240
  degraded: walker.degraded,