@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
package/src/tabs/tab.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  /// <reference lib="dom" />
2
2
  import { effectScope, reactive } from "../reactivity";
3
3
  import { formatByName, formatForPath } from "../format/format-host";
4
- import { normalizeArrayChildren } from "../state";
4
+ import type { FormatFrontmatter } from "../format/format-host";
5
+ import { normalizeDocument } from "./bare-repeaters";
6
+ import type { BareRepeaters } from "./bare-repeaters";
5
7
  import type { JxPath } from "../state";
6
8
  import type { FormulaEditDef, FunctionEditDef, InlineEditDef, JsonValue } from "../types";
7
9
  import { editorKindForMode } from "../commands/context";
8
10
  import type { EditorKind } from "../commands/context";
9
- import type { JxMutableNode } from "@jxsuite/schema/types";
11
+ import type { JsonObject, JxMutableNode } from "@jxsuite/schema/types";
10
12
  import type { JxDocOp, JxFmOp } from "./patch-ops";
11
13
  import type { JsonLayout } from "@jxsuite/schema/json-layout";
12
14
 
@@ -14,13 +16,20 @@ import type { JsonLayout } from "@jxsuite/schema/json-layout";
14
16
  * The project's configuration file, project-relative.
15
17
  *
16
18
  * Named here rather than at the four places that used to spell it, because it is a DOCUMENT PATH —
17
- * `inferModes` answers `["stylebook", "source"]` for it (editor kind `config`), and
18
- * `tabs/project-config.ts` binds the tab at this path as the configuration document.
19
+ * `inferModes` answers `["stylebook", "tokens", "source"]` for it (the Styles workspace's Elements,
20
+ * Variables and Code views; editor kind `config`), and `tabs/project-config.ts` binds the tab at
21
+ * this path as the configuration document.
19
22
  */
20
23
  export const PROJECT_CONFIG_PATH = "project.json";
21
24
 
22
25
  export interface TabUi {
26
+ /** The Inspector leaf showing (`shell.ts`'s `INSPECTOR_TAB_IDS`); Page on a fresh tab (§6). */
23
27
  rightTab: string;
28
+ /**
29
+ * The Element leaf last shown — Content, Style or Logic — so the selection-driven switch from
30
+ * Page returns to the view the author was using rather than always to Content (§6).
31
+ */
32
+ elementTab: string;
24
33
  canvasMode: string;
25
34
  /** Preview toggle — composes with an edit/design canvasMode; the effective mode becomes "preview". */
26
35
  preview: boolean;
@@ -125,7 +134,7 @@ export interface StoredLivePreview {
125
134
 
126
135
  interface HistorySnapshot {
127
136
  /** Full document at this state (checkpoint), or null when the ops describe the transition. */
128
- document: Record<string, unknown> | null;
137
+ document: JxMutableNode | null;
129
138
  /** Selection after this state's transaction — the whole set, so a batch undoes back to it. */
130
139
  selection: (string | number)[][];
131
140
  /** Selection before this state's transaction (restored on surgical undo). */
@@ -177,11 +186,10 @@ export interface Tab {
177
186
  scope: {
178
187
  stop: () => void;
179
188
  run: <T>(fn: () => T) => T | undefined;
180
- [k: string]: unknown;
181
189
  };
182
190
  doc: {
183
191
  document: JxMutableNode;
184
- content: { frontmatter: Record<string, unknown> };
192
+ content: { frontmatter: FormatFrontmatter };
185
193
  mode: string;
186
194
  sourceFormat: string | null;
187
195
  handlersSource: string | null;
@@ -198,6 +206,22 @@ export interface Tab {
198
206
  * file.
199
207
  */
200
208
  layout: JsonLayout | null;
209
+ /**
210
+ * The text a format-class file (Markdown) was read as, or null for a JSON document, a new
211
+ * document or a stub. The format's serializer is handed it on save
212
+ * (`files/serialize-document.ts`) so every frontmatter key the author did not edit keeps its
213
+ * own spelling and the body keeps its markers (`@jxsuite/parser` `source-style.ts`). The
214
+ * lifetime is `layout`'s: an edit leaves it alone, and a read from disk, a source-view commit,
215
+ * a peer's text or a save replaces it with the text just read or written.
216
+ */
217
+ source: string | null;
218
+ /**
219
+ * The repeaters the file wrote as a node's whole `children`, which loading rewrote into the
220
+ * member form the editor works in (`tabs/bare-repeaters.ts`); null when it wrote none. A fact
221
+ * about the file with the lifetime `layout` has: a reload or a source-view commit replaces it,
222
+ * an edit or an undo leaves it alone, and a save writes those repeaters back as they were.
223
+ */
224
+ bareRepeaters: BareRepeaters | null;
201
225
  };
202
226
  session: {
203
227
  /**
@@ -230,7 +254,7 @@ export interface Tab {
230
254
  // A serializable snapshot of the iframe's resolved `$defs` (data-source values), posted over
231
255
  // The bridge as a `dataScope` message and read by the data-explorer panel. Plain data now —
232
256
  // The old live `EffectScope` (with `.stop()`) moved into the iframe realm with buildScope.
233
- scope: Record<string, unknown> | null;
257
+ scope: JsonObject | null;
234
258
  // Latest live (iframe-evaluated) expression previews keyed by editing-target id, stored
235
259
  // Beside `scope` the same way (services/live-preview.ts owns reads/writes).
236
260
  livePreviews: Record<string, StoredLivePreview> | null;
@@ -249,7 +273,7 @@ export interface Tab {
249
273
  * @param {boolean} preview — initial preview-toggle state
250
274
  * @returns {TabUi}
251
275
  */
252
- function createDefaultUi(canvasMode: string, preview = false) {
276
+ function createDefaultUi(canvasMode: string, preview = false): TabUi {
253
277
  return {
254
278
  activeMedia: null,
255
279
  activeSelector: null,
@@ -264,10 +288,11 @@ function createDefaultUi(canvasMode: string, preview = false) {
264
288
  pendingInlineEdit: null,
265
289
  preview,
266
290
  previewColorScheme: "auto" as const,
267
- previewLocale: null as string | null,
291
+ previewLocale: null,
268
292
  previewParams: {},
269
293
  previewProps: null,
270
- rightTab: "properties",
294
+ rightTab: "page",
295
+ elementTab: "properties",
271
296
  showLayout: true,
272
297
  styleFilter: "",
273
298
  styleSections: {},
@@ -295,13 +320,14 @@ const ALL_MODES = ["edit", "design", "preview", "source", "stylebook", "git-diff
295
320
  * id: string;
296
321
  * documentPath?: string | null;
297
322
  * fileHandle?: FileSystemFileHandle | null;
298
- * document: Record<string, unknown>;
299
- * frontmatter?: Record<string, unknown>;
323
+ * document: JxMutableNode;
324
+ * frontmatter?: FormatFrontmatter;
300
325
  * sourceFormat?: string | null;
301
326
  * capabilities?: { modes?: string[] };
302
327
  * openedFrom?: TabOrigin | null;
303
328
  * preview?: boolean;
304
329
  * layout?: JsonLayout | null;
330
+ * source?: string | null;
305
331
  * }} opts
306
332
  * @returns {Tab}
307
333
  */
@@ -316,71 +342,93 @@ export function createTab({
316
342
  openedFrom = null,
317
343
  preview: previewTab = false,
318
344
  layout = null,
345
+ source = null,
346
+ canvasMode,
319
347
  }: {
320
348
  id: string;
321
349
  documentPath?: string | null;
322
350
  fileHandle?: FileSystemFileHandle | null;
323
- document: Record<string, unknown>;
324
- frontmatter?: Record<string, unknown>;
351
+ document: JxMutableNode;
352
+ frontmatter?: FormatFrontmatter;
325
353
  sourceFormat?: string | null;
326
354
  capabilities?: { modes?: string[] };
327
355
  openedFrom?: TabOrigin | null;
328
356
  preview?: boolean;
329
357
  layout?: JsonLayout | null;
358
+ /** The text a format-class file was read as (`doc.source`). */
359
+ source?: string | null;
360
+ /**
361
+ * The mode to open in instead of the first declared one: a comparison opens straight into
362
+ * `git-diff`, so the tab is never active in an edit mode that belongs to another workspace.
363
+ */
364
+ canvasMode?: string | undefined;
330
365
  }) {
331
366
  const scope = effectScope();
332
367
 
333
368
  // Normalize legacy whole-children repeaters to the canonical array-member form before the doc
334
369
  // (and its first history checkpoint) are stored.
335
- normalizeArrayChildren(document);
370
+ const bareRepeaters = normalizeDocument(document);
336
371
 
337
372
  const resolvedModes = capabilities?.modes ?? inferModes(documentPath, sourceFormat);
338
373
  // A tab opens in its first allowed mode — never one the toolbar would disable.
339
374
  // Formats author mode order so the default comes first (edit, stylebook, etc.).
340
375
  // "preview" is a per-tab toggle rather than a base mode: a preview-first format opens
341
376
  // In its first non-preview mode with the toggle already on.
342
- const initialCanvasMode = resolvedModes.find((m) => m !== "preview") ?? "edit";
377
+ const initialCanvasMode = canvasMode ?? resolvedModes.find((m) => m !== "preview") ?? "edit";
343
378
  const initialPreview = resolvedModes[0] === "preview";
344
379
 
380
+ const doc: Tab["doc"] = {
381
+ bareRepeaters,
382
+ content: { frontmatter: frontmatter || {} },
383
+ dirty: false,
384
+ document,
385
+ handlersSource: null,
386
+ layout,
387
+ mode: inferDocumentMode(documentPath, sourceFormat),
388
+ source,
389
+ sourceFormat,
390
+ };
391
+ const history: Tab["history"] = {
392
+ index: 0,
393
+ snapshots: [{ document: structuredClone(document), selection: [] }],
394
+ };
395
+ const session: Tab["session"] = {
396
+ canvas: {
397
+ refreshing: false,
398
+ error: null,
399
+ livePreviews: null,
400
+ pendingInlineEdit: null,
401
+ scope: null,
402
+ status: "idle",
403
+ },
404
+ clipboard: null,
405
+ hover: null,
406
+ openedFrom,
407
+ selection: [],
408
+ ui: createDefaultUi(initialCanvasMode, initialPreview),
409
+ };
410
+
411
+ /* SAFETY: `reactive()` returns a deep proxy carrying its target's own members, and none of these
412
+ Three trees holds a ref for `UnwrapNestedRefs` to unwrap, so each proxy IS the shape it is cast
413
+ To. The type argument is pinned to `object` because `UnwrapNestedRefs<JxMutableNode>` recurses
414
+ Deeply enough for tsc to give up (TS2589); the proxies are deep either way. */
345
415
  const tab = scope.run(() => ({
346
416
  capabilities: { modes: resolvedModes },
347
- doc: reactive({
348
- content: { frontmatter: frontmatter || {} },
349
- dirty: false,
350
- document,
351
- handlersSource: null,
352
- layout,
353
- mode: inferDocumentMode(documentPath, sourceFormat),
354
- sourceFormat,
355
- }),
417
+ doc: reactive<object>(doc) as Tab["doc"],
356
418
  documentPath,
357
419
  fileHandle,
358
- history: reactive({
359
- index: 0,
360
- snapshots: [{ document: structuredClone(document), selection: [] }],
361
- }),
420
+ history: reactive<object>(history) as Tab["history"],
362
421
  id,
363
422
  pinned: false,
364
423
  preview: previewTab,
365
424
  scope,
366
- session: reactive({
367
- canvas: {
368
- refreshing: false,
369
- error: null,
370
- livePreviews: null,
371
- pendingInlineEdit: null,
372
- scope: null,
373
- status: "idle",
374
- },
375
- clipboard: null,
376
- hover: null,
377
- openedFrom,
378
- selection: [],
379
- ui: createDefaultUi(initialCanvasMode, initialPreview),
380
- }),
381
- })) as unknown as Tab;
425
+ session: reactive<object>(session) as Tab["session"],
426
+ }));
382
427
 
383
- return tab;
428
+ /* SAFETY: `scope` was created at the top of this function and nothing has stopped it, and an
429
+ Active scope's `run` always returns its callback's value; `undefined` is only what an inactive
430
+ Scope answers. */
431
+ return tab as Tab;
384
432
  }
385
433
 
386
434
  /**
@@ -393,7 +441,10 @@ export function createTab({
393
441
  */
394
442
  function inferModes(documentPath: string | null | undefined, sourceFormat: string | null) {
395
443
  if (documentPath === PROJECT_CONFIG_PATH) {
396
- return ["stylebook", "source"];
444
+ /* Elements, Variables and Code: the Styles workspace's three views. Spelled here rather than
445
+ imported from `style/project-styles` (`STYLES_TAB_MODES`), whose imports reach `store`,
446
+ which imports this module; `tests/project-config.test.ts` holds the two lists equal. */
447
+ return ["stylebook", "tokens", "source"];
397
448
  }
398
449
  const format = formatByName(sourceFormat) ?? formatForPath(documentPath);
399
450
  if (format) {
@@ -4,9 +4,9 @@ import { jsonClone } from "../utils/studio-utils";
4
4
  import { childIndex, getNodeAtPath, parentElementPath, pathsEqual } from "../state";
5
5
  import {
6
6
  cloneSelection,
7
- isSpliceablePath,
8
7
  primarySelection,
9
8
  pruneSelection,
9
+ spliceCoordinate,
10
10
  structuralBatch,
11
11
  } from "./selection";
12
12
  import { applyDocOpToDoc, childArray, cloneValue, inverseOf } from "./doc-op-apply";
@@ -19,7 +19,7 @@ import {
19
19
  recordPatch,
20
20
  } from "./patch-ops";
21
21
 
22
- import type { JxDocOp, JxDocOpPair, JxFmOp, TransactionRecord } from "./patch-ops";
22
+ import type { JxDocOp, JxDocOpPair, TransactionRecord } from "./patch-ops";
23
23
 
24
24
  import type { Tab } from "../tabs/tab";
25
25
  import type { JxPath } from "../state";
@@ -27,12 +27,19 @@ import type { JxPath } from "../state";
27
27
  import type { JsonValue } from "../types";
28
28
  import type {
29
29
  JxAttributeValue,
30
+ JxDocumentValue,
30
31
  JxEventBinding,
31
32
  JxMutableNode,
32
33
  JxStateObject,
33
34
  JxStyle,
34
35
  } from "@jxsuite/schema/types";
35
- import { ensureNestedStyle, getNestedStyle, isEventBinding } from "@jxsuite/schema/guards";
36
+ import {
37
+ ensureNestedStyle,
38
+ getNestedStyle,
39
+ isEventBinding,
40
+ isNonNullObject,
41
+ isNumber,
42
+ } from "@jxsuite/schema/guards";
36
43
 
37
44
  const HISTORY_LIMIT = 100;
38
45
 
@@ -48,8 +55,26 @@ function patchHistoryEnabled() {
48
55
  }
49
56
  }
50
57
 
58
+ /**
59
+ * The node `path` names, for a mutation that cannot proceed without one. A path that no longer
60
+ * resolves throws a TypeError inside the transaction, which rolls the transaction back, exactly as
61
+ * dereferencing the missing node did before this check existed.
62
+ */
63
+ function requireNodeAt(doc: JxMutableNode, path: JxPath): JxMutableNode {
64
+ const node = getNodeAtPath(doc, path);
65
+ if (!node) {
66
+ throw new TypeError(`No node at path [${path.join(", ")}]`);
67
+ }
68
+ return node;
69
+ }
70
+
51
71
  /** Forward/inverse pair for a single-key change on the node at path. */
52
- function setKeyPair(path: JxPath, key: string, before: unknown, after: unknown): JxDocOpPair {
72
+ function setKeyPair(
73
+ path: JxPath,
74
+ key: string,
75
+ before: JxDocumentValue | undefined,
76
+ after: JxDocumentValue | undefined,
77
+ ): JxDocOpPair {
53
78
  return {
54
79
  forward: { key, op: "set-key", path, value: after },
55
80
  inverse: { key, op: "set-key", path, value: before },
@@ -71,10 +96,10 @@ function shiftPrefixedIndex(
71
96
  ): JxPath {
72
97
  const d = parentPath.length;
73
98
  const isProperPrefix = d < path.length && parentPath.every((seg, i) => seg === path[i]);
74
- if (!isProperPrefix || path[d] !== "children" || typeof path[d + 1] !== "number") {
99
+ const idx = path[d + 1];
100
+ if (!isProperPrefix || path[d] !== "children" || !isNumber(idx)) {
75
101
  return path;
76
102
  }
77
- const idx = path[d + 1] as number;
78
103
  if (inclusive ? idx < spliceIndex : idx <= spliceIndex) {
79
104
  return path;
80
105
  }
@@ -152,7 +177,7 @@ function rollbackFailedTransaction(
152
177
  dirtyBefore: boolean,
153
178
  ) {
154
179
  for (let i = record.docOps.length - 1; i >= 0; i--) {
155
- applyDocOpToDoc(tab.doc.document, toRaw(record.docOps[i]!.inverse) as JxDocOp);
180
+ applyDocOpToDoc(tab.doc.document, toRaw(record.docOps[i]!.inverse));
156
181
  }
157
182
  for (let i = record.fmOps.length - 1; i >= 0; i--) {
158
183
  const op = record.fmOps[i]!;
@@ -355,10 +380,11 @@ function materializeState(
355
380
  while (base >= 0 && !snapshots[base]!.document) {
356
381
  base -= 1;
357
382
  }
358
- if (base < 0) {
383
+ const checkpoint = base < 0 ? null : snapshots[base]!.document;
384
+ if (!checkpoint) {
359
385
  throw new Error("history-missing-checkpoint");
360
386
  }
361
- const doc = jsonClone(snapshots[base]!.document) as JxMutableNode;
387
+ const doc = jsonClone(checkpoint);
362
388
  for (let i = base + 1; i <= target; i++) {
363
389
  for (const op of snapshots[i]!.forwardOps ?? []) {
364
390
  applyDocOpToDoc(doc, op);
@@ -418,8 +444,11 @@ const DOC_META_KEYS = new Set(["state", "$media", "$head", "$elements", "imports
418
444
  * @param {JxDocOp} op
419
445
  */
420
446
  function applyDocOp(tab: Tab, op: JxDocOp) {
421
- const prev =
422
- op.op === "set-key" ? (getNodeAtPath(tab.doc.document, op.path)?.[op.key] as unknown) : null;
447
+ let prev: JxDocumentValue | undefined | null = null;
448
+ if (op.op === "set-key") {
449
+ const node = getNodeAtPath(tab.doc.document, op.path);
450
+ prev = node?.[op.key];
451
+ }
423
452
  applyDocOpToDoc(tab.doc.document, op);
424
453
  // The canvas lives in an iframe and can only be patched from VALUE-CARRYING ops (`record.docOps`),
425
454
  // Which is what crosses the bridge. Recording only the classification patch below left docOps
@@ -617,12 +646,12 @@ export function undo(tab: Tab) {
617
646
  (t) => {
618
647
  if (inverseOps) {
619
648
  for (let i = inverseOps.length - 1; i >= 0; i--) {
620
- applyDocOp(t, toRaw(inverseOps[i]) as JxDocOp);
649
+ applyDocOp(t, toRaw(inverseOps[i]!));
621
650
  }
622
651
  }
623
652
  if (fmOps) {
624
653
  for (let i = fmOps.length - 1; i >= 0; i--) {
625
- const op = toRaw(fmOps[i]) as JxFmOp;
654
+ const op = toRaw(fmOps[i]!);
626
655
  applyFmState(t, op.field, op.before);
627
656
  }
628
657
  }
@@ -666,12 +695,12 @@ export function redo(tab: Tab) {
666
695
  (t) => {
667
696
  if (forwardOps) {
668
697
  for (const op of forwardOps) {
669
- applyDocOp(t, toRaw(op) as JxDocOp);
698
+ applyDocOp(t, toRaw(op));
670
699
  }
671
700
  }
672
701
  if (fmOps) {
673
702
  for (const op of fmOps) {
674
- const raw = toRaw(op) as JxFmOp;
703
+ const raw = toRaw(op);
675
704
  applyFmState(t, raw.field, raw.after);
676
705
  }
677
706
  }
@@ -731,15 +760,20 @@ export function mutateInsertNode(
731
760
  * @param {JxPath} path
732
761
  */
733
762
  export function mutateRemoveNode(tab: Tab, path: JxPath) {
734
- if (!path || !isSpliceablePath(path)) {
763
+ const at = spliceCoordinate(path);
764
+ if (!at) {
735
765
  return;
736
766
  }
737
- const elemPath = parentElementPath(path) as JxPath;
738
- const idx = childIndex(path) as number;
739
- const [removed] = (getNodeAtPath(tab.doc.document, elemPath).children as JxMutableNode[]).splice(
740
- idx,
741
- 1,
742
- );
767
+ const { index: idx, parentPath: elemPath } = at;
768
+ /* SAFETY: a spliceable path addresses a member of its parent's children, and every document a
769
+ tab holds is in the static-array member form (`normalizeArrayChildren` runs on load), so the
770
+ parent resolves to a node whose children are an array. The paths that reach here are live ones
771
+ (the pruned selection, an inline edit's own block), so the index names a member and the splice
772
+ removes exactly one. A stale parent path throws (`requireNodeAt`), inside the transaction, which
773
+ rolls back. */
774
+ const [removed] = (
775
+ requireNodeAt(tab.doc.document, elemPath).children as (JxMutableNode | string)[]
776
+ ).splice(idx, 1) as [JxMutableNode | string];
743
777
  recordPatch({ op: "remove", path });
744
778
  recordDocOp({
745
779
  forward: { index: idx, op: "remove-child", parentPath: elemPath },
@@ -753,17 +787,19 @@ export function mutateRemoveNode(tab: Tab, path: JxPath) {
753
787
  * @param {JxPath} path
754
788
  */
755
789
  export function mutateDuplicateNode(tab: Tab, path: JxPath) {
756
- if (!path || !isSpliceablePath(path)) {
790
+ const at = spliceCoordinate(path);
791
+ if (!at) {
757
792
  return;
758
793
  }
759
794
  const node = getNodeAtPath(tab.doc.document, path);
760
795
  if (!node) {
761
796
  return;
762
797
  }
763
- const elemPath = parentElementPath(path) as JxPath;
764
- const idx = childIndex(path) as number;
798
+ const { index: idx, parentPath: elemPath } = at;
765
799
  const clone = structuredClone(toRaw(node));
766
- (getNodeAtPath(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx + 1, 0, clone);
800
+ /* SAFETY: `node` resolved above, so its parent does too, and every document a tab holds keeps
801
+ static children arrays (`normalizeArrayChildren` runs on load) — `node` is a member of one. */
802
+ (requireNodeAt(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx + 1, 0, clone);
767
803
  recordPatch({ index: idx + 1, op: "insert", parentPath: elemPath });
768
804
  recordDocOp({
769
805
  forward: { index: idx + 1, node: cloneValue(clone), op: "insert-child", parentPath: elemPath },
@@ -813,17 +849,16 @@ export function mutateDuplicateNodes(tab: Tab, paths: readonly JxPath[]) {
813
849
  const before = tab.session.selection;
814
850
  mutateDuplicateNode(tab, path);
815
851
  const made = primarySelection(tab.session.selection);
852
+ const at = spliceCoordinate(made);
816
853
  // `mutateDuplicateNode` refuses a path that addresses nothing and leaves the selection alone;
817
- // Only a real insertion contributes a clone.
818
- if (!made || tab.session.selection === before) {
854
+ // Only a real insertion contributes a clone, and it selects the clone at a splice coordinate.
855
+ if (!made || !at || tab.session.selection === before) {
819
856
  continue;
820
857
  }
821
858
  // Descending order keeps the ORIGINALS valid, but not the clones already made: this insertion
822
859
  // Sits before them, so every one of their coordinates moved up by one. Translating them here
823
860
  // Is the difference between "the copies are selected" and "two of the originals are".
824
- const parentPath = parentElementPath(made) as JxPath;
825
- const spliceIndex = childIndex(made) as number;
826
- clones = clones.map((clone) => shiftPrefixedIndex(parentPath, clone, spliceIndex, 1, true));
861
+ clones = clones.map((clone) => shiftPrefixedIndex(at.parentPath, clone, at.index, 1, true));
827
862
  clones.unshift(made);
828
863
  }
829
864
  if (clones.length > 0) {
@@ -837,21 +872,23 @@ export function mutateDuplicateNodes(tab: Tab, paths: readonly JxPath[]) {
837
872
  * @param {string} wrapperTag
838
873
  */
839
874
  export function mutateWrapNode(tab: Tab, path: JxPath, wrapperTag = "div") {
840
- if (!path || !isSpliceablePath(path)) {
875
+ const at = spliceCoordinate(path);
876
+ if (!at) {
841
877
  return;
842
878
  }
843
879
  const node = getNodeAtPath(tab.doc.document, path);
844
880
  if (!node) {
845
881
  return;
846
882
  }
847
- const elemPath = parentElementPath(path) as JxPath;
848
- const idx = childIndex(path) as number;
883
+ const { index: idx, parentPath: elemPath } = at;
849
884
  const wrapper = {
850
885
  children: [structuredClone(toRaw(node))],
851
886
  tagName: wrapperTag,
852
887
  };
853
888
  const original = cloneValue(node);
854
- (getNodeAtPath(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx, 1, wrapper);
889
+ /* SAFETY: `node` resolved above, so its parent does too, and every document a tab holds keeps
890
+ static children arrays (`normalizeArrayChildren` runs on load) — `node` is a member of one. */
891
+ (requireNodeAt(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx, 1, wrapper);
855
892
  recordPatch({ op: "replace", path });
856
893
  recordDocOp({
857
894
  forward: { index: idx, node: cloneValue(wrapper), op: "set-child", parentPath: elemPath },
@@ -868,9 +905,9 @@ export function mutateWrapNode(tab: Tab, path: JxPath, wrapperTag = "div") {
868
905
  */
869
906
  export function mutateMoveNode(tab: Tab, fromPath: JxPath, toParentPath: JxPath, toIndex: number) {
870
907
  const doc = tab.doc.document;
871
- const fromParentPath = parentElementPath(fromPath) as JxPath;
872
- const fromIdx = childIndex(fromPath) as number;
873
- if (!fromParentPath || typeof fromIdx !== "number") {
908
+ const fromParentPath = parentElementPath(fromPath);
909
+ const fromIdx = childIndex(fromPath);
910
+ if (!fromParentPath || !isNumber(fromIdx)) {
874
911
  return;
875
912
  }
876
913
  const fromParent = getNodeAtPath(doc, fromParentPath);
@@ -967,7 +1004,7 @@ export function mutateUpdateProperty(tab: Tab, path: JxPath, key: string, value?
967
1004
  * @param {string | undefined} value
968
1005
  */
969
1006
  export function mutateUpdateStyle(tab: Tab, path: JxPath, prop: string, value: string | undefined) {
970
- const node = getNodeAtPath(tab.doc.document, path);
1007
+ const node = requireNodeAt(tab.doc.document, path);
971
1008
  const styleBefore = cloneValue(node.style);
972
1009
  if (!node.style) {
973
1010
  node.style = {};
@@ -996,7 +1033,7 @@ export function mutateUpdateAttribute(
996
1033
  attr: string,
997
1034
  value?: JxAttributeValue | undefined,
998
1035
  ) {
999
- const node = getNodeAtPath(tab.doc.document, path);
1036
+ const node = requireNodeAt(tab.doc.document, path);
1000
1037
  const attrsBefore = cloneValue(node.attributes);
1001
1038
  if (!node.attributes) {
1002
1039
  node.attributes = {};
@@ -1030,7 +1067,7 @@ export function mutateUpdateMediaStyle(
1030
1067
  if (!mediaName) {
1031
1068
  return mutateUpdateStyle(tab, path, prop, value);
1032
1069
  }
1033
- const node = getNodeAtPath(tab.doc.document, path);
1070
+ const node = requireNodeAt(tab.doc.document, path);
1034
1071
  const styleBefore = cloneValue(node.style);
1035
1072
  if (!node.style) {
1036
1073
  node.style = {};
@@ -1066,7 +1103,7 @@ export function mutateUpdateNestedStyle(
1066
1103
  prop: string,
1067
1104
  value: string | undefined,
1068
1105
  ) {
1069
- const node = getNodeAtPath(tab.doc.document, path);
1106
+ const node = requireNodeAt(tab.doc.document, path);
1070
1107
  const styleBefore = cloneValue(node.style);
1071
1108
  if (!node.style) {
1072
1109
  node.style = {};
@@ -1103,7 +1140,7 @@ export function mutateUpdateMediaNestedStyle(
1103
1140
  prop: string,
1104
1141
  value: string | undefined,
1105
1142
  ) {
1106
- const node = getNodeAtPath(tab.doc.document, path);
1143
+ const node = requireNodeAt(tab.doc.document, path);
1107
1144
  const styleBefore = cloneValue(node.style);
1108
1145
  if (!node.style) {
1109
1146
  node.style = {};
@@ -1186,7 +1223,7 @@ export function mutateUpdateNestedStylePath(
1186
1223
  prop: string,
1187
1224
  value: string | undefined,
1188
1225
  ) {
1189
- const node = getNodeAtPath(tab.doc.document, path);
1226
+ const node = requireNodeAt(tab.doc.document, path);
1190
1227
  const styleBefore = cloneValue(node.style);
1191
1228
  if (!node.style) {
1192
1229
  node.style = {};
@@ -1226,7 +1263,7 @@ export function mutateUpdateMediaNestedStylePath(
1226
1263
  prop: string,
1227
1264
  value: string | undefined,
1228
1265
  ) {
1229
- const node = getNodeAtPath(tab.doc.document, path);
1266
+ const node = requireNodeAt(tab.doc.document, path);
1230
1267
  const styleBefore = cloneValue(node.style);
1231
1268
  if (!node.style) {
1232
1269
  node.style = {};
@@ -1259,7 +1296,7 @@ export function mutateUpdateMediaNestedStylePath(
1259
1296
  * @param {Record<string, string | undefined> | undefined} style
1260
1297
  */
1261
1298
  export function mutateReplaceStyle(tab: Tab, path: JxPath, style: JxStyle | undefined) {
1262
- const node = getNodeAtPath(tab.doc.document, path);
1299
+ const node = requireNodeAt(tab.doc.document, path);
1263
1300
  const styleBefore = cloneValue(node.style);
1264
1301
  if (style && Object.keys(style).length > 0) {
1265
1302
  node.style = style;
@@ -1308,17 +1345,25 @@ export function mutateRemoveDef(tab: Tab, name: string) {
1308
1345
  * @param {string} name
1309
1346
  * @param {Record<string, JsonValue>} updates
1310
1347
  */
1311
- export function mutateUpdateDef(tab: Tab, name: string, updates: Record<string, unknown>) {
1348
+ export function mutateUpdateDef(
1349
+ tab: Tab,
1350
+ name: string,
1351
+ updates: Record<string, JxDocumentValue | undefined>,
1352
+ ) {
1312
1353
  const doc = tab.doc.document;
1313
1354
  const stateBefore = cloneValue(doc.state);
1314
1355
  if (!doc.state) {
1315
1356
  doc.state = {};
1316
1357
  }
1317
1358
  const existing = doc.state[name];
1359
+ /* SAFETY: what is left after null, primitives and arrays is one of the object entry forms (an
1360
+ expanded signal, or a function, prototype, expression or server-function def). Each is a plain
1361
+ record whose keys the loop below edits one by one, and JxStateObject is the open record that
1362
+ edit needs; nothing here relies on a member that only one of the forms carries. */
1318
1363
  const entry: JxStateObject =
1319
1364
  existing == null
1320
1365
  ? {}
1321
- : typeof existing !== "object" || Array.isArray(existing)
1366
+ : !isNonNullObject(existing) || Array.isArray(existing)
1322
1367
  ? { default: existing }
1323
1368
  : (existing as JxStateObject);
1324
1369
  doc.state[name] = entry;
@@ -1379,7 +1424,7 @@ export function mutateUpdateMedia(tab: Tab, name: string, query?: string | undef
1379
1424
  * @param {JsonValue} value
1380
1425
  */
1381
1426
  export function mutateUpdateProp(tab: Tab, path: JxPath, propName: string, value: JsonValue) {
1382
- const node = getNodeAtPath(tab.doc.document, path);
1427
+ const node = requireNodeAt(tab.doc.document, path);
1383
1428
  const propsBefore = cloneValue(node.$props);
1384
1429
  if (!node.$props) {
1385
1430
  node.$props = {};
@@ -1408,7 +1453,7 @@ export function mutateAddSwitchCase(
1408
1453
  caseName: string,
1409
1454
  caseDef?: JxMutableNode,
1410
1455
  ) {
1411
- const node = getNodeAtPath(tab.doc.document, path);
1456
+ const node = requireNodeAt(tab.doc.document, path);
1412
1457
  const before = cloneValue(node.cases);
1413
1458
  if (!node.cases) {
1414
1459
  node.cases = {};
@@ -1424,7 +1469,7 @@ export function mutateAddSwitchCase(
1424
1469
  * @param {string} caseName
1425
1470
  */
1426
1471
  export function mutateRemoveSwitchCase(tab: Tab, path: JxPath, caseName: string) {
1427
- const node = getNodeAtPath(tab.doc.document, path);
1472
+ const node = requireNodeAt(tab.doc.document, path);
1428
1473
  if (node.cases) {
1429
1474
  const before = cloneValue(node.cases);
1430
1475
  delete node.cases[caseName];
@@ -1440,7 +1485,7 @@ export function mutateRemoveSwitchCase(tab: Tab, path: JxPath, caseName: string)
1440
1485
  * @param {string} newName
1441
1486
  */
1442
1487
  export function mutateRenameSwitchCase(tab: Tab, path: JxPath, oldName: string, newName: string) {
1443
- const node = getNodeAtPath(tab.doc.document, path);
1488
+ const node = requireNodeAt(tab.doc.document, path);
1444
1489
  if (!node.cases || !node.cases[oldName]) {
1445
1490
  return;
1446
1491
  }
@@ -1479,7 +1524,7 @@ export function mutateUpdateFrontmatter(tab: Tab, field: string, value?: JsonVal
1479
1524
  * Unlike `mutateUpdateFrontmatter`, values like `""`/`false`/`null` are written verbatim (source
1480
1525
  * round-trips can put them there) and no fm op is recorded — history replay must not re-record.
1481
1526
  */
1482
- function applyFmState(tab: Tab, field: string, value: unknown) {
1527
+ function applyFmState(tab: Tab, field: string, value: JxDocumentValue | undefined) {
1483
1528
  if (value === undefined) {
1484
1529
  delete tab.doc.content.frontmatter[field];
1485
1530
  } else {