@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
@@ -51,11 +51,21 @@ import type {
51
51
  SerializableRect,
52
52
  } from "./iframe-protocol";
53
53
  import type { DocPos } from "./iframe-position";
54
+ import { isNonNullObject, isString } from "@jxsuite/schema/guards";
54
55
  import type { JxPath } from "../state";
55
56
  import type { JxMutableNode } from "@jxsuite/schema/types";
56
57
 
58
+ /** The commit a block session posts when its text reaches the document. */
59
+ type EditCommitMsg = Extract<IframeToParent, { kind: "editCommit" }>;
60
+
61
+ /** The commit a prop-bound session posts for its instance's `$props` value. */
62
+ type EditCommitPropMsg = Extract<IframeToParent, { kind: "editCommitProp" }>;
63
+
64
+ /** The toolbar commands that toggle an inline tag (every intent but `link` and `insertData`). */
65
+ type InlineFormatCommand = Exclude<ApplyFormatIntent["command"], "link" | "insertData">;
66
+
57
67
  /** Toolbar command → inline tag (mirrors the parent's old `cmdToTag`, now iframe-side). */
58
- const CMD_TO_TAG: Record<string, string> = {
68
+ const CMD_TO_TAG = {
59
69
  bold: "strong",
60
70
  code: "code",
61
71
  italic: "em",
@@ -63,7 +73,19 @@ const CMD_TO_TAG: Record<string, string> = {
63
73
  subscript: "sub",
64
74
  superscript: "sup",
65
75
  underline: "u",
66
- };
76
+ } satisfies Record<InlineFormatCommand, string>;
77
+
78
+ /**
79
+ * The CSS Custom Highlight API as this realm may or may not provide it. lib.dom declares both
80
+ * members unconditionally, but happy-dom and non-Chromium engines ship neither.
81
+ */
82
+ interface HighlightRealm {
83
+ Highlight?: typeof Highlight;
84
+ CSS?: { highlights?: HighlightRegistry };
85
+ }
86
+
87
+ /** The global object, read through the optional shape above so the feature probes stay honest. */
88
+ const highlightRealm: HighlightRealm = globalThis;
67
89
 
68
90
  /** Inline tags whose active state the snapshot reports (everything except `a`, handled via link). */
69
91
  const ACTIVE_TAG_PROBES = ["strong", "em", "u", "del", "sub", "sup", "code"];
@@ -125,19 +147,19 @@ function deliveredOutsideProps(node: JxMutableNode | undefined, prop: string): b
125
147
  if (!node) {
126
148
  return false;
127
149
  }
128
- const attrs = node.attributes as Record<string, unknown> | undefined;
150
+ const attrs = node.attributes;
129
151
  if (attrs) {
130
152
  if (attrs[`props.${prop}`] !== undefined) {
131
153
  return true;
132
154
  }
133
155
  const reflected = new Set([prop.toLowerCase(), camelToKebab(prop).toLowerCase()]);
134
- for (const [name, val] of Object.entries(attrs)) {
135
- if (val !== undefined && reflected.has(name.toLowerCase())) {
156
+ for (const name of Object.keys(attrs)) {
157
+ if (attrs[name] !== undefined && reflected.has(name.toLowerCase())) {
136
158
  return true;
137
159
  }
138
160
  }
139
161
  const payload = attrs["data-jx-props"];
140
- if (typeof payload === "string" && payloadNames(payload, prop)) {
162
+ if (isString(payload) && payloadNames(payload, prop)) {
141
163
  return true;
142
164
  }
143
165
  }
@@ -145,14 +167,14 @@ function deliveredOutsideProps(node: JxMutableNode | undefined, prop: string): b
145
167
  if (RESERVED_KEYS.has(prop) || prop.startsWith("$")) {
146
168
  return false;
147
169
  }
148
- return (node as Record<string, unknown>)[prop] !== undefined;
170
+ return node[prop] !== undefined;
149
171
  }
150
172
 
151
173
  /** Whether a `data-jx-props` JSON payload carries `prop`. Unparseable payloads deliver nothing. */
152
174
  function payloadNames(payload: string, prop: string): boolean {
153
175
  try {
154
176
  const parsed: unknown = JSON.parse(payload);
155
- return typeof parsed === "object" && parsed !== null && prop in parsed;
177
+ return isNonNullObject(parsed) && prop in parsed;
156
178
  } catch {
157
179
  return false;
158
180
  }
@@ -238,11 +260,8 @@ export function startIframeInlineEdit(
238
260
  * `Highlight`/`CSS.highlights`, so this is a silent no-op there (and in non-Chromium engines).
239
261
  */
240
262
  const updateHighlight = () => {
241
- const HighlightCtor = (globalThis as { Highlight?: unknown }).Highlight as
242
- | (new (range: Range) => unknown)
243
- | undefined;
244
- const highlights = (globalThis.CSS as unknown as { highlights?: Map<string, unknown> })
245
- ?.highlights;
263
+ const HighlightCtor = highlightRealm.Highlight;
264
+ const highlights = highlightRealm.CSS?.highlights;
246
265
  if (!HighlightCtor || !highlights) {
247
266
  return;
248
267
  }
@@ -256,9 +275,7 @@ export function startIframeInlineEdit(
256
275
 
257
276
  /** Tear down the Custom Highlight (on teardown / real editEnd). */
258
277
  const clearHighlight = () => {
259
- const highlights = (globalThis.CSS as unknown as { highlights?: Map<string, unknown> })
260
- ?.highlights;
261
- highlights?.delete(HIGHLIGHT_NAME);
278
+ highlightRealm.CSS?.highlights?.delete(HIGHLIGHT_NAME);
262
279
  };
263
280
 
264
281
  /**
@@ -321,13 +338,11 @@ export function startIframeInlineEdit(
321
338
  // Optional, so omitting it keeps the message shape unchanged for every non-tick commit.
322
339
  onCommit: (p, children, textContent, inPlace) => {
323
340
  inputAnnounced = false;
324
- channel.post({
325
- children,
326
- kind: "editCommit",
327
- path: p,
328
- textContent,
329
- ...(inPlace ? { inPlace: true } : {}),
330
- });
341
+ const commit: EditCommitMsg = { children, kind: "editCommit", path: p, textContent };
342
+ if (inPlace) {
343
+ commit.inPlace = true;
344
+ }
345
+ channel.post(commit);
331
346
  },
332
347
  onEnd: () => {
333
348
  clearHighlight();
@@ -356,11 +371,11 @@ export function startIframeInlineEdit(
356
371
  if (!shadowDoc) {
357
372
  return true;
358
373
  }
359
- const node = getNodeAtPath(shadowDoc, hostPath) as JxMutableNode | undefined;
374
+ const node = getNodeAtPath(shadowDoc, hostPath);
360
375
  if (deliveredOutsideProps(node, prop)) {
361
376
  return false;
362
377
  }
363
- const raw = (node?.$props as Record<string, unknown> | undefined)?.[prop];
378
+ const raw = node?.$props?.[prop];
364
379
  if (raw == null) {
365
380
  return true; // Unset — editing ADDS the prop, overriding the definition default.
366
381
  }
@@ -371,7 +386,7 @@ export function startIframeInlineEdit(
371
386
  * Objects were already excluded; the scalar cases were not, and are the ones a component
372
387
  * actually declares. They stay editable in the properties panel, which knows their type.
373
388
  */
374
- if (typeof raw !== "string") {
389
+ if (!isString(raw)) {
375
390
  return false;
376
391
  }
377
392
  return !raw.includes("${");
@@ -390,13 +405,16 @@ export function startIframeInlineEdit(
390
405
  {
391
406
  onCommit: (p, _children, textContent, inPlace) => {
392
407
  inputAnnounced = false;
393
- channel.post({
408
+ const commit: EditCommitPropMsg = {
394
409
  kind: "editCommitProp",
395
410
  path: p,
396
411
  prop,
397
412
  value: textContent ?? "",
398
- ...(inPlace ? { inPlace: true } : {}),
399
- });
413
+ };
414
+ if (inPlace) {
415
+ commit.inPlace = true;
416
+ }
417
+ channel.post(commit);
400
418
  },
401
419
  onEnd: () => {
402
420
  clearHighlight();
@@ -519,6 +537,7 @@ export function startIframeInlineEdit(
519
537
  if (start === -1 || end === -1 || end <= start) {
520
538
  return false;
521
539
  }
540
+ // SAFETY: `blocksInOrder` selects `[data-jx-path]`, so every block it returns carries the key.
522
541
  const between = blocks
523
542
  .slice(start + 1, end)
524
543
  .map((el) => parseJxPath(el.dataset.jxPath as string));
@@ -573,7 +592,7 @@ export function startIframeInlineEdit(
573
592
  owns what a slash MEANS (start of a block or after a space; anywhere else it is punctuation).
574
593
  The matching `input` half re-filters the open menu, for the same reason: a contenteditable's
575
594
  `input` targets its host, not the block the caret happens to be in. */
576
- const onSlashKey = (e: Event) => handleSlashTrigger(e as KeyboardEvent);
595
+ const onSlashKey = (e: KeyboardEvent) => handleSlashTrigger(e);
577
596
  const onSlashInput = () => {
578
597
  if (isSlashActive()) {
579
598
  refreshSlashMenu();
@@ -17,6 +17,7 @@
17
17
  * (happy-dom's `elementFromPoint` returns null) and lives in iframe-interaction.
18
18
  */
19
19
 
20
+ import { isNumber } from "@jxsuite/schema/guards";
20
21
  import { parseJxPath } from "./path-mapping";
21
22
  import { rectOf } from "../utils/geometry";
22
23
  import { childIndex, parentElementPath } from "../state";
@@ -48,7 +49,7 @@ function isRowLayout(parent: HTMLElement): boolean {
48
49
  const isGrid = display === "grid" || display === "inline-grid";
49
50
  return (
50
51
  (isFlex && style.flexDirection.startsWith("row")) ||
51
- (isGrid && (style.gridAutoFlow ?? "").startsWith("column"))
52
+ (isGrid && style.gridAutoFlow.startsWith("column"))
52
53
  );
53
54
  }
54
55
 
@@ -78,11 +79,11 @@ export function computeInsertZones(
78
79
  shadowDoc: JxMutableNode,
79
80
  ): InsertZone[] | null {
80
81
  void shadowDoc;
81
- const serialized = targetEl.dataset?.jxPath;
82
+ const serialized = targetEl.dataset.jxPath;
82
83
  if (serialized == null) {
83
84
  return null;
84
85
  }
85
- const targetPath = parseJxPath(serialized) as JxPath;
86
+ const targetPath = parseJxPath(serialized);
86
87
 
87
88
  // Empty container: one centered "+" that inserts as the container's first child.
88
89
  if (targetEl.classList.contains(EMPTY_CONTAINER_CLASS)) {
@@ -99,7 +100,7 @@ export function computeInsertZones(
99
100
  return null;
100
101
  }
101
102
  const childIdx = childIndex(targetPath);
102
- if (typeof childIdx !== "number") {
103
+ if (!isNumber(childIdx)) {
103
104
  return null;
104
105
  }
105
106
 
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { jxPathSelector, parseJxPath, serializeJxPath } from "./path-mapping";
10
+ import { isFunction } from "@jxsuite/schema/guards";
10
11
  import { rectOf } from "../utils/geometry";
11
12
  import { computeInsertZones, insertZonesKey } from "./iframe-insert";
12
13
  import { getActiveElement, isEditing } from "../editor/inline-edit";
@@ -32,9 +33,10 @@ function isCanvasLeave(e: Event, doc: Document): boolean {
32
33
 
33
34
  /** Walk up from an element to the nearest ancestor carrying a `data-jx-path`; null if none. */
34
35
  function nearestPathEl(start: Element | null): HTMLElement | null {
35
- let el = start instanceof Element ? (start as HTMLElement) : null;
36
+ let el = start instanceof Element ? start : null;
36
37
  while (el) {
37
- if (el.dataset?.jxPath) {
38
+ // Only HTML elements are stamped (`makeStamper` skips everything else), so only they can match.
39
+ if (el instanceof HTMLElement && el.dataset.jxPath) {
38
40
  return el;
39
41
  }
40
42
  el = el.parentElement;
@@ -57,6 +59,7 @@ export function nearestHit(target: EventTarget | null): NodeHit | null {
57
59
  if (!el) {
58
60
  return null;
59
61
  }
62
+ // SAFETY: nearestPathEl returns only an element whose `data-jx-path` is a non-empty string.
60
63
  return measureHit(el, el.dataset.jxPath as string);
61
64
  }
62
65
 
@@ -75,8 +78,9 @@ export function nearestHit(target: EventTarget | null): NodeHit | null {
75
78
  * from a node that is on screen is a worse failure than drawing one for a node that is not.
76
79
  */
77
80
  function isRendered(el: Element): boolean {
78
- const check = (el as { checkVisibility?: (o?: object) => boolean }).checkVisibility;
79
- return typeof check === "function" ? check.call(el, { checkVisibilityCSS: true }) : true;
81
+ // Absent on engines that predate it, whatever lib.dom says.
82
+ const check: Element["checkVisibility"] | undefined = el.checkVisibility;
83
+ return isFunction(check) ? check.call(el, { checkVisibilityCSS: true }) : true;
80
84
  }
81
85
 
82
86
  /**
@@ -92,10 +96,7 @@ function isRendered(el: Element): boolean {
92
96
  * The serialized path is the same string the renderer stamps, so a stored selection path
93
97
  * round-trips back to its element.
94
98
  */
95
- export function measureHits(
96
- paths: (string | number)[][],
97
- doc: Document = document,
98
- ): { hits: NodeHit[]; hidden: (string | number)[][] } {
99
+ export function measureHits(paths: (string | number)[][], doc: Document = document) {
99
100
  const hits: NodeHit[] = [];
100
101
  const hidden: (string | number)[][] = [];
101
102
  for (const path of paths) {
@@ -119,8 +120,15 @@ export function measureHits(
119
120
  * {@link file://./iframe-drop.ts}'s `startGrabDetector` receives its deps rather than reaching for
120
121
  * module state.
121
122
  */
123
+ type InvokerAction = Extract<IframeToParent, { kind: "popoverTargetClick" }>["action"];
124
+
122
125
  /** The three `popovertargetaction` keywords. Anything else falls back to the HTML default. */
123
- const INVOKER_ACTIONS = new Set(["toggle", "show", "hide"]);
126
+ const INVOKER_ACTIONS = new Set<string>(["toggle", "show", "hide"] satisfies InvokerAction[]);
127
+
128
+ /** Whether an attribute value is one of the {@link INVOKER_ACTIONS} keywords. */
129
+ function isInvokerAction(value: string): value is InvokerAction {
130
+ return INVOKER_ACTIONS.has(value);
131
+ }
124
132
 
125
133
  /**
126
134
  * Report an invoker click, when the click landed on one and it names an addressable popover.
@@ -152,14 +160,14 @@ function postPopoverInvoke(
152
160
  need escaping — a rule this file already keeps in exactly one place (`jxPathSelector`) and
153
161
  should not gain a second spelling of. The set scanned is the addressable POPOVERS, which is
154
162
  also the set the answer has to come from, so the scan is the test. */
155
- const panels = invoker.ownerDocument.querySelectorAll("[data-jx-popover]");
156
- const panel = [...panels].find((el) => el.id === id) as HTMLElement | undefined;
163
+ const panels = invoker.ownerDocument.querySelectorAll<HTMLElement>("[data-jx-popover]");
164
+ const panel = [...panels].find((el) => el.id === id);
157
165
  const serialized = panel?.dataset.jxPath;
158
166
  if (!serialized) {
159
167
  return;
160
168
  }
161
169
  const raw = invoker.getAttribute("popovertargetaction") ?? "toggle";
162
- const action = INVOKER_ACTIONS.has(raw) ? (raw as "toggle" | "show" | "hide") : "toggle";
170
+ const action = isInvokerAction(raw) ? raw : "toggle";
163
171
  channel.post({ action, kind: "popoverTargetClick", targetPath: parseJxPath(serialized) });
164
172
  }
165
173
 
@@ -190,10 +198,10 @@ function postCommandInvoke(
190
198
  }
191
199
  // Scanned, not selected, for the reason `postPopoverInvoke` gives; the addressable overlays are
192
200
  // The de-popovered panels and the stamped dialogs.
193
- const overlays = invoker.ownerDocument.querySelectorAll(
201
+ const overlays = invoker.ownerDocument.querySelectorAll<HTMLElement>(
194
202
  "[data-jx-popover], dialog[data-jx-path]",
195
203
  );
196
- const overlay = [...overlays].find((el) => el.id === id) as HTMLElement | undefined;
204
+ const overlay = [...overlays].find((el) => el.id === id);
197
205
  const serialized = overlay?.dataset.jxPath;
198
206
  if (!serialized) {
199
207
  return;
@@ -270,7 +278,7 @@ export function startInteraction(
270
278
  channel.post({ kind: "paneFocus" });
271
279
  };
272
280
 
273
- const onClick = (e: Event) => {
281
+ const onClick = (e: MouseEvent) => {
274
282
  /*
275
283
  * Preview keeps anchors live, so a click would navigate this iframe and destroy the render (and
276
284
  * the editing session with it). Report the intent so the parent can open the real page in a real
@@ -303,9 +311,8 @@ export function startInteraction(
303
311
  // Ctrl/Cmd is the accumulate gesture (studio-ui-guidelines.md §8.1). The iframe reports the
304
312
  // Modifier and nothing else — it holds no selection state, so what a modified click MEANS is
305
313
  // The parent's to decide, exactly as the unmodified click already was.
306
- const mouse = e as MouseEvent;
307
314
  channel.post({
308
- additive: mouse.ctrlKey === true || mouse.metaKey === true,
315
+ additive: e.ctrlKey === true || e.metaKey === true,
309
316
  hit,
310
317
  kind: "hit",
311
318
  });
@@ -394,11 +401,10 @@ export function startInteraction(
394
401
  reportInsertZones(target, { x: moveX, y: moveY });
395
402
  };
396
403
 
397
- const onMove = (e: Event) => {
398
- const pe = e as PointerEvent;
404
+ const onMove = (e: PointerEvent) => {
399
405
  moveTarget = e.target;
400
- moveX = pe.clientX;
401
- moveY = pe.clientY;
406
+ moveX = e.clientX;
407
+ moveY = e.clientY;
402
408
  if (movePending) {
403
409
  return;
404
410
  }
@@ -415,8 +421,7 @@ export function startInteraction(
415
421
  }
416
422
  };
417
423
 
418
- const onContextMenu = (e: Event) => {
419
- const me = e as MouseEvent;
424
+ const onContextMenu = (e: MouseEvent) => {
420
425
  // Preview keeps the NATIVE menu: the Jx element menu's verbs (duplicate, delete, paste, wrap)
421
426
  // Are document edits, and preview does not edit. Copy Link Address does what it says instead.
422
427
  if (isPreview()) {
@@ -447,8 +452,8 @@ export function startInteraction(
447
452
  channel.post({
448
453
  kind: "contextMenu",
449
454
  path: hit.path,
450
- x: me.clientX,
451
- y: me.clientY,
455
+ x: e.clientX,
456
+ y: e.clientY,
452
457
  });
453
458
  };
454
459
 
@@ -56,6 +56,17 @@ import type { IframeToParent, ParentToIframe, SerializedKey, SyncedChord } from
56
56
  */
57
57
  export const FRAME_KEY_SCOPES = ["caret", "canvas", "global"] as const;
58
58
 
59
+ /**
60
+ * Commands whose chords the frame never forwards, though their scope is on its stack.
61
+ *
62
+ * `pane.backToHome` holds bare Escape in the global scope, and it applies only to a view opened
63
+ * beside a strip-less workspace's home (a media viewer, a comparison, `project.json` as Code), none
64
+ * of which is a canvas frame. Projected into the table, it made every frame cancel Escape in
65
+ * Preview and mid-sentence too, where nothing else claims it, so an author's own `<dialog>` or
66
+ * popover in the rendered page could no longer be dismissed with it.
67
+ */
68
+ export const HOST_ONLY_COMMANDS: ReadonlySet<string> = new Set(["pane.backToHome"]);
69
+
59
70
  /** The scope stack a caret session is in — app chords still fire, element-level ones do not. */
60
71
  const CARET_STACK = ["caret", "global"] as const;
61
72
  /** The stack with a selection but no caret: structural verbs are live. */
@@ -47,7 +47,7 @@ export function parentCursorToIframe(
47
47
  cursor: { x: number; y: number },
48
48
  iframeRect: { left: number; top: number },
49
49
  scale = 1,
50
- ): { x: number; y: number } {
50
+ ) {
51
51
  return {
52
52
  x: (cursor.x - iframeRect.left) / scale,
53
53
  y: (cursor.y - iframeRect.top) / scale,
@@ -15,17 +15,19 @@
15
15
  */
16
16
 
17
17
  import { reapplyStyle } from "@jxsuite/runtime";
18
- import { getNodeAtPath } from "../state";
18
+ import { isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
19
+ import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
19
20
  import { applyDocOpToDoc } from "../tabs/doc-op-apply";
20
21
  import { parseJxPath, serializeJxPath } from "./path-mapping";
21
22
  import { disposeSubtree, renderSubtreeIframe } from "./iframe-subtree";
22
23
  import {
23
24
  computeEmptyPlaceholderClass,
24
25
  EMPTY_PLACEHOLDER_CLASSES,
26
+ isRowBound,
25
27
  templateToEditDisplay,
26
28
  } from "../utils/edit-display";
27
29
  import type { IframeRenderCtx } from "./iframe-render";
28
- import type { WireDocOp } from "./iframe-protocol";
30
+ import type { JxDocOp } from "../tabs/patch-ops";
29
31
  import type { JxPath } from "../state";
30
32
  import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
31
33
 
@@ -36,7 +38,7 @@ import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
36
38
  */
37
39
  export function applyIframePatch(
38
40
  shadowDoc: JxMutableNode,
39
- forwardOps: WireDocOp[],
41
+ forwardOps: JxDocOp[],
40
42
  container: HTMLElement,
41
43
  ctx?: IframeRenderCtx,
42
44
  echoPaths?: JxPath[],
@@ -98,7 +100,7 @@ function requireCtx(ctx: IframeRenderCtx | undefined): IframeRenderCtx {
98
100
 
99
101
  function applyOpToDom(
100
102
  doc: JxMutableNode,
101
- op: WireDocOp,
103
+ op: JxDocOp,
102
104
  container: HTMLElement,
103
105
  ctx: IframeRenderCtx | undefined,
104
106
  ): void {
@@ -138,7 +140,7 @@ function applyOpToDom(
138
140
  return;
139
141
  }
140
142
  default: {
141
- // The WireDocOp union is exhaustively handled above; this guards a future op kind.
143
+ // The JxDocOp union is exhaustively handled above; this guards a future op kind.
142
144
  throw new Error(`iframe-patch-unsupported-op:${JSON.stringify(op)}`);
143
145
  }
144
146
  }
@@ -292,7 +294,7 @@ function remapChildPaths(
292
294
  continue;
293
295
  }
294
296
  const idx = p[depth + 1];
295
- if (typeof idx !== "number" || idx < fromIndex) {
297
+ if (!isNumber(idx) || idx < fromIndex) {
296
298
  continue;
297
299
  }
298
300
  if (!parentPath.every((seg, i) => p[i] === seg)) {
@@ -338,8 +340,10 @@ function patchStyle(
338
340
  ): void {
339
341
  const el = requireElement(container, path);
340
342
  const node = getNodeAtPath(doc, path);
341
- const mediaQueries = (ctx?.defs?.["$media"] as Record<string, string> | undefined) ?? {};
342
- reapplyStyle(el, editModeStyle(node?.style), mediaQueries);
343
+ /* SAFETY: buildScope writes `$media` only from the document's own `$media` map or the runtime's
344
+ * root media map, both Record<string, string>, and the host scope may not supply the key. */
345
+ const mediaQueries = (ctx?.defs["$media"] as Record<string, string> | undefined) ?? {};
346
+ reapplyStyle(el, editModeStyle(node?.style), mediaQueries, ctx?.defs ?? {});
343
347
  }
344
348
 
345
349
  /** Write the node's display text, syncing the empty-placeholder class like the full render. */
@@ -368,24 +372,24 @@ function findElement(container: HTMLElement, path: (string | number)[]): HTMLEle
368
372
  }
369
373
 
370
374
  /**
371
- * Edit-mode style transform — mirrors prepareForEditMode (and the legacy patcher's editModeStyle):
372
- * top-level template-string values are blanked so no reactive bindings are created for them.
375
+ * Edit-mode style transform — mirrors prepareForEditMode: bindings are live and resolve against the
376
+ * render's scope, except a declaration that reads the repeater row, which the perimeter cannot
377
+ * supply and so is omitted.
373
378
  */
374
379
  function editModeStyle(style: JxStyle | undefined): JxStyle | undefined {
375
- if (!style || typeof style !== "object") {
380
+ if (!style || !isNonNullObject(style)) {
376
381
  return undefined;
377
382
  }
378
- const out: Record<string, unknown> = {};
383
+ const out: JxStyle = {};
379
384
  for (const [k, v] of Object.entries(style)) {
380
- /* OMITTED, not blanked. It used to be written as `""`, which was a silent no-op while a
381
- declaration went to `el.style` and is a malformed declaration now that it goes into a rule.
382
- Dropping the key is what blanking always meant: the property falls back to the cascade. */
383
- if (typeof v === "string" && v.includes("${")) {
385
+ /* OMITTED, not blanked: `color: ` is a malformed declaration in a rule, and an absent one lets
386
+ the cascade answer, which is what blanking always meant. */
387
+ if (isRowBound(v)) {
384
388
  continue;
385
389
  }
386
390
  out[k] = v;
387
391
  }
388
- return out as JxStyle;
392
+ return out;
389
393
  }
390
394
 
391
395
  /**
@@ -393,15 +397,15 @@ function editModeStyle(style: JxStyle | undefined): JxStyle | undefined {
393
397
  * template-string and $ref display rules (and the legacy patcher's textDisplayValue).
394
398
  */
395
399
  function textDisplayValue(node: JxMutableNode | undefined): string {
396
- const v = (node as { textContent?: unknown } | undefined)?.textContent;
400
+ const v = node?.textContent;
397
401
  if (v == null) {
398
402
  return "";
399
403
  }
400
- if (typeof v === "string") {
404
+ if (isString(v)) {
401
405
  return v.includes("${") ? templateToEditDisplay(v) : v;
402
406
  }
403
- if (typeof v === "object" && (v as Record<string, unknown>).$ref) {
404
- const ref = String((v as Record<string, unknown>).$ref);
407
+ if (isNonNullObject(v) && v.$ref) {
408
+ const ref = String(v.$ref);
405
409
  const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
406
410
  return `{${label}}`;
407
411
  }
@@ -33,6 +33,12 @@ export interface DocRange {
33
33
  head: DocPos;
34
34
  }
35
35
 
36
+ /** A live DOM caret position: a node and an offset into it, as a Selection endpoint carries. */
37
+ export interface DomPosition {
38
+ node: Node;
39
+ offset: number;
40
+ }
41
+
36
42
  /** Whether an element is a block the caret may live inside. Injected so the editable set is policy. */
37
43
  export type EditablePredicate = (el: HTMLElement) => boolean;
38
44
 
@@ -91,7 +97,7 @@ export function elementForPath(container: HTMLElement, path: JxPath): HTMLElemen
91
97
 
92
98
  /** The block's rendered text length — the maximum valid offset within it. */
93
99
  export function blockTextLength(block: HTMLElement): number {
94
- return block.textContent?.length ?? 0;
100
+ return block.textContent.length;
95
101
  }
96
102
 
97
103
  /**
@@ -126,11 +132,12 @@ export function offsetOf(block: HTMLElement, node: Node, offset: number): number
126
132
  * every offset-based editor carries at a line break, and it is invisible for the paths that use
127
133
  * this (caret restore after a patch, and block-boundary edits, which clamp to 0 / length anyway).
128
134
  */
129
- export function domPositionAt(block: HTMLElement, offset: number): { node: Node; offset: number } {
135
+ export function domPositionAt(block: HTMLElement, offset: number): DomPosition {
130
136
  const target = Math.max(0, Math.min(offset, blockTextLength(block)));
131
137
  const walker = block.ownerDocument.createTreeWalker(block, NodeFilter.SHOW_TEXT);
132
138
  let seen = 0;
133
139
  let last: Text | null = null;
140
+ // SAFETY: the walker was created with NodeFilter.SHOW_TEXT, so every node it yields is a Text.
134
141
  let current = walker.nextNode() as Text | null;
135
142
  while (current) {
136
143
  const len = current.length;
@@ -139,6 +146,7 @@ export function domPositionAt(block: HTMLElement, offset: number): { node: Node;
139
146
  }
140
147
  seen += len;
141
148
  last = current;
149
+ // SAFETY: the same SHOW_TEXT walker as above, so the next node is a Text or the walk's end.
142
150
  current = walker.nextNode() as Text | null;
143
151
  }
144
152
  // No text node reaches the target: either the block has no text at all (caret goes to the element
@@ -169,10 +177,7 @@ export function toDocPos(
169
177
  * block whose text shrank under a remote edit lands at the block's new end instead of being
170
178
  * dropped.
171
179
  */
172
- export function toDomPosition(
173
- container: HTMLElement,
174
- pos: DocPos,
175
- ): { node: Node; offset: number } | null {
180
+ export function toDomPosition(container: HTMLElement, pos: DocPos): DomPosition | null {
176
181
  const el = elementForPath(container, pos.path);
177
182
  return el ? domPositionAt(el, pos.offset) : null;
178
183
  }
@@ -246,6 +251,7 @@ export function adjacentBlock(
246
251
  const key = serializeJxPath(path);
247
252
  const index = blocks.findIndex((el) => el.dataset.jxPath === key);
248
253
  const neighbour = index === -1 ? undefined : blocks[index + direction];
254
+ // SAFETY: blocksInOrder collects only elements matching `[data-jx-path]`, so the attribute is set.
249
255
  return neighbour
250
256
  ? { el: neighbour, path: parseJxPath(neighbour.dataset.jxPath as string) }
251
257
  : null;