@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
@@ -12,16 +12,7 @@
12
12
  import type { AssetContext } from "./asset-resolve";
13
13
  import type { JxDocOp } from "../tabs/patch-ops";
14
14
  import type { JxContentResult, SlashCommand } from "../editor/inline-edit";
15
- import type { JxExpressionNode, JxMutableNode } from "@jxsuite/schema/types";
16
-
17
- /**
18
- * The wire form of a value-carrying document op (the `forward` half of a recorded
19
- * {@link JxDocOpPair} — see {@link file://../tabs/patch-ops.ts}). It is structurally a
20
- * {@link JxDocOp}: it carries the inserted/replaced `node` and the set `value`, NOT just a path, so
21
- * the iframe can fold it into its shadow doc and re-render subtrees without ever reading the
22
- * parent's reactive document.
23
- */
24
- export type WireDocOp = JxDocOp;
15
+ import type { JsonObject, JxExpressionNode, JxMutableNode, JxStyle } from "@jxsuite/schema/types";
25
16
 
26
17
  export const CANVAS_MODES = ["preview", "design", "edit", "stylebook", "git-diff"] as const;
27
18
 
@@ -37,7 +28,7 @@ export const CANVAS_MODES = ["preview", "design", "edit", "stylebook", "git-diff
37
28
  export type CanvasMode = (typeof CANVAS_MODES)[number];
38
29
 
39
30
  export function isCanvasMode(value: unknown): value is CanvasMode {
40
- return typeof value === "string" && (CANVAS_MODES as readonly string[]).includes(value);
31
+ return typeof value === "string" && CANVAS_MODES.some((mode) => mode === value);
41
32
  }
42
33
 
43
34
  /**
@@ -86,6 +77,12 @@ export interface WireDiffMark {
86
77
  /** An artboard's whole mark set. Each side receives only its own; `[]` clears. */
87
78
  export type WireDiffMarks = readonly WireDiffMark[];
88
79
 
80
+ /** A language as the frame applies it: the BCP 47 tag for `lang`, and its direction for `dir`. */
81
+ export interface WireLocale {
82
+ locale: string;
83
+ dir: "ltr" | "rtl";
84
+ }
85
+
89
86
  /** Messages the editor (parent) sends into the canvas iframe. */
90
87
  export type ParentToIframe =
91
88
  | { kind: "init"; gen: number }
@@ -121,7 +118,7 @@ export type ParentToIframe =
121
118
  */
122
119
  assets?: AssetContext | null;
123
120
  mapperCtx: WireMapperCtx;
124
- siteStyle: Record<string, unknown> | null;
121
+ siteStyle: JxStyle | null;
125
122
  // Forced color-scheme preview (spec.md §9.5): "light"/"dark" sets data-color-scheme on the
126
123
  // Iframe root, null clears it (auto — follow the OS).
127
124
  colorScheme: "light" | "dark" | null;
@@ -144,6 +141,13 @@ export type ParentToIframe =
144
141
  * every re-render would close the panel the author is editing.
145
142
  */
146
143
  popoverOpen?: (string | number)[] | null;
144
+ /**
145
+ * The language the artboard is drawn in, carried on `render` for `colorScheme`'s reason: a
146
+ * frame that boots after the pane's locale was posted (a new host, a reload) would otherwise
147
+ * draw an Arabic document left to right until the locale next CHANGED. Absent or null clears
148
+ * `lang` and `dir`.
149
+ */
150
+ locale?: WireLocale | null;
147
151
  /** The dialog to draw open after this render, for the same reason. */
148
152
  dialogOpen?: (string | number)[] | null;
149
153
  gen: number;
@@ -197,8 +201,10 @@ export type ParentToIframe =
197
201
  * the frame — `localeDirection` is CLDR's answer via `Intl.Locale`, and the frame has no reason
198
202
  * to hold a second copy of the RTL script list.
199
203
  *
200
- * `null` is "the document's own language": both attributes come off, and the frame falls back to
201
- * whatever the rendered document declares.
204
+ * The host posts the language the pane DRAWS, not only an override: the preview choice, else the
205
+ * file's own, else the site default (`canvasLocaleOf`). `null` is a project that declares no
206
+ * locales: both attributes come off, and the frame falls back to whatever the rendered document
207
+ * declares.
202
208
  */
203
209
  | { kind: "setLocale"; locale: string | null; dir: "ltr" | "rtl" }
204
210
  /**
@@ -239,7 +245,7 @@ export type ParentToIframe =
239
245
  // Render-free; the superseding render carries the same style via its own siteStyle.
240
246
  | {
241
247
  kind: "siteStyleUpdate";
242
- siteStyle: Record<string, unknown> | null;
248
+ siteStyle: JxStyle | null;
243
249
  media: Record<string, string>;
244
250
  }
245
251
  // Ask the iframe to measure the given document paths and post their current rects back. Used to
@@ -255,7 +261,12 @@ export type ParentToIframe =
255
261
  // In place. `gen` matches the last render so the iframe drops patches superseded by a re-render.
256
262
  | {
257
263
  kind: "patch";
258
- forwardOps: WireDocOp[];
264
+ /**
265
+ * The `forward` halves of the recorded {@link JxDocOp} pairs (tabs/patch-ops.ts). Each carries
266
+ * the inserted/replaced `node` and the set `value`, not just a path, so the iframe folds it
267
+ * into its shadow doc without ever reading the parent's reactive document.
268
+ */
269
+ forwardOps: JxDocOp[];
259
270
  gen: number;
260
271
  /**
261
272
  * Paths whose DOM the RECIPIENT already has correct, because this patch is the echo of an
@@ -273,7 +284,7 @@ export type ParentToIframe =
273
284
  // Regenerates the whole scoped-CSS cascade (real @media included) without a re-render. `style` is
274
285
  // Already transposed parent-side (transposeStylebookStyle); `gen` must equal the iframe's
275
286
  // RenderedGen — a stale update is dropped (the superseding render carries the same style).
276
- | { kind: "styleUpdate"; style: Record<string, unknown>; gen: number }
287
+ | { kind: "styleUpdate"; style: JxStyle; gen: number }
277
288
  // Enter inline editing on the node at `path` (used to re-enter after a split/insert re-renders).
278
289
  | {
279
290
  kind: "enterEdit";
@@ -381,10 +392,14 @@ export type DropInstructionType = "reorder-above" | "reorder-below" | "make-chil
381
392
 
382
393
  /**
383
394
  * The kind of thing being dragged. `tree-node` carries the source's existing document path (a
384
- * move); `block` carries nothing on the wire — its full `fragment` (a {@link JxMutableNode}) is
385
- * retained PARENT-SIDE keyed by `dragSeq` and never crosses the boundary.
395
+ * move); `block` carries only its fragment's tag on the wire — its full `fragment` (a
396
+ * {@link JxMutableNode}) is retained PARENT-SIDE keyed by `dragSeq` and never crosses the boundary.
397
+ * The tag is what lets the iframe keep a block out of a paragraph (`iframe-drop.ts`); an OS file
398
+ * drag has none, and is placed as a block.
386
399
  */
387
- export type DragSrcKind = { type: "tree-node"; path: (string | number)[] } | { type: "block" };
400
+ export type DragSrcKind =
401
+ | { type: "tree-node"; path: (string | number)[] }
402
+ | { type: "block"; tag?: string };
388
403
 
389
404
  /**
390
405
  * A display-only drop preview the iframe posts on `dragOver`: where the drop indicator should draw
@@ -490,7 +505,7 @@ export type IframeToParent =
490
505
  // `S.canvas.scope` so the data-explorer panel shows live data instead of "pending" (the iframe,
491
506
  // Not the parent, now resolves the scope). `gen` lets the parent drop a snapshot from a superseded
492
507
  // Render. Posted right after `renderComplete`; values are JSON-safe deep clones (see serialize-scope).
493
- | { kind: "dataScope"; gen: number; scope: Record<string, unknown> }
508
+ | { kind: "dataScope"; gen: number; scope: JsonObject }
494
509
  // The frame's own quiescence, ANSWERED rather than polled (studio.md §13.5).
495
510
  // Nothing in the parent realm can see inside a cross-origin frame, so a parent that wanted to
496
511
  // Know whether the canvas had settled could only sleep. The frame samples itself at its own rAF
@@ -37,8 +37,9 @@ import { classifyRenderNode, jxPathSelector, serializeJxPath } from "./path-mapp
37
37
  import { elementForPath } from "./iframe-position";
38
38
  import type { AssetContext } from "./asset-resolve";
39
39
  import { SITE_STYLE_ID, buildSiteStyleCSS } from "@jxsuite/site/site-style";
40
- import type { CanvasMode, WireDiffMarks } from "./iframe-protocol";
41
- import type { JxDocument } from "@jxsuite/schema/types";
40
+ import type { CanvasMode, WireDiffMarks, WireLocale } from "./iframe-protocol";
41
+ import { isNonNullObject, isString } from "@jxsuite/schema/guards";
42
+ import type { JxDocument, JxElement, JxStyle } from "@jxsuite/schema/types";
42
43
  import type { PathMapCtx } from "./path-mapping";
43
44
 
44
45
  /**
@@ -61,18 +62,12 @@ export interface RenderHandle {
61
62
  ctx: IframeRenderCtx;
62
63
  }
63
64
 
64
- interface HeadEntry {
65
- tagName?: string;
66
- attributes?: Record<string, unknown>;
67
- textContent?: string;
68
- }
69
-
70
65
  /**
71
66
  * Register the document's `$elements` (components) in this iframe realm so the runtime can render
72
67
  * them.
73
68
  */
74
69
  export async function registerElements(doc: JxDocument, docBase: string): Promise<void> {
75
- const elements = (doc as { $elements?: unknown[] }).$elements;
70
+ const elements = doc.$elements;
76
71
  if (!Array.isArray(elements)) {
77
72
  return;
78
73
  }
@@ -81,13 +76,16 @@ export async function registerElements(doc: JxDocument, docBase: string): Promis
81
76
  await Promise.all(
82
77
  elements.map(async (entry) => {
83
78
  const task = (async () => {
84
- if (typeof entry === "string") {
79
+ if (isString(entry)) {
85
80
  const specifier =
86
81
  entry.startsWith("/") || entry.startsWith(".") ? entry : `/node_modules/${entry}`;
87
82
  await import(specifier);
88
- } else if (entry && typeof entry === "object" && "$ref" in entry) {
89
- await defineElement(new URL(String((entry as { $ref: string }).$ref), docBase).href);
90
- } else if (entry && typeof entry === "object") {
83
+ } else if (isNonNullObject(entry) && "$ref" in entry) {
84
+ await defineElement(new URL(String(entry.$ref), docBase).href);
85
+ } else if (isNonNullObject(entry)) {
86
+ /* SAFETY: an `$elements` entry that is neither a specifier nor a `$ref` is an inline
87
+ * component definition by the schema (JxDocument is JxElement with a literal tagName).
88
+ * A malformed one throws inside this task, which the race below catches and logs. */
91
89
  await defineElement(entry as JxDocument, docBase);
92
90
  }
93
91
  })();
@@ -633,6 +631,10 @@ export const STYLEBOOK_CSS = `
633
631
  .element-card-preview > * {
634
632
  max-width: 100%;
635
633
  margin: 0;
634
+ }
635
+ /* A list keeps its inline-start padding: its markers are drawn in it, and with none they are
636
+ clipped by the card ("1." shows as "."). Every other specimen sits flush in its card. */
637
+ .element-card-preview > :not(ol, ul, menu) {
636
638
  padding: 0;
637
639
  }
638
640
  .element-card-preview > hr {
@@ -696,11 +698,11 @@ export function syncStylebookCss(doc: Document, mode: CanvasMode): void {
696
698
  * selectors can win (spec.md §9.5), and so removed tokens can't linger on reused iframes.
697
699
  */
698
700
  export function applySiteStyle(
699
- siteStyle: Record<string, unknown> | null | undefined,
701
+ siteStyle: JxStyle | null | undefined,
700
702
  mediaQueries: Record<string, string> = {},
701
703
  ): void {
702
704
  const existing = document.head.querySelector(`#${SITE_STYLE_ID}`);
703
- if (!siteStyle || typeof siteStyle !== "object") {
705
+ if (!siteStyle || !isNonNullObject(siteStyle)) {
704
706
  existing?.remove();
705
707
  return;
706
708
  }
@@ -730,6 +732,49 @@ export function applyPreviewColorScheme(doc: Document, scheme: "light" | "dark"
730
732
  }
731
733
  }
732
734
 
735
+ /** The `lang` and `dir` a frame's root booted with, which a frame with no language goes back to. */
736
+ export interface LocaleBaseline {
737
+ lang: string | null;
738
+ dir: string | null;
739
+ }
740
+
741
+ /** Read the root's `lang` and `dir` as the frame booted them (`canvas.html` is `lang="en"`). */
742
+ export function captureLocaleBaseline(doc: Document): LocaleBaseline {
743
+ const root = doc.documentElement;
744
+ return { dir: root.getAttribute("dir"), lang: root.getAttribute("lang") };
745
+ }
746
+
747
+ /** Write one root attribute, or remove it for null. */
748
+ function setRootAttribute(root: Element, name: string, value: string | null): void {
749
+ if (value === null) {
750
+ root.removeAttribute(name);
751
+ } else {
752
+ root.setAttribute(name, value);
753
+ }
754
+ }
755
+
756
+ /**
757
+ * Set the artboard's language (studio.md §20.2): `lang` and `dir` on the frame's root, the only
758
+ * writer of either. `dir` is what makes an RTL document actually mirror, and `lang` is what CSS's
759
+ * `:lang()` and the font stack select on. The root survives a render, which replaces only the
760
+ * container's children, so the value holds until the next one arrives.
761
+ *
762
+ * `null`, a project that declares no locales, restores the language the frame booted with rather
763
+ * than removing it, so applying the value on every render does not strip `canvas.html`'s
764
+ * `lang="en"` from every canvas of a monolingual project. A left-to-right language writes no
765
+ * `dir="ltr"`, as the built page never does (`site-architecture.md` §13.4): it restores the booted
766
+ * `dir`.
767
+ */
768
+ export function applyPreviewLocale(
769
+ doc: Document,
770
+ locale: WireLocale | null,
771
+ baseline: LocaleBaseline,
772
+ ): void {
773
+ const root = doc.documentElement;
774
+ setRootAttribute(root, "lang", locale?.locale ?? baseline.lang);
775
+ setRootAttribute(root, "dir", locale?.dir === "rtl" ? "rtl" : baseline.dir);
776
+ }
777
+
733
778
  /**
734
779
  * Draw the popover at `path` open, and every other one closed.
735
780
  *
@@ -746,15 +791,15 @@ export function applyPreviewColorScheme(doc: Document, scheme: "light" | "dark"
746
791
  * @docs studio/interface/canvas
747
792
  */
748
793
  export function applyCanvasPopoverOpen(root: ParentNode, path: string | null): void {
749
- for (const el of root.querySelectorAll("[data-jx-popover-open]")) {
750
- delete (el as HTMLElement).dataset.jxPopoverOpen;
794
+ for (const el of root.querySelectorAll<HTMLElement>("[data-jx-popover-open]")) {
795
+ delete el.dataset.jxPopoverOpen;
751
796
  }
752
797
  if (path === null) {
753
798
  return;
754
799
  }
755
- const target = root.querySelector(`[data-jx-popover]${jxPathSelector(path)}`);
800
+ const target = root.querySelector<HTMLElement>(`[data-jx-popover]${jxPathSelector(path)}`);
756
801
  if (target) {
757
- (target as HTMLElement).dataset.jxPopoverOpen = "";
802
+ target.dataset.jxPopoverOpen = "";
758
803
  }
759
804
  }
760
805
 
@@ -783,26 +828,27 @@ export function applyCanvasPopoverOpen(root: ParentNode, path: string | null): v
783
828
  * backdrop and all.
784
829
  */
785
830
  export function applyCanvasDialogOpen(root: ParentNode, path: string | null): void {
786
- for (const el of root.querySelectorAll("[data-jx-dialog-open]")) {
787
- delete (el as HTMLElement).dataset.jxDialogOpen;
831
+ for (const el of root.querySelectorAll<HTMLElement>("[data-jx-dialog-open]")) {
832
+ delete el.dataset.jxDialogOpen;
788
833
  }
789
834
  if (path === null) {
790
835
  return;
791
836
  }
792
- const target = root.querySelector(`dialog${jxPathSelector(path)}`);
837
+ const target = root.querySelector<HTMLElement>(`dialog${jxPathSelector(path)}`);
793
838
  if (target) {
794
- (target as HTMLElement).dataset.jxDialogOpen = "";
839
+ target.dataset.jxDialogOpen = "";
795
840
  }
796
841
  }
797
842
 
798
843
  /** Inject the document's `$head` (link/meta/script) into the iframe's <head>, de-duped by href/src. */
799
844
  export function injectHead(doc: JxDocument, assets: AssetContext | null = null): void {
800
- const head = (doc as { $head?: HeadEntry[] }).$head;
845
+ const head = doc.$head;
801
846
  if (!Array.isArray(head)) {
802
847
  return;
803
848
  }
804
849
  for (const entry of head) {
805
- if (!entry?.tagName) {
850
+ // A `$head` array read off disk can hold a null or a tagless entry; neither emits anything.
851
+ if (!isNonNullObject(entry) || !entry.tagName) {
806
852
  continue;
807
853
  }
808
854
  const tag = String(entry.tagName).toLowerCase();
@@ -810,10 +856,10 @@ export function injectHead(doc: JxDocument, assets: AssetContext | null = null):
810
856
  if (tag === "script" && !entry.attributes?.src) {
811
857
  continue;
812
858
  }
813
- const attrs = { ...entry.attributes } as Record<string, unknown>;
859
+ const attrs = { ...entry.attributes };
814
860
  for (const key of ["href", "src"]) {
815
861
  const val = attrs[key];
816
- if (typeof val !== "string" || val === "") {
862
+ if (!isString(val) || val === "") {
817
863
  continue;
818
864
  }
819
865
  if (!val.startsWith("/") && !val.startsWith(".") && !val.startsWith("http")) {
@@ -833,7 +879,7 @@ export function injectHead(doc: JxDocument, assets: AssetContext | null = null):
833
879
  el.setAttribute(k, String(v));
834
880
  }
835
881
  if (entry.textContent) {
836
- el.textContent = entry.textContent;
882
+ el.textContent = String(entry.textContent);
837
883
  }
838
884
  document.head.append(el);
839
885
  }
@@ -856,7 +902,7 @@ export function makeStamper(ctx: PathMapCtx) {
856
902
  (island) => path.length > island.length && island.every((seg, i) => path[i] === seg),
857
903
  );
858
904
 
859
- return (created: Node, path: (string | number)[], def: unknown) => {
905
+ return (created: Node, path: (string | number)[], def: JxElement | string) => {
860
906
  if (!(created instanceof HTMLElement)) {
861
907
  return;
862
908
  }
@@ -866,7 +912,10 @@ export function makeStamper(ctx: PathMapCtx) {
866
912
  // Editable tree and re-render a live instance with default state. Mark the root so the
867
913
  // Runtime's element class leaves it alone (see defineElement's connectedCallback guard).
868
914
  const isDefinitionRoot =
869
- path.length === 0 && (def as { tagName?: string } | null)?.tagName?.includes("-");
915
+ path.length === 0 &&
916
+ isNonNullObject(def) &&
917
+ isString(def.tagName) &&
918
+ def.tagName.includes("-");
870
919
  if (isDefinitionRoot) {
871
920
  created.dataset.jxDefinitionRoot = "";
872
921
  }
@@ -984,7 +1033,7 @@ export async function renderResolvedDocument(opts: {
984
1033
  docBase: string;
985
1034
  mode: CanvasMode;
986
1035
  mapperCtx: PathMapCtx;
987
- siteStyle?: Record<string, unknown> | null;
1036
+ siteStyle?: JxStyle | null;
988
1037
  /**
989
1038
  * How this host addresses project media, or null when the canvas origin serves the site's own URL
990
1039
  * space (desktop, `jx dev`) and references need no resolution at all.
@@ -1037,7 +1086,7 @@ export async function renderResolvedDocument(opts: {
1037
1086
  // Iframe clears it (page-level templates are inert in design/edit via prepareForEditMode, so only
1038
1087
  // Component internals get stamped).
1039
1088
  setStampPropBindings(opts.mode === "design" || opts.mode === "edit");
1040
- applySiteStyle(opts.siteStyle, (opts.doc as { $media?: Record<string, string> }).$media ?? {});
1089
+ applySiteStyle(opts.siteStyle, opts.doc.$media ?? {});
1041
1090
  injectHead(opts.doc, assets);
1042
1091
  syncEditModeCss(opts.container.ownerDocument, opts.mode);
1043
1092
  // The substitute rules for the attributes the de-link above renamed. Same predicate as the
@@ -1052,7 +1101,7 @@ export async function renderResolvedDocument(opts: {
1052
1101
  // But no own `$media` resolves the breakpoint to its real query (the iframe path calls buildScope
1053
1102
  // Directly and never the runtime's `Jx()` entry, which is the only other place _rootMedia is set).
1054
1103
  // Set it every render (even to `{}`) so a stale map from a previous document cannot leak.
1055
- setRootMedia((opts.doc as { $media?: Record<string, string> }).$media ?? {});
1104
+ setRootMedia(opts.doc.$media ?? {});
1056
1105
  // Register components BEFORE renderNode. The runtime only applies a custom element's `$props` when
1057
1106
  // That element is ALREADY defined (renderNode gates renderCustomElementWithProps on a truthy
1058
1107
  // `customElements.get(tagName)`); if we register after render, every component paints with its
@@ -1066,8 +1115,8 @@ export async function renderResolvedDocument(opts: {
1066
1115
  // The scope MUST be the runtime's (runScoped): renderNode creates its binding effects with the
1067
1116
  // Runtime's copy of @vue/reactivity, and scope collection is per module instance — a studio
1068
1117
  // EffectScope here collects nothing and dispose() would leak every effect of this render.
1069
- const { result: el, stop } = runScoped(
1070
- () => renderNode(opts.doc, $defs, { _path: [], onNodeCreated }) as HTMLElement,
1118
+ const { result: el, stop } = runScoped(() =>
1119
+ renderNode(opts.doc, $defs, { _path: [], onNodeCreated }),
1071
1120
  );
1072
1121
  opts.container.replaceChildren(el);
1073
1122
  applyCanvasPopoverOpen(opts.container, opts.popoverOpen ?? null);
@@ -21,7 +21,17 @@ import type { IframeToParent, ParentToIframe } from "./iframe-protocol";
21
21
 
22
22
  type SlashNavKey = Extract<IframeToParent, { kind: "slashNav" }>["key"];
23
23
 
24
- const NAV_KEYS = new Set(["ArrowUp", "ArrowDown", "Enter", "Escape"]);
24
+ const NAV_KEYS = new Set<string>([
25
+ "ArrowUp",
26
+ "ArrowDown",
27
+ "Enter",
28
+ "Escape",
29
+ ] satisfies SlashNavKey[]);
30
+
31
+ /** Whether `key` is one of the four keys the parent menu navigates by. */
32
+ function isNavKey(key: string): key is SlashNavKey {
33
+ return NAV_KEYS.has(key);
34
+ }
25
35
 
26
36
  /**
27
37
  * Register the bridge SlashController for this iframe realm and wire its keyboard/dismissal
@@ -55,28 +65,31 @@ export function startIframeSlashBridge(
55
65
  open = true;
56
66
  lastPostedFilter = filter;
57
67
  const r = rectOf(anchorEl);
58
- channel.post({
68
+ const message: Extract<IframeToParent, { kind: "slashShow" }> = {
59
69
  filter,
60
70
  kind: "slashShow",
61
71
  rect: { height: r.height, width: r.width, x: r.left, y: r.top },
62
- /* Carried, because the parent draws the menu and only the FRAME knows why it opened. A
63
- menu opened by name has no "/…" run in the document to filter with, so it needs its own
64
- field; the "/" gesture needs none, because the author types into the block. This option
65
- was dropped at this boundary and the loss was invisible — the menu still appeared, just
66
- with no way past fifteen items but scrolling. */
67
- ...(cbs.showFilter === true ? { showFilter: true } : {}),
68
- });
72
+ };
73
+ /* Carried, because the parent draws the menu and only the FRAME knows why it opened. A
74
+ menu opened by name has no "/…" run in the document to filter with, so it needs its own
75
+ field; the "/" gesture needs none, because the author types into the block. This option
76
+ was dropped at this boundary and the loss was invisible — the menu still appeared, just
77
+ with no way past fifteen items but scrolling. */
78
+ if (cbs.showFilter === true) {
79
+ message.showFilter = true;
80
+ }
81
+ channel.post(message);
69
82
  },
70
83
  };
71
84
  setSlashController(controller);
72
85
 
73
86
  const onKeyDown = (e: KeyboardEvent) => {
74
- if (!open || !NAV_KEYS.has(e.key)) {
87
+ if (!open || !isNavKey(e.key)) {
75
88
  return;
76
89
  }
77
90
  e.preventDefault();
78
91
  e.stopPropagation();
79
- channel.post({ key: e.key as SlashNavKey, kind: "slashNav" });
92
+ channel.post({ key: e.key, kind: "slashNav" });
80
93
  };
81
94
  const onMouseDown = () => {
82
95
  // The parent menu's outside-click listener can't see iframe clicks — any in-iframe press while
@@ -12,9 +12,10 @@
12
12
  */
13
13
 
14
14
  import { releaseElementStyles, renderNode, runScoped } from "@jxsuite/runtime";
15
+ import { isNumber, isString } from "@jxsuite/schema/guards";
15
16
  import { getNodeAtPath } from "../state";
16
17
  import { makeStamper } from "./iframe-render";
17
- import { prepareForEditMode } from "../utils/edit-display";
18
+ import { prepareForEditMode, sampleRowAt } from "../utils/edit-display";
18
19
  import { stripEventHandlers } from "../utils/strip-events";
19
20
  import type { IframeRenderCtx } from "./iframe-render";
20
21
  import type { JxPath } from "../state";
@@ -39,11 +40,17 @@ export function renderSubtreeIframe(
39
40
  docPath: JxPath,
40
41
  ctx: IframeRenderCtx,
41
42
  ): HTMLElement | Text {
43
+ /* SAFETY: a widening of getNodeAtPath's declared return. A patch path addresses an entry of a
44
+ * `children` array, which the schema types as `JxMutableNode | string`, and a missing step
45
+ * answers undefined, so those three cases are the whole range. */
42
46
  const node = getNodeAtPath(shadowDoc, docPath) as JxMutableNode | string | undefined;
43
47
  if (node === undefined) {
44
48
  throw new Error(`iframe-patch-node-not-found:${docPath.join("/")}`);
45
49
  }
46
- const def = typeof node === "string" ? node : prepareForEditMode(stripEventHandlers(node));
50
+ // Inside a repeater, the template is drawn with the sample row the full render used.
51
+ const def = isString(node)
52
+ ? node
53
+ : prepareForEditMode(stripEventHandlers(node), sampleRowAt(shadowDoc, docPath));
47
54
  const { result: rendered, stop } = runScoped(() =>
48
55
  renderNode(def, ctx.defs, {
49
56
  _path: docPathToRenderPath(docPath, ctx),
@@ -98,7 +105,7 @@ function docPathToRenderPath(docPath: JxPath, ctx: IframeRenderCtx): (string | n
98
105
  const { mapperCtx } = ctx;
99
106
  if (mapperCtx.layoutWrapped && mapperCtx.pageContentPrefix && docPath[0] === "children") {
100
107
  const [, idx] = docPath;
101
- return typeof idx === "number"
108
+ return isNumber(idx)
102
109
  ? [
103
110
  ...mapperCtx.pageContentPrefix,
104
111
  idx + (mapperCtx.pageContentOffset ?? 0),
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Where a live render imports an `npm:` package from (spec.md §5.3, 4c).
3
+ *
4
+ * The dev server answers `/node_modules/<package>/<subpath>` by resolving the package's `exports`
5
+ * and bundling the entry on demand (`@jxsuite/server`), the same URL space a bare `$elements`
6
+ * specifier and a bare `$head` asset are already fetched from. Both realms that render a project
7
+ * live install it into the runtime (`setNpmModuleResolver`): the canvas frame against its own
8
+ * address, and the editor window, which draws the Site panel's and the Content home's previews,
9
+ * against the project's asset origin.
10
+ *
11
+ * Dependency-free so it rides in the slim canvas bundle.
12
+ */
13
+
14
+ /**
15
+ * The URL a package specifier is imported from, under `base`.
16
+ *
17
+ * @param specifier - `@scope/pkg/subpath`, as the document wrote it after `npm:`
18
+ * @param base - The origin (or any URL on it) that serves the project
19
+ */
20
+ export function npmModuleUrl(specifier: string, base: string): string {
21
+ return new URL(`/node_modules/${specifier}`, base).href;
22
+ }
@@ -11,6 +11,8 @@
11
11
  * result for the `data-jx-path` attribute.
12
12
  */
13
13
 
14
+ import { isJsonObject, isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
15
+ import type { JxElement } from "@jxsuite/schema/types";
14
16
  import type { JxPath } from "../state";
15
17
 
16
18
  /**
@@ -83,22 +85,27 @@ export function wrapsPageContent(path: JxPath, prefix: JxPath | null): boolean {
83
85
  * Resolve a runtime render path to a document path (or flag it as layout-originated). Pure — the
84
86
  * caller decides whether to record the result in a WeakMap or `data-jx-*` attributes.
85
87
  */
86
- export function classifyRenderNode(path: JxPath, def: unknown, ctx: PathMapCtx): RenderNodeClass {
88
+ export function classifyRenderNode(
89
+ path: JxPath,
90
+ def: JxElement | string,
91
+ ctx: PathMapCtx,
92
+ ): RenderNodeClass {
87
93
  // Layout-originated nodes have no page-document path; the caller stamps their origin instead
88
94
  // (data-jx-layout-path / data-jx-layout-file).
89
- const marker =
90
- ctx.layoutWrapped && typeof def === "object"
91
- ? (def as { $__layout?: unknown } | null)?.$__layout
92
- : undefined;
95
+ const marker = ctx.layoutWrapped && isNonNullObject(def) ? def["$__layout"] : undefined;
93
96
  if (marker) {
94
- const origin = (typeof marker === "object" ? marker : {}) as Partial<LayoutMarker>;
97
+ // A legacy bare `true` marker carries no origin, so it reads as an empty one.
98
+ const origin = isJsonObject(marker) ? marker : {};
99
+ const { file, path: originPath } = origin;
95
100
  return {
96
101
  // The root is never chrome even when the layout distributed nothing: it IS the render, and a
97
102
  // Dimmed, frozen root would be a canvas nobody can touch.
98
103
  chrome: path.length > 0 && !wrapsPageContent(path, ctx.pageContentPrefix),
99
104
  kind: "layout",
100
- layoutFile: typeof origin.file === "string" ? origin.file : "",
101
- layoutPath: Array.isArray(origin.path) ? origin.path : [],
105
+ layoutFile: isString(file) ? file : "",
106
+ /* SAFETY: markLayoutNodes (canvas-live-render.ts) is the only writer of `$__layout`, and the
107
+ * `path` it stamps is a LayoutMarker's JxPath. */
108
+ layoutPath: Array.isArray(originPath) ? (originPath as JxPath) : [],
102
109
  };
103
110
  }
104
111
 
@@ -112,10 +119,9 @@ export function classifyRenderNode(path: JxPath, def: unknown, ctx: PathMapCtx):
112
119
  if (path.length >= pfx.length && pfx.every((seg, i) => path[i] === seg)) {
113
120
  const rest = path.slice(pfx.length);
114
121
  const [containerIdx] = rest;
115
- mappedPath =
116
- typeof containerIdx === "number"
117
- ? ["children", containerIdx - (ctx.pageContentOffset ?? 0), ...rest.slice(1)]
118
- : ["children", ...rest];
122
+ mappedPath = isNumber(containerIdx)
123
+ ? ["children", containerIdx - (ctx.pageContentOffset ?? 0), ...rest.slice(1)]
124
+ : ["children", ...rest];
119
125
  }
120
126
  }
121
127
 
@@ -154,5 +160,6 @@ export function serializeJxPath(path: JxPath): string {
154
160
 
155
161
  /** Decode a `data-jx-path` attribute back into a document path. */
156
162
  export function parseJxPath(serialized: string): JxPath {
163
+ // SAFETY: only serializeJxPath writes `data-jx-path`, and it is JSON.stringify of a JxPath.
157
164
  return JSON.parse(serialized) as JxPath;
158
165
  }
@@ -14,6 +14,7 @@
14
14
  import { activeTab } from "../workspace/workspace";
15
15
  import { getNodeAtPath } from "../state";
16
16
  import { documentHasPopover, isPopover } from "@jxsuite/schema/overlays";
17
+ import { isNonNullObject } from "@jxsuite/schema/guards";
17
18
  import { INVOKER_TAGS, POPOVER_TAGS } from "@jxsuite/ui";
18
19
  import { primarySelection } from "../tabs/selection";
19
20
  import type { JxMutableNode } from "@jxsuite/schema/types";
@@ -49,7 +50,7 @@ export function ancestorPopoverPath(
49
50
  for (let end = path.length; end >= 0; end -= 1) {
50
51
  const prefix = path.slice(0, end);
51
52
  const node = getNodeAtPath(doc, prefix);
52
- if (node && typeof node === "object" && isPopover(node, KIT_SCOPE)) {
53
+ if (isNonNullObject(node) && isPopover(node, KIT_SCOPE)) {
53
54
  return prefix;
54
55
  }
55
56
  }
@@ -72,13 +73,16 @@ export function ancestorPopoverPath(
72
73
  * @returns The popover's path, or null.
73
74
  */
74
75
  export function popoverPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
76
+ /* SAFETY: a widening, not a narrowing. A tab built by createTab always carries a document, but
77
+ * the command is a public entry point and the contract (pinned in popover-state.test.ts) is that
78
+ * a tab record without one answers null rather than throwing inside getNodeAtPath. */
75
79
  const doc = tab.doc.document as JxMutableNode | undefined;
76
80
  if (!doc) {
77
81
  return null;
78
82
  }
79
83
  if (explicit) {
80
84
  const node = getNodeAtPath(doc, explicit);
81
- return node && typeof node === "object" && isPopover(node, KIT_SCOPE) ? explicit : null;
85
+ return isNonNullObject(node) && isPopover(node, KIT_SCOPE) ? explicit : null;
82
86
  }
83
87
  return ancestorPopoverPath(doc, primarySelection(tab.session.selection));
84
88
  }
@@ -101,6 +105,6 @@ export function popoverPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
101
105
  * @returns True when the focused document declares at least one popover.
102
106
  */
103
107
  export function activeDocumentHasPopover(): boolean {
104
- const doc = activeTab.value?.doc.document as JxMutableNode | undefined;
108
+ const doc = activeTab.value?.doc.document;
105
109
  return doc ? documentHasPopover(doc, KIT_SCOPE) : false;
106
110
  }
@@ -31,7 +31,6 @@ import { effect, pauseTracking, resetTracking } from "../reactivity";
31
31
  import { postPopoverOpen, revealCanvasPath } from "./iframe-host";
32
32
  import { primarySelection } from "../tabs/selection";
33
33
  import { updateSession } from "../store";
34
- import type { JxMutableNode } from "@jxsuite/schema/types";
35
34
  import type { JxPath } from "../state";
36
35
  import type { Tab } from "../tabs/tab";
37
36
 
@@ -59,7 +58,7 @@ export function setOpenPopover(tab: Tab, path: JxPath | null): void {
59
58
 
60
59
  /** Open the popover containing `path`, if any. Returns whether anything changed. */
61
60
  function openPopoverFor(tab: Tab, path: JxPath | null): boolean {
62
- const target = ancestorPopoverPath(tab.doc.document as JxMutableNode, path);
61
+ const target = ancestorPopoverPath(tab.doc.document, path);
63
62
  if (target === null || samePath(tab.session.ui.openPopover, target)) {
64
63
  return false;
65
64
  }