@jxsuite/studio 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) 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-fyf63pmy.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-2w1f35qs.js +18 -0
  15. package/dist/chunks/content-source-3wqeas45.js +46 -0
  16. package/dist/chunks/convert-to-repeater-d0cgnb6d.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-d6g50j7s.js +42 -0
  20. package/dist/chunks/extension-sections-fy7q4fe9.js +651 -0
  21. package/dist/chunks/file-ops-3btj6st0.js +47 -0
  22. package/dist/chunks/files-ef8fgs3w.js +72 -0
  23. package/dist/chunks/format-host-3c33nwr8.js +40 -0
  24. package/dist/chunks/fs-events-13tj6sex.js +18 -0
  25. package/dist/chunks/git-panel-4wp2rn9b.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-jgesd924.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-1nq5evsh.js +29 -0
  37. package/dist/chunks/layers-panel-ar2gh90g.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-2qbetq73.js +33 -0
  41. package/dist/chunks/menu-q99sy9rf.js +285 -0
  42. package/dist/chunks/menu-rf7n72mf.js +14 -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-98f7sr3g.js +27 -0
  52. package/dist/chunks/quick-search-srzz83k2.js +45 -0
  53. package/dist/chunks/references-n553f0e1.js +26 -0
  54. package/dist/chunks/right-panel-rrgx2dn3.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-18avnhjp.js +2430 -0
  60. package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
  61. package/dist/chunks/{studio-msd847zn.js → studio-25hkdrkw.js} +357 -86
  62. package/dist/chunks/studio-26d7myd1.js +258 -0
  63. package/dist/chunks/{studio-4r1pv6zf.js → studio-38emantv.js} +22 -5
  64. package/dist/chunks/studio-3gxv60tn.js +422 -0
  65. package/dist/chunks/{studio-fbf92ckf.js → studio-3hxkd92t.js} +275 -163
  66. package/dist/chunks/studio-4m0haseg.js +185 -0
  67. package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
  68. package/dist/chunks/{studio-1wagb550.js → studio-5523bpzt.js} +11 -11
  69. package/dist/chunks/{studio-x4qkdat5.js → studio-57mf66w2.js} +1749 -2481
  70. package/dist/chunks/studio-5jy81t3s.js +17463 -0
  71. package/dist/chunks/studio-5rt7sqa0.js +1168 -0
  72. package/dist/chunks/studio-5te5tqng.js +81 -0
  73. package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
  74. package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
  75. package/dist/chunks/studio-6xa21ej9.js +28 -0
  76. package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
  77. package/dist/chunks/{studio-ahn3pdgx.js → studio-79y5sz51.js} +52 -38
  78. package/dist/chunks/{studio-gcye7qka.js → studio-7e11jpa9.js} +21 -21
  79. package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
  80. package/dist/chunks/studio-7xptrg0j.js +954 -0
  81. package/dist/chunks/{studio-cft9r4r7.js → studio-81390n6f.js} +22 -22
  82. package/dist/chunks/{studio-q43a5y9h.js → studio-8jn5yhyn.js} +16 -16
  83. package/dist/chunks/studio-8qtrpzr3.js +839 -0
  84. package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
  85. package/dist/chunks/studio-9xxz1q69.js +1356 -0
  86. package/dist/chunks/studio-akbww0j5.js +13615 -0
  87. package/dist/chunks/{studio-x813zp48.js → studio-arfpe389.js} +30 -30
  88. package/dist/chunks/{studio-trxrabqf.js → studio-az3zd49t.js} +475 -283
  89. package/dist/chunks/studio-cpvb2ed1.js +1171 -0
  90. package/dist/chunks/{studio-f3wqjtk5.js → studio-d0300636.js} +5076 -18
  91. package/dist/chunks/{studio-bgxt93ga.js → studio-d055c37e.js} +13 -13
  92. package/dist/chunks/studio-d1ja2x9r.js +362 -0
  93. package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
  94. package/dist/chunks/{studio-3bqpr0zh.js → studio-em9nw8eh.js} +299 -110
  95. package/dist/chunks/studio-erdatzvp.js +1190 -0
  96. package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
  97. package/dist/chunks/studio-fabxk6r9.js +2811 -0
  98. package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
  99. package/dist/chunks/{studio-dm19q43r.js → studio-hhvs4sdg.js} +10 -10
  100. package/dist/chunks/{studio-q9jd1a60.js → studio-kcgff4r0.js} +15 -18
  101. package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
  102. package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
  103. package/dist/chunks/studio-pm6hgy7r.js +4763 -0
  104. package/dist/chunks/studio-q0a3yk4n.js +33 -0
  105. package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
  106. package/dist/chunks/studio-qahxvnan.js +111 -0
  107. package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
  108. package/dist/chunks/{studio-2b946z26.js → studio-rkstz940.js} +3658 -6134
  109. package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
  110. package/dist/chunks/studio-rpyah2ew.js +2805 -0
  111. package/dist/chunks/studio-rs76k67r.js +12 -0
  112. package/dist/chunks/{studio-jkftxyvz.js → studio-s6z853aq.js} +5858 -2152
  113. package/dist/chunks/{studio-6yw4y3my.js → studio-sgdc5pfc.js} +8 -8
  114. package/dist/chunks/studio-tb3ev01j.js +763 -0
  115. package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
  116. package/dist/chunks/studio-vhv5tgxm.js +51 -0
  117. package/dist/chunks/{studio-qjy2z9bv.js → studio-vz68yn9e.js} +32 -137
  118. package/dist/chunks/studio-wqpngpsk.js +174 -0
  119. package/dist/chunks/{studio-b55y6ewx.js → studio-x3rty6tr.js} +58 -58
  120. package/dist/chunks/studio-xsykpvsh.js +8448 -0
  121. package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
  122. package/dist/chunks/studio-yxa81f45.js +12 -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-wrew8zk4.js +69 -0
  133. package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
  134. package/dist/iframe-entry.js +1780 -667
  135. package/dist/studio.js +52819 -36480
  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 +310 -117
  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 +369 -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 +165 -8
  178. package/src/content/entry-commands.ts +16 -23
  179. package/src/content/entry-editor.ts +144 -101
  180. package/src/editor/canvas-slash-bridge.ts +2 -2
  181. package/src/editor/context-menu.ts +49 -200
  182. package/src/editor/convert-to-component.ts +42 -82
  183. package/src/editor/convert-to-repeater.ts +132 -173
  184. package/src/editor/inline-edit.ts +11 -0
  185. package/src/editor/shortcuts.ts +65 -26
  186. package/src/editor/slash-menu.ts +150 -157
  187. package/src/files/file-ops.ts +117 -11
  188. package/src/files/files.ts +943 -660
  189. package/src/files/json-layout.ts +474 -0
  190. package/src/files/serialize-document.ts +8 -1
  191. package/src/format/convert-file.ts +16 -10
  192. package/src/format/format-host.ts +50 -1
  193. package/src/github/github-auth.ts +71 -29
  194. package/src/github/github-publish.ts +57 -65
  195. package/src/grid/cell-editors.ts +46 -4
  196. package/src/grid/cell-popovers.ts +65 -62
  197. package/src/grid/grid-open.ts +86 -64
  198. package/src/grid/grid-panel.ts +390 -469
  199. package/src/grid/redirects-grid.ts +40 -44
  200. package/src/hosting/layout.ts +2 -0
  201. package/src/i18n/i18n-commands.ts +127 -62
  202. package/src/media/media-pane.ts +83 -133
  203. package/src/new-project/add-repo-modal.ts +125 -176
  204. package/src/new-project/import-tab.ts +181 -252
  205. package/src/new-project/location-fields.ts +93 -160
  206. package/src/new-project/new-project-modal.ts +376 -367
  207. package/src/packages/jxsuite-update.ts +76 -18
  208. package/src/panels/activity-panel.ts +137 -104
  209. package/src/panels/ai-chat/chat-markdown.ts +15 -13
  210. package/src/panels/ai-chat/chat-view.ts +307 -472
  211. package/src/panels/ai-chat/composer.ts +175 -163
  212. package/src/panels/ai-chat/sessions-view.ts +31 -62
  213. package/src/panels/ai-panel.ts +210 -185
  214. package/src/panels/block-action-bar.ts +437 -643
  215. package/src/panels/bottom-dock.ts +112 -47
  216. package/src/panels/chat-panel.ts +19 -14
  217. package/src/panels/data-explorer.ts +141 -102
  218. package/src/panels/data-grid.ts +183 -150
  219. package/src/panels/dnd.ts +75 -20
  220. package/src/panels/editors.ts +26 -19
  221. package/src/panels/elements-panel.ts +243 -186
  222. package/src/panels/empty-state.ts +26 -42
  223. package/src/panels/events-panel.ts +950 -729
  224. package/src/panels/formula-workspace.ts +434 -207
  225. package/src/panels/frontmatter-fields.ts +185 -153
  226. package/src/panels/frontmatter-panel.ts +411 -187
  227. package/src/panels/git-diff-open.ts +148 -0
  228. package/src/panels/git-panel.ts +679 -605
  229. package/src/panels/head-panel.ts +617 -435
  230. package/src/panels/i18n-panel.ts +153 -133
  231. package/src/panels/imports-panel.ts +388 -414
  232. package/src/panels/jump-bar.ts +174 -147
  233. package/src/panels/layers-panel.ts +785 -671
  234. package/src/panels/left-panel.ts +166 -94
  235. package/src/panels/navigator-panels.ts +1 -1
  236. package/src/panels/pane-context.ts +529 -677
  237. package/src/panels/pane-grid.ts +265 -241
  238. package/src/panels/panel-registry.ts +15 -4
  239. package/src/panels/problems-panel.ts +177 -99
  240. package/src/panels/properties-panel.ts +1525 -966
  241. package/src/panels/provenance.ts +31 -113
  242. package/src/panels/quick-search.ts +217 -172
  243. package/src/panels/right-panel.ts +135 -169
  244. package/src/panels/seo-modal.ts +346 -167
  245. package/src/panels/settings-menu.ts +109 -646
  246. package/src/panels/settings-pane.ts +102 -86
  247. package/src/panels/signals-panel.ts +1318 -1172
  248. package/src/panels/statement-editor.ts +556 -428
  249. package/src/panels/style-panel.ts +1367 -630
  250. package/src/panels/style-utils.ts +36 -32
  251. package/src/panels/stylebook-doc.ts +30 -73
  252. package/src/panels/stylebook-layers-panel.ts +202 -109
  253. package/src/panels/stylebook-panel.ts +124 -88
  254. package/src/panels/tab-strip.ts +385 -287
  255. package/src/platforms/cloud.ts +106 -16
  256. package/src/platforms/devserver.ts +13 -0
  257. package/src/publish/deploy-checklist.ts +124 -78
  258. package/src/publish/publish-commands.ts +4 -12
  259. package/src/publish/publish-panel.ts +134 -328
  260. package/src/services/a11y-report.ts +100 -43
  261. package/src/services/ai-command-tools.ts +468 -0
  262. package/src/services/ai-session-store.ts +6 -0
  263. package/src/services/ai-system-prompt.ts +110 -18
  264. package/src/services/ai-tools.ts +28 -143
  265. package/src/services/ai-write-report.ts +174 -0
  266. package/src/services/document-assistant.ts +50 -2
  267. package/src/services/idle.ts +16 -14
  268. package/src/services/live-surfaces.ts +237 -0
  269. package/src/services/model-uri.ts +75 -0
  270. package/src/services/notify.ts +63 -6
  271. package/src/services/popover-report.ts +325 -0
  272. package/src/services/surface-registry.ts +56 -0
  273. package/src/services/tool-executor.ts +6 -0
  274. package/src/settings/contexts-section.ts +301 -299
  275. package/src/settings/contributed-section.ts +361 -222
  276. package/src/settings/css-vars-editor.ts +320 -325
  277. package/src/settings/defs-editor.ts +572 -535
  278. package/src/settings/dependencies-editor.ts +79 -107
  279. package/src/settings/extension-commands.ts +379 -0
  280. package/src/settings/extension-rows.ts +113 -0
  281. package/src/settings/extensions-section.ts +287 -0
  282. package/src/settings/general-settings.ts +130 -181
  283. package/src/settings/head-editor.ts +10 -305
  284. package/src/settings/locales-section.ts +146 -196
  285. package/src/settings/preferences-accounts.ts +1 -1
  286. package/src/settings/preferences-dialog.ts +350 -330
  287. package/src/settings/project-sections.ts +108 -181
  288. package/src/settings/schema-field-ui.ts +11 -399
  289. package/src/settings/section-registry.ts +8 -1
  290. package/src/settings/settings-document.ts +31 -29
  291. package/src/shell/tree.ts +42 -87
  292. package/src/shell.ts +48 -36
  293. package/src/studio.ts +90 -67
  294. package/src/style/token-ref.ts +0 -39
  295. package/src/surfaces/about.json +263 -0
  296. package/src/surfaces/about.ts +163 -0
  297. package/src/surfaces/add-repo.json +486 -0
  298. package/src/surfaces/add-repo.ts +236 -0
  299. package/src/surfaces/ai-chat.json +2185 -0
  300. package/src/surfaces/ai-chat.ts +549 -0
  301. package/src/surfaces/ai-credentials-form.json +332 -0
  302. package/src/surfaces/ai-credentials-form.ts +151 -0
  303. package/src/surfaces/ai-managed-connect.json +108 -0
  304. package/src/surfaces/ai-managed-connect.ts +123 -0
  305. package/src/surfaces/ai-model-picker.json +114 -0
  306. package/src/surfaces/ai-model-picker.ts +139 -0
  307. package/src/surfaces/block-action-bar.json +640 -0
  308. package/src/surfaces/block-action-bar.ts +368 -0
  309. package/src/surfaces/bottom-dock.json +154 -0
  310. package/src/surfaces/bottom-dock.ts +125 -0
  311. package/src/surfaces/canvas-stage.json +444 -0
  312. package/src/surfaces/canvas-stage.ts +253 -0
  313. package/src/surfaces/cf-account-picker.json +300 -0
  314. package/src/surfaces/cf-account-picker.ts +214 -0
  315. package/src/surfaces/commandbar.json +984 -0
  316. package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +414 -389
  317. package/src/surfaces/convert-repeater.json +309 -0
  318. package/src/surfaces/convert-repeater.ts +276 -0
  319. package/src/surfaces/data-actions.json +157 -0
  320. package/src/surfaces/data-actions.ts +115 -0
  321. package/src/surfaces/dialog.json +289 -0
  322. package/src/surfaces/dialog.ts +343 -0
  323. package/src/surfaces/diff-toolbar.json +266 -0
  324. package/src/surfaces/diff-toolbar.ts +139 -0
  325. package/src/surfaces/doc-header.json +739 -0
  326. package/src/surfaces/doc-header.ts +223 -0
  327. package/src/surfaces/empty-state.json +152 -0
  328. package/src/surfaces/empty-state.ts +173 -0
  329. package/src/surfaces/entry-editor.json +281 -0
  330. package/src/surfaces/entry-editor.ts +191 -0
  331. package/src/surfaces/expression-editor.json +977 -0
  332. package/src/surfaces/expression-editor.ts +266 -0
  333. package/src/surfaces/files-panel.json +592 -0
  334. package/src/surfaces/files-panel.ts +301 -0
  335. package/src/surfaces/formula-palette.json +364 -0
  336. package/src/surfaces/formula-palette.ts +340 -0
  337. package/src/surfaces/git-panel.json +1822 -0
  338. package/src/surfaces/git-panel.ts +272 -0
  339. package/src/surfaces/github-auth.json +112 -0
  340. package/src/surfaces/github-auth.ts +139 -0
  341. package/src/surfaces/github-publish.json +206 -0
  342. package/src/surfaces/github-publish.ts +169 -0
  343. package/src/surfaces/grid-cell.json +218 -0
  344. package/src/surfaces/grid-cell.ts +120 -0
  345. package/src/surfaces/grid-open.json +147 -0
  346. package/src/surfaces/grid-open.ts +87 -0
  347. package/src/surfaces/grid-panel.json +706 -0
  348. package/src/surfaces/grid-panel.ts +206 -0
  349. package/src/surfaces/grid-replace.json +179 -0
  350. package/src/surfaces/grid-replace.ts +89 -0
  351. package/src/surfaces/grid-views.json +446 -0
  352. package/src/surfaces/grid-views.ts +172 -0
  353. package/src/surfaces/inspector-dock.json +187 -0
  354. package/src/surfaces/inspector-dock.ts +161 -0
  355. package/src/surfaces/jump-bar.json +243 -0
  356. package/src/surfaces/jump-bar.ts +129 -0
  357. package/src/surfaces/jxsuite-update.json +146 -0
  358. package/src/surfaces/jxsuite-update.ts +149 -0
  359. package/src/surfaces/library-pane.json +1509 -0
  360. package/src/surfaces/library-pane.ts +363 -0
  361. package/src/surfaces/logic-panel.json +1949 -0
  362. package/src/surfaces/logic-panel.ts +369 -0
  363. package/src/surfaces/logic-workspace.json +685 -0
  364. package/src/surfaces/logic-workspace.ts +238 -0
  365. package/src/surfaces/media-browser.json +303 -0
  366. package/src/surfaces/media-browser.ts +145 -0
  367. package/src/surfaces/media-field.json +163 -0
  368. package/src/surfaces/media-field.ts +116 -0
  369. package/src/surfaces/media-pane.json +513 -0
  370. package/src/surfaces/media-pane.ts +197 -0
  371. package/src/surfaces/menu.json +232 -0
  372. package/src/surfaces/menu.ts +375 -0
  373. package/src/surfaces/navigator-dock.json +113 -0
  374. package/src/surfaces/navigator-dock.ts +130 -0
  375. package/src/surfaces/new-project.json +1654 -0
  376. package/src/surfaces/new-project.ts +411 -0
  377. package/src/surfaces/palette.json +535 -0
  378. package/src/surfaces/pane-context.json +1497 -0
  379. package/src/surfaces/pane-context.ts +513 -0
  380. package/src/surfaces/pane-grid.json +188 -0
  381. package/src/surfaces/pane-grid.ts +250 -0
  382. package/src/surfaces/panel-activity.json +563 -0
  383. package/src/surfaces/panel-activity.ts +187 -0
  384. package/src/surfaces/panel-data.json +141 -0
  385. package/src/surfaces/panel-data.ts +156 -0
  386. package/src/surfaces/panel-deploy-checklist.json +283 -0
  387. package/src/surfaces/panel-deploy-checklist.ts +175 -0
  388. package/src/surfaces/panel-elements.json +367 -0
  389. package/src/surfaces/panel-elements.ts +175 -0
  390. package/src/surfaces/panel-i18n.json +569 -0
  391. package/src/surfaces/panel-i18n.ts +212 -0
  392. package/src/surfaces/panel-imports.json +780 -0
  393. package/src/surfaces/panel-imports.ts +209 -0
  394. package/src/surfaces/panel-outline.json +734 -0
  395. package/src/surfaces/panel-outline.ts +326 -0
  396. package/src/surfaces/panel-page.json +1017 -0
  397. package/src/surfaces/panel-page.ts +240 -0
  398. package/src/surfaces/panel-problems.json +497 -0
  399. package/src/surfaces/panel-problems.ts +157 -0
  400. package/src/surfaces/panel-signals.json +1973 -0
  401. package/src/surfaces/panel-signals.ts +436 -0
  402. package/src/surfaces/panel-stylebook-layers.json +317 -0
  403. package/src/surfaces/panel-stylebook-layers.ts +155 -0
  404. package/src/surfaces/preferences.json +850 -0
  405. package/src/surfaces/preferences.ts +332 -0
  406. package/src/surfaces/progress-modal.json +110 -0
  407. package/src/surfaces/progress-modal.ts +150 -0
  408. package/src/surfaces/properties-panel.json +1578 -0
  409. package/src/surfaces/properties-panel.ts +337 -0
  410. package/src/surfaces/publish.json +945 -0
  411. package/src/surfaces/publish.ts +392 -0
  412. package/src/surfaces/push-plan.json +110 -0
  413. package/src/surfaces/push-plan.ts +87 -0
  414. package/src/surfaces/rail.json +255 -0
  415. package/src/surfaces/rail.ts +206 -0
  416. package/src/surfaces/reference-field.json +191 -0
  417. package/src/surfaces/reference-field.ts +168 -0
  418. package/src/surfaces/schema-builder.json +1011 -0
  419. package/src/surfaces/schema-builder.ts +181 -0
  420. package/src/surfaces/schema-form.json +1013 -0
  421. package/src/surfaces/schema-form.ts +287 -0
  422. package/src/surfaces/secret-field.json +60 -0
  423. package/src/surfaces/secret-field.ts +146 -0
  424. package/src/surfaces/seo.json +932 -0
  425. package/src/surfaces/seo.ts +334 -0
  426. package/src/surfaces/settings-contexts.json +538 -0
  427. package/src/surfaces/settings-contexts.ts +196 -0
  428. package/src/surfaces/settings-contributed.json +489 -0
  429. package/src/surfaces/settings-contributed.ts +199 -0
  430. package/src/surfaces/settings-css-vars.json +820 -0
  431. package/src/surfaces/settings-css-vars.ts +199 -0
  432. package/src/surfaces/settings-defs.json +1363 -0
  433. package/src/surfaces/settings-defs.ts +232 -0
  434. package/src/surfaces/settings-deploy.json +108 -0
  435. package/src/surfaces/settings-deploy.ts +135 -0
  436. package/src/surfaces/settings-extensions.json +486 -0
  437. package/src/surfaces/settings-extensions.ts +201 -0
  438. package/src/surfaces/settings-head.json +779 -0
  439. package/src/surfaces/settings-head.ts +397 -0
  440. package/src/surfaces/settings-locales.json +420 -0
  441. package/src/surfaces/settings-locales.ts +137 -0
  442. package/src/surfaces/settings-overview.json +423 -0
  443. package/src/surfaces/settings-overview.ts +218 -0
  444. package/src/surfaces/settings-packages.json +549 -0
  445. package/src/surfaces/settings-packages.ts +158 -0
  446. package/src/surfaces/settings-pane.json +147 -0
  447. package/src/surfaces/settings-pane.ts +150 -0
  448. package/src/surfaces/settings-rawjson.json +104 -0
  449. package/src/surfaces/settings-rawjson.ts +107 -0
  450. package/src/surfaces/shell.json +99 -0
  451. package/src/surfaces/shell.ts +30 -0
  452. package/src/surfaces/slash-menu.json +180 -0
  453. package/src/surfaces/slash-menu.ts +272 -0
  454. package/src/surfaces/statements.json +607 -0
  455. package/src/surfaces/statements.ts +238 -0
  456. package/src/surfaces/statusbar.json +94 -0
  457. package/src/{panels → surfaces}/statusbar.ts +163 -90
  458. package/src/surfaces/style-panel.json +1643 -0
  459. package/src/surfaces/style-panel.ts +338 -0
  460. package/src/surfaces/stylebook-chrome.json +122 -0
  461. package/src/surfaces/stylebook-chrome.ts +122 -0
  462. package/src/surfaces/tab-strip.json +448 -0
  463. package/src/surfaces/tab-strip.ts +200 -0
  464. package/src/surfaces/target-line.json +419 -0
  465. package/src/surfaces/target-line.ts +349 -0
  466. package/src/surfaces/toasts.json +189 -0
  467. package/src/surfaces/welcome.json +571 -0
  468. package/src/surfaces/welcome.ts +338 -0
  469. package/src/tabs/project-config.ts +71 -15
  470. package/src/tabs/tab.ts +52 -1
  471. package/src/types.ts +22 -0
  472. package/src/ui/ai-credentials-form.ts +104 -100
  473. package/src/ui/ai-managed-connect.ts +54 -36
  474. package/src/ui/ai-model-picker.ts +75 -47
  475. package/src/ui/cf-account-picker.ts +76 -141
  476. package/src/ui/color-selector.ts +80 -301
  477. package/src/ui/dynamic-slot.ts +43 -283
  478. package/src/ui/expression-editor.ts +797 -576
  479. package/src/ui/field-input.ts +8 -181
  480. package/src/ui/form-controls.ts +838 -366
  481. package/src/ui/formula-chips.ts +80 -85
  482. package/src/ui/kit.ts +33 -0
  483. package/src/ui/layers.ts +293 -593
  484. package/src/ui/media-picker.ts +203 -284
  485. package/src/ui/panel-resize.ts +251 -64
  486. package/src/ui/popover-surface.ts +153 -0
  487. package/src/ui/progress-modal.ts +22 -60
  488. package/src/ui/regions.ts +13 -7
  489. package/src/ui/schema-form.ts +906 -440
  490. package/src/ui/surface.ts +122 -0
  491. package/src/ui/unit-selector.ts +15 -131
  492. package/src/ui/value-source.ts +14 -0
  493. package/src/ui/virtual-window.ts +88 -9
  494. package/src/utils/canvas-media.ts +72 -0
  495. package/src/utils/edit-display.ts +7 -2
  496. package/src/utils/element-selectors.ts +69 -0
  497. package/src/utils/link-target.ts +2 -2
  498. package/src/utils/studio-utils.ts +0 -10
  499. package/src/view.ts +15 -0
  500. package/src/workspace/pane-derive.ts +36 -14
  501. package/src/workspace/workspace.ts +15 -6
  502. package/styles/canvas.css +72 -467
  503. package/styles/forced-colors.css +48 -82
  504. package/styles/forced-colors.json +41 -0
  505. package/styles/inspector.css +2 -1301
  506. package/styles/overlays.css +96 -2823
  507. package/styles/panels.css +6 -1423
  508. package/styles/shell-frame.css +272 -0
  509. package/styles/shell-frame.json +227 -0
  510. package/styles/shell.css +0 -1568
  511. package/styles/tokens.css +65 -136
  512. package/styles/tokens.json +84 -0
  513. package/dist/chunks/Overlay.dev-etqjwyf9.js +0 -23
  514. package/dist/chunks/adapter-jkcyhgtr.js +0 -14
  515. package/dist/chunks/cf-account-picker-en86v7x7.js +0 -163
  516. package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
  517. package/dist/chunks/components-zmx10t62.js +0 -21
  518. package/dist/chunks/content-source-48xg86wj.js +0 -49
  519. package/dist/chunks/convert-to-repeater-43tfn7cs.js +0 -268
  520. package/dist/chunks/editor-cptq5jp1.js +0 -37
  521. package/dist/chunks/entry-commands-e63f1xc0.js +0 -46
  522. package/dist/chunks/extension-sections-txv08xxg.js +0 -311
  523. package/dist/chunks/file-ops-wbh4hhsx.js +0 -48
  524. package/dist/chunks/files-3kfkwhk4.js +0 -93
  525. package/dist/chunks/flow-qbfgrpeh.js +0 -634
  526. package/dist/chunks/focus-trap.esm-9t2drp0g.js +0 -1025
  527. package/dist/chunks/focus-visible-6eg70z18.js +0 -167
  528. package/dist/chunks/format-host-w16q81tf.js +0 -43
  529. package/dist/chunks/fs-events-hrrg328g.js +0 -21
  530. package/dist/chunks/git-panel-532whr1y.js +0 -59
  531. package/dist/chunks/index-zqxmqxmh.js +0 -109
  532. package/dist/chunks/jx-validate-8er6gbxy.js +0 -19
  533. package/dist/chunks/layers-panel-07hm7g5j.js +0 -67
  534. package/dist/chunks/layers-q75tj2mf.js +0 -45
  535. package/dist/chunks/lit-html-j055mkh8.js +0 -22
  536. package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
  537. package/dist/chunks/notify-yjm79n4s.js +0 -30
  538. package/dist/chunks/parse-24d0gay3.js +0 -19
  539. package/dist/chunks/platform-ba1j1gbh.js +0 -16
  540. package/dist/chunks/publish-panel-v9st96ja.js +0 -29
  541. package/dist/chunks/quick-search-zccjp6gv.js +0 -66
  542. package/dist/chunks/references-3qx8fkyp.js +0 -29
  543. package/dist/chunks/right-panel-vm3b6kwy.js +0 -46
  544. package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
  545. package/dist/chunks/sp-overlay.dev-qgvhnxf4.js +0 -18
  546. package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
  547. package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
  548. package/dist/chunks/sp-tooltip.dev-4sastdnw.js +0 -15
  549. package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
  550. package/dist/chunks/studio-0a5qrh01.js +0 -3
  551. package/dist/chunks/studio-0bq6eh7v.js +0 -12
  552. package/dist/chunks/studio-18j3bmcz.js +0 -14
  553. package/dist/chunks/studio-1ngbejft.js +0 -181
  554. package/dist/chunks/studio-4b5z1x43.js +0 -424
  555. package/dist/chunks/studio-4n2b5gzb.js +0 -357
  556. package/dist/chunks/studio-4rzyrtjz.js +0 -426
  557. package/dist/chunks/studio-5fx3g9jg.js +0 -4325
  558. package/dist/chunks/studio-5myknm0a.js +0 -1903
  559. package/dist/chunks/studio-7afd21nw.js +0 -67
  560. package/dist/chunks/studio-7nte2hj4.js +0 -613
  561. package/dist/chunks/studio-8jpzqk5s.js +0 -128
  562. package/dist/chunks/studio-8q517dfr.js +0 -24
  563. package/dist/chunks/studio-950k0dx6.js +0 -6939
  564. package/dist/chunks/studio-9n4mrmnb.js +0 -184
  565. package/dist/chunks/studio-a0tswy0w.js +0 -58
  566. package/dist/chunks/studio-ahnzd9rg.js +0 -23
  567. package/dist/chunks/studio-cmb03bg5.js +0 -13890
  568. package/dist/chunks/studio-d1ks410h.js +0 -175
  569. package/dist/chunks/studio-ef49pnzx.js +0 -387
  570. package/dist/chunks/studio-eqq1w638.js +0 -113
  571. package/dist/chunks/studio-ew0djmhg.js +0 -341
  572. package/dist/chunks/studio-gfgb8pe6.js +0 -1652
  573. package/dist/chunks/studio-h4rxscfc.js +0 -10
  574. package/dist/chunks/studio-jc994dnr.js +0 -1066
  575. package/dist/chunks/studio-kyh9avvv.js +0 -28
  576. package/dist/chunks/studio-m3hwn7y1.js +0 -120
  577. package/dist/chunks/studio-mtfnaqs9.js +0 -659
  578. package/dist/chunks/studio-n6j9t10q.js +0 -318
  579. package/dist/chunks/studio-n8b9wqwy.js +0 -291
  580. package/dist/chunks/studio-qcy05dp8.js +0 -1743
  581. package/dist/chunks/studio-qq6jym04.js +0 -53
  582. package/dist/chunks/studio-rdx8jcxy.js +0 -83
  583. package/dist/chunks/studio-rn9ta2mz.js +0 -111
  584. package/dist/chunks/studio-t7qb9db8.js +0 -665
  585. package/dist/chunks/studio-tmc5emrw.js +0 -8
  586. package/dist/chunks/studio-z6nw2ek2.js +0 -18
  587. package/dist/chunks/studio-zczps70q.js +0 -378
  588. package/dist/chunks/studio-zqazsct2.js +0 -1823
  589. package/dist/chunks/workspace-fjx52ryv.js +0 -89
  590. package/src/panels/activity-bar.ts +0 -251
  591. package/src/panels/panel-scheduler.ts +0 -219
  592. package/src/panels/style-inputs.ts +0 -237
  593. package/src/panels/target-line.ts +0 -274
  594. package/src/panels/welcome-screen.ts +0 -346
  595. package/src/ui/button-group.ts +0 -102
  596. package/src/ui/choice-field.ts +0 -72
  597. package/src/ui/field-row.ts +0 -249
  598. package/src/ui/formula-palette.ts +0 -213
  599. package/src/ui/icons.ts +0 -52
  600. package/src/ui/jx-theme.ts +0 -130
  601. package/src/ui/spectrum.ts +0 -340
  602. package/src/ui/value-selector.ts +0 -174
  603. package/src/ui/widgets.ts +0 -172
  604. /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
  605. /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
  606. /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
  607. /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
  },