@jxsuite/studio 2.0.0 → 2.1.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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +23711 -35185
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -120
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +75 -2
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +113 -0
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -1,23 +1,26 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
- * Definitions Editor — visual editor for project-level $defs (JSON Schema type definitions).
3
+ * Definitions — the visual editor for project-level `$defs` (JSON Schema type definitions).
4
4
  *
5
5
  * Manages entries in project.json `$defs` — reusable type schemas for external datasets, API
6
- * responses, CMS payloads, etc. Same concept as component-level $defs but scoped to the entire
7
- * project.
6
+ * responses, CMS payloads, etc. Same concept as component-level `$defs` but scoped to the entire
7
+ * project. The on-disk key stays `$defs` and the section key stays `definitions`.
8
+ *
9
+ * **The reference field type is complete here for the first time.** `schema-field-ui.ts` has always
10
+ * been able to draw the target picker, and `ui/form-controls.ts` (the content-types builder) has
11
+ * always passed it the available content types — this editor never did, so choosing "reference"
12
+ * emitted a bare `#/content/` that pointed at nothing and offered no way to say what it pointed at.
13
+ * The list is read straight off the live config's `content` map, which is where a
14
+ * `#/content/<type>` pointer resolves.
8
15
  */
9
16
 
10
17
  import { html, render as litRender } from "lit-html";
11
- import { getPlatform } from "../platform";
12
18
  import { projectState } from "../store";
19
+ import { commitProjectConfig } from "../tabs/project-config";
13
20
  import { addFieldFormTpl, detectFieldFormat, fieldCardTpl, schemaForType } from "./schema-field-ui";
14
21
 
15
22
  import type { FieldHandlers, SchemaProperty } from "./schema-field-ui.js";
16
- import type {
17
- ContentTypeSchema,
18
- ContentTypeSchemaField,
19
- ProjectConfig,
20
- } from "@jxsuite/schema/types";
23
+ import type { ContentTypeSchema, ContentTypeSchemaField } from "@jxsuite/schema/types";
21
24
 
22
25
  // ─── Module state ─────────────────────────────────────────────────────────────
23
26
 
@@ -29,10 +32,21 @@ let newDefName = "";
29
32
 
30
33
  // ─── Persistence ──────────────────────────────────────────────────────────────
31
34
 
32
- async function saveProjectConfig() {
33
- const platform = getPlatform();
34
- const config = (projectState as { projectConfig: ProjectConfig }).projectConfig;
35
- await platform.writeFile("project.json", JSON.stringify(config, null, "\t"));
35
+ /**
36
+ * Commit the configuration this editor has just mutated in place.
37
+ *
38
+ * Every handler below edits `projectState.projectConfig.$defs` directly and then says so here. The
39
+ * predecessor was this module's own writer — `JSON.stringify(config, null, "\t")` straight to
40
+ * `platform.writeFile`, called as `void saveProjectConfig()` at fourteen sites. It re-indented the
41
+ * whole file (every `project.json` on disk uses two spaces), it recorded nothing an undo could
42
+ * reach, and a rejected write became an unhandled rejection while the form went on showing a data
43
+ * shape that was never saved.
44
+ *
45
+ * `commitProjectConfig` transacts the mutation onto the configuration document and reports its own
46
+ * failures as Problems, so there is nothing left here to await or to swallow.
47
+ */
48
+ function persist(): void {
49
+ void commitProjectConfig();
36
50
  }
37
51
 
38
52
  // ─── Helpers ─────────────────────────────────────────────────────────────────
@@ -43,6 +57,20 @@ function getSelectedDef(): ContentTypeSchema | undefined {
43
57
  return config?.$defs?.[selectedDef as string] as ContentTypeSchema | undefined;
44
58
  }
45
59
 
60
+ /**
61
+ * The content types a `reference` field can point at — the same list the content-types builder
62
+ * resolves through `#/$context/content`, read here without a schema-form context to go through.
63
+ *
64
+ * @returns {string[]}
65
+ */
66
+ function contentTypeNames(): string[] {
67
+ const content = (projectState?.projectConfig as Record<string, unknown> | null | undefined)
68
+ ?.content;
69
+ return content && typeof content === "object" && !Array.isArray(content)
70
+ ? Object.keys(content)
71
+ : [];
72
+ }
73
+
46
74
  // ─── Handlers ─────────────────────────────────────────────────────────────────
47
75
 
48
76
  /** @param {() => void} rerender */
@@ -73,7 +101,7 @@ function handleNewDef(rerender: () => void) {
73
101
  showNewDef = false;
74
102
  newDefName = "";
75
103
  rerender();
76
- void saveProjectConfig();
104
+ persist();
77
105
  }
78
106
 
79
107
  /** @param {() => void} rerender */
@@ -105,7 +133,7 @@ function handleAddField(rerender: () => void) {
105
133
  showAddField = false;
106
134
  newFieldState = { format: "", name: "", required: false, type: "string" };
107
135
  rerender();
108
- void saveProjectConfig();
136
+ persist();
109
137
  }
110
138
 
111
139
  /**
@@ -124,7 +152,7 @@ function handleDeleteField(fieldName: string, rerender: () => void) {
124
152
  }
125
153
 
126
154
  rerender();
127
- void saveProjectConfig();
155
+ persist();
128
156
  }
129
157
 
130
158
  /**
@@ -148,7 +176,7 @@ function handleToggleRequired(fieldName: string, rerender: () => void) {
148
176
  }
149
177
 
150
178
  rerender();
151
- void saveProjectConfig();
179
+ persist();
152
180
  }
153
181
 
154
182
  /**
@@ -173,7 +201,7 @@ function handleRenameField(oldName: string, newName: string, rerender: () => voi
173
201
  }
174
202
 
175
203
  rerender();
176
- void saveProjectConfig();
204
+ persist();
177
205
  }
178
206
 
179
207
  /**
@@ -193,7 +221,26 @@ function handleChangeType(fieldName: string, newType: string, rerender: () => vo
193
221
  : undefined;
194
222
  def.properties[fieldName] = schemaForType(newType, oldFormat || undefined);
195
223
  rerender();
196
- void saveProjectConfig();
224
+ persist();
225
+ }
226
+
227
+ /**
228
+ * Point a reference field at a content type. The pointer form is `#/content/<type>` — the same one
229
+ * `ui/form-controls.ts` writes, so a reference authored here and one authored in the content-types
230
+ * builder are the same value.
231
+ *
232
+ * @param {string} fieldName
233
+ * @param {string} target
234
+ * @param {() => void} rerender
235
+ */
236
+ function handleChangeRefTarget(fieldName: string, target: string, rerender: () => void) {
237
+ const def = getSelectedDef();
238
+ if (!def?.properties?.[fieldName]) {
239
+ return;
240
+ }
241
+ def.properties[fieldName] = { $ref: `#/content/${target}` } as ContentTypeSchemaField;
242
+ rerender();
243
+ persist();
197
244
  }
198
245
 
199
246
  /**
@@ -211,7 +258,7 @@ function handleChangeFormat(fieldName: string, format: string, rerender: () => v
211
258
  const type = prop.type || "string";
212
259
  def.properties[fieldName] = schemaForType(type, format || undefined);
213
260
  rerender();
214
- void saveProjectConfig();
261
+ persist();
215
262
  }
216
263
 
217
264
  // ─── Nested field handlers ───────────────────────────────────────────────────
@@ -247,7 +294,7 @@ function handleAddNestedField(
247
294
  }
248
295
 
249
296
  rerender();
250
- void saveProjectConfig();
297
+ persist();
251
298
  }
252
299
 
253
300
  /**
@@ -268,7 +315,7 @@ function handleDeleteNested(parentName: string, childName: string, rerender: ()
268
315
  }
269
316
 
270
317
  rerender();
271
- void saveProjectConfig();
318
+ persist();
272
319
  }
273
320
 
274
321
  /**
@@ -294,7 +341,7 @@ function handleToggleNestedRequired(parentName: string, childName: string, reren
294
341
  }
295
342
 
296
343
  rerender();
297
- void saveProjectConfig();
344
+ persist();
298
345
  }
299
346
 
300
347
  /**
@@ -326,7 +373,7 @@ function handleRenameNested(
326
373
  }
327
374
 
328
375
  rerender();
329
- void saveProjectConfig();
376
+ persist();
330
377
  }
331
378
 
332
379
  /**
@@ -353,7 +400,7 @@ function handleChangeNestedType(
353
400
  : undefined;
354
401
  parent.properties[childName] = schemaForType(newType, oldFormat || undefined);
355
402
  rerender();
356
- void saveProjectConfig();
403
+ persist();
357
404
  }
358
405
 
359
406
  /**
@@ -378,7 +425,7 @@ function handleChangeNestedFormat(
378
425
  const type = prop.type || "string";
379
426
  parent.properties[childName] = schemaForType(type, format || undefined);
380
427
  rerender();
381
- void saveProjectConfig();
428
+ persist();
382
429
  }
383
430
 
384
431
  /** @param {() => void} rerender */
@@ -395,13 +442,13 @@ function handleDeleteDef(rerender: () => void) {
395
442
  selectedDef = null;
396
443
 
397
444
  rerender();
398
- void saveProjectConfig();
445
+ persist();
399
446
  }
400
447
 
401
448
  // ─── Render ───────────────────────────────────────────────────────────────────
402
449
 
403
450
  /**
404
- * Render the definitions editor.
451
+ * Render the Data Shapes editor.
405
452
  *
406
453
  * @param {HTMLElement} container
407
454
  */
@@ -435,7 +482,7 @@ export function renderDefsEditor(container: HTMLElement) {
435
482
  <div class="settings-inline-form">
436
483
  <sp-textfield
437
484
  size="s"
438
- placeholder="TypeName"
485
+ placeholder="ProductReview"
439
486
  .value=${newDefName}
440
487
  @input=${(e: Event) => {
441
488
  newDefName = (e.target as HTMLInputElement).value;
@@ -464,7 +511,7 @@ export function renderDefsEditor(container: HTMLElement) {
464
511
  rerender();
465
512
  }}
466
513
  >
467
- <sp-icon-add slot="icon"></sp-icon-add> New Definition
514
+ <sp-icon-add slot="icon"></sp-icon-add> New Data Shape
468
515
  </sp-action-button>
469
516
  `
470
517
  }
@@ -474,7 +521,9 @@ export function renderDefsEditor(container: HTMLElement) {
474
521
  // Right column — schema editor
475
522
  let editorTpl;
476
523
  if (!selectedDef || !defs[selectedDef]) {
477
- editorTpl = html`<div class="settings-empty-state">Select or create a type definition</div>`;
524
+ editorTpl = html`<div class="settings-empty-state">
525
+ Pick a data shape on the left, or create one.
526
+ </div>`;
478
527
  } else {
479
528
  const def = defs[selectedDef] as ContentTypeSchema;
480
529
  const properties = def.properties || {};
@@ -488,6 +537,7 @@ export function renderDefsEditor(container: HTMLElement) {
488
537
  handleChangeNestedFormat(p, c, f, rerender),
489
538
  onChangeNestedType: (p: string, c: string, t: string) =>
490
539
  handleChangeNestedType(p, c, t, rerender),
540
+ onChangeRefTarget: (n: string, t: string) => handleChangeRefTarget(n, t, rerender),
491
541
  onChangeType: (n: string, t: string) => handleChangeType(n, t, rerender),
492
542
  onDelete: (n: string) => handleDeleteField(n, rerender),
493
543
  onDeleteNested: (p: string, c: string) => handleDeleteNested(p, c, rerender),
@@ -497,8 +547,9 @@ export function renderDefsEditor(container: HTMLElement) {
497
547
  onToggleRequired: (n: string) => handleToggleRequired(n, rerender),
498
548
  };
499
549
 
550
+ const targets = contentTypeNames();
500
551
  const fieldCards = Object.entries(properties).map(([name, fieldDef]) =>
501
- fieldCardTpl(name, fieldDef as SchemaProperty, required.includes(name), handlers),
552
+ fieldCardTpl(name, fieldDef as SchemaProperty, required.includes(name), handlers, targets),
502
553
  );
503
554
 
504
555
  editorTpl = html`
@@ -508,7 +559,7 @@ export function renderDefsEditor(container: HTMLElement) {
508
559
  <sp-action-button
509
560
  size="xs"
510
561
  quiet
511
- title="Delete definition"
562
+ title="Delete data shape"
512
563
  @click=${() => handleDeleteDef(rerender)}
513
564
  >
514
565
  <sp-icon-delete slot="icon"></sp-icon-delete>
@@ -551,7 +602,15 @@ export function renderDefsEditor(container: HTMLElement) {
551
602
  `;
552
603
  }
553
604
 
554
- const tpl = html` <div class="settings-two-col">${listTpl} ${editorTpl}</div> `;
605
+ // Every section names itself in an <h3> matching its nav entry (Overview, Contexts, Head,
606
+ // Packages, Extensions, Deploy, Raw JSON). This one did not, so it was the only section whose
607
+ // Body never said what the reader had clicked.
608
+ const tpl = html`
609
+ <div class="settings-section">
610
+ <h3 class="settings-section-title">Data Shapes</h3>
611
+ <div class="settings-two-col">${listTpl} ${editorTpl}</div>
612
+ </div>
613
+ `;
555
614
 
556
615
  litRender(tpl, container);
557
616
  }
@@ -9,7 +9,7 @@
9
9
  import { html, render as litRender } from "lit-html";
10
10
  import { getPlatform } from "../platform";
11
11
  import { VERSION } from "../version";
12
- import { statusMessage } from "../panels/statusbar";
12
+ import { notify } from "../services/notify";
13
13
  import { showProgressModal } from "../ui/progress-modal";
14
14
  import { isComparable, isUpgrade, stripRange } from "../packages/semver";
15
15
  import type { PackageInfo } from "../types";
@@ -83,14 +83,14 @@ async function onAdd() {
83
83
  await withBusy(async () => {
84
84
  await getPlatform().addPackage(name);
85
85
  _addName = "";
86
- statusMessage(`Added ${name}`);
86
+ notify.success(`Added ${name}.`);
87
87
  });
88
88
  }
89
89
 
90
90
  async function onRemove(p: PackageInfo) {
91
91
  await withBusy(async () => {
92
92
  await getPlatform().removePackage(p.name);
93
- statusMessage(`Removed ${p.name}`);
93
+ notify.success(`Removed ${p.name}.`);
94
94
  });
95
95
  }
96
96
 
@@ -107,7 +107,7 @@ async function onUpdate(p: PackageInfo, latest: string) {
107
107
  if (!res.ok) {
108
108
  throw new Error(res.log ?? "Update failed");
109
109
  }
110
- statusMessage(`Updated ${p.name} to ${target}`);
110
+ notify.success(`Updated ${p.name} to ${target}.`);
111
111
  });
112
112
  }
113
113
 
@@ -132,7 +132,7 @@ async function onUpdateAll() {
132
132
  if (!res.ok) {
133
133
  throw new Error(res.log ?? "Update failed");
134
134
  }
135
- statusMessage(`Updated ${updates.length} package(s)`);
135
+ notify.success(`Updated ${updates.length} package(s).`);
136
136
  });
137
137
  }
138
138
 
@@ -146,7 +146,7 @@ async function onReinstall() {
146
146
  if (!res.ok) {
147
147
  throw new Error(res.log ?? "Install failed");
148
148
  }
149
- statusMessage("Dependencies reinstalled");
149
+ notify.success("Dependencies reinstalled.");
150
150
  });
151
151
  }
152
152
 
@@ -198,7 +198,7 @@ function render() {
198
198
 
199
199
  const tpl = html`
200
200
  <div class="settings-section">
201
- <h3 class="settings-section-title">Dependencies</h3>
201
+ <h3 class="settings-section-title">Packages</h3>
202
202
  <p class="settings-field-desc">Manage this project's npm dependencies.</p>
203
203
 
204
204
  <div style="display:flex;gap:8px;margin-bottom:12px;align-items:center">
@@ -1,7 +1,7 @@
1
1
  /// <reference lib="dom" />
2
2
  /**
3
3
  * Extension settings sections — bridges the extensions payload (platform `listExtensions`) into the
4
- * settings-modal registry. Every project-section contribution whose class declares a
4
+ * Project Settings section registry. Every project-section contribution whose class declares a
5
5
  * `$studio.settings` block (specs/extensions.md §9.1) gets a section rendered generically by
6
6
  * renderContributedSection; sections vanish again when their extension is disabled. The studio
7
7
  * hard-codes nothing per extension — parser's Content Types section arrives through this exact
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { getFormats, loadExtensions, loadFormats } from "../format/format-host";
12
- import { registerSettingsSection, unregisterSettingsSection } from "./settings-modal";
12
+ import { registerSettingsSection, unregisterSettingsSection } from "./section-registry";
13
13
  import { renderContributedSection } from "./contributed-section";
14
14
  import { dataSectionActions } from "../panels/data-grid";
15
15
  import type { ExtensionContributionInfo } from "../types";
@@ -25,7 +25,7 @@ interface StudioSettingsBlock {
25
25
  entry?: SettingsContribution["settings"]["entry"];
26
26
  }
27
27
 
28
- /** A contribution resolved into settings-modal registration inputs. */
28
+ /** A contribution resolved into section-registry registration inputs. */
29
29
  export interface DerivedSettingsSection {
30
30
  key: string;
31
31
  label: string;
@@ -38,7 +38,7 @@ export interface DerivedSettingsSection {
38
38
  const DEFAULT_SECTION_ORDER = 100;
39
39
 
40
40
  /**
41
- * Derive the settings-modal registration for one contribution, or null when its class declares no
41
+ * Derive the section registration for one contribution, or null when its class declares no
42
42
  * `$studio.settings` block. The wire `entrySchema` is the SECTION value schema (`properties[<key>]`
43
43
  * of the project fragment); map layouts edit one entry at a time, so their form schema is that
44
44
  * section schema's `additionalProperties`.
@@ -86,13 +86,45 @@ export function deriveSettingsSection(
86
86
  /** Section keys this module registered, so stale ones unregister on project/extension change. */
87
87
  const registeredKeys = new Set<string>();
88
88
 
89
+ /**
90
+ * The sync currently running, so concurrent callers join it instead of racing it.
91
+ *
92
+ * This is half of the deep-link fix (plan §12 P6.2). `refreshExtensionUi` (`format/format-host.ts`)
93
+ * fires this function **fire-and-forget** on project activation and after every `project.json`
94
+ * write, and the settings surface used to start a SECOND, interleaved run and await only its own.
95
+ * The two runs share {@link registeredKeys} and both reach {@link unregisterSettingsSection}, so a
96
+ * key one run had just registered could be seen as stale by the other and unregistered — after the
97
+ * awaited promise had already resolved. Coalescing makes "the sections are ready" one fact about
98
+ * the registry rather than one fact per caller.
99
+ */
100
+ let _inFlight: Promise<void> | null = null;
101
+
102
+ /**
103
+ * Await whatever contribution sync is in flight. Resolves immediately when none is.
104
+ *
105
+ * @returns {Promise<void>}
106
+ */
107
+ export function extensionSectionsReady(): Promise<void> {
108
+ return _inFlight ?? Promise.resolve();
109
+ }
110
+
89
111
  /**
90
112
  * Load the extensions payload and (re)register a settings section per `$studio.settings`
91
113
  * contribution, unregistering sections whose extension is no longer enabled. Formats load alongside
92
114
  * so the `$formats` context root has data at render time. Call on project activation and after
93
115
  * project.json `extensions` changes; loadExtensions caches, so repeat calls are cheap.
116
+ *
117
+ * Concurrent calls share one run — see {@link _inFlight}.
94
118
  */
95
- export async function syncExtensionSettingsSections(): Promise<void> {
119
+ export function syncExtensionSettingsSections(): Promise<void> {
120
+ _inFlight ??= runSync().finally(() => {
121
+ _inFlight = null;
122
+ });
123
+ return _inFlight;
124
+ }
125
+
126
+ /** One pass over the extensions payload. Never called concurrently with itself. */
127
+ async function runSync(): Promise<void> {
96
128
  const [extensions] = await Promise.all([loadExtensions(), loadFormats()]);
97
129
  const next = new Set<string>();
98
130
  for (const ext of extensions) {