@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
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * - **Repeater · Switch · Observed Attributes · CSS Properties · CSS Parts → the Logic tab.** Wiring
10
10
  * a `$switch` and wiring a click handler are the same task (`panels/events-panel.ts`).
11
- * - **The Page section → the Document Header card.** `panels/head-panel.ts` owns the one layout
11
+ * - **The Page section → the Inspector's Page tab.** `panels/head-panel.ts` owns the one layout
12
12
  * picker; this panel drew a second one that could disagree with it.
13
13
  * - **Media breakpoint DEFINITIONS → Project Settings › Contexts** (§17.1). Nothing remains here: the
14
14
  * only reason adding a breakpoint used to cost you your element selection.
@@ -43,8 +43,15 @@
43
43
 
44
44
  import { getNodeAtPath } from "../store";
45
45
  import { effect, effectScope, reactive } from "../reactivity";
46
- import { displayTagName, isRef, isTagExpression } from "@jxsuite/schema/guards";
47
- import type { DirEntry, JsonValue } from "../types";
46
+ import {
47
+ displayTagName,
48
+ isJsonObject,
49
+ isNonNullObject,
50
+ isRef,
51
+ isString,
52
+ isTagExpression,
53
+ } from "@jxsuite/schema/guards";
54
+ import type { JsonValue } from "../types";
48
55
  import {
49
56
  mutateUpdateAttribute,
50
57
  mutateUpdateDef,
@@ -63,7 +70,7 @@ import {
63
70
  stringArg,
64
71
  stringProperty,
65
72
  } from "../commands/command-args";
66
- import type { LayoutSelection } from "../shell";
73
+ import type { LayoutHit } from "../canvas/iframe-protocol";
67
74
  import type { AnyCommand, CommandRegistry } from "../commands/registry";
68
75
  import { activeRegistry } from "../commands/active-registry";
69
76
  import { componentRegistry } from "../files/components";
@@ -108,6 +115,7 @@ import { clickAnythingTo, openPageAction, staleSelectionMessage } from "./empty-
108
115
  import { mountMediaPicker, unmountMediaPicker } from "../ui/media-picker";
109
116
  import { colorTokens, resolvedColor } from "../ui/color-selector";
110
117
  import { mountExpressionEditor } from "../ui/expression-editor";
118
+ import type { ExpressionEditorOpts } from "../ui/expression-editor";
111
119
  import {
112
120
  loadUsages,
113
121
  peekUsages,
@@ -115,6 +123,7 @@ import {
115
123
  usageFiles,
116
124
  usageHeadline,
117
125
  } from "../services/references";
126
+ import type { UsageQuery } from "../services/references";
118
127
  import { getPlatform } from "../platform";
119
128
  import htmlMeta from "../../data/html-meta.json";
120
129
  import { popoverIdsIn } from "@jxsuite/schema/overlays";
@@ -123,7 +132,6 @@ import { showPromptDialog } from "../ui/layers";
123
132
  import { emptyContentView, mountContentSurface } from "../surfaces/properties-panel";
124
133
 
125
134
  import type {
126
- ContentOption,
127
135
  ContentPanelActions,
128
136
  ContentPanelSurface,
129
137
  ContentPanelView,
@@ -132,21 +140,19 @@ import type {
132
140
  } from "../surfaces/properties-panel";
133
141
  import type {
134
142
  JxAttributeValue,
135
- JxElement,
143
+ JxDocumentValue,
136
144
  JxMutableNode,
137
- JxPrototypeDef,
138
145
  JxStateDefinition,
139
- JxStateObject,
140
146
  } from "@jxsuite/schema/types";
141
- import type { SignalOption } from "../ui/dynamic-slot";
142
147
  import type { JxPath } from "../state";
143
148
  import type { EffectScope } from "@vue/reactivity";
149
+ import type { SurfaceOption } from "../ui/surface";
144
150
 
145
151
  /** The picker's escape hatch: a popover declared in another file, typed by hand. */
146
152
  const POPOVER_TARGET_OTHER = "jx:other";
147
153
 
148
154
  /** The empty row a picker offers so a value can be taken away with the same control that set it. */
149
- const CLEAR_OPTION: ContentOption = { label: "—", value: "" };
155
+ const CLEAR_OPTION: SurfaceOption = { label: "—", value: "" };
150
156
 
151
157
  interface HtmlMetaEntry {
152
158
  $section: string;
@@ -157,7 +163,20 @@ interface HtmlMetaEntry {
157
163
  $input?: string;
158
164
  $shorthand?: boolean;
159
165
  type?: string;
160
- [key: string]: unknown;
166
+ enum?: string[];
167
+ /** Every value in `data/html-meta.json` is a string, a number, a boolean or a list of names. */
168
+ [key: string]: string | number | boolean | string[] | undefined;
169
+ }
170
+
171
+ /** Every attribute `data/html-meta.json` describes, by its `$defs` key. */
172
+ const HTML_META_DEFS: ReadonlyMap<string, HtmlMetaEntry> = new Map(Object.entries(htmlMeta.$defs));
173
+
174
+ /**
175
+ * The node at `path`, typed as what `getNodeAtPath` really returns: `undefined` once the path walks
176
+ * off the tree, which a stale selection (or a sibling's path in a multi-selection) does.
177
+ */
178
+ function nodeAtPath(doc: JxMutableNode, path: JxPath): JxMutableNode | undefined {
179
+ return getNodeAtPath(doc, path);
161
180
  }
162
181
 
163
182
  // ─── The binding vocabulary, shared with the Logic tab ───────────────────────
@@ -171,7 +190,7 @@ interface HtmlMetaEntry {
171
190
  * Exported because Content and Logic both offer them and there is one right answer: a `$switch`
172
191
  * inside a `$map` can read `$map/item`, and so can the `alt` attribute two nodes below it.
173
192
  */
174
- export function mapSignalsFor(path: JxPath): SignalOption[] | null {
193
+ export function mapSignalsFor(path: JxPath): SurfaceOption[] | null {
175
194
  return path.includes("map")
176
195
  ? [
177
196
  { label: "$map/item", value: "$map/item" },
@@ -182,13 +201,9 @@ export function mapSignalsFor(path: JxPath): SignalOption[] | null {
182
201
 
183
202
  /** State keys a value position may bind to — handlers and Functions are not values. */
184
203
  export function bindableSignalNames(doc: JxMutableNode): string[] {
185
- return Object.entries(doc.state || {})
186
- .filter(
187
- ([, d]) =>
188
- !(d as Record<string, unknown>)?.$handler &&
189
- (d as JxPrototypeDef)?.$prototype !== "Function",
190
- )
191
- .map(([defName]) => defName);
204
+ return Object.entries(doc.state || {}).flatMap(([defName, d]) =>
205
+ isJsonObject(d) && (d.$handler || d.$prototype === "Function") ? [] : [defName],
206
+ );
192
207
  }
193
208
 
194
209
  /**
@@ -198,23 +213,24 @@ export function bindableSignalNames(doc: JxMutableNode): string[] {
198
213
  * @returns {string}
199
214
  */
200
215
  export function defaultAsString(def: JxStateDefinition | undefined) {
201
- if (!def || typeof def !== "object" || Array.isArray(def)) {
216
+ if (!isJsonObject(def)) {
202
217
  return "";
203
218
  }
204
- const dv = (def as JxStateObject).default;
219
+ const dv = def.default;
205
220
  if (dv === undefined) {
206
221
  return "";
207
222
  }
208
- return typeof dv === "object" ? JSON.stringify(dv) : String(dv);
223
+ // `null` prints as "null" either way, so only a structure needs JSON.
224
+ return isNonNullObject(dv) ? JSON.stringify(dv) : String(dv);
209
225
  }
210
226
 
211
227
  /** Who a bound value comes from, in the fewest words that are true — the chip's donor text. */
212
- function bindingDonor(value: unknown): string {
228
+ function bindingDonor(value: JxDocumentValue | undefined): string {
213
229
  if (isRef(value)) {
214
230
  const ref = value.$ref;
215
231
  return ref.startsWith("#/state/") ? ref.slice(8) : ref || "nothing yet";
216
232
  }
217
- return typeof value === "string" ? "a template" : "a formula";
233
+ return isString(value) ? "a template" : "a formula";
218
234
  }
219
235
 
220
236
  /**
@@ -227,12 +243,12 @@ function bindingDonor(value: unknown): string {
227
243
  * `templateSignalOf`, because both spellings of a template (`${x}` and `${state.x}`) name the same
228
244
  * entry.
229
245
  */
230
- function boundSignalOf(value: unknown): string | null {
246
+ function boundSignalOf(value: JxDocumentValue | undefined): string | null {
231
247
  if (isRef(value)) {
232
248
  const ref = value.$ref;
233
249
  return ref.startsWith("#/state/") ? (ref.slice(8).split("/")[0] ?? null) : null;
234
250
  }
235
- if (typeof value !== "string") {
251
+ if (!isString(value)) {
236
252
  return null;
237
253
  }
238
254
  return /\$\{\s*(?:state\.)?([A-Za-z_$][\w$]*)/.exec(value)?.[1] ?? null;
@@ -257,18 +273,17 @@ function revealSignal(name: string): void {
257
273
  * provenance functions differ in everything else, and the question "does this document define
258
274
  * `title`?" has one answer that neither of them should have to be handed.
259
275
  */
260
- function boundProvenance(value: unknown, title: string): FieldProvenance {
276
+ function boundProvenance(value: JxDocumentValue | undefined, title: string): FieldProvenance {
261
277
  const signal = boundSignalOf(value);
262
278
  const document = activeTab.value?.doc.document;
263
279
  const known = signal && document ? bindableSignalNames(document).includes(signal) : false;
264
- return {
265
- donor: bindingDonor(value),
266
- state: "bound",
267
- title,
268
- // Only when the document actually defines it: a chip that jumps to a row that is not there
269
- // Would be a worse answer than a chip that does not jump.
270
- ...(known && signal ? { onClick: () => revealSignal(signal) } : {}),
271
- };
280
+ const provenance: FieldProvenance = { donor: bindingDonor(value), state: "bound", title };
281
+ // Only when the document actually defines it: a chip that jumps to a row that is not there
282
+ // Would be a worse answer than a chip that does not jump.
283
+ if (known && signal) {
284
+ provenance.onClick = () => revealSignal(signal);
285
+ }
286
+ return provenance;
272
287
  }
273
288
 
274
289
  /**
@@ -294,7 +309,7 @@ export function isComponentDefinitionOpen(node: JxMutableNode): boolean {
294
309
  */
295
310
  function componentPropProvenance(
296
311
  prop: { name: string; default?: unknown; description?: string },
297
- rawValue: unknown,
312
+ rawValue: JxDocumentValue | undefined,
298
313
  hasVal: boolean,
299
314
  actions: {
300
315
  onClear: () => void;
@@ -313,12 +328,15 @@ function componentPropProvenance(
313
328
  unset field means this component ships no default for that setting — which is `default`, the
314
329
  state that draws nothing, not a badge pointing at itself. */
315
330
  if (prop.default !== undefined && !actions.isDefinition) {
316
- return {
331
+ const inherited: FieldProvenance = {
317
332
  donor: "the component default",
318
333
  state: "inherited",
319
334
  title: `Not set here — the component's default (${String(prop.default)}) applies`,
320
- ...(actions.openDefinition ? { onClick: actions.openDefinition } : {}),
321
335
  };
336
+ if (actions.openDefinition) {
337
+ inherited.onClick = actions.openDefinition;
338
+ }
339
+ return inherited;
322
340
  }
323
341
  return { state: "default" };
324
342
  }
@@ -326,7 +344,7 @@ function componentPropProvenance(
326
344
  /** Which of §6.7's states an HTML-attribute row is in. Attributes have no third cascade layer. */
327
345
  function attributeProvenance(
328
346
  attr: string,
329
- value: unknown,
347
+ value: JxAttributeValue | undefined,
330
348
  hasVal: boolean,
331
349
  onClear: () => void,
332
350
  mixedCount = 0,
@@ -337,7 +355,7 @@ function attributeProvenance(
337
355
  if (mixedCount > 0) {
338
356
  return { donor: String(mixedCount), onClick: onClear, state: "mixed" };
339
357
  }
340
- if (hasVal && (isRef(value) || (typeof value === "string" && value.includes("${")))) {
358
+ if (hasVal && (isRef(value) || (isString(value) && value.includes("${")))) {
341
359
  return boundProvenance(value, `Bound — ${attr}`);
342
360
  }
343
361
  return hasVal ? { onClick: onClear, state: "set", title: `Clear ${attr}` } : { state: "default" };
@@ -353,12 +371,12 @@ function attributeProvenance(
353
371
  export function mixedAcrossSelection(
354
372
  doc: JxMutableNode,
355
373
  targets: readonly JxPath[],
356
- read: (node: JxMutableNode | undefined) => unknown,
374
+ read: (node: JxMutableNode | undefined) => JxDocumentValue | undefined,
357
375
  ): number {
358
376
  if (targets.length < 2) {
359
377
  return 0;
360
378
  }
361
- const values = targets.map((path) => read(getNodeAtPath(doc, path) as JxMutableNode | undefined));
379
+ const values = targets.map((path) => read(nodeAtPath(doc, path)));
362
380
  return unifyValues(values).mixed ? targets.length : 0;
363
381
  }
364
382
 
@@ -366,8 +384,8 @@ export function mixedAcrossSelection(
366
384
  * True when an attribute value is a binding (a `$ref` object or a template string containing
367
385
  * `${…}`), so the Link-target special-case must fall back to the raw widget to keep it editable.
368
386
  */
369
- function isBoundAttrValue(value: unknown): boolean {
370
- return isRef(value) || (typeof value === "string" && value.includes("${"));
387
+ function isBoundAttrValue(value: JxAttributeValue | undefined): boolean {
388
+ return isRef(value) || (isString(value) && value.includes("${"));
371
389
  }
372
390
 
373
391
  // ─── Page-route enumeration (for the Link-target Internal picker) ─────────────
@@ -400,6 +418,16 @@ function routeForPagePath(relPath: string): string {
400
418
  return isIndex || body.includes(":") ? `/${body}${isIndex ? "/" : ""}` : `/${body}/`;
401
419
  }
402
420
 
421
+ /**
422
+ * What the route walk reads from a listing entry. `path` is optional because the cloud adapter
423
+ * hands back its response body unvalidated, so an entry without one is addressed under its parent.
424
+ */
425
+ interface ListedEntry {
426
+ name: string;
427
+ path?: string;
428
+ type: string;
429
+ }
430
+
403
431
  /**
404
432
  * Recursively walk the pages/ tree and populate {@link pageRouteEntries} with derived routes.
405
433
  *
@@ -415,7 +443,7 @@ async function loadPageRouteEntries() {
415
443
  try {
416
444
  const platform = getPlatform();
417
445
  const walk = async (dir: string, rel: string): Promise<void> => {
418
- let listing: DirEntry[];
446
+ let listing: readonly ListedEntry[];
419
447
  try {
420
448
  listing = await platform.listDirectory(dir);
421
449
  } catch {
@@ -519,7 +547,7 @@ interface LadderPlan {
519
547
  mode: SlotMode;
520
548
  offered: SlotMode[];
521
549
  /** Every pointer the From data… rung offers, state entries and repeater signals alike. */
522
- sources: SignalOption[];
550
+ sources: SurfaceOption[];
523
551
  /**
524
552
  * The state entries alone, kept apart from {@link sources} because `slotModeSeed` reads them
525
553
  * differently: a fresh Mixed text rung seeds `${state.<first>}` from a state entry and `${}` from
@@ -527,7 +555,7 @@ interface LadderPlan {
527
555
  * template instead of naming the signal it had just left.
528
556
  */
529
557
  stateDefs: string[];
530
- extraSignals: SignalOption[];
558
+ extraSignals: SurfaceOption[];
531
559
  value: JsonValue | undefined;
532
560
  onChange: (v?: JsonValue) => void;
533
561
  literalDefault: JsonValue | undefined;
@@ -577,6 +605,12 @@ interface RowPlan {
577
605
  control?: ((host: HTMLElement) => void) | undefined;
578
606
  }
579
607
 
608
+ /** A row and the plan that reads its gestures back, before {@link withPlan} files the plan. */
609
+ interface PlannedRow {
610
+ row: ContentRowView;
611
+ plan: RowPlan;
612
+ }
613
+
580
614
  /** A row view with every field filled in, before the caller narrows it. */
581
615
  function blankRow(key: string, prop: string, label: string): ContentRowView {
582
616
  return {
@@ -601,7 +635,6 @@ function blankRow(key: string, prop: string, label: string): ContentRowView {
601
635
  prop,
602
636
  removeLabel: "",
603
637
  resolved: "",
604
- shape: "field",
605
638
  source: "fixed",
606
639
  sourceLabel: "",
607
640
  sourceLocked: false,
@@ -610,6 +643,7 @@ function blankRow(key: string, prop: string, label: string): ContentRowView {
610
643
  title: "",
611
644
  tokens: [],
612
645
  value: "",
646
+ variant: "field",
613
647
  };
614
648
  }
615
649
 
@@ -898,7 +932,7 @@ function openSourceMenu(key: string, anchor: HTMLElement): void {
898
932
  opener: anchor,
899
933
  region: "value-source",
900
934
  rows: offered.map((rung) => ({
901
- checked: (rung === mode ? "true" : "false") as "true" | "false",
935
+ checked: rung === mode ? ("true" as const) : ("false" as const),
902
936
  destructive: false,
903
937
  disabled: false,
904
938
  dividerAbove: false,
@@ -906,8 +940,9 @@ function openSourceMenu(key: string, anchor: HTMLElement): void {
906
940
  title: VALUE_SOURCE_LABELS[rung],
907
941
  })),
908
942
  run: (id) => {
909
- const next = id as SlotMode;
910
- if (next === mode) {
943
+ // The rows ARE `offered`, so a picked id is always one of its rungs.
944
+ const next = offered.find((rung) => rung === id);
945
+ if (next === undefined || next === mode) {
911
946
  return;
912
947
  }
913
948
  /* Leaving From data… seeds an empty Fixed value stash with the signal's declared default, so
@@ -978,10 +1013,10 @@ function applyChip(
978
1013
  interface LadderOpts {
979
1014
  fieldKey: string;
980
1015
  caps: SlotCapsSource;
981
- value: unknown;
1016
+ value: JxDocumentValue | undefined;
982
1017
  onChange: (v?: JsonValue) => void;
983
1018
  stateDefs: string[];
984
- extraSignals?: SignalOption[] | null;
1019
+ extraSignals?: SurfaceOption[] | null;
985
1020
  literalDefault?: JsonValue | undefined;
986
1021
  seedFor?: ((mode: SlotMode) => JsonValue | undefined) | undefined;
987
1022
  /** The operators this position's grammar admits, when it admits fewer than all of them. */
@@ -998,7 +1033,7 @@ interface LadderOpts {
998
1033
  function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void {
999
1034
  const caps = slotCaps(opts.caps);
1000
1035
  const mode = effectiveSlotMode(opts.fieldKey, opts.value);
1001
- const sources: SignalOption[] = [
1036
+ const sources: SurfaceOption[] = [
1002
1037
  ...opts.stateDefs.map((name) => ({ label: name, value: `#/state/${name}` })),
1003
1038
  ...(opts.extraSignals ?? []),
1004
1039
  ];
@@ -1026,6 +1061,9 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
1026
1061
  seedFor: opts.seedFor,
1027
1062
  sources,
1028
1063
  stateDefs: opts.stateDefs,
1064
+ /* SAFETY: a ladder position's value was read out of the JSON document (an attribute, a prop, a
1065
+ `tagName`), so it is JSON; `JxRef` and the expression shapes are interfaces, which TypeScript
1066
+ will not match against `JsonObject`'s index signature. */
1029
1067
  value: cloneValue(opts.value as JsonValue | undefined),
1030
1068
  };
1031
1069
  if (mode === "ref") {
@@ -1046,7 +1084,7 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
1046
1084
  row.kind = "text";
1047
1085
  row.mono = true;
1048
1086
  row.placeholder = "${state.…}";
1049
- row.value = getFieldValue(templateDraft, typeof opts.value === "string" ? opts.value : "");
1087
+ row.value = getFieldValue(templateDraft, isString(opts.value) ? opts.value : "");
1050
1088
  plan.commit = (raw) => opts.onChange(raw);
1051
1089
  plan.debounceMs = LIVE_PREVIEW;
1052
1090
  plan.draft = templateDraft;
@@ -1054,22 +1092,26 @@ function applyLadder(row: ContentRowView, plan: RowPlan, opts: LadderOpts): void
1054
1092
  return;
1055
1093
  }
1056
1094
  if (mode === "expression") {
1057
- const node = (opts.value as { $expression?: unknown } | undefined)?.$expression;
1095
+ const node = isJsonObject(opts.value) ? opts.value.$expression : undefined;
1058
1096
  row.kind = "control";
1059
1097
  plan.commit = undefined;
1060
1098
  plan.draft = undefined;
1099
+ const editorOpts: ExpressionEditorOpts = {
1100
+ allowEventRef: false,
1101
+ preview: null,
1102
+ stateDefs: opts.stateDefs,
1103
+ stateEntries: null,
1104
+ };
1105
+ if (opts.operators) {
1106
+ editorOpts.operators = opts.operators;
1107
+ }
1061
1108
  plan.control = (host) =>
1062
1109
  mountExpressionEditor(
1063
1110
  host,
1064
1111
  node,
1112
+ // SAFETY: the expression editor hands back the JSON expression node it built from `node`.
1065
1113
  (next) => opts.onChange({ $expression: next } as JsonValue),
1066
- {
1067
- allowEventRef: false,
1068
- ...(opts.operators ? { operators: opts.operators } : {}),
1069
- preview: null,
1070
- stateDefs: opts.stateDefs,
1071
- stateEntries: null,
1072
- },
1114
+ editorOpts,
1073
1115
  );
1074
1116
  }
1075
1117
  }
@@ -1083,7 +1125,7 @@ function textRow(opts: {
1083
1125
  value: string;
1084
1126
  placeholder?: string;
1085
1127
  commit: (raw: string) => void;
1086
- }): { row: ContentRowView; plan: RowPlan } {
1128
+ }): PlannedRow {
1087
1129
  const row = blankRow(opts.key, opts.prop, opts.label);
1088
1130
  row.kind = "text";
1089
1131
  row.value = getFieldValue(opts.draft, opts.value);
@@ -1130,7 +1172,7 @@ function projectPanel(): ContentPanelView {
1130
1172
  // Layout chrome first: it is mutually exclusive with a document selection, and it is the one
1131
1173
  // Target whose name has to say where it came FROM.
1132
1174
  if (shell.layoutSelection) {
1133
- return layoutView(shell.layoutSelection as LayoutSelection);
1175
+ return layoutView(shell.layoutSelection);
1134
1176
  }
1135
1177
 
1136
1178
  const selected = primarySelection(tab.session.selection);
@@ -1138,7 +1180,7 @@ function projectPanel(): ContentPanelView {
1138
1180
  return emptyView(clickAnythingTo("edit its content"), "", []);
1139
1181
  }
1140
1182
  const path: JxPath = selected;
1141
- const node = getNodeAtPath(tab.doc.document, path);
1183
+ const node = nodeAtPath(tab.doc.document, path);
1142
1184
  if (!node) {
1143
1185
  return emptyView(staleSelectionMessage(), "", []);
1144
1186
  }
@@ -1161,7 +1203,7 @@ function projectPanel(): ContentPanelView {
1161
1203
  }
1162
1204
 
1163
1205
  /** The Layout-element card — what the inspector says when you click page chrome. */
1164
- function layoutView(selection: LayoutSelection): ContentPanelView {
1206
+ function layoutView(selection: LayoutHit): ContentPanelView {
1165
1207
  const displayPath = selection.layoutFile || "layout";
1166
1208
  return {
1167
1209
  ...emptyContentView(),
@@ -1192,26 +1234,26 @@ function sectionsFor(node: JxMutableNode, path: JxPath): ContentSectionView[] {
1192
1234
  const bindableSignals = bindableSignalNames(doc);
1193
1235
 
1194
1236
  // ── Which attributes this tag has, by section ──
1195
- const applicableAttrs = {} as Record<string, HtmlMetaEntry>;
1196
- for (const [attr, entry] of Object.entries(htmlMeta.$defs) as [string, HtmlMetaEntry][]) {
1237
+ const applicableAttrs = new Map<string, HtmlMetaEntry>();
1238
+ for (const [attr, entry] of HTML_META_DEFS) {
1197
1239
  if (!entry.$elements || entry.$elements.includes(displayTagName(tagName))) {
1198
1240
  // The $attr field aliases a $defs key to a different attribute name, so the same attribute
1199
1241
  // (e.g. "name") can carry per-element metadata.
1200
- applicableAttrs[entry.$attr ?? attr] = entry;
1242
+ applicableAttrs.set(entry.$attr ?? attr, entry);
1201
1243
  }
1202
1244
  }
1203
1245
  const attrSections: Record<string, { name: string; entry: HtmlMetaEntry }[]> = {};
1204
1246
  for (const sec of htmlMeta.$sections) {
1205
1247
  attrSections[sec.key] = [];
1206
1248
  }
1207
- for (const [attr, entry] of Object.entries(applicableAttrs)) {
1249
+ for (const [attr, entry] of applicableAttrs) {
1208
1250
  attrSections[entry.$section]?.push({ entry, name: attr });
1209
1251
  }
1210
1252
  for (const sec of htmlMeta.$sections) {
1211
1253
  attrSections[sec.key]!.sort((a, b) => a.entry.$order - b.entry.$order);
1212
1254
  }
1213
1255
 
1214
- const knownAttrNames = new Set(Object.keys(applicableAttrs));
1256
+ const knownAttrNames = new Set(applicableAttrs.keys());
1215
1257
  if (isCustomInstance) {
1216
1258
  const comp = componentRegistry.find((c) => c.tagName === node.tagName);
1217
1259
  for (const p of comp?.props ?? []) {
@@ -1222,7 +1264,7 @@ function sectionsFor(node: JxMutableNode, path: JxPath): ContentSectionView[] {
1222
1264
 
1223
1265
  const autoOpen = new Set<string>();
1224
1266
  for (const attr of Object.keys(attrs)) {
1225
- const entry = applicableAttrs[attr];
1267
+ const entry = applicableAttrs.get(attr);
1226
1268
  if (entry) {
1227
1269
  autoOpen.add(entry.$section);
1228
1270
  }
@@ -1328,7 +1370,7 @@ function elementRows(
1328
1370
  node: JxMutableNode,
1329
1371
  path: JxPath,
1330
1372
  tagName: string,
1331
- mapSignals: SignalOption[] | null,
1373
+ mapSignals: SurfaceOption[] | null,
1332
1374
  bindableSignals: string[],
1333
1375
  ): ContentRowView[] {
1334
1376
  const chosenTag = isTagExpression(node.tagName) ? node.tagName.$expression : null;
@@ -1385,7 +1427,7 @@ function elementRows(
1385
1427
  ? { $expression: { initial: tagName, operator: "?:", target: null, value: tagName } }
1386
1428
  : undefined,
1387
1429
  stateDefs: bindableSignals,
1388
- value: node.tagName as JsonValue | undefined,
1430
+ value: node.tagName,
1389
1431
  });
1390
1432
  void chosenTag;
1391
1433
  rows.push(withPlan(tag.row, tag.plan));
@@ -1420,10 +1462,7 @@ function elementRows(
1420
1462
  const textDraft = draft(draftKey(path, "textContent"));
1421
1463
  const text = blankRow("prop|textContent", "textContent", "Text Content");
1422
1464
  text.kind = "textarea";
1423
- text.value = getFieldValue(
1424
- textDraft,
1425
- typeof node.textContent === "string" ? node.textContent : "",
1426
- );
1465
+ text.value = getFieldValue(textDraft, isString(node.textContent) ? node.textContent : "");
1427
1466
  const plan: RowPlan = {
1428
1467
  commit: writeProperty("textContent"),
1429
1468
  debounceMs: LIVE_PREVIEW,
@@ -1475,7 +1514,7 @@ function elementRows(
1475
1514
  function componentPropRows(
1476
1515
  node: JxMutableNode,
1477
1516
  path: JxPath,
1478
- mapSignals: SignalOption[] | null,
1517
+ mapSignals: SurfaceOption[] | null,
1479
1518
  definitionOfThis: boolean,
1480
1519
  ): ContentRowView[] {
1481
1520
  const tab = activeTab.value!;
@@ -1491,9 +1530,14 @@ function componentPropRows(
1491
1530
  const isNpm = comp.source === "npm";
1492
1531
  /* In the definition the "value" of a setting is its DECLARED DEFAULT — the state entry's
1493
1532
  `default` — not a per-instance override, so the row reads and writes there instead. */
1494
- const stateEntries = (tab.doc.document.state ?? {}) as Record<string, { default?: JsonValue }>;
1495
- const currentVals: Record<string, unknown> = definitionOfThis
1496
- ? Object.fromEntries(comp.props.map((prop) => [prop.name, stateEntries[prop.name]?.default]))
1533
+ const stateEntries = tab.doc.document.state ?? {};
1534
+ const currentVals: Readonly<Record<string, JxDocumentValue | undefined>> = definitionOfThis
1535
+ ? Object.fromEntries(
1536
+ comp.props.map((prop) => {
1537
+ const entry = stateEntries[prop.name];
1538
+ return [prop.name, isJsonObject(entry) ? entry.default : undefined];
1539
+ }),
1540
+ )
1497
1541
  : isNpm
1498
1542
  ? node.attributes || {}
1499
1543
  : node.$props || {};
@@ -1507,6 +1551,8 @@ function componentPropRows(
1507
1551
  t,
1508
1552
  path,
1509
1553
  name,
1554
+ /* SAFETY: `componentProp` offers the literal, ref and template rungs only, so what
1555
+ reaches here is a control's string or `true`, a `{ $ref }`, or a template string. */
1510
1556
  v === "" ? undefined : (v as JxAttributeValue | undefined),
1511
1557
  ),
1512
1558
  )
@@ -1537,7 +1583,9 @@ function componentPropRows(
1537
1583
  if (isMediaFormat(prop.format)) {
1538
1584
  row.kind = "control";
1539
1585
  plan.control = (host) =>
1540
- mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v));
1586
+ mountMediaPicker(host, prop.name, staticVal, (v: string) => onChange(v), {
1587
+ images: prop.format === "image",
1588
+ });
1541
1589
  } else if (prop.format === "color") {
1542
1590
  row.kind = "color";
1543
1591
  row.tokens = colorTokens();
@@ -1566,6 +1614,8 @@ function componentPropRows(
1566
1614
  row.value = staticVal;
1567
1615
  row.options = [
1568
1616
  CLEAR_OPTION,
1617
+ /* SAFETY: `parseCemType` returns kind "combobox" only with `options` read from the capture
1618
+ group of `'([^']*)'`, which takes part in every match, so each option is a string. */
1569
1619
  ...(parsed.options as string[]).map((o) => ({ label: camelToLabel(o), value: o })),
1570
1620
  ];
1571
1621
  plan.commit = (raw) => onChange(raw || undefined);
@@ -1599,7 +1649,7 @@ function componentPropRows(
1599
1649
  // "→ the component definition" would open the document already in front of you.
1600
1650
  isDefinition: definitionOfThis,
1601
1651
  onClear: () => updateFn(prop.name),
1602
- ...(openDefinition ? { openDefinition } : {}),
1652
+ openDefinition,
1603
1653
  }),
1604
1654
  );
1605
1655
  rows.push(withPlan(row, plan));
@@ -1633,14 +1683,14 @@ interface AttrCtx {
1633
1683
  doc: JxMutableNode;
1634
1684
  targets: JxPath[];
1635
1685
  tagName: string;
1636
- mapSignals: SignalOption[] | null;
1686
+ mapSignals: SurfaceOption[] | null;
1637
1687
  bindableSignals: string[];
1638
1688
  }
1639
1689
 
1640
1690
  function attributeRow(
1641
1691
  attr: string,
1642
1692
  entry: HtmlMetaEntry,
1643
- value: unknown,
1693
+ value: JxAttributeValue | undefined,
1644
1694
  ctx: AttrCtx,
1645
1695
  ): ContentRowView {
1646
1696
  const { doc, node, path, tagName, targets } = ctx;
@@ -1652,6 +1702,8 @@ function attributeRow(
1652
1702
  const commitAttr = (v?: JsonValue) =>
1653
1703
  transactDoc(activeTab.value!, (t) => {
1654
1704
  for (const target of targets) {
1705
+ /* SAFETY: `attribute` offers the literal, ref and template rungs only, so what reaches here
1706
+ is a control's string, a `{ $ref }`, or a template string. */
1655
1707
  mutateUpdateAttribute(t, target, attr, v as JxAttributeValue | undefined);
1656
1708
  }
1657
1709
  });
@@ -1680,14 +1732,8 @@ function attributeRow(
1680
1732
  if (attr === "target") {
1681
1733
  const row = blankRow(key, attr, label);
1682
1734
  row.kind = "select";
1683
- row.value = typeof node.attributes?.target === "string" ? node.attributes.target : "";
1684
- row.options = [
1685
- CLEAR_OPTION,
1686
- ...(Array.isArray(entry.enum) ? (entry.enum as string[]) : []).map((o) => ({
1687
- label: o,
1688
- value: o,
1689
- })),
1690
- ];
1735
+ row.value = isString(node.attributes?.target) ? node.attributes.target : "";
1736
+ row.options = [CLEAR_OPTION, ...(entry.enum ?? []).map((o) => ({ label: o, value: o }))];
1691
1737
  const plan: RowPlan = { commit: (raw) => commitAttr(raw || undefined), debounceMs: 0 };
1692
1738
  applyChip(row, plan, attr, chip());
1693
1739
  return withPlan(row, plan);
@@ -1699,10 +1745,10 @@ function attributeRow(
1699
1745
  if (entry.$input === "popover-target" && !isBoundAttrValue(value)) {
1700
1746
  const row = blankRow(key, attr, label);
1701
1747
  row.kind = "select";
1702
- row.value = typeof value === "string" ? value : "";
1748
+ row.value = isString(value) ? value : "";
1703
1749
  row.options = [
1704
1750
  CLEAR_OPTION,
1705
- ...popoverIdsIn((activeTab.value?.doc.document ?? {}) as JxElement, {
1751
+ ...popoverIdsIn(activeTab.value?.doc.document ?? {}, {
1706
1752
  popoverTags: POPOVER_TAGS,
1707
1753
  }).map((id) => ({ label: id, value: id })),
1708
1754
  { label: "Type an id…", value: POPOVER_TARGET_OTHER },
@@ -1740,17 +1786,13 @@ function attributeRow(
1740
1786
  row.kind = "control";
1741
1787
  const staticVal = isRef(value) ? "" : String(value || "");
1742
1788
  plan.control = (host) =>
1743
- mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined));
1789
+ mountMediaPicker(host, attr, staticVal, (v: string) => commitAttr(v || undefined), {
1790
+ images: entry.format === "image",
1791
+ });
1744
1792
  } else if (type === "select") {
1745
1793
  row.kind = "select";
1746
1794
  row.value = isRef(value) ? "" : String(value || "");
1747
- row.options = [
1748
- CLEAR_OPTION,
1749
- ...(Array.isArray(entry.enum) ? (entry.enum as string[]) : []).map((o) => ({
1750
- label: o,
1751
- value: o,
1752
- })),
1753
- ];
1795
+ row.options = [CLEAR_OPTION, ...(entry.enum ?? []).map((o) => ({ label: o, value: o }))];
1754
1796
  plan.commit = (raw) => commitAttr(raw || undefined);
1755
1797
  plan.debounceMs = 0;
1756
1798
  } else {
@@ -1772,6 +1814,15 @@ function attributeRow(
1772
1814
  return withPlan(row, plan);
1773
1815
  }
1774
1816
 
1817
+ /** The Link row's kinds, in the order its picker lists them. */
1818
+ const LINK_KIND_OPTIONS = [
1819
+ { label: "Internal Page", value: "internal" },
1820
+ { label: "External URL", value: "external" },
1821
+ { label: "Anchor", value: "anchor" },
1822
+ { label: "Email", value: "mailto" },
1823
+ { label: "Phone", value: "tel" },
1824
+ ] as const satisfies readonly { label: string; value: LinkKind }[];
1825
+
1775
1826
  /**
1776
1827
  * The Link target: a kind and a value over one `href`.
1777
1828
  *
@@ -1780,7 +1831,7 @@ function attributeRow(
1780
1831
  * `mailto:a@b.com`. Internal targets offer the routes enumerated from the `pages/` tree.
1781
1832
  */
1782
1833
  function linkRow(key: string, label: string, node: JxMutableNode, path: JxPath): ContentRowView {
1783
- const raw = typeof node.attributes?.href === "string" ? node.attributes.href : "";
1834
+ const raw = isString(node.attributes?.href) ? node.attributes.href : "";
1784
1835
  const { kind, value } = classifyHref(raw);
1785
1836
  const commit = (nextKind: LinkKind, nextValue: string) => {
1786
1837
  const composed = composeHref(nextKind, nextValue);
@@ -1792,16 +1843,16 @@ function linkRow(key: string, label: string, node: JxMutableNode, path: JxPath):
1792
1843
  const row = blankRow(key, "href", label);
1793
1844
  row.kind = "link";
1794
1845
  row.linkKind = kind;
1795
- row.kindOptions = [
1796
- { label: "Internal Page", value: "internal" },
1797
- { label: "External URL", value: "external" },
1798
- { label: "Anchor", value: "anchor" },
1799
- { label: "Email", value: "mailto" },
1800
- { label: "Phone", value: "tel" },
1801
- ];
1846
+ row.kindOptions = LINK_KIND_OPTIONS.map((option) => ({ ...option }));
1802
1847
  const plan: RowPlan = {
1803
1848
  commit: (next) => commit(kind, next),
1804
- commitKind: (nextKind) => commit(nextKind as LinkKind, value),
1849
+ commitKind: (nextKind) => {
1850
+ // The picker's options ARE `LINK_KIND_OPTIONS`, so a picked kind is always one of them.
1851
+ const picked = LINK_KIND_OPTIONS.find((option) => option.value === nextKind);
1852
+ if (picked) {
1853
+ commit(picked.value, value);
1854
+ }
1855
+ },
1805
1856
  debounceMs: INPUT_DEBOUNCE,
1806
1857
  };
1807
1858
 
@@ -1854,7 +1905,7 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
1854
1905
  const nameKey = draft(`kvname:${path.join("/")}:${attr}`);
1855
1906
  const valueKey = draft(`kvval:${path.join("/")}:${attr}`);
1856
1907
  const row = blankRow(key, attr, `${attr} value`);
1857
- row.shape = "kv";
1908
+ row.variant = "kv";
1858
1909
  row.name = getFieldValue(nameKey, attr);
1859
1910
  row.value = getFieldValue(valueKey, String(val));
1860
1911
  row.removeLabel = `Remove ${attr}`;
@@ -1890,6 +1941,15 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
1890
1941
 
1891
1942
  // ─── Usage (§9.1.1) ──────────────────────────────────────────────────────────
1892
1943
 
1944
+ /** The usage question for a component: its tag, and its definition file when the library knows it. */
1945
+ function usageQueryFor(tagName: string, componentPath: string | null): UsageQuery {
1946
+ const query: UsageQuery = { tagName };
1947
+ if (componentPath) {
1948
+ query.path = componentPath;
1949
+ }
1950
+ return query;
1951
+ }
1952
+
1893
1953
  /**
1894
1954
  * The component instance's usage line — "Used on 7 pages →", expanding to the files.
1895
1955
  *
@@ -1901,7 +1961,7 @@ function customRows(path: JxPath, customAttrs: [string, unknown][]): ContentRowV
1901
1961
  * check" and "nothing uses this" are the two answers a user must never confuse.
1902
1962
  */
1903
1963
  function usagesSection(tagName: string, componentPath: string | null): ContentSectionView | null {
1904
- const query = { tagName, ...(componentPath ? { path: componentPath } : {}) };
1964
+ const query = usageQueryFor(tagName, componentPath);
1905
1965
  const state = peekUsages(query);
1906
1966
  // ONE gate, and it is the peek itself: a host with no `findReferences` answers "unsupported"
1907
1967
  // Synchronously, and the section does not exist.
@@ -1936,7 +1996,7 @@ function usagesSection(tagName: string, componentPath: string | null): ContentSe
1936
1996
  } else {
1937
1997
  for (const file of files) {
1938
1998
  const row = blankRow(`usage|${file.path}`, file.path, file.path);
1939
- row.shape = "file";
1999
+ row.variant = "file";
1940
2000
  row.text = file.path;
1941
2001
  row.detail = String(file.count);
1942
2002
  row.title = file.refs.map((r) => `${r.refType} ${r.ref} ×${r.count}`).join(", ");
@@ -1957,7 +2017,7 @@ function usagesSection(tagName: string, componentPath: string | null): ContentSe
1957
2017
 
1958
2018
  function noteRow(key: string, text: string): ContentRowView {
1959
2019
  const row = blankRow(key, key, "");
1960
- row.shape = "note";
2020
+ row.variant = "note";
1961
2021
  row.text = text;
1962
2022
  plans.set(key, { debounceMs: 0 });
1963
2023
  return row;
@@ -1965,7 +2025,7 @@ function noteRow(key: string, text: string): ContentRowView {
1965
2025
 
1966
2026
  function actionRow(key: string, prop: string, text: string, run: () => void): ContentRowView {
1967
2027
  const row = blankRow(key, prop, text);
1968
- row.shape = "action";
2028
+ row.variant = "action";
1969
2029
  row.text = text;
1970
2030
  return withPlan(row, { action: run, debounceMs: 0 });
1971
2031
  }
@@ -2030,9 +2090,7 @@ export function inspectorCommands(): AnyCommand[] {
2030
2090
  }
2031
2091
  const componentPath = componentRegistry.find((c) => c.tagName === tagName)?.path ?? null;
2032
2092
  setInspectorSection(USAGES_SECTION, true);
2033
- void loadUsages({ tagName, ...(componentPath ? { path: componentPath } : {}) }).then(() =>
2034
- renderPropertiesPanel(),
2035
- );
2093
+ void loadUsages(usageQueryFor(tagName, componentPath)).then(() => renderPropertiesPanel());
2036
2094
  },
2037
2095
  title: "Find Usages",
2038
2096
  },
@@ -2053,8 +2111,8 @@ function componentSelectionTag(): string | null {
2053
2111
  if (!tab || !selection) {
2054
2112
  return null;
2055
2113
  }
2056
- const node = getNodeAtPath(tab.doc.document, selection);
2057
- const tagName = typeof node?.tagName === "string" ? node.tagName : "";
2114
+ const node = nodeAtPath(tab.doc.document, selection);
2115
+ const tagName = isString(node?.tagName) ? node.tagName : "";
2058
2116
  return tagName.includes("-") ? tagName : null;
2059
2117
  }
2060
2118