@jxsuite/studio 6.1.1 → 6.1.2

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 (637) hide show
  1. package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +97 -97
  140. package/package.json +6 -6
  141. package/src/about/about-modal.ts +4 -3
  142. package/src/account/action-flow.ts +45 -38
  143. package/src/account-status.ts +7 -2
  144. package/src/browse/library-layouts.ts +8 -5
  145. package/src/browse/library-model.ts +18 -6
  146. package/src/browse/library-pane.ts +37 -21
  147. package/src/browse/library-preview.ts +14 -9
  148. package/src/browse/library-source.ts +1 -1
  149. package/src/canvas/asset-refs.ts +24 -9
  150. package/src/canvas/asset-resolve.ts +19 -23
  151. package/src/canvas/canvas-helpers.ts +7 -6
  152. package/src/canvas/canvas-live-render.ts +44 -53
  153. package/src/canvas/canvas-patcher.ts +30 -30
  154. package/src/canvas/canvas-perf.ts +11 -5
  155. package/src/canvas/canvas-render.ts +62 -41
  156. package/src/canvas/canvas-surface.ts +5 -3
  157. package/src/canvas/canvas-utils.ts +90 -49
  158. package/src/canvas/dialog-path.ts +9 -4
  159. package/src/canvas/dialog-state.ts +1 -2
  160. package/src/canvas/diff-marks.ts +9 -16
  161. package/src/canvas/diff-toolbar.ts +8 -7
  162. package/src/canvas/edit-width-drag.ts +4 -1
  163. package/src/canvas/edit-width.ts +1 -3
  164. package/src/canvas/iframe-channel.ts +27 -13
  165. package/src/canvas/iframe-drop.ts +13 -12
  166. package/src/canvas/iframe-editable-root.ts +29 -16
  167. package/src/canvas/iframe-entry.ts +80 -63
  168. package/src/canvas/iframe-eval.ts +73 -49
  169. package/src/canvas/iframe-host.ts +135 -96
  170. package/src/canvas/iframe-inline-edit.ts +49 -30
  171. package/src/canvas/iframe-insert.ts +5 -4
  172. package/src/canvas/iframe-interaction.ts +30 -25
  173. package/src/canvas/iframe-overlay.ts +1 -1
  174. package/src/canvas/iframe-patch.ts +18 -15
  175. package/src/canvas/iframe-position.ts +12 -6
  176. package/src/canvas/iframe-protocol.ts +12 -16
  177. package/src/canvas/iframe-render.ts +36 -34
  178. package/src/canvas/iframe-slash.ts +24 -11
  179. package/src/canvas/iframe-subtree.ts +6 -2
  180. package/src/canvas/path-mapping.ts +19 -12
  181. package/src/canvas/popover-path.ts +7 -3
  182. package/src/canvas/popover-state.ts +1 -2
  183. package/src/canvas/serialize-scope.ts +13 -5
  184. package/src/canvas/stage-scrollbar.ts +2 -1
  185. package/src/canvas/surface-registry.ts +21 -3
  186. package/src/collab/collab-commands.ts +7 -2
  187. package/src/collab/collab-session.ts +84 -45
  188. package/src/collab/collab-state.ts +4 -3
  189. package/src/collab/monaco-binding.ts +16 -13
  190. package/src/collab/monaco-cursors.ts +5 -2
  191. package/src/commands/budget.ts +3 -3
  192. package/src/commands/command-args.ts +103 -71
  193. package/src/commands/context.ts +22 -20
  194. package/src/commands/keymap.ts +47 -43
  195. package/src/commands/levels.ts +3 -3
  196. package/src/commands/live-context.ts +7 -7
  197. package/src/commands/reference.ts +2 -1
  198. package/src/commands/registry.ts +12 -10
  199. package/src/commands/run-reported.ts +15 -10
  200. package/src/component-props.ts +46 -30
  201. package/src/content/collection-match.ts +5 -4
  202. package/src/content/draft-state.ts +4 -3
  203. package/src/content/entry-commands.ts +3 -2
  204. package/src/content/entry-editor.ts +29 -17
  205. package/src/content/entry-fields.ts +12 -7
  206. package/src/content/entry-model.ts +21 -12
  207. package/src/editor/canvas-context-menu.ts +1 -2
  208. package/src/editor/canvas-slash-bridge.ts +3 -6
  209. package/src/editor/content-slice.ts +16 -14
  210. package/src/editor/context-menu.ts +35 -22
  211. package/src/editor/convert-targets.ts +30 -35
  212. package/src/editor/convert-to-component.ts +11 -5
  213. package/src/editor/convert-to-repeater.ts +34 -22
  214. package/src/editor/editable-tags.ts +17 -2
  215. package/src/editor/file-drop-action.ts +21 -22
  216. package/src/editor/inline-edit-apply.ts +35 -17
  217. package/src/editor/inline-edit.ts +66 -50
  218. package/src/editor/inline-format.ts +59 -56
  219. package/src/editor/inline-link.ts +40 -15
  220. package/src/editor/insert-zone-action.ts +1 -1
  221. package/src/editor/merge-tags.ts +58 -19
  222. package/src/editor/repeater-scope.ts +39 -28
  223. package/src/editor/shortcuts.ts +32 -20
  224. package/src/editor/slash-menu.ts +1 -6
  225. package/src/files/asset-versions.ts +4 -4
  226. package/src/files/components.ts +15 -10
  227. package/src/files/elements.ts +5 -6
  228. package/src/files/file-ops.ts +77 -36
  229. package/src/files/files.ts +90 -95
  230. package/src/files/media-meta.ts +2 -1
  231. package/src/files/media-paths.ts +3 -0
  232. package/src/files/serialize-document.ts +2 -2
  233. package/src/format/constraints.ts +1 -1
  234. package/src/format/convert-file.ts +27 -13
  235. package/src/format/format-choices.ts +2 -1
  236. package/src/format/format-host.ts +76 -50
  237. package/src/github/github-auth-status.ts +27 -3
  238. package/src/github/github-auth.ts +19 -9
  239. package/src/github/github-publish.ts +24 -20
  240. package/src/grid/cell-editors.ts +46 -31
  241. package/src/grid/cell-popovers.ts +5 -3
  242. package/src/grid/edit-buffer.ts +10 -9
  243. package/src/grid/grid-controller.ts +20 -22
  244. package/src/grid/grid-layout.ts +21 -5
  245. package/src/grid/grid-open.ts +3 -6
  246. package/src/grid/grid-panel.ts +11 -4
  247. package/src/grid/grid-source.ts +8 -8
  248. package/src/grid/grid-view.ts +14 -17
  249. package/src/grid/redirects-grid.ts +14 -5
  250. package/src/grid/redirects.ts +16 -14
  251. package/src/grid/schema-columns.ts +25 -19
  252. package/src/grid/sources/connector-source.ts +47 -20
  253. package/src/grid/sources/content-source.ts +25 -24
  254. package/src/grid/sources/csv-file-source.ts +2 -2
  255. package/src/grid/tabulator-tables.d.ts +55 -34
  256. package/src/hosting/stage.ts +7 -7
  257. package/src/i18n/i18n-commands.ts +1 -2
  258. package/src/media/media-pane.ts +4 -1
  259. package/src/new-project/add-repo-modal.ts +20 -19
  260. package/src/new-project/import-tab.ts +10 -14
  261. package/src/new-project/location-fields.ts +2 -1
  262. package/src/new-project/new-project-modal.ts +12 -9
  263. package/src/packages/jxsuite-update.ts +4 -3
  264. package/src/packages/pull-package-sync.ts +26 -25
  265. package/src/page-params.ts +97 -68
  266. package/src/panels/activity-panel.ts +17 -9
  267. package/src/panels/ai-chat/attached-context.ts +13 -7
  268. package/src/panels/ai-chat/chat-view.ts +80 -73
  269. package/src/panels/ai-chat/composer.ts +30 -33
  270. package/src/panels/ai-chat/sessions-view.ts +1 -2
  271. package/src/panels/ai-panel.ts +23 -20
  272. package/src/panels/block-action-bar.ts +46 -35
  273. package/src/panels/bottom-dock.ts +5 -3
  274. package/src/panels/canvas-dnd-bridge.ts +31 -24
  275. package/src/panels/data-explorer.ts +62 -25
  276. package/src/panels/data-grid.ts +14 -11
  277. package/src/panels/dnd.ts +108 -118
  278. package/src/panels/editors.ts +52 -21
  279. package/src/panels/elements-panel.ts +10 -3
  280. package/src/panels/events-panel.ts +84 -69
  281. package/src/panels/formula-workspace.ts +76 -51
  282. package/src/panels/frontmatter-fields.ts +24 -19
  283. package/src/panels/frontmatter-panel.ts +44 -34
  284. package/src/panels/git-diff-open.ts +4 -4
  285. package/src/panels/git-panel.ts +49 -61
  286. package/src/panels/head-panel.ts +131 -111
  287. package/src/panels/i18n-panel.ts +10 -3
  288. package/src/panels/imports-panel.ts +23 -47
  289. package/src/panels/jump-bar.ts +48 -29
  290. package/src/panels/layers-panel.ts +97 -74
  291. package/src/panels/left-panel.ts +3 -3
  292. package/src/panels/pane-context.ts +31 -22
  293. package/src/panels/pane-grid.ts +49 -20
  294. package/src/panels/panel-registry.ts +22 -37
  295. package/src/panels/properties-panel.ts +175 -121
  296. package/src/panels/quick-search.ts +53 -31
  297. package/src/panels/right-panel.ts +3 -3
  298. package/src/panels/seo-modal.ts +13 -17
  299. package/src/panels/settings-menu.ts +15 -15
  300. package/src/panels/signals-panel.ts +153 -131
  301. package/src/panels/statement-editor.ts +230 -140
  302. package/src/panels/style-panel.ts +218 -205
  303. package/src/panels/style-utils.ts +114 -51
  304. package/src/panels/stylebook-doc.ts +57 -54
  305. package/src/panels/stylebook-layers-panel.ts +9 -9
  306. package/src/panels/stylebook-panel.ts +13 -17
  307. package/src/panels/tab-drop.ts +27 -11
  308. package/src/panels/tab-strip.ts +36 -26
  309. package/src/platform-errors.ts +57 -43
  310. package/src/platform.ts +58 -30
  311. package/src/platforms/cloud.ts +345 -175
  312. package/src/platforms/default-platform.ts +10 -4
  313. package/src/platforms/devserver.ts +129 -117
  314. package/src/platforms/read-batcher.ts +16 -8
  315. package/src/project-list.ts +2 -1
  316. package/src/publish/deploy-checklist.ts +8 -2
  317. package/src/publish/pages-service.ts +28 -13
  318. package/src/publish/publish-commands.ts +5 -4
  319. package/src/publish/publish-panel.ts +10 -6
  320. package/src/recent-projects.ts +15 -8
  321. package/src/resize-edges.ts +26 -36
  322. package/src/services/a11y-report.ts +26 -19
  323. package/src/services/agent-seed.ts +23 -11
  324. package/src/services/ai-ask.ts +9 -12
  325. package/src/services/ai-command-tools.ts +68 -62
  326. package/src/services/ai-import-tools.ts +80 -67
  327. package/src/services/ai-models.ts +17 -13
  328. package/src/services/ai-project-tools.ts +68 -32
  329. package/src/services/ai-session-store.ts +19 -10
  330. package/src/services/ai-system-prompt.ts +46 -20
  331. package/src/services/ai-tools.ts +71 -27
  332. package/src/services/ai-write-report.ts +20 -12
  333. package/src/services/ai-writes.ts +4 -4
  334. package/src/services/automation.ts +58 -31
  335. package/src/services/cem-export.ts +149 -58
  336. package/src/services/clock.ts +6 -1
  337. package/src/services/code-services.ts +37 -31
  338. package/src/services/context-manager.ts +14 -10
  339. package/src/services/context-resolver.ts +20 -8
  340. package/src/services/data-service.ts +19 -15
  341. package/src/services/directory-picker.ts +18 -12
  342. package/src/services/document-assistant.ts +39 -19
  343. package/src/services/gated-registry.ts +10 -6
  344. package/src/services/harness/chat-reducer.ts +23 -1
  345. package/src/services/import-client.ts +91 -38
  346. package/src/services/import-seed.ts +8 -2
  347. package/src/services/jx-validate.ts +28 -31
  348. package/src/services/live-preview.ts +0 -0
  349. package/src/services/live-surfaces.ts +6 -3
  350. package/src/services/model-uri.ts +10 -2
  351. package/src/services/module-preloads.ts +12 -8
  352. package/src/services/monaco-buffer.ts +43 -24
  353. package/src/services/monaco-lazy.ts +7 -8
  354. package/src/services/monaco-setup.ts +23 -16
  355. package/src/services/notify.ts +44 -17
  356. package/src/services/popover-report.ts +25 -10
  357. package/src/services/preview-eval.ts +20 -8
  358. package/src/services/profile.ts +13 -6
  359. package/src/services/project-path.ts +13 -10
  360. package/src/services/references.ts +0 -0
  361. package/src/services/render-critic.ts +8 -7
  362. package/src/services/settings/kernel.ts +13 -4
  363. package/src/services/settings/write-queue.ts +9 -9
  364. package/src/services/token-lint.ts +12 -10
  365. package/src/services/tool-executor.ts +17 -5
  366. package/src/services/tool-outcomes.ts +44 -24
  367. package/src/services/trusted-types.ts +24 -7
  368. package/src/settings/contexts-section.ts +11 -8
  369. package/src/settings/contributed-section.ts +79 -60
  370. package/src/settings/css-vars-editor.ts +37 -16
  371. package/src/settings/defs-editor.ts +38 -35
  372. package/src/settings/extension-rows.ts +16 -8
  373. package/src/settings/extension-sections.ts +23 -13
  374. package/src/settings/extensions-section.ts +4 -1
  375. package/src/settings/general-settings.ts +11 -8
  376. package/src/settings/locales-section.ts +20 -12
  377. package/src/settings/preferences-dialog.ts +9 -6
  378. package/src/settings/preferences-keymap.ts +7 -5
  379. package/src/settings/preferences-sections.ts +11 -5
  380. package/src/settings/project-sections.ts +1 -1
  381. package/src/settings/schema-field-ui.ts +9 -0
  382. package/src/settings/settings-document.ts +5 -5
  383. package/src/shell/tree.ts +6 -5
  384. package/src/shell.ts +104 -81
  385. package/src/site-context.ts +37 -22
  386. package/src/state.ts +41 -49
  387. package/src/store.ts +54 -34
  388. package/src/studio.ts +25 -75
  389. package/src/style/live-preview.ts +1 -1
  390. package/src/style/project-styles.ts +6 -7
  391. package/src/style/token-ref.ts +5 -4
  392. package/src/surfaces/about.ts +18 -19
  393. package/src/surfaces/add-repo.ts +17 -19
  394. package/src/surfaces/ai-chat.ts +31 -36
  395. package/src/surfaces/ai-credentials-form.ts +6 -16
  396. package/src/surfaces/ai-managed-connect.ts +3 -4
  397. package/src/surfaces/ai-model-picker.ts +3 -5
  398. package/src/surfaces/block-action-bar.ts +22 -11
  399. package/src/surfaces/boot-failure.ts +4 -5
  400. package/src/surfaces/bottom-dock.ts +9 -18
  401. package/src/surfaces/canvas-stage.ts +12 -11
  402. package/src/surfaces/cf-account-picker.ts +17 -18
  403. package/src/surfaces/commandbar.ts +14 -9
  404. package/src/surfaces/convert-repeater.ts +17 -19
  405. package/src/surfaces/data-actions.ts +9 -7
  406. package/src/surfaces/dialog.ts +26 -28
  407. package/src/surfaces/diff-toolbar.ts +9 -7
  408. package/src/surfaces/doc-header.ts +10 -19
  409. package/src/surfaces/empty-state.ts +7 -10
  410. package/src/surfaces/entry-editor.ts +14 -11
  411. package/src/surfaces/expression-editor.ts +11 -25
  412. package/src/surfaces/files-panel.ts +27 -14
  413. package/src/surfaces/formula-palette.ts +4 -5
  414. package/src/surfaces/git-panel.ts +7 -15
  415. package/src/surfaces/github-auth.ts +16 -20
  416. package/src/surfaces/github-publish.ts +17 -22
  417. package/src/surfaces/grid-cell.ts +30 -31
  418. package/src/surfaces/grid-open.ts +10 -14
  419. package/src/surfaces/grid-panel.ts +13 -9
  420. package/src/surfaces/grid-replace.ts +13 -13
  421. package/src/surfaces/grid-views.ts +15 -18
  422. package/src/surfaces/inspector-dock.ts +13 -12
  423. package/src/surfaces/jump-bar.ts +5 -6
  424. package/src/surfaces/jxsuite-update.ts +16 -22
  425. package/src/surfaces/library-pane.ts +19 -20
  426. package/src/surfaces/logic-panel.ts +17 -30
  427. package/src/surfaces/logic-workspace.ts +13 -15
  428. package/src/surfaces/media-browser.ts +11 -10
  429. package/src/surfaces/media-field.ts +4 -5
  430. package/src/surfaces/media-pane.ts +8 -7
  431. package/src/surfaces/menu.ts +29 -23
  432. package/src/surfaces/navigator-dock.ts +11 -12
  433. package/src/surfaces/new-project.ts +27 -26
  434. package/src/surfaces/pane-context.ts +20 -25
  435. package/src/surfaces/pane-grid.ts +15 -10
  436. package/src/surfaces/panel-activity.ts +5 -6
  437. package/src/surfaces/panel-data.ts +3 -4
  438. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  439. package/src/surfaces/panel-elements.ts +5 -7
  440. package/src/surfaces/panel-i18n.ts +5 -7
  441. package/src/surfaces/panel-imports.ts +6 -13
  442. package/src/surfaces/panel-outline.ts +25 -19
  443. package/src/surfaces/panel-page.ts +11 -18
  444. package/src/surfaces/panel-problems.ts +5 -7
  445. package/src/surfaces/panel-signals.ts +20 -34
  446. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  447. package/src/surfaces/preferences.ts +21 -11
  448. package/src/surfaces/progress-modal.ts +15 -9
  449. package/src/surfaces/properties-panel.json +1 -1
  450. package/src/surfaces/properties-panel.ts +20 -42
  451. package/src/surfaces/publish.ts +18 -18
  452. package/src/surfaces/push-plan.ts +7 -8
  453. package/src/surfaces/rail.ts +13 -13
  454. package/src/surfaces/reference-field.ts +11 -15
  455. package/src/surfaces/schema-builder.ts +16 -22
  456. package/src/surfaces/schema-form.ts +15 -25
  457. package/src/surfaces/secret-field.ts +9 -6
  458. package/src/surfaces/seo.ts +21 -15
  459. package/src/surfaces/settings-contexts.ts +9 -7
  460. package/src/surfaces/settings-contributed.ts +14 -10
  461. package/src/surfaces/settings-css-vars.ts +5 -12
  462. package/src/surfaces/settings-defs.json +2 -2
  463. package/src/surfaces/settings-defs.ts +17 -21
  464. package/src/surfaces/settings-deploy.ts +8 -15
  465. package/src/surfaces/settings-extensions.ts +5 -6
  466. package/src/surfaces/settings-head.ts +33 -39
  467. package/src/surfaces/settings-locales.ts +8 -20
  468. package/src/surfaces/settings-overview.ts +5 -6
  469. package/src/surfaces/settings-packages.ts +8 -7
  470. package/src/surfaces/settings-pane.ts +9 -18
  471. package/src/surfaces/settings-rawjson.ts +5 -6
  472. package/src/surfaces/shell.ts +1 -2
  473. package/src/surfaces/slash-menu.ts +19 -9
  474. package/src/surfaces/statements.ts +13 -18
  475. package/src/surfaces/statusbar.ts +17 -14
  476. package/src/surfaces/style-panel.ts +18 -31
  477. package/src/surfaces/stylebook-chrome.ts +3 -5
  478. package/src/surfaces/tab-strip.ts +14 -13
  479. package/src/surfaces/target-line.ts +6 -7
  480. package/src/surfaces/welcome.ts +5 -7
  481. package/src/tabs/patch-ops.ts +4 -3
  482. package/src/tabs/project-config.ts +32 -21
  483. package/src/tabs/selection.ts +36 -8
  484. package/src/tabs/tab.ts +52 -41
  485. package/src/tabs/transact.ts +98 -53
  486. package/src/types.ts +32 -17
  487. package/src/ui/ai-credentials-form.ts +10 -13
  488. package/src/ui/ai-model-picker.ts +3 -3
  489. package/src/ui/cf-account-picker.ts +7 -9
  490. package/src/ui/color-selector.ts +9 -5
  491. package/src/ui/dynamic-slot.ts +7 -8
  492. package/src/ui/expression-editor.ts +112 -105
  493. package/src/ui/form-controls.ts +57 -48
  494. package/src/ui/formula-catalog.ts +239 -230
  495. package/src/ui/formula-chips.ts +33 -18
  496. package/src/ui/layers.ts +44 -31
  497. package/src/ui/media-picker.ts +18 -9
  498. package/src/ui/popover-surface.ts +20 -12
  499. package/src/ui/progress-modal.ts +13 -8
  500. package/src/ui/regions.ts +7 -6
  501. package/src/ui/schema-form.ts +113 -70
  502. package/src/ui/surface.ts +71 -8
  503. package/src/ui/timing.ts +9 -0
  504. package/src/ui/value-source.ts +44 -31
  505. package/src/ui/virtual-window.ts +3 -2
  506. package/src/utils/base64.ts +3 -1
  507. package/src/utils/edit-display.ts +73 -73
  508. package/src/utils/element-selectors.ts +3 -2
  509. package/src/utils/google-fonts.ts +15 -14
  510. package/src/utils/inherited-style.ts +18 -20
  511. package/src/utils/link-target.ts +1 -1
  512. package/src/utils/preview-format.ts +25 -3
  513. package/src/utils/strip-events.ts +49 -22
  514. package/src/utils/studio-utils.ts +29 -14
  515. package/src/view.ts +2 -3
  516. package/src/workspace/pane-derive.ts +10 -12
  517. package/src/workspace/session.ts +53 -43
  518. package/src/workspace/workspace.ts +40 -36
  519. package/dist/chunks/adapter-f93pafd7.js +0 -4
  520. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  521. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  522. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  523. package/dist/chunks/color-field-embq5ctg.js +0 -4
  524. package/dist/chunks/color-fpezvnkt.js +0 -4
  525. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  526. package/dist/chunks/combobox-773hdzyj.js +0 -4
  527. package/dist/chunks/components-ax2f1fnn.js +0 -4
  528. package/dist/chunks/content-source-108aqtk1.js +0 -4
  529. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  530. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  531. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  532. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  533. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  534. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  535. package/dist/chunks/files-44vp8a2s.js +0 -4
  536. package/dist/chunks/format-host-7q1petb9.js +0 -4
  537. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  538. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  539. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  540. package/dist/chunks/icons-p44xhjf0.js +0 -4
  541. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  542. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  543. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  544. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  545. package/dist/chunks/index-wkyfjeqz.js +0 -4
  546. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  547. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  548. package/dist/chunks/layers-xd92fg8d.js +0 -4
  549. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  550. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  551. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  552. package/dist/chunks/menu-37d07z9m.js +0 -4
  553. package/dist/chunks/menu-5c55ea3d.js +0 -4
  554. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  555. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  556. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  557. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  558. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  559. package/dist/chunks/parse-897fvqah.js +0 -4
  560. package/dist/chunks/platform-v1qctbe6.js +0 -4
  561. package/dist/chunks/popover-8htra4er.js +0 -4
  562. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  563. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  564. package/dist/chunks/references-gmqp82fs.js +0 -4
  565. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  566. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  567. package/dist/chunks/select-n3v7gwas.js +0 -4
  568. package/dist/chunks/split-pff8f3ze.js +0 -4
  569. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  570. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  571. package/dist/chunks/studio-1b04pd0j.js +0 -64
  572. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  573. package/dist/chunks/studio-4tanh828.js +0 -5
  574. package/dist/chunks/studio-55h4mstj.js +0 -4
  575. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  576. package/dist/chunks/studio-60dqgb0c.js +0 -5
  577. package/dist/chunks/studio-61dp09qg.js +0 -9
  578. package/dist/chunks/studio-63epcrj2.js +0 -5
  579. package/dist/chunks/studio-74k29dy9.js +0 -5
  580. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  581. package/dist/chunks/studio-7zx31knw.js +0 -9
  582. package/dist/chunks/studio-8bxk97km.js +0 -5
  583. package/dist/chunks/studio-933e30n4.js +0 -5
  584. package/dist/chunks/studio-98wnwhbg.js +0 -5
  585. package/dist/chunks/studio-9mccjwjh.js +0 -14
  586. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  587. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  588. package/dist/chunks/studio-e81q1vb9.js +0 -5
  589. package/dist/chunks/studio-epgrmqqm.js +0 -5
  590. package/dist/chunks/studio-ery42sqr.js +0 -4
  591. package/dist/chunks/studio-g1shz58g.js +0 -5
  592. package/dist/chunks/studio-gf0fz03c.js +0 -5
  593. package/dist/chunks/studio-gjtpe62q.js +0 -6
  594. package/dist/chunks/studio-gkskhg7m.js +0 -5
  595. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  596. package/dist/chunks/studio-j03zga3y.js +0 -9
  597. package/dist/chunks/studio-jhpxeckz.js +0 -5
  598. package/dist/chunks/studio-k01r7ykp.js +0 -5
  599. package/dist/chunks/studio-kk7h30ne.js +0 -7
  600. package/dist/chunks/studio-kt1zqney.js +0 -5
  601. package/dist/chunks/studio-m3cwhvye.js +0 -5
  602. package/dist/chunks/studio-mcayt6hz.js +0 -5
  603. package/dist/chunks/studio-myjcghv3.js +0 -5
  604. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  605. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  606. package/dist/chunks/studio-nj5a01jy.js +0 -928
  607. package/dist/chunks/studio-pcgz8heb.js +0 -5
  608. package/dist/chunks/studio-qcsq0t15.js +0 -5
  609. package/dist/chunks/studio-qkstvve9.js +0 -5
  610. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  611. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  612. package/dist/chunks/studio-s8dmmz66.js +0 -5
  613. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  614. package/dist/chunks/studio-szsjbj0g.js +0 -5
  615. package/dist/chunks/studio-t1xzawhr.js +0 -16
  616. package/dist/chunks/studio-t6b6qe31.js +0 -5
  617. package/dist/chunks/studio-tdcprbqb.js +0 -5
  618. package/dist/chunks/studio-vyc0b4he.js +0 -10
  619. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  620. package/dist/chunks/studio-w3hskzqk.js +0 -5
  621. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  622. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  623. package/dist/chunks/studio-y6n42tgs.js +0 -5
  624. package/dist/chunks/studio-yb560vxr.js +0 -5
  625. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  626. package/dist/chunks/studio-yw05w8f0.js +0 -7
  627. package/dist/chunks/studio-z16sgavc.js +0 -5
  628. package/dist/chunks/studio-zyqn40w4.js +0 -5
  629. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  630. package/dist/chunks/tabs-jwthg40w.js +0 -4
  631. package/dist/chunks/textfield-spy3hc77.js +0 -4
  632. package/dist/chunks/toast-4d35zd64.js +0 -4
  633. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  634. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  635. package/dist/chunks/tree-h19v1jfz.js +0 -4
  636. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  637. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/studio",
3
- "version": "6.1.1",
3
+ "version": "6.1.2",
4
4
  "description": "Jx Studio — visual builder for Jx documents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -71,7 +71,7 @@
71
71
  "@jxsuite/schema": "^3.0.0",
72
72
  "@jxsuite/site": "^2.0.4",
73
73
  "@jxsuite/ui": "^0.5.1",
74
- "@vue/reactivity": "3.5.43",
74
+ "@vue/reactivity": "3.5.44",
75
75
  "ajv": "^8.20.0",
76
76
  "ajv-formats": "^3.0.1",
77
77
  "lit-html": "^3.3.3",
@@ -80,11 +80,11 @@
80
80
  "yaml": "^2.9.1"
81
81
  },
82
82
  "devDependencies": {
83
- "@happy-dom/global-registrator": "^20.14.6",
83
+ "@happy-dom/global-registrator": "^21.0.3",
84
84
  "@types/mdast": "^4.0.4",
85
- "@webref/css": "^8.7.6",
86
- "@webref/elements": "^2.9.1",
87
- "@webref/idl": "^3.85.1"
85
+ "@webref/css": "^8.7.7",
86
+ "@webref/elements": "^2.9.2",
87
+ "@webref/idl": "^3.85.2"
88
88
  },
89
89
  "//vue-reactivity": "Exact pin required — must match @jxsuite/runtime to avoid cross-boundary proxy bugs"
90
90
  }
@@ -20,9 +20,10 @@ import { openAboutSurface } from "../surfaces/about";
20
20
  import { layerHost } from "../ui/layers";
21
21
  import { getPlatform } from "../platform";
22
22
  import { APP_NAME, BUILD_DATE, GIT_COMMIT, LINKS, VERSION } from "../version";
23
- import type { AboutRow, AboutSurfaceHandle } from "../surfaces/about";
23
+ import type { AboutSurfaceHandle } from "../surfaces/about";
24
24
  import type { AppInfo } from "../types";
25
25
  import type { Command, CommandRegistry } from "../commands/registry";
26
+ import type { SurfaceOption } from "../ui/surface";
26
27
 
27
28
  let _handle: AboutSurfaceHandle | null = null;
28
29
 
@@ -36,8 +37,8 @@ function formatBuildDate(iso: string): string {
36
37
  }
37
38
 
38
39
  /** The metadata rows, with the desktop's two appended when the platform reported them. */
39
- function metaRows(info: AppInfo | null): AboutRow[] {
40
- const rows: AboutRow[] = [
40
+ function metaRows(info: AppInfo | null): SurfaceOption[] {
41
+ const rows: SurfaceOption[] = [
41
42
  { label: "Version", value: VERSION },
42
43
  { label: "Build date", value: formatBuildDate(BUILD_DATE) },
43
44
  { label: "Commit", value: GIT_COMMIT },
@@ -22,12 +22,14 @@
22
22
  * @docs studio/interface/welcome-screen
23
23
  */
24
24
 
25
+ import { isFunction } from "@jxsuite/schema/guards";
25
26
  import { hydrateAccountStatus, takeToastNotices } from "../account-status";
26
27
  import { getPlatform, hasPlatform } from "../platform";
27
28
  import { platformErrorInfo } from "../platform-errors";
28
29
  import { notify } from "../services/notify";
29
30
  import { resetModelCache } from "../services/ai-models";
30
31
  import { openDialogSurface } from "../surfaces/dialog";
32
+ import type { DialogSurfaceOptions } from "../surfaces/dialog";
31
33
  import { layerHost } from "../ui/layers";
32
34
  import { onActionRequired } from "./action-required";
33
35
  import type { ActionRequiredReport } from "./action-required";
@@ -43,7 +45,7 @@ export interface ActionPrompt {
43
45
 
44
46
  /** Whether this platform can perform an offered action at all. */
45
47
  export function canPerformActions(): boolean {
46
- return hasPlatform() && typeof getPlatform().performAction === "function";
48
+ return hasPlatform() && isFunction(getPlatform().performAction);
47
49
  }
48
50
 
49
51
  /** The action a surface leads with — the one marked primary, else the first — and one other. */
@@ -87,14 +89,14 @@ export function promptAction(prompt: ActionPrompt): Promise<boolean> {
87
89
  * whether the caller should now try again: false for any other error (nothing was offered) and for
88
90
  * an offer declined.
89
91
  */
90
- export async function actIfRequired(error: unknown): Promise<boolean> {
91
- const info = platformErrorInfo(error);
92
+ export async function actIfRequired(cause: unknown): Promise<boolean> {
93
+ const info = platformErrorInfo(cause);
92
94
  if (info.code !== "action-required" || !info.actions?.length) {
93
95
  return false;
94
96
  }
95
97
  return promptAction({
96
98
  actions: info.actions,
97
- detail: error instanceof Error ? error.message : undefined,
99
+ detail: cause instanceof Error ? cause.message : undefined,
98
100
  heading: info.heading,
99
101
  retry: info.retry,
100
102
  });
@@ -137,6 +139,35 @@ function offer(
137
139
  });
138
140
  };
139
141
 
142
+ /* Follow a started action to its end. A function of its own rather than inline, so `phase` is
143
+ read as it stands when the action settles, not as it stood when the action began. */
144
+ const follow = async (flow: Promise<ActionOutcome | null>) => {
145
+ let outcome: ActionOutcome | null;
146
+ try {
147
+ outcome = await flow;
148
+ } catch (error) {
149
+ if (phase === "waiting") {
150
+ offerAgain(error instanceof Error ? error.message : String(error));
151
+ }
152
+ return;
153
+ }
154
+ /* A done action is re-read even when the dialog is already gone — the user may have
155
+ dismissed the waiting dialog and finished in the window anyway, and the account must
156
+ not go on saying otherwise. */
157
+ if (outcome?.status === "done") {
158
+ await settleDone();
159
+ finish(true);
160
+ return;
161
+ }
162
+ if (phase !== "waiting" || !outcome || outcome.status === "redirect") {
163
+ // Dismissed meanwhile, or the page is navigating to the action: nothing to draw.
164
+ return;
165
+ }
166
+ // Closed without saying: the account may have changed anyway, so re-read it, and offer again.
167
+ void hydrateAccountStatus();
168
+ offerAgain(message);
169
+ };
170
+
140
171
  const begin = (action: OfferedAction) => {
141
172
  if (phase !== "offer") {
142
173
  return;
@@ -157,34 +188,11 @@ function offer(
157
188
  message: "Finish in the window that opened. This closes by itself once it is done.",
158
189
  secondaryLabel: "",
159
190
  });
160
- void flow.then(
161
- async (outcome) => {
162
- /* A done action is re-read even when the dialog is already gone — the user may have
163
- dismissed the waiting dialog and finished in the window anyway, and the account must
164
- not go on saying otherwise. */
165
- if (outcome?.status === "done") {
166
- await settleDone();
167
- finish(true);
168
- return;
169
- }
170
- if (phase !== "waiting" || !outcome || outcome.status === "redirect") {
171
- // Dismissed meanwhile, or the page is navigating to the action: nothing to draw.
172
- return;
173
- }
174
- // Closed without saying: the account may have changed anyway, so re-read it, and offer again.
175
- void hydrateAccountStatus();
176
- offerAgain(message);
177
- },
178
- (error: unknown) => {
179
- if (phase === "waiting") {
180
- offerAgain(error instanceof Error ? error.message : String(error));
181
- }
182
- },
183
- );
191
+ void follow(flow);
184
192
  };
185
193
 
186
194
  const { lead, other } = leading;
187
- const handle = openDialogSurface({
195
+ const options: DialogSurfaceOptions = {
188
196
  cancelLabel: "Not now",
189
197
  confirmLabel: lead.label,
190
198
  headline: prompt.heading ?? "One more step",
@@ -201,15 +209,14 @@ function offer(
201
209
  begin(lead);
202
210
  },
203
211
  region: "account/action",
204
- ...(other
205
- ? {
206
- onSecondary: () => {
207
- begin(other);
208
- },
209
- secondaryLabel: other.label,
210
- }
211
- : {}),
212
- });
212
+ };
213
+ if (other) {
214
+ options.onSecondary = () => {
215
+ begin(other);
216
+ };
217
+ options.secondaryLabel = other.label;
218
+ }
219
+ const handle = openDialogSurface(options);
213
220
  });
214
221
  }
215
222
 
@@ -4,6 +4,7 @@
4
4
  * (studio.ts) like the project-list cache; the welcome screen reads it synchronously to prompt
5
5
  * "install the GitHub App" when the user has no repository access yet.
6
6
  */
7
+ import { isFunction } from "@jxsuite/schema/guards";
7
8
  import { getPlatform, hasPlatform } from "./platform";
8
9
  import type { AccountEntry, AccountNotice, AccountStatus } from "./types";
9
10
 
@@ -11,7 +12,7 @@ let cache: AccountStatus | null = null;
11
12
 
12
13
  /** Refresh the cache from the platform; null when unsupported, failing, or unknown. */
13
14
  export async function hydrateAccountStatus(): Promise<void> {
14
- if (!hasPlatform() || typeof getPlatform().getAccountStatus !== "function") {
15
+ if (!hasPlatform() || !isFunction(getPlatform().getAccountStatus)) {
15
16
  cache = null;
16
17
  return;
17
18
  }
@@ -59,7 +60,11 @@ export function getRepoAccessLinks(): RepoAccessLinks | null {
59
60
  if (manage.length === 0 && !cache.appInstallUrl) {
60
61
  return null;
61
62
  }
62
- return { manage, ...(cache.appInstallUrl ? { installUrl: cache.appInstallUrl } : {}) };
63
+ const links: RepoAccessLinks = { manage };
64
+ if (cache.appInstallUrl) {
65
+ links.installUrl = cache.appInstallUrl;
66
+ }
67
+ return links;
63
68
  }
64
69
 
65
70
  /** The rows the platform adds to Preferences › Accounts (desktop.md §10.4); none when absent. */
@@ -128,7 +128,7 @@ export function cellText(file: LibraryFile, field: string): string {
128
128
  }
129
129
 
130
130
  /** Row-shaped access for a caller holding grid cells rather than the typed record. */
131
- export function cellTextOf(value: GridCellValue): string {
131
+ export function cellTextOf(value: GridCellValue | undefined): string {
132
132
  return value === null || value === undefined ? "" : String(value);
133
133
  }
134
134
 
@@ -172,6 +172,12 @@ function nameRow(file: LibraryFile): LibraryRow {
172
172
 
173
173
  // ─── Calendar ────────────────────────────────────────────────────────────────
174
174
 
175
+ /** The calendar layout: its day sections, and the sentence naming the older days it left out. */
176
+ export interface CalendarView {
177
+ groups: LibraryGroup[];
178
+ truncated: string;
179
+ }
180
+
175
181
  /**
176
182
  * Calendar: one section per day, newest first, plus an explicit account of what it did not place.
177
183
  *
@@ -181,10 +187,7 @@ function nameRow(file: LibraryFile): LibraryRow {
181
187
  *
182
188
  * @returns The day sections, and the sentence naming the older days it did not draw.
183
189
  */
184
- export function calendarView(files: readonly LibraryFile[]): {
185
- groups: LibraryGroup[];
186
- truncated: string;
187
- } {
190
+ export function calendarView(files: readonly LibraryFile[]): CalendarView {
188
191
  const { days, undated } = groupByDate(files);
189
192
  const shown = days.slice(0, CALENDAR_DAY_LIMIT);
190
193
  const hiddenDays = days.length - shown.length;
@@ -140,6 +140,9 @@ export function categoryFor(dir: string, ext: string): string {
140
140
  * @returns {string | null}
141
141
  */
142
142
  export function contentTypeFor(filePath: string): string | null {
143
+ /* SAFETY: `content` is the parser extension's opaque project section, which its project fragment
144
+ schema defines as a map of section entries; the loop reads only the optional `source`, and skips
145
+ an entry without one. */
143
146
  const content = (projectState?.projectConfig?.content ?? {}) as Record<
144
147
  string,
145
148
  ContentSectionEntry
@@ -199,7 +202,7 @@ async function walk(
199
202
  name: entry.name,
200
203
  path: entry.path,
201
204
  size: entry.size,
202
- type: category === "Content" ? (contentTypeFor(entry.path) ?? ext ?? "file") : ext || "file",
205
+ type: category === "Content" ? (contentTypeFor(entry.path) ?? ext) : ext || "file",
203
206
  });
204
207
  }
205
208
  // Siblings in parallel, depth serialized per branch: the platform counts every call as in-flight,
@@ -278,7 +281,7 @@ export const LIBRARY_LAYOUT_LABELS: Readonly<Record<LibraryLayout, string>> = {
278
281
 
279
282
  /** Whether a string names a layout — the guard behind `library.setLayout`'s argument. */
280
283
  export function isLibraryLayout(value: string): value is LibraryLayout {
281
- return (LIBRARY_LAYOUTS as readonly string[]).includes(value);
284
+ return LIBRARY_LAYOUTS.some((layout) => layout === value);
282
285
  }
283
286
 
284
287
  /** Layouts that draw a live preview per item. Table and Board draw text, and stay cheap. */
@@ -345,11 +348,20 @@ export function libraryLocales(files: readonly LibraryFile[]): string[] {
345
348
  return projectLocales().filter((tag) => present.has(tag));
346
349
  }
347
350
 
351
+ /** One Calendar day: the files whose derived date is `date`. */
352
+ export interface LibraryDay {
353
+ date: string;
354
+ files: LibraryFile[];
355
+ }
356
+
348
357
  /** Calendar buckets, newest day first, plus the files no date could be derived for. */
349
- export function groupByDate(files: readonly LibraryFile[]): {
350
- days: { date: string; files: LibraryFile[] }[];
358
+ export interface LibraryDateGroups {
359
+ days: LibraryDay[];
351
360
  undated: LibraryFile[];
352
- } {
361
+ }
362
+
363
+ /** Calendar buckets, newest day first, plus the files no date could be derived for. */
364
+ export function groupByDate(files: readonly LibraryFile[]): LibraryDateGroups {
353
365
  const byDay = new Map<string, LibraryFile[]>();
354
366
  const undated: LibraryFile[] = [];
355
367
  for (const file of files) {
@@ -366,7 +378,7 @@ export function groupByDate(files: readonly LibraryFile[]): {
366
378
  }
367
379
  }
368
380
  const days = [...byDay.entries()]
369
- .map(([date, dayFiles]) => ({ date, files: dayFiles }))
381
+ .map(([date, dayFiles]): LibraryDay => ({ date, files: dayFiles }))
370
382
  .toSorted((a, b) => b.date.localeCompare(a.date));
371
383
  return { days, undated };
372
384
  }
@@ -35,6 +35,7 @@ import { errorMessage } from "@jxsuite/schema/parse";
35
35
  import { notify } from "../services/notify";
36
36
  import { beginActivity } from "../panels/activity-panel";
37
37
  import { showPromptDialog } from "../ui/layers";
38
+ import type { PromptDialogOptions } from "../ui/layers";
38
39
  import { openMenu } from "../surfaces/menu";
39
40
  import { rectOf } from "../utils/geometry";
40
41
  import { getPlatform } from "../platform";
@@ -63,7 +64,7 @@ import { paneRegion } from "../ui/regions";
63
64
  import { LAYOUT_METRICS, boardView, calendarView, columnsAt, libraryRow } from "./library-layouts";
64
65
  import { mountLibrarySurface } from "../surfaces/library-pane";
65
66
  import type { ActivityHandle } from "../panels/activity-panel";
66
- import type { FormatChoice } from "../files/files";
67
+ import type { FormatChoice, NewFileRequest } from "../files/files";
67
68
  import type { EffectScope } from "@vue/reactivity";
68
69
  import type { MenuHandle, MenuRowProjection } from "../surfaces/menu";
69
70
  import type { LibraryFile, LibraryLayout } from "./library-model";
@@ -195,13 +196,18 @@ const SCAN_PROBLEM_KEY = "library.scan";
195
196
  * contract exists to end. The row is informational, and it only appears when the scan is slow
196
197
  * enough that its absence would look like a hang.
197
198
  */
199
+ /** The scan's Activity row, filled in only once the scan outlasts {@link SCAN_ACTIVITY_DELAY_MS}. */
200
+ interface SlowScanActivity {
201
+ handle: ActivityHandle | null;
202
+ }
203
+
198
204
  async function loadLibrary(): Promise<void> {
199
205
  const current = librarySource();
200
206
  scanAttempted = true;
201
207
  libraryView.loading = true;
202
208
  bump();
203
209
 
204
- const slow: { handle: ActivityHandle | null } = { handle: null };
210
+ const slow: SlowScanActivity = { handle: null };
205
211
  const timer = setTimeout(() => {
206
212
  slow.handle = beginActivity({
207
213
  source: "Library",
@@ -584,13 +590,16 @@ function showLibraryNewMenu(opener: HTMLElement): void {
584
590
  */
585
591
  async function renameLibraryFile(file: LibraryFile) {
586
592
  const message = await renamePromptMessage(file.path);
587
- const newName = await showPromptDialog("Rename", {
593
+ const prompt: PromptDialogOptions = {
588
594
  confirmLabel: "Rename",
589
- ...(message === undefined ? {} : { message }),
590
595
  select: "stem",
591
596
  validate: (value) => (value.trim() ? "" : "Enter a file name."),
592
597
  value: file.name,
593
- });
598
+ };
599
+ if (message !== undefined) {
600
+ prompt.message = message;
601
+ }
602
+ const newName = await showPromptDialog("Rename", prompt);
594
603
  if (!newName || newName === file.name) {
595
604
  return;
596
605
  }
@@ -724,11 +733,11 @@ export function libraryNewEntries(): LibraryNewEntry[] {
724
733
  * through the format's own serializer, because this module knows no format's syntax.
725
734
  */
726
735
  /** How each document kind's extension is settled. Anything else falls back to the full picker. */
727
- const FORMAT_CHOICE_BY_KIND: Record<string, FormatChoice> = {
728
- component: { defaultExt: ".json", docKind: "component", kind: "choose" },
729
- layout: { ext: ".json", kind: "fixed" },
730
- page: { defaultExt: ".json", docKind: "page", kind: "choose" },
731
- };
736
+ const FORMAT_CHOICE_BY_KIND = new Map<string, FormatChoice>([
737
+ ["component", { defaultExt: ".json", docKind: "component", kind: "choose" }],
738
+ ["layout", { ext: ".json", kind: "fixed" }],
739
+ ["page", { defaultExt: ".json", docKind: "page", kind: "choose" }],
740
+ ]);
732
741
 
733
742
  /**
734
743
  * The body a new component starts as, when the reader picked a format rather than `.json`.
@@ -767,17 +776,22 @@ export async function createLibraryEntry(key: string): Promise<string | null> {
767
776
  if (!entry) {
768
777
  return null;
769
778
  }
770
- const created =
771
- entry.collection === undefined
772
- ? await createFileIn({
773
- ...(entry.key === "component" ? { content: componentSeed } : {}),
774
- dir: entry.dir,
775
- format: FORMAT_CHOICE_BY_KIND[entry.key] ?? { defaultExt: ".json", kind: "choose" },
776
- source: "Library",
777
- suggestedName: "untitled",
778
- title: `New ${entry.label}`,
779
- })
780
- : await createEntry(entry.collection);
779
+ let created: string | null;
780
+ if (entry.collection === undefined) {
781
+ const request: NewFileRequest = {
782
+ dir: entry.dir,
783
+ format: FORMAT_CHOICE_BY_KIND.get(entry.key) ?? { defaultExt: ".json", kind: "choose" },
784
+ source: "Library",
785
+ suggestedName: "untitled",
786
+ title: `New ${entry.label}`,
787
+ };
788
+ if (entry.key === "component") {
789
+ request.content = componentSeed;
790
+ }
791
+ created = await createFileIn(request);
792
+ } else {
793
+ created = await createEntry(entry.collection);
794
+ }
781
795
  if (created === null) {
782
796
  return null;
783
797
  }
@@ -1017,6 +1031,8 @@ export function renderLibraryMode(surface: CanvasSurface, tab: Tab): void {
1017
1031
  },
1018
1032
  search: (value) => setLibrarySearch(value),
1019
1033
  setCategory: (key) => setLibraryCategory(key),
1034
+ /* SAFETY: the surface's layout buttons pass `$map.item.key`, and the `layouts` state they map is
1035
+ built from LIBRARY_LAYOUTS in the projection above, so every key is a LibraryLayout. */
1020
1036
  setLayout: (key) => setLibraryLayout(key as LibraryLayout),
1021
1037
  setLocale: (value) => setLibraryLocale(value === "all" ? "" : value),
1022
1038
  upload: (input) => {
@@ -25,6 +25,7 @@ import {
25
25
  setCanvasAssetResolver,
26
26
  setSkipServerFunctions,
27
27
  } from "@jxsuite/runtime";
28
+ import { isFunction } from "@jxsuite/schema/guards";
28
29
  import { assetContextFor, hostAssetDeclarations, resolveAssetRef } from "../canvas/asset-refs";
29
30
  import { assetVersionsSnapshot } from "../files/asset-versions";
30
31
  import { componentRegistry } from "../files/components";
@@ -74,12 +75,13 @@ export function createPreviewCache(limit: number = PREVIEW_CACHE_LIMIT): Preview
74
75
  const entries = new Map<string, HTMLElement>();
75
76
 
76
77
  function evict() {
77
- // `size > limit` guarantees a first key, so the iterator result is never `done` here.
78
- while (entries.size > limit) {
79
- const oldest = entries.keys().next().value as string;
80
- const stale = entries.get(oldest);
78
+ // Insertion order is LRU order, and deleting the entry being visited is safe mid-iteration.
79
+ for (const [oldest, stale] of entries) {
80
+ if (entries.size <= limit) {
81
+ break;
82
+ }
81
83
  entries.delete(oldest);
82
- stale?.remove();
84
+ stale.remove();
83
85
  }
84
86
  }
85
87
 
@@ -127,8 +129,13 @@ export async function renderDocPreview(filePath: string): Promise<HTMLElement |
127
129
  let document_: JxDocument;
128
130
  if (formatForPath(filePath)) {
129
131
  const parsed = await parseSourceForPath(filePath, content);
132
+ /* SAFETY: a format class's parser returns its file as a Jx element tree (the format contract),
133
+ and the split hands that same tree back as `document`; a tree renderNode cannot draw throws
134
+ into the catch below, which is "no preview". */
130
135
  document_ = parsed.document as JxDocument;
131
136
  } else {
137
+ /* SAFETY: a `.json` file in the Library is a project document by the project layout; malformed
138
+ JSON or a shape renderNode cannot draw throws into the catch below, which is "no preview". */
132
139
  document_ = JSON.parse(content) as JxDocument;
133
140
  }
134
141
  const scope = await buildScope(document_, {}, location.href);
@@ -166,9 +173,7 @@ export async function previewFor(
166
173
  let rendered: HTMLElement | null | undefined;
167
174
  try {
168
175
  const component = componentRegistry.find((c: ComponentEntry) => c.path === path);
169
- rendered = component
170
- ? ((await renderComponentPreview(component)) as HTMLElement | undefined)
171
- : await renderDocPreview(path);
176
+ rendered = component ? await renderComponentPreview(component) : await renderDocPreview(path);
172
177
  } catch {
173
178
  return undefined;
174
179
  }
@@ -219,7 +224,7 @@ export interface PreviewObserver {
219
224
  * retained on that path, so there is nothing for the sweep to find.
220
225
  */
221
226
  export function createPreviewObserver(onVisible: (element: Element) => void): PreviewObserver {
222
- if (typeof IntersectionObserver !== "function") {
227
+ if (!isFunction(globalThis.IntersectionObserver)) {
223
228
  return {
224
229
  destroy() {
225
230
  /* Nothing to disconnect. */
@@ -93,7 +93,7 @@ export function createLibrarySource(dirs?: () => readonly string[]): LibrarySour
93
93
  let scan: LibraryScan | null = null;
94
94
  let inFlight: Promise<LibraryScan> | null = null;
95
95
 
96
- const projectDirs = dirs ?? (() => (projectState?.projectDirs ?? []) as readonly string[]);
96
+ const projectDirs = dirs ?? (() => projectState?.projectDirs ?? []);
97
97
 
98
98
  async function ensureScan(): Promise<LibraryScan> {
99
99
  if (scan) {
@@ -53,6 +53,9 @@ export function assetContextFor(
53
53
  const space = over?.space ?? "site";
54
54
  const mount = contentMountFor(
55
55
  documentPath,
56
+ /* SAFETY: `content` is the parser extension's opaque project section, which its project
57
+ fragment schema defines as a map of section entries; contentMountFor reads only each entry's
58
+ optional `source` and skips an entry without one. */
56
59
  projectState?.projectConfig?.content as Record<string, ContentSectionEntry> | undefined,
57
60
  projectLocales(),
58
61
  );
@@ -61,13 +64,16 @@ export function assetContextFor(
61
64
  if (space === "site" && !mount) {
62
65
  return null;
63
66
  }
64
- return {
67
+ const context: AssetContext = {
65
68
  documentDir: dirOfPath(documentPath ?? ""),
66
- ...(over?.fileBaseUrl === undefined ? {} : { fileBaseUrl: over.fileBaseUrl }),
67
69
  lanes: BUILD_LANES,
68
70
  mounts: mount ? [mount] : [],
69
71
  space,
70
72
  };
73
+ if (over?.fileBaseUrl !== undefined) {
74
+ context.fileBaseUrl = over.fileBaseUrl;
75
+ }
76
+ return context;
71
77
  }
72
78
 
73
79
  /**
@@ -99,6 +105,15 @@ export function previewAssetSrc(value: string): string {
99
105
  return loopbackAssetSrc(resolveAssetRef(value, versioned) ?? value);
100
106
  }
101
107
 
108
+ /**
109
+ * The registered host's media declarations: its asset space, and the base project files serve
110
+ * under.
111
+ */
112
+ export interface HostAssetDeclarations {
113
+ space?: "site" | "repo" | undefined;
114
+ fileBaseUrl: string;
115
+ }
116
+
102
117
  /**
103
118
  * What the registered host says about media — the platform's `assetSpace`, and the base project
104
119
  * files are served under.
@@ -108,14 +123,14 @@ export function previewAssetSrc(value: string): string {
108
123
  * The canvas pipeline builds the same two values from the same two places; the difference is only
109
124
  * that it already has the document in hand.
110
125
  *
111
- * @returns {{ space?: "site" | "repo"; fileBaseUrl: string }} The host's declarations
126
+ * @returns {HostAssetDeclarations} The host's declarations
112
127
  */
113
- export function hostAssetDeclarations(): {
114
- space?: "site" | "repo" | undefined;
115
- fileBaseUrl: string;
116
- } {
117
- return {
128
+ export function hostAssetDeclarations(): HostAssetDeclarations {
129
+ const declarations: HostAssetDeclarations = {
118
130
  fileBaseUrl: documentBase(projectState?.projectRoot),
119
- ...(hasPlatform() ? { space: getPlatform().assetSpace } : {}),
120
131
  };
132
+ if (hasPlatform()) {
133
+ declarations.space = getPlatform().assetSpace;
134
+ }
135
+ return declarations;
121
136
  }