@jxsuite/studio 4.1.0 → 5.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 (612) hide show
  1. package/README.md +1 -1
  2. package/data/elements-meta.json +5 -15
  3. package/data/html-meta.json +51 -6
  4. package/dist/chunks/{2020-n6tfwnda.js → 2020-g79n01v9.js} +14 -14
  5. package/dist/chunks/action-group-sp6tna8v.js +118 -0
  6. package/dist/chunks/adapter-nj7tnjfn.js +13 -0
  7. package/dist/chunks/cf-account-picker-qwkm9zrf.js +495 -0
  8. package/dist/chunks/cf-settings-71bv5zn9.js +20 -0
  9. package/dist/chunks/color-area-v17df7b8.js +154 -0
  10. package/dist/chunks/color-field-anwybnkn.js +208 -0
  11. package/dist/chunks/color-slider-44ez96fc.js +79 -0
  12. package/dist/chunks/color-xgg3kfw7.js +35 -0
  13. package/dist/chunks/combobox-5e7jev23.js +236 -0
  14. package/dist/chunks/components-vj72gqtq.js +20 -0
  15. package/dist/chunks/content-source-5mex4x1h.js +46 -0
  16. package/dist/chunks/convert-to-repeater-n64h8znc.js +639 -0
  17. package/dist/chunks/dialog-s890b918.js +85 -0
  18. package/dist/chunks/editor-3qhbg51x.js +35 -0
  19. package/dist/chunks/entry-commands-234hjnqw.js +42 -0
  20. package/dist/chunks/extension-sections-3hpcambp.js +651 -0
  21. package/dist/chunks/file-ops-8yhd83xr.js +47 -0
  22. package/dist/chunks/files-hnxqxtsg.js +72 -0
  23. package/dist/chunks/format-host-779sfp2n.js +40 -0
  24. package/dist/chunks/fs-events-b88z7g4h.js +18 -0
  25. package/dist/chunks/git-panel-xwj8fpab.js +49 -0
  26. package/dist/chunks/icons-yy10wk9r.js +402 -0
  27. package/dist/chunks/iframe-entry-15g3n6xv.js +114 -0
  28. package/dist/chunks/iframe-entry-b27vq81n.js +203 -0
  29. package/dist/chunks/iframe-entry-nbyxee1y.js +154 -0
  30. package/dist/chunks/iframe-host-syr0f9sb.js +115 -0
  31. package/dist/chunks/{index-wcnt3r9g.js → index-mdmyx6s2.js} +11 -11
  32. package/dist/chunks/index-n4j7qxyr.js +109 -0
  33. package/dist/chunks/{javascript-q8kpmfah.js → javascript-xvrfrpkb.js} +8 -9
  34. package/dist/chunks/{jsonMode-dkr040ga.js → jsonMode-tyx2kj6p.js} +526 -527
  35. package/dist/chunks/jx-validate-j0wxk72w.js +15 -0
  36. package/dist/chunks/layers-ff81wthn.js +30 -0
  37. package/dist/chunks/layers-panel-pnnghw12.js +40 -0
  38. package/dist/chunks/listbox-6v2ac08j.js +44 -0
  39. package/dist/chunks/lit-html-m244w9nh.js +17 -0
  40. package/dist/chunks/media-picker-cqhhxhhe.js +33 -0
  41. package/dist/chunks/menu-9p2w46gj.js +15 -0
  42. package/dist/chunks/menu-q99sy9rf.js +285 -0
  43. package/dist/chunks/{monaco-binding-rj6xpx9y.js → monaco-binding-sw6en4dw.js} +12 -15
  44. package/dist/chunks/monaco-buffer-bhy3hb6m.js +24 -0
  45. package/dist/chunks/{monaco-setup-vx9bhp1d.js → monaco-setup-8r62fj6y.js} +27 -37
  46. package/dist/chunks/notify-628t0anh.js +21 -0
  47. package/dist/chunks/number-field-5cndyft8.js +72 -0
  48. package/dist/chunks/parse-0zx14y15.js +10 -0
  49. package/dist/chunks/platform-ts9cg1a4.js +15 -0
  50. package/dist/chunks/popover-47z3ytva.js +25 -0
  51. package/dist/chunks/publish-panel-5zt840sy.js +27 -0
  52. package/dist/chunks/quick-search-3748564r.js +45 -0
  53. package/dist/chunks/references-qvvxej7h.js +26 -0
  54. package/dist/chunks/right-panel-eccz92qt.js +45 -0
  55. package/dist/chunks/section-registry-5pq32t0q.js +25 -0
  56. package/dist/chunks/select-2r16ez41.js +49 -0
  57. package/dist/chunks/split-g7nm1rgb.js +191 -0
  58. package/dist/chunks/studio-0hqbpbd0.js +62 -0
  59. package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
  60. package/dist/chunks/{studio-b55y6ewx.js → studio-1knfqgy7.js} +58 -58
  61. package/dist/chunks/{studio-2b946z26.js → studio-1z1kcjv4.js} +3628 -6095
  62. package/dist/chunks/studio-3773086z.js +111 -0
  63. package/dist/chunks/{studio-4r1pv6zf.js → studio-38emantv.js} +22 -5
  64. package/dist/chunks/{studio-x813zp48.js → studio-3rz5md06.js} +30 -30
  65. package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
  66. package/dist/chunks/studio-5te5tqng.js +81 -0
  67. package/dist/chunks/studio-5wt9nvhd.js +4763 -0
  68. package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
  69. package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
  70. package/dist/chunks/studio-6xa21ej9.js +28 -0
  71. package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
  72. package/dist/chunks/{studio-gcye7qka.js → studio-7e11jpa9.js} +21 -21
  73. package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
  74. package/dist/chunks/studio-7xnmgv66.js +13615 -0
  75. package/dist/chunks/studio-8scdew0e.js +258 -0
  76. package/dist/chunks/{studio-fbf92ckf.js → studio-93zafjcm.js} +275 -163
  77. package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
  78. package/dist/chunks/studio-a79k90n9.js +1162 -0
  79. package/dist/chunks/studio-aj37eer3.js +422 -0
  80. package/dist/chunks/studio-b0k5tqgp.js +2432 -0
  81. package/dist/chunks/studio-b4s9eykd.js +2811 -0
  82. package/dist/chunks/{studio-f3wqjtk5.js → studio-d0300636.js} +5076 -18
  83. package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
  84. package/dist/chunks/studio-e1pgga3k.js +839 -0
  85. package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
  86. package/dist/chunks/{studio-q43a5y9h.js → studio-g3jevyjt.js} +16 -16
  87. package/dist/chunks/studio-gb13095a.js +2806 -0
  88. package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
  89. package/dist/chunks/{studio-dm19q43r.js → studio-hhvs4sdg.js} +10 -10
  90. package/dist/chunks/{studio-x4qkdat5.js → studio-js8nv53n.js} +1749 -2481
  91. package/dist/chunks/{studio-qjy2z9bv.js → studio-jxp12rnj.js} +32 -137
  92. package/dist/chunks/{studio-trxrabqf.js → studio-k75n7vhp.js} +527 -283
  93. package/dist/chunks/{studio-q9jd1a60.js → studio-kcgff4r0.js} +15 -18
  94. package/dist/chunks/studio-kkqkcp3d.js +17668 -0
  95. package/dist/chunks/studio-mhhyamxf.js +763 -0
  96. package/dist/chunks/{studio-cft9r4r7.js → studio-nq5yf5mp.js} +22 -22
  97. package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
  98. package/dist/chunks/studio-nzzpvzx9.js +185 -0
  99. package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
  100. package/dist/chunks/{studio-3bqpr0zh.js → studio-pxbgypmg.js} +299 -110
  101. package/dist/chunks/studio-q0a3yk4n.js +33 -0
  102. package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
  103. package/dist/chunks/{studio-6yw4y3my.js → studio-qhhm6hbt.js} +8 -8
  104. package/dist/chunks/studio-qk4bfsq2.js +362 -0
  105. package/dist/chunks/{studio-msd847zn.js → studio-qk90fgqm.js} +361 -90
  106. package/dist/chunks/{studio-jkftxyvz.js → studio-r6nvacqs.js} +5861 -2154
  107. package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
  108. package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
  109. package/dist/chunks/studio-rs76k67r.js +12 -0
  110. package/dist/chunks/studio-sbjyc8bt.js +954 -0
  111. package/dist/chunks/{studio-1wagb550.js → studio-syg2tadj.js} +11 -11
  112. package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
  113. package/dist/chunks/studio-tqgryxwg.js +1171 -0
  114. package/dist/chunks/studio-try13h8c.js +8448 -0
  115. package/dist/chunks/studio-vfq8qpjt.js +1219 -0
  116. package/dist/chunks/studio-vhv5tgxm.js +51 -0
  117. package/dist/chunks/{studio-ahn3pdgx.js → studio-vw7mzp6z.js} +52 -38
  118. package/dist/chunks/studio-wqpngpsk.js +174 -0
  119. package/dist/chunks/studio-wqz6dggm.js +1356 -0
  120. package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
  121. package/dist/chunks/studio-yxa81f45.js +12 -0
  122. package/dist/chunks/studio-zdn2g6dt.js +148 -0
  123. package/dist/chunks/swatch-group-t0n6h2rn.js +139 -0
  124. package/dist/chunks/tabs-wbp1cdws.js +156 -0
  125. package/dist/chunks/textfield-abk6qyee.js +73 -0
  126. package/dist/chunks/toast-780pvfbv.js +27 -0
  127. package/dist/chunks/toast-host-3sqv46sn.js +116 -0
  128. package/dist/chunks/toolbar-xbh5bhtr.js +194 -0
  129. package/dist/chunks/tooltip-eptb614w.js +369 -0
  130. package/dist/chunks/tree-a73p0pqm.js +367 -0
  131. package/dist/chunks/{tsMode-76kr53q0.js → tsMode-jy4m86rv.js} +83 -85
  132. package/dist/chunks/workspace-t55jdjbx.js +69 -0
  133. package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
  134. package/dist/iframe-entry.js +1873 -673
  135. package/dist/studio.js +52757 -36535
  136. package/dist/workers/editor.worker.js +1040 -1085
  137. package/dist/workers/json.worker.js +1946 -1991
  138. package/dist/workers/ts.worker.js +4960 -5005
  139. package/index.html +1 -0
  140. package/package.json +18 -52
  141. package/src/about/about-modal.ts +72 -123
  142. package/src/browse/library-commands.ts +20 -49
  143. package/src/browse/library-layouts.ts +87 -218
  144. package/src/browse/library-pane.ts +406 -438
  145. package/src/canvas/canvas-helpers.ts +0 -49
  146. package/src/canvas/canvas-live-render.ts +25 -2
  147. package/src/canvas/canvas-render.ts +666 -231
  148. package/src/canvas/canvas-surface.ts +0 -1
  149. package/src/canvas/canvas-utils.ts +333 -113
  150. package/src/canvas/dialog-path.ts +76 -0
  151. package/src/canvas/dialog-state.ts +67 -0
  152. package/src/canvas/diff-marks.ts +252 -0
  153. package/src/canvas/diff-toolbar.ts +349 -0
  154. package/src/canvas/diff-view.ts +123 -0
  155. package/src/canvas/edit-width-drag.ts +187 -0
  156. package/src/canvas/edit-width.ts +150 -0
  157. package/src/canvas/iframe-entry.ts +125 -8
  158. package/src/canvas/iframe-host.ts +271 -15
  159. package/src/canvas/iframe-interaction.ts +133 -13
  160. package/src/canvas/iframe-patch.ts +7 -1
  161. package/src/canvas/iframe-position.ts +5 -6
  162. package/src/canvas/iframe-protocol.ts +106 -5
  163. package/src/canvas/iframe-render.ts +373 -5
  164. package/src/canvas/iframe-slash.ts +2 -2
  165. package/src/canvas/iframe-subtree.ts +5 -8
  166. package/src/canvas/path-mapping.ts +25 -3
  167. package/src/canvas/popover-path.ts +106 -0
  168. package/src/canvas/popover-state.ts +155 -0
  169. package/src/canvas/surface-registry.ts +21 -10
  170. package/src/collab/presence-chips.ts +51 -73
  171. package/src/commands/app-commands.ts +10 -0
  172. package/src/commands/budget.ts +12 -0
  173. package/src/commands/command-args.ts +404 -6
  174. package/src/commands/defaults.ts +44 -14
  175. package/src/commands/live-context.ts +11 -5
  176. package/src/commands/reference.ts +12 -2
  177. package/src/commands/registry.ts +177 -10
  178. package/src/commands/run-reported.ts +120 -0
  179. package/src/content/entry-commands.ts +16 -23
  180. package/src/content/entry-editor.ts +144 -101
  181. package/src/editor/canvas-slash-bridge.ts +2 -2
  182. package/src/editor/context-menu.ts +49 -200
  183. package/src/editor/convert-to-component.ts +42 -82
  184. package/src/editor/convert-to-repeater.ts +132 -173
  185. package/src/editor/inline-edit.ts +11 -0
  186. package/src/editor/shortcuts.ts +76 -49
  187. package/src/editor/slash-menu.ts +150 -157
  188. package/src/files/components.ts +39 -0
  189. package/src/files/file-ops.ts +117 -11
  190. package/src/files/files.ts +944 -660
  191. package/src/files/json-layout.ts +474 -0
  192. package/src/files/serialize-document.ts +8 -1
  193. package/src/format/convert-file.ts +16 -10
  194. package/src/format/format-host.ts +50 -1
  195. package/src/github/github-auth.ts +71 -29
  196. package/src/github/github-publish.ts +57 -65
  197. package/src/grid/cell-editors.ts +46 -4
  198. package/src/grid/cell-popovers.ts +65 -62
  199. package/src/grid/grid-open.ts +86 -64
  200. package/src/grid/grid-panel.ts +390 -469
  201. package/src/grid/redirects-grid.ts +40 -44
  202. package/src/hosting/layout.ts +2 -0
  203. package/src/i18n/i18n-commands.ts +137 -62
  204. package/src/media/media-pane.ts +83 -133
  205. package/src/new-project/add-repo-modal.ts +125 -176
  206. package/src/new-project/import-tab.ts +181 -252
  207. package/src/new-project/location-fields.ts +93 -160
  208. package/src/new-project/new-project-modal.ts +376 -367
  209. package/src/packages/jxsuite-update.ts +76 -18
  210. package/src/packages/pull-package-sync.ts +5 -1
  211. package/src/panels/activity-panel.ts +137 -104
  212. package/src/panels/ai-chat/chat-markdown.ts +15 -13
  213. package/src/panels/ai-chat/chat-view.ts +307 -472
  214. package/src/panels/ai-chat/composer.ts +175 -163
  215. package/src/panels/ai-chat/sessions-view.ts +31 -62
  216. package/src/panels/ai-panel.ts +213 -185
  217. package/src/panels/block-action-bar.ts +444 -645
  218. package/src/panels/bottom-dock.ts +112 -47
  219. package/src/panels/chat-panel.ts +19 -14
  220. package/src/panels/data-explorer.ts +141 -102
  221. package/src/panels/data-grid.ts +183 -150
  222. package/src/panels/dnd.ts +75 -20
  223. package/src/panels/editors.ts +26 -19
  224. package/src/panels/elements-panel.ts +243 -186
  225. package/src/panels/empty-state.ts +26 -42
  226. package/src/panels/events-panel.ts +950 -729
  227. package/src/panels/formula-workspace.ts +434 -207
  228. package/src/panels/frontmatter-fields.ts +185 -153
  229. package/src/panels/frontmatter-panel.ts +411 -187
  230. package/src/panels/git-diff-open.ts +148 -0
  231. package/src/panels/git-panel.ts +679 -605
  232. package/src/panels/head-panel.ts +617 -435
  233. package/src/panels/i18n-panel.ts +148 -135
  234. package/src/panels/imports-panel.ts +388 -414
  235. package/src/panels/jump-bar.ts +175 -147
  236. package/src/panels/layers-panel.ts +785 -671
  237. package/src/panels/left-panel.ts +166 -94
  238. package/src/panels/navigator-panels.ts +1 -1
  239. package/src/panels/pane-context.ts +529 -677
  240. package/src/panels/pane-grid.ts +265 -241
  241. package/src/panels/panel-registry.ts +15 -4
  242. package/src/panels/problems-panel.ts +181 -99
  243. package/src/panels/properties-panel.ts +1525 -966
  244. package/src/panels/provenance.ts +31 -113
  245. package/src/panels/quick-search.ts +223 -184
  246. package/src/panels/right-panel.ts +135 -169
  247. package/src/panels/seo-modal.ts +346 -167
  248. package/src/panels/settings-menu.ts +114 -661
  249. package/src/panels/settings-pane.ts +102 -86
  250. package/src/panels/signals-panel.ts +1318 -1172
  251. package/src/panels/statement-editor.ts +556 -428
  252. package/src/panels/style-panel.ts +1367 -630
  253. package/src/panels/style-utils.ts +36 -32
  254. package/src/panels/stylebook-doc.ts +30 -73
  255. package/src/panels/stylebook-layers-panel.ts +202 -109
  256. package/src/panels/stylebook-panel.ts +124 -88
  257. package/src/panels/tab-strip.ts +386 -288
  258. package/src/platforms/cloud.ts +106 -16
  259. package/src/platforms/devserver.ts +13 -0
  260. package/src/publish/deploy-checklist.ts +124 -78
  261. package/src/publish/publish-commands.ts +4 -12
  262. package/src/publish/publish-panel.ts +134 -328
  263. package/src/services/a11y-report.ts +100 -43
  264. package/src/services/ai-command-tools.ts +538 -0
  265. package/src/services/ai-project-tools.ts +8 -2
  266. package/src/services/ai-session-store.ts +6 -0
  267. package/src/services/ai-system-prompt.ts +112 -24
  268. package/src/services/ai-tools.ts +36 -212
  269. package/src/services/ai-write-report.ts +174 -0
  270. package/src/services/document-assistant.ts +59 -8
  271. package/src/services/idle.ts +16 -14
  272. package/src/services/live-surfaces.ts +237 -0
  273. package/src/services/model-uri.ts +75 -0
  274. package/src/services/notify.ts +63 -6
  275. package/src/services/popover-report.ts +325 -0
  276. package/src/services/surface-registry.ts +56 -0
  277. package/src/services/tool-executor.ts +6 -0
  278. package/src/settings/contexts-section.ts +301 -299
  279. package/src/settings/contributed-section.ts +361 -222
  280. package/src/settings/css-vars-editor.ts +320 -325
  281. package/src/settings/defs-editor.ts +572 -535
  282. package/src/settings/dependencies-editor.ts +79 -107
  283. package/src/settings/extension-commands.ts +379 -0
  284. package/src/settings/extension-rows.ts +113 -0
  285. package/src/settings/extensions-section.ts +287 -0
  286. package/src/settings/general-settings.ts +130 -181
  287. package/src/settings/head-editor.ts +10 -305
  288. package/src/settings/locales-section.ts +146 -196
  289. package/src/settings/preferences-accounts.ts +1 -1
  290. package/src/settings/preferences-dialog.ts +350 -330
  291. package/src/settings/project-sections.ts +108 -181
  292. package/src/settings/schema-field-ui.ts +11 -399
  293. package/src/settings/section-registry.ts +8 -1
  294. package/src/settings/settings-document.ts +31 -29
  295. package/src/shell/tree.ts +42 -87
  296. package/src/shell.ts +48 -36
  297. package/src/studio.ts +104 -69
  298. package/src/style/token-ref.ts +0 -39
  299. package/src/surfaces/about.json +263 -0
  300. package/src/surfaces/about.ts +163 -0
  301. package/src/surfaces/add-repo.json +486 -0
  302. package/src/surfaces/add-repo.ts +236 -0
  303. package/src/surfaces/ai-chat.json +2185 -0
  304. package/src/surfaces/ai-chat.ts +549 -0
  305. package/src/surfaces/ai-credentials-form.json +332 -0
  306. package/src/surfaces/ai-credentials-form.ts +151 -0
  307. package/src/surfaces/ai-managed-connect.json +108 -0
  308. package/src/surfaces/ai-managed-connect.ts +123 -0
  309. package/src/surfaces/ai-model-picker.json +114 -0
  310. package/src/surfaces/ai-model-picker.ts +139 -0
  311. package/src/surfaces/block-action-bar.json +640 -0
  312. package/src/surfaces/block-action-bar.ts +368 -0
  313. package/src/surfaces/bottom-dock.json +154 -0
  314. package/src/surfaces/bottom-dock.ts +125 -0
  315. package/src/surfaces/canvas-stage.json +444 -0
  316. package/src/surfaces/canvas-stage.ts +253 -0
  317. package/src/surfaces/cf-account-picker.json +300 -0
  318. package/src/surfaces/cf-account-picker.ts +214 -0
  319. package/src/surfaces/commandbar.json +985 -0
  320. package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +417 -391
  321. package/src/surfaces/convert-repeater.json +309 -0
  322. package/src/surfaces/convert-repeater.ts +276 -0
  323. package/src/surfaces/data-actions.json +157 -0
  324. package/src/surfaces/data-actions.ts +115 -0
  325. package/src/surfaces/dialog.json +289 -0
  326. package/src/surfaces/dialog.ts +343 -0
  327. package/src/surfaces/diff-toolbar.json +266 -0
  328. package/src/surfaces/diff-toolbar.ts +139 -0
  329. package/src/surfaces/doc-header.json +739 -0
  330. package/src/surfaces/doc-header.ts +223 -0
  331. package/src/surfaces/empty-state.json +152 -0
  332. package/src/surfaces/empty-state.ts +173 -0
  333. package/src/surfaces/entry-editor.json +281 -0
  334. package/src/surfaces/entry-editor.ts +191 -0
  335. package/src/surfaces/expression-editor.json +977 -0
  336. package/src/surfaces/expression-editor.ts +266 -0
  337. package/src/surfaces/files-panel.json +592 -0
  338. package/src/surfaces/files-panel.ts +301 -0
  339. package/src/surfaces/formula-palette.json +364 -0
  340. package/src/surfaces/formula-palette.ts +340 -0
  341. package/src/surfaces/git-panel.json +1822 -0
  342. package/src/surfaces/git-panel.ts +272 -0
  343. package/src/surfaces/github-auth.json +112 -0
  344. package/src/surfaces/github-auth.ts +139 -0
  345. package/src/surfaces/github-publish.json +206 -0
  346. package/src/surfaces/github-publish.ts +169 -0
  347. package/src/surfaces/grid-cell.json +218 -0
  348. package/src/surfaces/grid-cell.ts +120 -0
  349. package/src/surfaces/grid-open.json +147 -0
  350. package/src/surfaces/grid-open.ts +87 -0
  351. package/src/surfaces/grid-panel.json +706 -0
  352. package/src/surfaces/grid-panel.ts +206 -0
  353. package/src/surfaces/grid-replace.json +179 -0
  354. package/src/surfaces/grid-replace.ts +89 -0
  355. package/src/surfaces/grid-views.json +446 -0
  356. package/src/surfaces/grid-views.ts +172 -0
  357. package/src/surfaces/inspector-dock.json +187 -0
  358. package/src/surfaces/inspector-dock.ts +161 -0
  359. package/src/surfaces/jump-bar.json +243 -0
  360. package/src/surfaces/jump-bar.ts +129 -0
  361. package/src/surfaces/jxsuite-update.json +146 -0
  362. package/src/surfaces/jxsuite-update.ts +149 -0
  363. package/src/surfaces/library-pane.json +1509 -0
  364. package/src/surfaces/library-pane.ts +363 -0
  365. package/src/surfaces/logic-panel.json +1949 -0
  366. package/src/surfaces/logic-panel.ts +369 -0
  367. package/src/surfaces/logic-workspace.json +685 -0
  368. package/src/surfaces/logic-workspace.ts +238 -0
  369. package/src/surfaces/media-browser.json +303 -0
  370. package/src/surfaces/media-browser.ts +145 -0
  371. package/src/surfaces/media-field.json +163 -0
  372. package/src/surfaces/media-field.ts +116 -0
  373. package/src/surfaces/media-pane.json +513 -0
  374. package/src/surfaces/media-pane.ts +197 -0
  375. package/src/surfaces/menu.json +232 -0
  376. package/src/surfaces/menu.ts +375 -0
  377. package/src/surfaces/navigator-dock.json +113 -0
  378. package/src/surfaces/navigator-dock.ts +130 -0
  379. package/src/surfaces/new-project.json +1654 -0
  380. package/src/surfaces/new-project.ts +411 -0
  381. package/src/surfaces/palette.json +535 -0
  382. package/src/surfaces/pane-context.json +1497 -0
  383. package/src/surfaces/pane-context.ts +513 -0
  384. package/src/surfaces/pane-grid.json +188 -0
  385. package/src/surfaces/pane-grid.ts +250 -0
  386. package/src/surfaces/panel-activity.json +563 -0
  387. package/src/surfaces/panel-activity.ts +187 -0
  388. package/src/surfaces/panel-data.json +141 -0
  389. package/src/surfaces/panel-data.ts +156 -0
  390. package/src/surfaces/panel-deploy-checklist.json +283 -0
  391. package/src/surfaces/panel-deploy-checklist.ts +175 -0
  392. package/src/surfaces/panel-elements.json +367 -0
  393. package/src/surfaces/panel-elements.ts +175 -0
  394. package/src/surfaces/panel-i18n.json +569 -0
  395. package/src/surfaces/panel-i18n.ts +212 -0
  396. package/src/surfaces/panel-imports.json +780 -0
  397. package/src/surfaces/panel-imports.ts +209 -0
  398. package/src/surfaces/panel-outline.json +734 -0
  399. package/src/surfaces/panel-outline.ts +326 -0
  400. package/src/surfaces/panel-page.json +1017 -0
  401. package/src/surfaces/panel-page.ts +240 -0
  402. package/src/surfaces/panel-problems.json +497 -0
  403. package/src/surfaces/panel-problems.ts +157 -0
  404. package/src/surfaces/panel-signals.json +1973 -0
  405. package/src/surfaces/panel-signals.ts +436 -0
  406. package/src/surfaces/panel-stylebook-layers.json +317 -0
  407. package/src/surfaces/panel-stylebook-layers.ts +155 -0
  408. package/src/surfaces/preferences.json +850 -0
  409. package/src/surfaces/preferences.ts +332 -0
  410. package/src/surfaces/progress-modal.json +110 -0
  411. package/src/surfaces/progress-modal.ts +150 -0
  412. package/src/surfaces/properties-panel.json +1578 -0
  413. package/src/surfaces/properties-panel.ts +337 -0
  414. package/src/surfaces/publish.json +945 -0
  415. package/src/surfaces/publish.ts +392 -0
  416. package/src/surfaces/push-plan.json +110 -0
  417. package/src/surfaces/push-plan.ts +87 -0
  418. package/src/surfaces/rail.json +255 -0
  419. package/src/surfaces/rail.ts +206 -0
  420. package/src/surfaces/reference-field.json +191 -0
  421. package/src/surfaces/reference-field.ts +168 -0
  422. package/src/surfaces/schema-builder.json +1011 -0
  423. package/src/surfaces/schema-builder.ts +181 -0
  424. package/src/surfaces/schema-form.json +1013 -0
  425. package/src/surfaces/schema-form.ts +287 -0
  426. package/src/surfaces/secret-field.json +60 -0
  427. package/src/surfaces/secret-field.ts +146 -0
  428. package/src/surfaces/seo.json +932 -0
  429. package/src/surfaces/seo.ts +334 -0
  430. package/src/surfaces/settings-contexts.json +538 -0
  431. package/src/surfaces/settings-contexts.ts +196 -0
  432. package/src/surfaces/settings-contributed.json +489 -0
  433. package/src/surfaces/settings-contributed.ts +199 -0
  434. package/src/surfaces/settings-css-vars.json +820 -0
  435. package/src/surfaces/settings-css-vars.ts +199 -0
  436. package/src/surfaces/settings-defs.json +1363 -0
  437. package/src/surfaces/settings-defs.ts +232 -0
  438. package/src/surfaces/settings-deploy.json +108 -0
  439. package/src/surfaces/settings-deploy.ts +135 -0
  440. package/src/surfaces/settings-extensions.json +486 -0
  441. package/src/surfaces/settings-extensions.ts +201 -0
  442. package/src/surfaces/settings-head.json +779 -0
  443. package/src/surfaces/settings-head.ts +397 -0
  444. package/src/surfaces/settings-locales.json +420 -0
  445. package/src/surfaces/settings-locales.ts +137 -0
  446. package/src/surfaces/settings-overview.json +423 -0
  447. package/src/surfaces/settings-overview.ts +218 -0
  448. package/src/surfaces/settings-packages.json +549 -0
  449. package/src/surfaces/settings-packages.ts +158 -0
  450. package/src/surfaces/settings-pane.json +147 -0
  451. package/src/surfaces/settings-pane.ts +150 -0
  452. package/src/surfaces/settings-rawjson.json +104 -0
  453. package/src/surfaces/settings-rawjson.ts +107 -0
  454. package/src/surfaces/shell.json +99 -0
  455. package/src/surfaces/shell.ts +30 -0
  456. package/src/surfaces/slash-menu.json +180 -0
  457. package/src/surfaces/slash-menu.ts +272 -0
  458. package/src/surfaces/statements.json +607 -0
  459. package/src/surfaces/statements.ts +238 -0
  460. package/src/surfaces/statusbar.json +94 -0
  461. package/src/{panels → surfaces}/statusbar.ts +164 -90
  462. package/src/surfaces/style-panel.json +1643 -0
  463. package/src/surfaces/style-panel.ts +338 -0
  464. package/src/surfaces/stylebook-chrome.json +122 -0
  465. package/src/surfaces/stylebook-chrome.ts +122 -0
  466. package/src/surfaces/tab-strip.json +448 -0
  467. package/src/surfaces/tab-strip.ts +200 -0
  468. package/src/surfaces/target-line.json +419 -0
  469. package/src/surfaces/target-line.ts +349 -0
  470. package/src/surfaces/toasts.json +189 -0
  471. package/src/surfaces/welcome.json +571 -0
  472. package/src/surfaces/welcome.ts +338 -0
  473. package/src/tabs/project-config.ts +111 -21
  474. package/src/tabs/tab.ts +52 -1
  475. package/src/types.ts +22 -0
  476. package/src/ui/ai-credentials-form.ts +104 -100
  477. package/src/ui/ai-managed-connect.ts +54 -36
  478. package/src/ui/ai-model-picker.ts +75 -47
  479. package/src/ui/cf-account-picker.ts +76 -141
  480. package/src/ui/color-selector.ts +80 -301
  481. package/src/ui/dynamic-slot.ts +43 -283
  482. package/src/ui/expression-editor.ts +797 -576
  483. package/src/ui/field-input.ts +8 -181
  484. package/src/ui/form-controls.ts +838 -366
  485. package/src/ui/formula-chips.ts +80 -85
  486. package/src/ui/kit.ts +33 -0
  487. package/src/ui/layers.ts +296 -593
  488. package/src/ui/media-picker.ts +203 -284
  489. package/src/ui/panel-resize.ts +251 -64
  490. package/src/ui/popover-surface.ts +153 -0
  491. package/src/ui/progress-modal.ts +22 -60
  492. package/src/ui/regions.ts +13 -7
  493. package/src/ui/schema-form.ts +906 -440
  494. package/src/ui/surface.ts +122 -0
  495. package/src/ui/unit-selector.ts +15 -131
  496. package/src/ui/value-source.ts +14 -0
  497. package/src/ui/virtual-window.ts +88 -9
  498. package/src/utils/canvas-media.ts +72 -0
  499. package/src/utils/edit-display.ts +7 -2
  500. package/src/utils/element-selectors.ts +69 -0
  501. package/src/utils/link-target.ts +2 -2
  502. package/src/utils/studio-utils.ts +0 -10
  503. package/src/view.ts +15 -0
  504. package/src/workspace/pane-derive.ts +36 -14
  505. package/src/workspace/workspace.ts +75 -6
  506. package/styles/canvas.css +72 -467
  507. package/styles/forced-colors.css +48 -82
  508. package/styles/forced-colors.json +41 -0
  509. package/styles/inspector.css +2 -1301
  510. package/styles/overlays.css +96 -2823
  511. package/styles/panels.css +6 -1423
  512. package/styles/shell-frame.css +272 -0
  513. package/styles/shell-frame.json +227 -0
  514. package/styles/shell.css +0 -1568
  515. package/styles/tokens.css +65 -136
  516. package/styles/tokens.json +84 -0
  517. package/dist/chunks/Overlay.dev-etqjwyf9.js +0 -23
  518. package/dist/chunks/adapter-jkcyhgtr.js +0 -14
  519. package/dist/chunks/cf-account-picker-en86v7x7.js +0 -163
  520. package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
  521. package/dist/chunks/components-zmx10t62.js +0 -21
  522. package/dist/chunks/content-source-48xg86wj.js +0 -49
  523. package/dist/chunks/convert-to-repeater-43tfn7cs.js +0 -268
  524. package/dist/chunks/editor-cptq5jp1.js +0 -37
  525. package/dist/chunks/entry-commands-e63f1xc0.js +0 -46
  526. package/dist/chunks/extension-sections-txv08xxg.js +0 -311
  527. package/dist/chunks/file-ops-wbh4hhsx.js +0 -48
  528. package/dist/chunks/files-3kfkwhk4.js +0 -93
  529. package/dist/chunks/flow-qbfgrpeh.js +0 -634
  530. package/dist/chunks/focus-trap.esm-9t2drp0g.js +0 -1025
  531. package/dist/chunks/focus-visible-6eg70z18.js +0 -167
  532. package/dist/chunks/format-host-w16q81tf.js +0 -43
  533. package/dist/chunks/fs-events-hrrg328g.js +0 -21
  534. package/dist/chunks/git-panel-532whr1y.js +0 -59
  535. package/dist/chunks/index-zqxmqxmh.js +0 -109
  536. package/dist/chunks/jx-validate-8er6gbxy.js +0 -19
  537. package/dist/chunks/layers-panel-07hm7g5j.js +0 -67
  538. package/dist/chunks/layers-q75tj2mf.js +0 -45
  539. package/dist/chunks/lit-html-j055mkh8.js +0 -22
  540. package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
  541. package/dist/chunks/notify-yjm79n4s.js +0 -30
  542. package/dist/chunks/parse-24d0gay3.js +0 -19
  543. package/dist/chunks/platform-ba1j1gbh.js +0 -16
  544. package/dist/chunks/publish-panel-v9st96ja.js +0 -29
  545. package/dist/chunks/quick-search-zccjp6gv.js +0 -66
  546. package/dist/chunks/references-3qx8fkyp.js +0 -29
  547. package/dist/chunks/right-panel-vm3b6kwy.js +0 -46
  548. package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
  549. package/dist/chunks/sp-overlay.dev-qgvhnxf4.js +0 -18
  550. package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
  551. package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
  552. package/dist/chunks/sp-tooltip.dev-4sastdnw.js +0 -15
  553. package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
  554. package/dist/chunks/studio-0a5qrh01.js +0 -3
  555. package/dist/chunks/studio-0bq6eh7v.js +0 -12
  556. package/dist/chunks/studio-18j3bmcz.js +0 -14
  557. package/dist/chunks/studio-1ngbejft.js +0 -181
  558. package/dist/chunks/studio-4b5z1x43.js +0 -424
  559. package/dist/chunks/studio-4n2b5gzb.js +0 -357
  560. package/dist/chunks/studio-4rzyrtjz.js +0 -426
  561. package/dist/chunks/studio-5fx3g9jg.js +0 -4325
  562. package/dist/chunks/studio-5myknm0a.js +0 -1903
  563. package/dist/chunks/studio-7afd21nw.js +0 -67
  564. package/dist/chunks/studio-7nte2hj4.js +0 -613
  565. package/dist/chunks/studio-8jpzqk5s.js +0 -128
  566. package/dist/chunks/studio-8q517dfr.js +0 -24
  567. package/dist/chunks/studio-950k0dx6.js +0 -6939
  568. package/dist/chunks/studio-9n4mrmnb.js +0 -184
  569. package/dist/chunks/studio-a0tswy0w.js +0 -58
  570. package/dist/chunks/studio-ahnzd9rg.js +0 -23
  571. package/dist/chunks/studio-bgxt93ga.js +0 -62
  572. package/dist/chunks/studio-cmb03bg5.js +0 -13890
  573. package/dist/chunks/studio-d1ks410h.js +0 -175
  574. package/dist/chunks/studio-ef49pnzx.js +0 -387
  575. package/dist/chunks/studio-eqq1w638.js +0 -113
  576. package/dist/chunks/studio-ew0djmhg.js +0 -341
  577. package/dist/chunks/studio-gfgb8pe6.js +0 -1652
  578. package/dist/chunks/studio-h4rxscfc.js +0 -10
  579. package/dist/chunks/studio-jc994dnr.js +0 -1066
  580. package/dist/chunks/studio-kyh9avvv.js +0 -28
  581. package/dist/chunks/studio-m3hwn7y1.js +0 -120
  582. package/dist/chunks/studio-mtfnaqs9.js +0 -659
  583. package/dist/chunks/studio-n6j9t10q.js +0 -318
  584. package/dist/chunks/studio-n8b9wqwy.js +0 -291
  585. package/dist/chunks/studio-qcy05dp8.js +0 -1743
  586. package/dist/chunks/studio-qq6jym04.js +0 -53
  587. package/dist/chunks/studio-rdx8jcxy.js +0 -83
  588. package/dist/chunks/studio-rn9ta2mz.js +0 -111
  589. package/dist/chunks/studio-t7qb9db8.js +0 -665
  590. package/dist/chunks/studio-tmc5emrw.js +0 -8
  591. package/dist/chunks/studio-z6nw2ek2.js +0 -18
  592. package/dist/chunks/studio-zczps70q.js +0 -378
  593. package/dist/chunks/studio-zqazsct2.js +0 -1823
  594. package/dist/chunks/workspace-fjx52ryv.js +0 -89
  595. package/src/panels/activity-bar.ts +0 -251
  596. package/src/panels/panel-scheduler.ts +0 -219
  597. package/src/panels/style-inputs.ts +0 -237
  598. package/src/panels/target-line.ts +0 -274
  599. package/src/panels/welcome-screen.ts +0 -346
  600. package/src/ui/button-group.ts +0 -102
  601. package/src/ui/choice-field.ts +0 -72
  602. package/src/ui/field-row.ts +0 -249
  603. package/src/ui/formula-palette.ts +0 -213
  604. package/src/ui/icons.ts +0 -52
  605. package/src/ui/jx-theme.ts +0 -130
  606. package/src/ui/spectrum.ts +0 -340
  607. package/src/ui/value-selector.ts +0 -174
  608. package/src/ui/widgets.ts +0 -172
  609. /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
  610. /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
  611. /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
  612. /package/dist/chunks/{tsMode-ef187txx.css → tsMode-hnxxb73h.css} +0 -0
@@ -25,6 +25,7 @@ import type {
25
25
  ComponentMeta,
26
26
  CreateProjectDestination,
27
27
  DirEntry,
28
+ ExtensionCatalogEntry,
28
29
  ExtensionsInfo,
29
30
  FsEvent,
30
31
  GitBranchesResult,
@@ -60,6 +61,15 @@ interface ProjectInfoWire {
60
61
  projectConfig: Record<string, unknown> | null;
61
62
  }
62
63
 
64
+ /** One row of the platform's project catalogue (`GET /api/v1/projects`). */
65
+ interface ProjectListWire {
66
+ fullName: string;
67
+ owner: string;
68
+ name: string;
69
+ defaultBranch: string;
70
+ permission: string;
71
+ }
72
+
63
73
  interface SessionEventWire {
64
74
  kind: "fs" | "git";
65
75
  events?: FsEvent[];
@@ -304,6 +314,35 @@ export function parseRootKey(root: string): CloudProject | null {
304
314
  return { owner, repo, branch };
305
315
  }
306
316
 
317
+ /** Every project this account can open, straight off the wire; [] when the catalogue is unreachable. */
318
+ async function fetchProjects(): Promise<ProjectListWire[]> {
319
+ const res = await fetch("/api/v1/projects", { credentials: "include" });
320
+ return res.ok ? ((await res.json()) as ProjectListWire[]) : [];
321
+ }
322
+
323
+ /**
324
+ * The project a root key names, for the two members that navigate by one.
325
+ *
326
+ * Tolerates the branchless "owner/repo" keys older studios wrote into Recent: they cannot say which
327
+ * branch they meant, so the catalogue's default branch answers for them — the same branch that
328
+ * project's Projects row opens. Null when the key is neither form, or names nothing this account
329
+ * can reach.
330
+ */
331
+ export async function resolveRootKey(rootKey: string): Promise<CloudProject | null> {
332
+ const parsed = parseRootKey(rootKey);
333
+ if (parsed) {
334
+ return parsed;
335
+ }
336
+ const legacy = /^([^/@]+)\/([^/@]+)$/.exec(rootKey);
337
+ if (!legacy) {
338
+ return null;
339
+ }
340
+ const [, owner, repo] = legacy;
341
+ const catalogue = await fetchProjects().catch(() => []);
342
+ const match = catalogue.find((p) => p.owner === owner && p.name === repo);
343
+ return match ? { owner: match.owner, repo: match.name, branch: match.defaultBranch } : null;
344
+ }
345
+
307
346
  /**
308
347
  * Bound mode (project non-null) drives one repo+branch session; project-less mode (null, the
309
348
  * /studio route) exposes only the catalogue surface — listProjects/listStarters/createProject and
@@ -311,7 +350,17 @@ export function parseRootKey(root: string): CloudProject | null {
311
350
  */
312
351
  export function createCloudPlatform(project: CloudProject | null): StudioPlatform {
313
352
  const base = project ? sessionBase(project) : "";
314
- const root = project ? `${project.owner}/${project.repo}` : "";
353
+ /* The ROOT KEY, branch included — not a bare "owner/repo". This value is the project's identity
354
+ everywhere the shell keeps one: `probeRootProject` hands it to the recent-projects list, and
355
+ `setWindowProject` reopens a project by parsing it back with `parseRootKey`, which answers null
356
+ for a branchless key. So every Recent row a bound session had written was a click that did
357
+ nothing — no navigation, no error, and `deduped: true` telling the caller the open had been
358
+ handled — while the SAME project opened fine from the Projects catalogue, whose entries carry
359
+ the branch (`listProjects` below builds them with `projectRootKey`). Agreeing with the catalogue
360
+ also restores the welcome screen's dedupe (it matches the two lists by root, so the project
361
+ stopped appearing in both) and gives a branch its own Recent row, which is what a root key that
362
+ names a branch is for. */
363
+ const root = project ? projectRootKey(project) : "";
315
364
  /**
316
365
  * One multiplexed collab socket per session; per-doc handles come from openDoc. Memoized as a
317
366
  * promise so concurrent first opens share the connection instead of racing two sockets.
@@ -629,6 +678,45 @@ export function createCloudPlatform(project: CloudProject | null): StudioPlatfor
629
678
  }
630
679
  },
631
680
 
681
+ /**
682
+ * The extensions THIS WORKER bundles — not the shipped first-party catalogue.
683
+ *
684
+ * A Worker ships a fixed set of extension packages (specs/extensions.md §5.5), decided by the
685
+ * platform build rather than by this repository's `extensions/` tree, so the gateway is the
686
+ * only thing that knows. Everything it returns is therefore `bundled: true`: enabling one is a
687
+ * `project.json` write alone, and an extension the Worker does not bundle is dropped from the
688
+ * registry before composition — advertising it would promise a toggle that silently does
689
+ * nothing.
690
+ *
691
+ * `installed` here means DECLARED. Nothing resolves a module in a Worker: `addPackage` is a
692
+ * manifest edit and resolution happens later in Pages CI, so the manifest is the only fact this
693
+ * adapter has, and it is the one the reader is being asked about.
694
+ *
695
+ * Degrades to an EMPTY list, which is the whole contract: a session whose gateway predates this
696
+ * route must offer nothing rather than five extensions three of which it cannot load.
697
+ */
698
+ async listExtensionCatalog(): Promise<ExtensionCatalogEntry[]> {
699
+ try {
700
+ const res = await api("/catalog");
701
+ if (!res.ok) {
702
+ return [];
703
+ }
704
+ const entries = (await res.json()) as ExtensionCatalogEntry[];
705
+ const pkg = await readPackageJson();
706
+ const declared = new Set([
707
+ ...Object.keys((pkg["dependencies"] ?? {}) as Record<string, string>),
708
+ ...Object.keys((pkg["devDependencies"] ?? {}) as Record<string, string>),
709
+ ]);
710
+ for (const entry of entries) {
711
+ entry.bundled = true;
712
+ entry.installed = declared.has(entry.name);
713
+ }
714
+ return entries;
715
+ } catch {
716
+ return [];
717
+ }
718
+ },
719
+
632
720
  /**
633
721
  * The session's generated entry documents, composed server-side from the core schemas and each
634
722
  * enabled extension's fragments (extensions.md §5.2) and returned PRE-BUNDLED — Monaco and the
@@ -928,17 +1016,7 @@ export function createCloudPlatform(project: CloudProject | null): StudioPlatfor
928
1016
  // ─── Project catalogue & navigation (Studio welcome / New Project UI) ──
929
1017
 
930
1018
  async listProjects(): Promise<ProjectListEntry[]> {
931
- const res = await fetch("/api/v1/projects", { credentials: "include" });
932
- if (!res.ok) {
933
- return [];
934
- }
935
- const entries = (await res.json()) as {
936
- fullName: string;
937
- owner: string;
938
- name: string;
939
- defaultBranch: string;
940
- permission: string;
941
- }[];
1019
+ const entries = await fetchProjects();
942
1020
  return entries.map((p) => ({
943
1021
  name: p.fullName,
944
1022
  root: projectRootKey({ owner: p.owner, repo: p.name, branch: p.defaultBranch }),
@@ -956,8 +1034,15 @@ export function createCloudPlatform(project: CloudProject | null): StudioPlatfor
956
1034
 
957
1035
  /** Welcome/recents open path: navigate this tab into the project's editor. */
958
1036
  async setWindowProject(rootKey: string) {
959
- const target = parseRootKey(rootKey);
960
- if (target && typeof location !== "undefined") {
1037
+ const target = await resolveRootKey(rootKey);
1038
+ /* Throw rather than fall through: `deduped` tells the caller the open was handled, so an
1039
+ unresolvable key answered "done" and left the user looking at the screen they clicked on.
1040
+ The throw reaches `openRecentProject`'s catch, which reports the failure and drops the
1041
+ entry — the right end for a row naming a project this account can no longer open. */
1042
+ if (!target) {
1043
+ throw new Error(`No project to open at ${rootKey}`);
1044
+ }
1045
+ if (typeof location !== "undefined") {
961
1046
  location.assign(editUrl(target));
962
1047
  }
963
1048
  // Navigation unloads the page; deduped stops the caller's follow-up work.
@@ -965,8 +1050,13 @@ export function createCloudPlatform(project: CloudProject | null): StudioPlatfor
965
1050
  },
966
1051
 
967
1052
  async openProjectInNewWindow(rootKey: string) {
968
- const target = parseRootKey(rootKey);
969
- if (target && typeof window !== "undefined") {
1053
+ const target = await resolveRootKey(rootKey);
1054
+ // Same contract as setWindowProject: the caller reports "Opened in another window" on any
1055
+ // Resolved call, so a key that opens nothing has to fail rather than answer.
1056
+ if (!target) {
1057
+ throw new Error(`No project to open at ${rootKey}`);
1058
+ }
1059
+ if (typeof window !== "undefined") {
970
1060
  window.open(editUrl(target), "_blank", "noopener");
971
1061
  }
972
1062
  // `_blank` always makes a tab; a browser tab already showing this project is not something
@@ -25,6 +25,7 @@ import type {
25
25
  DataRowsResult,
26
26
  DataRowUpdate,
27
27
  DirEntry,
28
+ ExtensionCatalogEntry,
28
29
  ExtensionsInfo,
29
30
  FsEvent,
30
31
  ImportProgressEvent,
@@ -745,6 +746,18 @@ export function createDevServerPlatform() {
745
746
  return body.extensions ?? [];
746
747
  },
747
748
 
749
+ /**
750
+ * What this backend can offer, enabled or not.
751
+ *
752
+ * Its own route rather than a field on `formats`: that one builds the project's registry and
753
+ * fails when a declared extension does not resolve, which is exactly when a reader needs the
754
+ * catalogue to repair it.
755
+ */
756
+ async listExtensionCatalog(): Promise<ExtensionCatalogEntry[]> {
757
+ const res = await fetch(`/__studio/catalog?dir=${encodeURIComponent(serverPath("."))}`);
758
+ return res.ok ? await readJson<ExtensionCatalogEntry[]>(res) : [];
759
+ },
760
+
748
761
  /** Pre-bundled per-project entry schemas for Monaco registration (empty when unavailable). */
749
762
  async fetchProjectSchemas(): Promise<ProjectSchemasResponse> {
750
763
  const res = await fetch(
@@ -13,11 +13,12 @@
13
13
  *
14
14
  * - {@link deployChecklist} is the ordered prerequisite list, each step carrying **the command that
15
15
  * satisfies it** rather than a sentence telling the reader to go and find one;
16
- * - {@link renderDeployChecklist} is its rendering, and it lives in the Bottom dock's **Activity**
17
- * tab because a deploy is a long operation with a log and the dock cap is four (§2 principle 9).
18
- * It draws in the Activity vocabulary — `activity-row`, `activity-steps`, `activity-step--done` —
19
- * for the same reason: a fifth visual idiom for "an ordered list of stages that finish" would be
20
- * a second design of a thing the tab already has;
16
+ * - {@link deployChecklistView} is its projection and {@link syncDeployChecklist} mounts the document
17
+ * that draws it (`surfaces/panel-deploy-checklist.json`), in the Bottom dock's **Activity** tab
18
+ * because a deploy is a long operation with a log and the dock cap is four (§2 principle 9). It
19
+ * draws in the Activity tab's vocabulary — the same row, the same ordered steps, the same glyphs
20
+ * — for the same reason: a fifth visual idiom for "an ordered list of stages that finish" would
21
+ * be a second design of a thing the tab already has;
21
22
  * - {@link deployStatusItem} is the status bar's project-field item, whose **label is the next
22
23
  * blocking prerequisite** — the shortcut and the explanation in one 24px item, and ambient state
23
24
  * rather than a transient message, which is the only thing that bar carries (§3.2 ⑫).
@@ -34,14 +35,18 @@
34
35
  * renders (`studio.md` §15 rule 1).
35
36
  */
36
37
 
37
- import { html, nothing } from "lit-html";
38
38
  import { activeRegistry } from "../commands/active-registry";
39
39
  import { platformSupportsPublish } from "./pages-service";
40
40
  import { projectState } from "../store";
41
+ import { shallowReactive } from "../reactivity";
41
42
  import { shell } from "../shell";
43
+ import {
44
+ disposeDeployChecklistSurface,
45
+ mountDeployChecklistSurface,
46
+ } from "../surfaces/panel-deploy-checklist";
47
+ import type { DeployChecklistView, DeployStepRowView } from "../surfaces/panel-deploy-checklist";
42
48
  import type { DeployConfig, ProjectConfig } from "@jxsuite/schema/types";
43
49
  import type { PagesDeploymentInfo } from "./pages-service";
44
- import type { TemplateResult } from "lit-html";
45
50
 
46
51
  /** The chain, in the order the links must be forged. */
47
52
  export const DEPLOY_STEP_IDS = ["repo", "remote", "provider", "deployed"] as const;
@@ -84,32 +89,38 @@ export function currentDeploy(): DeployConfig | undefined {
84
89
  }
85
90
 
86
91
  /**
87
- * The last deployment anybody actually observed, or null when nobody has asked.
92
+ * The last deployment anybody actually observed, and whether anybody has asked at all.
88
93
  *
89
94
  * Module state rather than a field on the config: a deployment is a fact about Cloudflare, not
90
95
  * about this repository, and writing it into `project.json` would commit a timestamp that is stale
91
96
  * the moment it is pushed.
97
+ *
98
+ * Reactive, because the checklist is a document now and follows its inputs rather than being
99
+ * repainted by whatever else the dock was drawing: a deploy that finishes writes here, and the row
100
+ * moves off `unknown` with nothing subscribing by hand. `shallowReactive` and not `reactive`, so
101
+ * {@link observedDeployment} hands back the record Cloudflare answered with rather than a proxy of
102
+ * it — `asked` is the flag anything tracks, and the info is read whole or not at all.
92
103
  */
93
- let _observed: PagesDeploymentInfo | null = null;
94
-
95
- /** Whether anybody has asked at all — the difference between `todo` and `unknown`. */
96
- let _asked = false;
104
+ const _seen = shallowReactive<{ asked: boolean; observed: PagesDeploymentInfo | null }>({
105
+ asked: false,
106
+ observed: null,
107
+ });
97
108
 
98
109
  /** Record what Cloudflare answered. `null` means "asked, and there are none". */
99
110
  export function noteDeployment(info: PagesDeploymentInfo | null): void {
100
- _observed = info;
101
- _asked = true;
111
+ _seen.observed = info;
112
+ _seen.asked = true;
102
113
  }
103
114
 
104
115
  /** The observed deployment, or null. */
105
116
  export function observedDeployment(): PagesDeploymentInfo | null {
106
- return _observed;
117
+ return _seen.observed;
107
118
  }
108
119
 
109
120
  /** Forget the observation — project close, and every test that asserts the `unknown` branch. */
110
121
  export function forgetDeployment(): void {
111
- _observed = null;
112
- _asked = false;
122
+ _seen.observed = null;
123
+ _seen.asked = false;
113
124
  }
114
125
 
115
126
  function repoStep(): DeployStep {
@@ -219,7 +230,7 @@ function deployedStep(): DeployStep {
219
230
  state: "todo",
220
231
  };
221
232
  }
222
- if (!_asked) {
233
+ if (!_seen.asked) {
223
234
  return {
224
235
  command: "publish.deploy",
225
236
  detail: "Cloudflare has not been asked yet, so this is not a claim that nothing shipped.",
@@ -228,7 +239,7 @@ function deployedStep(): DeployStep {
228
239
  state: "unknown",
229
240
  };
230
241
  }
231
- if (_observed === null) {
242
+ if (_seen.observed === null) {
232
243
  return {
233
244
  command: "publish.deploy",
234
245
  detail: "Cloudflare reports no deployments for this project.",
@@ -237,17 +248,18 @@ function deployedStep(): DeployStep {
237
248
  state: "todo",
238
249
  };
239
250
  }
240
- return _observed.status === "success"
251
+ const { observed } = _seen;
252
+ return observed.status === "success"
241
253
  ? {
242
254
  command: "publish.deploy",
243
- detail: `${_observed.environment} — ${_observed.url}`,
255
+ detail: `${observed.environment} — ${observed.url}`,
244
256
  id: "deployed",
245
257
  label: "Deploy",
246
258
  state: "done",
247
259
  }
248
260
  : {
249
261
  command: "publish.deploy",
250
- detail: `Last deployment ${_observed.stage}: ${_observed.status}.`,
262
+ detail: `Last deployment ${observed.stage}: ${observed.status}.`,
251
263
  id: "deployed",
252
264
  label: "Deploy",
253
265
  state: "todo",
@@ -298,86 +310,120 @@ export function deployStatusItem(): DeployStatusItem | null {
298
310
  };
299
311
  }
300
312
 
301
- // ─── Rendering ────────────────────────────────────────────────────────────────
302
-
303
- /** Checklist state → the Activity tab's step classes, so one vocabulary draws both. */
304
- const STEP_CLASS: Readonly<Record<DeployStepState, string>> = {
305
- done: "done",
306
- todo: "pending",
307
- unknown: "pending",
308
- };
313
+ // ─── The surface ──────────────────────────────────────────────────────────────
309
314
 
315
+ /** Which glyph a link's state wears. One character, so it fits the row it labels. */
310
316
  const STEP_ICON: Readonly<Record<DeployStepState, string>> = {
311
317
  done: "✓",
312
318
  todo: "·",
313
319
  unknown: "?",
314
320
  };
315
321
 
322
+ /** One prerequisite, flattened for the document: a key, a state, a glyph and a sentence. */
323
+ function stepView(step: DeployStep): DeployStepRowView {
324
+ return {
325
+ icon: STEP_ICON[step.state],
326
+ id: step.id,
327
+ state: step.state,
328
+ /* The detail is dropped once the link is forged: what a done step buys you is not news, and
329
+ four sentences about things that are fine bury the one about the thing that is not. */
330
+ text: step.state === "done" ? step.label : `${step.label} — ${step.detail}`,
331
+ };
332
+ }
333
+
316
334
  /**
317
- * The next action, as a button — or nothing.
335
+ * The next action, as the document reads it — or nothing.
318
336
  *
319
- * A command the registry does not have, or whose `when` is false, renders NOTHING rather than a
320
- * dead label. The status bar's `itemTpl` takes the same position for the same reason: a surface may
321
- * choose whether to show a command, never whether it exists.
337
+ * A command the registry does not have, or whose `when` is false, draws NOTHING rather than a dead
338
+ * label. The status bar's projection takes the same position for the same reason: a surface may
339
+ * choose whether to show a command, never whether it exists (§12.4).
322
340
  */
323
- function actionTpl(step: DeployStep | null): TemplateResult | typeof nothing {
341
+ function actionView(
342
+ step: DeployStep | null,
343
+ ): Pick<DeployChecklistView, "actionDisabled" | "actionLabel" | "actionTitle" | "hasAction"> {
344
+ const none = { actionDisabled: false, actionLabel: "", actionTitle: "", hasAction: false };
324
345
  if (!step) {
325
- return nothing;
346
+ return none;
326
347
  }
327
348
  const registry = activeRegistry();
328
349
  const command = registry?.get(step.command);
329
350
  if (!registry || !command || !registry.isVisible(step.command)) {
330
- return nothing;
351
+ return none;
331
352
  }
332
353
  const reason = registry.disabledReason(step.command);
333
- return html`<sp-action-button
334
- size="s"
335
- ?disabled=${reason !== undefined}
336
- title=${reason ? `${command.title} — requires ${reason}` : command.title}
337
- @click=${() => {
338
- void registry.run(step.command);
339
- }}
340
- >${command.title}</sp-action-button
341
- >`;
354
+ return {
355
+ actionDisabled: reason !== undefined,
356
+ actionLabel: command.title,
357
+ actionTitle: reason ? `${command.title} — requires ${reason}` : command.title,
358
+ hasAction: true,
359
+ };
342
360
  }
343
361
 
344
362
  /**
345
- * The checklist, as the Activity tab draws it — or nothing, when no project is open.
363
+ * The checklist as the document draws it — or an empty row set, when no project is open.
346
364
  *
347
- * Rendered ABOVE the operation list rather than as an entry in it: an activity is something that
348
- * happened, and this is something that has not. It carries no `data-jx-region` stamp — the region
349
- * is `dock.bottom/panel:activity`, which the dock derives, and a hand-stamped leaf is a committed
350
- * budget (§13.2) that this does not need to spend.
365
+ * Read from inside the surface's own effect, so every reactive record it touches on the way (source
366
+ * control's status, the project config, the observation above, the active registry) is tracked and
367
+ * the row follows them.
351
368
  */
352
- export function renderDeployChecklist(): TemplateResult | typeof nothing {
369
+ export function deployChecklistView(): DeployChecklistView {
353
370
  if (!projectState) {
354
- return nothing;
371
+ return {
372
+ actionDisabled: false,
373
+ actionLabel: "",
374
+ actionTitle: "",
375
+ hasAction: false,
376
+ hasProject: false,
377
+ rowIcon: "",
378
+ rowState: "running",
379
+ steps: [],
380
+ summary: "",
381
+ };
355
382
  }
356
383
  const steps = deployChecklist();
357
384
  const next = steps.find((step) => step.state !== "done") ?? null;
358
- return html`
359
- <ul class="activity-list">
360
- <li class="activity-row ${next ? "activity-row--running" : "activity-row--done"}">
361
- <span class="activity-icon" aria-hidden="true">${next ? "⋯" : "✓"}</span>
362
- <div class="activity-body">
363
- <div class="activity-head">
364
- <span class="activity-title">Deploy checklist</span>
365
- <span class="activity-source">Publish</span>
366
- </div>
367
- <div class="activity-status">
368
- ${next ? next.detail : "Everything this project needs to ship is in place."}
369
- </div>
370
- <ol class="activity-steps">
371
- ${steps.map(
372
- (step) => html`<li class="activity-step activity-step--${STEP_CLASS[step.state]}">
373
- <span class="activity-step-icon" aria-hidden="true">${STEP_ICON[step.state]}</span>
374
- ${step.label}${step.state === "done" ? "" : ` — ${step.detail}`}
375
- </li>`,
376
- )}
377
- </ol>
378
- ${actionTpl(next)}
379
- </div>
380
- </li>
381
- </ul>
382
- `;
385
+ return {
386
+ ...actionView(next),
387
+ hasProject: true,
388
+ rowIcon: next ? "⋯" : "✓",
389
+ rowState: next ? "running" : "done",
390
+ steps: steps.map((entry) => stepView(entry)),
391
+ summary: next ? next.detail : "Everything this project needs to ship is in place.",
392
+ };
393
+ }
394
+
395
+ /** Run the next blocking step's command, if the registry has one it will run. */
396
+ function runNextStep(): void {
397
+ const next = nextDeployStep();
398
+ if (!next) {
399
+ return;
400
+ }
401
+ void activeRegistry()?.run(next.command);
402
+ }
403
+
404
+ /** What the surface asks this module for: the projection, and the one decision a click makes. */
405
+ const CHECKLIST_SURFACE = { project: deployChecklistView, runAction: runNextStep };
406
+
407
+ /**
408
+ * Mount the checklist into the container the Activity tab just painted, or take it down.
409
+ *
410
+ * The tab's `afterRender`, so it runs against the DOM lit has committed — and it runs on every
411
+ * paint of the dock, including the ones where another tab is showing. No container means this tab
412
+ * is not on screen, and the document standing in DOM that lit has already thrown away is disposed
413
+ * rather than left holding an effect.
414
+ *
415
+ * Rendered ABOVE the operation feed rather than as an entry in it: an activity is something that
416
+ * happened, and this is something that has not. It carries no `data-jx-region` stamp — the region
417
+ * is `dock.bottom/panel:activity`, which the dock derives, and a hand-stamped leaf is a committed
418
+ * budget (§13.2) that this does not need to spend.
419
+ *
420
+ * @param host The dock body element the tab was rendered into.
421
+ */
422
+ export function syncDeployChecklist(host: HTMLElement): void {
423
+ const container = host.querySelector<HTMLElement>("[data-deploy-checklist]");
424
+ if (!container) {
425
+ disposeDeployChecklistSurface();
426
+ return;
427
+ }
428
+ mountDeployChecklistSurface(container, CHECKLIST_SURFACE);
383
429
  }
@@ -157,12 +157,8 @@ export function publishCommands(): AnyCommand[] {
157
157
  when: (ctx) => ctx.project.open,
158
158
  // `when` already asked about the project.
159
159
  enablement: () => platformSupportsPublish(),
160
- aiTool: {
161
- description:
162
- "Open the publishing set-up flow, which connects this project to a Cloudflare Pages " +
163
- "project that rebuilds on every push.",
164
- name: "set_up_publishing",
165
- },
160
+ /* No `aiTool`, by §12.4's second deletion rule: an auth flow that waits on a person, with
161
+ credentials. */
166
162
  run: async () => {
167
163
  const { openPublishPanel } = await import("./publish-panel");
168
164
  openPublishPanel();
@@ -181,12 +177,8 @@ export function publishCommands(): AnyCommand[] {
181
177
  when: (ctx) => ctx.project.open,
182
178
  enablement: (ctx) =>
183
179
  ctx.project.isRepo && currentDeploy() !== undefined && platformSupportsPublish(),
184
- aiTool: {
185
- description:
186
- "Push the current branch so the connected provider builds it, then report the " +
187
- "deployment. Does not commit — commit first if there are unsaved changes.",
188
- name: "deploy_site",
189
- },
180
+ /* No `aiTool`, by §12.4's third deletion rule: remote and irreversible, the same class as
181
+ `packages.remove`. */
190
182
  run: async () => {
191
183
  await runDeploy();
192
184
  },