@jxsuite/studio 4.1.0 → 5.1.0

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