@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
@@ -18,13 +18,23 @@
18
18
  *
19
19
  * A row shows `—` only where there is genuinely nothing to show: a `workspace:`/`file:`/git spec, a
20
20
  * package the registry does not answer for, or a host with no registry lookup at all.
21
+ *
22
+ * **The markup left.** The section is the `settings-packages` surface
23
+ * (`surfaces/settings-packages.json`), mounted by `surfaces/settings-packages.ts`; what is here is
24
+ * the section itself — what the platform is asked, which of two versions is newer, what each verb
25
+ * runs and what it says when it fails. `renderDependenciesEditor` is unchanged as a contract: the
26
+ * registry hands a container to a `render`, and this one mounts a document into it instead of
27
+ * rendering lit.
28
+ *
29
+ * @docs studio/projects/settings
21
30
  */
22
31
 
23
- import { html, render as litRender } from "lit-html";
24
32
  import { getPlatform } from "../platform";
25
33
  import { notify } from "../services/notify";
26
34
  import { showProgressModal } from "../ui/progress-modal";
27
35
  import { isUpgrade, stripRange } from "../packages/semver";
36
+ import { renderPackagesSurface } from "../surfaces/settings-packages";
37
+ import type { PackageRow, PackagesActions, PackagesView } from "../surfaces/settings-packages";
28
38
  import type { PackageInfo } from "../types";
29
39
 
30
40
  interface Update {
@@ -56,6 +66,11 @@ function upgradeFor(p: PackageInfo): string | null {
56
66
  return latest && isUpgrade(p.version, latest) ? latest : null;
57
67
  }
58
68
 
69
+ /** The package a row's button names, or undefined when the list has moved on since it was drawn. */
70
+ function packageNamed(name: string): PackageInfo | undefined {
71
+ return (_packages ?? []).find((p) => p.name === name);
72
+ }
73
+
59
74
  async function load() {
60
75
  const platform = getPlatform();
61
76
  try {
@@ -106,16 +121,18 @@ async function onAdd() {
106
121
  });
107
122
  }
108
123
 
109
- async function onRemove(p: PackageInfo) {
124
+ async function onRemove(name: string) {
110
125
  await withBusy(async () => {
111
- await getPlatform().removePackage(p.name);
112
- notify.success(`Removed ${p.name}.`);
126
+ await getPlatform().removePackage(name);
127
+ notify.success(`Removed ${name}.`);
113
128
  });
114
129
  }
115
130
 
116
- async function onUpdate(p: PackageInfo, latest: string) {
131
+ async function onUpdate(name: string) {
117
132
  const platform = getPlatform();
118
- if (!platform.setPackageVersions) {
133
+ const p = packageNamed(name);
134
+ const latest = p ? upgradeFor(p) : null;
135
+ if (!platform.setPackageVersions || !p || !latest) {
119
136
  return;
120
137
  }
121
138
  await withBusy(async () => {
@@ -169,113 +186,68 @@ async function onReinstall() {
169
186
  });
170
187
  }
171
188
 
172
- function row(p: PackageInfo) {
173
- const latest = latestFor(p);
174
- const upgrade = upgradeFor(p);
175
- return html`
176
- <sp-table-row>
177
- <sp-table-cell>
178
- ${p.name}${
179
- p.dev ? html`<span style="color:var(--fg-dim);font-size:10px"> · dev</span>` : ""
180
- }
181
- </sp-table-cell>
182
- <sp-table-cell>${p.version}</sp-table-cell>
183
- <sp-table-cell>${latest ?? "—"}</sp-table-cell>
184
- <sp-table-cell>
185
- ${
186
- upgrade
187
- ? html`<sp-action-button
188
- size="s"
189
- quiet
190
- ?disabled=${_busy}
191
- title="Update to ${upgrade}"
192
- @click=${() => onUpdate(p, upgrade)}
193
- >
194
- <sp-icon-refresh slot="icon"></sp-icon-refresh>
195
- </sp-action-button>`
196
- : ""
197
- }
198
- <sp-action-button
199
- size="s"
200
- quiet
201
- ?disabled=${_busy}
202
- title="Remove"
203
- @click=${() => onRemove(p)}
204
- >
205
- <sp-icon-delete slot="icon"></sp-icon-delete>
206
- </sp-action-button>
207
- </sp-table-cell>
208
- </sp-table-row>
209
- `;
189
+ /**
190
+ * One dependency as the surface draws it.
191
+ *
192
+ * The two version columns are answered separately on purpose. `latest` is what the registry said
193
+ * and is shown whatever it says, `—` when it said nothing at all; `upgrade` is the far narrower
194
+ * claim that the row is BEHIND that version, and it is the only one an update button may act on.
195
+ */
196
+ function row(p: PackageInfo): PackageRow {
197
+ return {
198
+ dev: Boolean(p.dev),
199
+ latest: latestFor(p) ?? "—",
200
+ name: p.name,
201
+ upgrade: upgradeFor(p) ?? "",
202
+ version: p.version,
203
+ };
210
204
  }
211
205
 
206
+ /** What the section shows right now. */
207
+ function view(): PackagesView {
208
+ return {
209
+ addName: _addName,
210
+ busy: _busy,
211
+ loading: _packages === null,
212
+ rows: (_packages ?? []).map((p) => row(p)),
213
+ };
214
+ }
215
+
216
+ /**
217
+ * What the reader may do. One set for the module, because the section's whole state is the module's
218
+ * — one project's dependencies, and one `bun` run at a time over them.
219
+ */
220
+ const ACTIONS: PackagesActions = {
221
+ add: () => {
222
+ void onAdd();
223
+ },
224
+ edit: (value: string) => {
225
+ /* The echo. The scope has to be told what the field now holds even though nothing about the
226
+ section changes, because emptying it after a successful add is otherwise a write of "" over
227
+ a scope that already said "" — no change, no binding, and the installed package's name left
228
+ sitting in the field. */
229
+ _addName = value;
230
+ render();
231
+ },
232
+ reinstall: () => {
233
+ void onReinstall();
234
+ },
235
+ remove: (name: string) => {
236
+ void onRemove(name);
237
+ },
238
+ update: (name: string) => {
239
+ void onUpdate(name);
240
+ },
241
+ updateAll: () => {
242
+ void onUpdateAll();
243
+ },
244
+ };
245
+
212
246
  function render() {
213
247
  if (!_container) {
214
248
  return;
215
249
  }
216
- const pkgs = _packages ?? [];
217
- const hasUpdates = pkgs.some((p) => upgradeFor(p) !== null);
218
-
219
- const tpl = html`
220
- <div class="settings-section">
221
- <h3 class="settings-section-title">Packages</h3>
222
- <p class="settings-field-desc">Manage this project's npm dependencies.</p>
223
-
224
- <div style="display:flex;gap:8px;margin-bottom:12px;align-items:center">
225
- <sp-textfield
226
- size="s"
227
- placeholder="package-name"
228
- .value=${_addName}
229
- ?disabled=${_busy}
230
- @input=${(e: Event) => {
231
- _addName = (e.target as HTMLInputElement).value;
232
- }}
233
- ></sp-textfield>
234
- <sp-action-button size="s" ?disabled=${_busy} @click=${onAdd}>
235
- <sp-icon-add slot="icon"></sp-icon-add>
236
- Add
237
- </sp-action-button>
238
- <span style="flex:1"></span>
239
- ${
240
- hasUpdates
241
- ? html`<sp-action-button size="s" ?disabled=${_busy} @click=${onUpdateAll}>
242
- Update all
243
- </sp-action-button>`
244
- : ""
245
- }
246
- <sp-action-button
247
- size="s"
248
- quiet
249
- ?disabled=${_busy}
250
- title="Reinstall (bun install)"
251
- @click=${onReinstall}
252
- >
253
- <sp-icon-refresh slot="icon"></sp-icon-refresh>
254
- Reinstall
255
- </sp-action-button>
256
- </div>
257
-
258
- ${
259
- _packages === null
260
- ? html`<p class="about-muted">Loading…</p>`
261
- : pkgs.length === 0
262
- ? html`<p class="about-muted">No dependencies.</p>`
263
- : html`
264
- <sp-table size="s">
265
- <sp-table-head>
266
- <sp-table-head-cell>Package</sp-table-head-cell>
267
- <sp-table-head-cell>Current</sp-table-head-cell>
268
- <sp-table-head-cell>Latest</sp-table-head-cell>
269
- <sp-table-head-cell></sp-table-head-cell>
270
- </sp-table-head>
271
- <sp-table-body> ${pkgs.map((p) => row(p))} </sp-table-body>
272
- </sp-table>
273
- `
274
- }
275
- </div>
276
- `;
277
-
278
- litRender(tpl, _container);
250
+ renderPackagesSurface(_container, view(), ACTIONS);
279
251
  }
280
252
 
281
253
  /** @param {HTMLElement} container */
@@ -0,0 +1,379 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * The three verbs over `project.json` `extensions[]`, and the operations behind them.
4
+ *
5
+ * **They are command records because the array has two writers.** The person flips a switch and the
6
+ * assistant calls a tool, and `specs/studio-ui-guidelines.md` §12.4 is about exactly that: "the
7
+ * agent counts as a surface", and a family over one piece of state declares ONE availability rule.
8
+ * The assistant's `enable_extension` / `disable_extension` ARE these records — the `aiTool`
9
+ * projection below is what `services/ai-command-tools.ts` lists, and its `execute` is
10
+ * `registry.run` — so the two gates cannot drift into the shape that table catalogues, where the
11
+ * loose member is always the one that writes. What the record cannot say for itself is what to tell
12
+ * the model afterwards, and that is `aiTool.report`, written beside `run`.
13
+ *
14
+ * **There is no `list_extensions` read tool, deliberately.** The system prompt already carries the
15
+ * catalogue, the enabled set and each entry's sections at turn start, so a read tool could only
16
+ * answer a question the prompt has answered. The one thing it would add — "what changed after I
17
+ * enabled that" — is served by `enable_extension`'s own report, which costs no prompt budget
18
+ * because it is a result rather than an advertisement.
19
+ *
20
+ * **`enablement` is `ctx.project.open` and nothing else, on all three.** A precondition that
21
+ * depends on an ARGUMENT cannot live there — `enablement` cannot see one — so "is this a real
22
+ * extension?", "can this backend run it?" and "is it still enabled?" are refused with a
23
+ * `RangeError` naming the value, the shape §12.4 prescribes and `pane.derive` already uses. The
24
+ * first two are answered by the derived enum that `registry.run` coerces `package` against — a
25
+ * value outside it reads `is not declared — declared: …` — and the sentences inside `run` remain
26
+ * for the callers that reach it directly (the Extensions section's switch) and for a row that
27
+ * changed between the schema being read and the verb running.
28
+ *
29
+ * **The in-flight latch lives here, not in the section**, because the assistant can run these too:
30
+ * a latch the renderer owned would let a tool call and a click install concurrently.
31
+ */
32
+
33
+ import {
34
+ argsSchema,
35
+ derivedEnumProperty,
36
+ stringArg,
37
+ stringProperty,
38
+ } from "../commands/command-args";
39
+ import { beginActivity } from "../panels/activity-panel";
40
+ import { buildRows, enabledSpecifiers } from "./extension-rows";
41
+ import { getPlatform } from "../platform";
42
+ import { notify } from "../services/notify";
43
+ import { notifySettingsDocument } from "./section-registry";
44
+ import { updateSiteConfig } from "../site-context";
45
+ import type { AnyCommand, CommandRegistry } from "../commands/registry";
46
+
47
+ /** The package an extension operation is running for, or null. */
48
+ let _inFlight: string | null = null;
49
+
50
+ /**
51
+ * The files the LAST enable wrote: `[]` for a run that found the row already enabled and returned,
52
+ * `["project.json"]` for one that only enabled, both files for one that installed first.
53
+ *
54
+ * A latch beside `_inFlight` rather than a return value, because `run` returns void and the report
55
+ * is a separate call: `enable_extension`'s ledger entry has to name `package.json` exactly when
56
+ * this run touched it, and the row's `installed` flag has already flipped by the time the report
57
+ * reads it. The empty case is the one that matters most — {@link enableExtension} is idempotent by
58
+ * design (its enum offers enabled rows), and a report that answered "Enabled X" with a
59
+ * `project.json` entry for a run that wrote nothing would be the phantom write the ledger exists to
60
+ * keep out. Runs are serialised by `_inFlight`, so one slot is enough.
61
+ */
62
+ let _lastEnableWrote: readonly string[] = [];
63
+
64
+ /**
65
+ * What an extension operation is currently running for, if anything.
66
+ *
67
+ * Read by every surface that offers one, so a second install cannot start while the first is
68
+ * writing `package.json` and `project.json`.
69
+ *
70
+ * @returns {string | null}
71
+ */
72
+ export function extensionOpInFlight(): string | null {
73
+ return _inFlight;
74
+ }
75
+
76
+ /**
77
+ * Names this backend offers — the palette's and the agent's choice list, ENABLED rows included.
78
+ *
79
+ * The enum is what `registry.run` coerces `package` against before `run`, so it has to name the
80
+ * STATES the verb accepts rather than the changes it would make: a list that excluded enabled rows
81
+ * would refuse "enable what is already on" as an undeclared value, where {@link enableExtension}'s
82
+ * own early return keeps the verb idempotent. A row this backend cannot run stays out — a choice
83
+ * list that offered it would be offering a refusal.
84
+ */
85
+ function enableable(): string[] {
86
+ return buildRows()
87
+ .filter((row) => row.unavailable === undefined)
88
+ .map((row) => row.name);
89
+ }
90
+
91
+ /**
92
+ * Install the package if it is missing, then add it to `project.json`.
93
+ *
94
+ * **The order is the point.** A `project.json` naming a package that is not installed is a hard
95
+ * registry failure at the next build, so config-first opens a window in which the whole project is
96
+ * broken, and on an install failure it never closes. Install-first can only ever leave an unused
97
+ * dependency, which is inert.
98
+ *
99
+ * So a failed install DOES NOT write the config: writing anyway would manufacture the very state
100
+ * this section exists to remove. A failed config write does not roll the install back either — that
101
+ * is the same asymmetry as turning an extension off, and an automatic uninstall triggered by an
102
+ * unrelated failure is a destructive act nobody asked for.
103
+ *
104
+ * Nothing here refreshes the extension surfaces: `commitProjectConfig` compares the `extensions`
105
+ * key and does it already, and it is awaited before `updateSiteConfig` resolves.
106
+ *
107
+ * @param {string} specifier
108
+ * @returns {Promise<void>}
109
+ */
110
+ export async function enableExtension(specifier: string): Promise<void> {
111
+ if (_inFlight !== null) {
112
+ throw new Error(`Another extension operation is running (${_inFlight}).`);
113
+ }
114
+ const row = buildRows().find((r) => r.specifier === specifier || r.name === specifier);
115
+ if (row === undefined) {
116
+ throw new RangeError(
117
+ `command "project.enableExtension" argument "package": "${specifier}" is not an extension ` +
118
+ `this backend offers and is not installed — offered: ${enableable().join(", ") || "none"}`,
119
+ );
120
+ }
121
+ if (row.unavailable !== undefined) {
122
+ throw new RangeError(
123
+ `command "project.enableExtension" argument "package": "${specifier}" cannot be enabled on ` +
124
+ `this backend — ${row.unavailable}`,
125
+ );
126
+ }
127
+ /* Reset BEFORE the idempotent return, so the report of a no-op cannot read the previous run's
128
+ files — the same package enabled twice in a row would otherwise report its install twice. */
129
+ _lastEnableWrote = [];
130
+ if (row.enabled) {
131
+ return;
132
+ }
133
+
134
+ _inFlight = row.name;
135
+ let installed = false;
136
+ notifySettingsDocument();
137
+ try {
138
+ if (!row.installed && !row.bundled) {
139
+ /*
140
+ * `beginActivity`, not `showProgressModal`. §13.3 reserves blocking for an operation that
141
+ * cannot proceed while the author edits, and this one can — the only real hazard is a second
142
+ * concurrent write, which the latch closes for a fraction of the cost of freezing the app.
143
+ * `ui/progress-modal.ts` also enumerates its four call sites as a closed set, and a fifth
144
+ * would make a written invariant false.
145
+ */
146
+ const activity = beginActivity({
147
+ source: "Extensions",
148
+ status: "Running bun…",
149
+ title: `Install ${row.name}`,
150
+ });
151
+ try {
152
+ await getPlatform().addPackage(row.name);
153
+ installed = true;
154
+ } catch (error) {
155
+ activity.fail(
156
+ `Could not install ${row.name} — ${error instanceof Error ? error.message : String(error)}`,
157
+ );
158
+ throw error;
159
+ }
160
+ /*
161
+ * The activity ends HERE, before the config write, and that boundary is load-bearing:
162
+ * `ActivityHandle.fail` raises its own Problem and `commitProjectConfig` raises another keyed
163
+ * `save:project.json`, so an activity spanning both would post two Problems for one failure
164
+ * with different keys — undeduplicable, and exactly what §13.3 rule 3 forbids. It is also
165
+ * honest: the install did succeed.
166
+ */
167
+ activity.done();
168
+ }
169
+ await updateSiteConfig({ extensions: [...enabledSpecifiers(), row.specifier] });
170
+ /* Set after the write resolved, so the latch never claims a file the write did not reach. */
171
+ _lastEnableWrote = installed ? ["project.json", "package.json"] : ["project.json"];
172
+ } finally {
173
+ _inFlight = null;
174
+ notifySettingsDocument();
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Remove an extension from `project.json`, leaving its package installed.
180
+ *
181
+ * Turning something off is always safe, so this refuses nothing but a no-op — including on a
182
+ * backend that reports the extension as unrunnable, which is the case where being able to remove it
183
+ * matters most. Through `registry.run` the no-op IS a refusal: `package` is coerced against
184
+ * `enabledSpecifiers()` before this is entered, so a name `project.json` does not hold reads `is
185
+ * not declared — declared: …`, which is what the palette already said by never offering it.
186
+ *
187
+ * @param {string} specifier
188
+ * @returns {Promise<void>}
189
+ */
190
+ export async function disableExtension(specifier: string): Promise<void> {
191
+ if (_inFlight !== null) {
192
+ throw new Error(`Another extension operation is running (${_inFlight}).`);
193
+ }
194
+ const current = enabledSpecifiers();
195
+ if (!current.includes(specifier)) {
196
+ return;
197
+ }
198
+ _inFlight = specifier;
199
+ notifySettingsDocument();
200
+ try {
201
+ await updateSiteConfig({ extensions: current.filter((entry) => entry !== specifier) });
202
+ } finally {
203
+ _inFlight = null;
204
+ notifySettingsDocument();
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Uninstall an extension's package.
210
+ *
211
+ * Refuses while `project.json` still names it, because removing the package under a live
212
+ * `extensions` entry produces precisely the enabled-but-missing state that fails the next build.
213
+ * §12.4's rule: the strict member's refusal is evidence the write is unsafe, so the loose member
214
+ * must not do it anyway.
215
+ *
216
+ * @param {string} name
217
+ * @returns {Promise<void>}
218
+ */
219
+ export async function removeExtensionPackage(name: string): Promise<void> {
220
+ if (enabledSpecifiers().includes(name)) {
221
+ throw new RangeError(
222
+ `command "packages.remove" argument "package": "${name}" is still enabled in project.json ` +
223
+ `"extensions" — disable it first, or the next build will fail on a missing package.`,
224
+ );
225
+ }
226
+ if (_inFlight !== null) {
227
+ throw new Error(`Another extension operation is running (${_inFlight}).`);
228
+ }
229
+ _inFlight = name;
230
+ notifySettingsDocument();
231
+ try {
232
+ await getPlatform().removePackage(name);
233
+ // A toast, unlike enable/disable: this one leaves no Activity entry behind, and it is
234
+ // Destructive and not undoable, so silence would be the wrong report.
235
+ notify.success(`Removed ${name}.`);
236
+ } finally {
237
+ _inFlight = null;
238
+ notifySettingsDocument();
239
+ }
240
+ }
241
+
242
+ /** The `project.json` sections an extension owns, for the report. */
243
+ function sectionsOf(name: string): string[] {
244
+ return buildRows().find((row) => row.name === name || row.specifier === name)?.sections ?? [];
245
+ }
246
+
247
+ /** The specifiers the project enables right now, for the report. */
248
+ function enabledNow(): string {
249
+ return (
250
+ buildRows()
251
+ .filter((row) => row.enabled)
252
+ .map((row) => row.specifier)
253
+ .join(", ") || "none"
254
+ );
255
+ }
256
+
257
+ /** The three records, for `appCommandSet()` and the bootstrap registry. */
258
+ export function extensionCommands(): AnyCommand[] {
259
+ return [
260
+ {
261
+ args: argsSchema({
262
+ package: derivedEnumProperty(
263
+ enableable,
264
+ 'The extension package to turn on, e.g. "@jxsuite/parser". A package that is not ' +
265
+ "installed is installed first.",
266
+ ),
267
+ }),
268
+ category: "Project",
269
+ group: "7_settings_extensions",
270
+ id: "project.enableExtension",
271
+ level: "project",
272
+ menus: ["palette"],
273
+ requires: "an open project",
274
+ enablement: (ctx) => ctx.project.open,
275
+ /*
276
+ * `none`, not `project`. The `project.json` half IS a transaction and ⌘Z takes it back, but
277
+ * the install is not — a record claiming `project` would promise an undo that leaves the
278
+ * package on disk.
279
+ */
280
+ undo: "none",
281
+ aiTool: {
282
+ /* "Installing is not undoable" used to be this sentence's last clause; the bridge appends
283
+ `Not undoable.` from `undo` for every record, so saying it here would say it twice. */
284
+ description:
285
+ "Turn on a Jx extension for this project: install its npm package if it is missing and " +
286
+ 'add it to project.json "extensions". Enable an extension BEFORE writing the ' +
287
+ "project.json section it owns, because a section belonging to a disabled extension is a " +
288
+ "schema error.",
289
+ name: "enable_extension",
290
+ /* The result carries what a read tool would otherwise have to be advertised to answer: the
291
+ sections that became legal and the enabled set. `wrote` is explicit because `undo` is
292
+ `none` — the ledger cannot infer a disk path — and is the latch's own list: `package.json`
293
+ only for the run that installed, and EMPTY for the run that found the row already on,
294
+ which is then a statement rather than a change and files nothing. */
295
+ report: ({ args }) => {
296
+ const name = stringArg("project.enableExtension", args, "package");
297
+ const sections = sectionsOf(name);
298
+ const owned =
299
+ sections.length > 0
300
+ ? ` Its project.json sections are ${_lastEnableWrote.length > 0 ? "now " : ""}valid: ${sections.join(", ")}.`
301
+ : "";
302
+ const verb =
303
+ _lastEnableWrote.length > 0 ? `Enabled ${name}.` : `${name} was already enabled.`;
304
+ return {
305
+ summary: `${verb}${owned} Enabled extensions: ${enabledNow()}.`,
306
+ wrote: _lastEnableWrote,
307
+ };
308
+ },
309
+ },
310
+ run: async (_ctx, args) =>
311
+ enableExtension(stringArg("project.enableExtension", args, "package")),
312
+ title: "Enable Extension",
313
+ },
314
+ {
315
+ args: argsSchema({
316
+ package: derivedEnumProperty(
317
+ enabledSpecifiers,
318
+ "The extension to turn off. Its npm package stays installed.",
319
+ ),
320
+ }),
321
+ category: "Project",
322
+ group: "7_settings_extensions",
323
+ id: "project.disableExtension",
324
+ level: "project",
325
+ menus: ["palette"],
326
+ requires: "an open project",
327
+ enablement: (ctx) => ctx.project.open,
328
+ undo: "project",
329
+ aiTool: {
330
+ description:
331
+ 'Remove an extension from project.json "extensions". Its npm package stays installed, ' +
332
+ "and the settings sections it contributed disappear. Remove any project.json sections " +
333
+ "it owns first, or the configuration will not validate.",
334
+ name: "disable_extension",
335
+ /* "Ask before uninstalling" is the sentence that keeps `packages.remove` — deliberately not
336
+ projected — from being reached for by inference. `wrote` defaults from `undo: "project"`
337
+ to `project.json`, which is the one file this touches. */
338
+ report: ({ args }) =>
339
+ `Disabled ${stringArg("project.disableExtension", args, "package")}; its npm package ` +
340
+ `is still installed. Ask before uninstalling it. Enabled extensions: ${enabledNow()}.`,
341
+ },
342
+ run: async (_ctx, args) =>
343
+ disableExtension(stringArg("project.disableExtension", args, "package")),
344
+ title: "Disable Extension",
345
+ },
346
+ {
347
+ args: argsSchema({
348
+ package: stringProperty("The npm package to uninstall from this project."),
349
+ }),
350
+ category: "Project",
351
+ destructive: true,
352
+ group: "9_danger",
353
+ id: "packages.remove",
354
+ level: "project",
355
+ menus: ["palette"],
356
+ requires: "an open project",
357
+ enablement: (ctx) => ctx.project.open,
358
+ undo: "none",
359
+ /*
360
+ * Deliberately no `aiTool`. §12.4 binds an agent tool that WRITES what a command writes to
361
+ * the command's rule; it does not require every command to have one. The model has no read
362
+ * that tells it whether a dependency is load-bearing elsewhere in the project, so it cannot
363
+ * form the judgement this verb needs, and the act is destructive and not undoable.
364
+ */
365
+ run: async (_ctx, args) =>
366
+ removeExtensionPackage(stringArg("packages.remove", args, "package")),
367
+ title: "Remove Package",
368
+ },
369
+ ];
370
+ }
371
+
372
+ /**
373
+ * Register the three records.
374
+ *
375
+ * @param {CommandRegistry} registry
376
+ */
377
+ export function registerExtensionCommands(registry: CommandRegistry): void {
378
+ registry.registerAll(extensionCommands());
379
+ }