@jxsuite/studio 4.0.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.
- package/README.md +1 -1
- package/data/elements-meta.json +5 -15
- package/data/html-meta.json +51 -6
- package/dist/chunks/{2020-xp8vnwma.js → 2020-g79n01v9.js} +14 -14
- package/dist/chunks/action-group-sp6tna8v.js +118 -0
- package/dist/chunks/adapter-nj7tnjfn.js +13 -0
- package/dist/chunks/cf-account-picker-fyf63pmy.js +495 -0
- package/dist/chunks/cf-settings-71bv5zn9.js +20 -0
- package/dist/chunks/color-area-v17df7b8.js +154 -0
- package/dist/chunks/color-field-anwybnkn.js +208 -0
- package/dist/chunks/color-slider-44ez96fc.js +79 -0
- package/dist/chunks/color-xgg3kfw7.js +35 -0
- package/dist/chunks/combobox-5e7jev23.js +236 -0
- package/dist/chunks/components-2w1f35qs.js +18 -0
- package/dist/chunks/content-source-3wqeas45.js +46 -0
- package/dist/chunks/convert-to-repeater-d0cgnb6d.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-d6g50j7s.js +42 -0
- package/dist/chunks/extension-sections-fy7q4fe9.js +651 -0
- package/dist/chunks/file-ops-3btj6st0.js +47 -0
- package/dist/chunks/files-ef8fgs3w.js +72 -0
- package/dist/chunks/format-host-3c33nwr8.js +40 -0
- package/dist/chunks/fs-events-13tj6sex.js +18 -0
- package/dist/chunks/git-panel-4wp2rn9b.js +49 -0
- package/dist/chunks/icons-yy10wk9r.js +402 -0
- package/dist/chunks/iframe-entry-15g3n6xv.js +114 -0
- package/dist/chunks/iframe-entry-b27vq81n.js +203 -0
- package/dist/chunks/iframe-entry-nbyxee1y.js +154 -0
- package/dist/chunks/iframe-host-jgesd924.js +115 -0
- package/dist/chunks/{index-nj44jpzj.js → index-mdmyx6s2.js} +11 -11
- package/dist/chunks/index-n4j7qxyr.js +109 -0
- package/dist/chunks/{javascript-q8kpmfah.js → javascript-xvrfrpkb.js} +8 -9
- package/dist/chunks/{jsonMode-dkr040ga.js → jsonMode-tyx2kj6p.js} +526 -527
- package/dist/chunks/jx-validate-j0wxk72w.js +15 -0
- package/dist/chunks/layers-1nq5evsh.js +29 -0
- package/dist/chunks/layers-panel-ar2gh90g.js +40 -0
- package/dist/chunks/listbox-6v2ac08j.js +44 -0
- package/dist/chunks/lit-html-m244w9nh.js +17 -0
- package/dist/chunks/media-picker-2qbetq73.js +33 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -0
- package/dist/chunks/menu-rf7n72mf.js +14 -0
- package/dist/chunks/{monaco-binding-rj6xpx9y.js → monaco-binding-sw6en4dw.js} +12 -15
- package/dist/chunks/monaco-buffer-bhy3hb6m.js +24 -0
- package/dist/chunks/{monaco-setup-rws7k4br.js → monaco-setup-8r62fj6y.js} +27 -37
- package/dist/chunks/notify-628t0anh.js +21 -0
- package/dist/chunks/number-field-5cndyft8.js +72 -0
- package/dist/chunks/parse-0zx14y15.js +10 -0
- package/dist/chunks/platform-ts9cg1a4.js +15 -0
- package/dist/chunks/popover-47z3ytva.js +25 -0
- package/dist/chunks/publish-panel-98f7sr3g.js +27 -0
- package/dist/chunks/quick-search-srzz83k2.js +45 -0
- package/dist/chunks/references-n553f0e1.js +26 -0
- package/dist/chunks/right-panel-rrgx2dn3.js +45 -0
- package/dist/chunks/section-registry-5pq32t0q.js +25 -0
- package/dist/chunks/select-2r16ez41.js +49 -0
- package/dist/chunks/split-g7nm1rgb.js +191 -0
- package/dist/chunks/studio-0hqbpbd0.js +62 -0
- package/dist/chunks/studio-18avnhjp.js +2430 -0
- package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-hbtp0eh1.js → studio-25hkdrkw.js} +356 -85
- package/dist/chunks/studio-26d7myd1.js +258 -0
- package/dist/chunks/{studio-p8j86wag.js → studio-38emantv.js} +22 -5
- package/dist/chunks/studio-3gxv60tn.js +422 -0
- package/dist/chunks/{studio-8swrjbny.js → studio-3hxkd92t.js} +275 -163
- package/dist/chunks/studio-4m0haseg.js +185 -0
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/{studio-gv8vvshc.js → studio-5523bpzt.js} +11 -11
- package/dist/chunks/{studio-5q69gfag.js → studio-57mf66w2.js} +1753 -2484
- package/dist/chunks/studio-5jy81t3s.js +17463 -0
- package/dist/chunks/studio-5rt7sqa0.js +1168 -0
- package/dist/chunks/studio-5te5tqng.js +81 -0
- package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
- package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
- package/dist/chunks/studio-6xa21ej9.js +28 -0
- package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
- package/dist/chunks/{studio-eenfkt4e.js → studio-79y5sz51.js} +52 -38
- package/dist/chunks/{studio-4q0wznzf.js → studio-7e11jpa9.js} +461 -145
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xptrg0j.js +954 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-81390n6f.js} +22 -22
- package/dist/chunks/{studio-q43a5y9h.js → studio-8jn5yhyn.js} +16 -16
- package/dist/chunks/studio-8qtrpzr3.js +839 -0
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-9xxz1q69.js +1356 -0
- package/dist/chunks/studio-akbww0j5.js +13615 -0
- package/dist/chunks/studio-arfpe389.js +195 -0
- package/dist/chunks/{studio-2zkz8evn.js → studio-az3zd49t.js} +473 -281
- package/dist/chunks/studio-cpvb2ed1.js +1171 -0
- package/dist/chunks/{studio-9r6j5ev1.js → studio-d0300636.js} +5078 -19
- package/dist/chunks/{studio-bgxt93ga.js → studio-d055c37e.js} +13 -13
- package/dist/chunks/studio-d1ja2x9r.js +362 -0
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/{studio-4pqqxbrt.js → studio-em9nw8eh.js} +301 -112
- package/dist/chunks/studio-erdatzvp.js +1190 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/studio-fabxk6r9.js +2811 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/studio-hhvs4sdg.js +195 -0
- package/dist/chunks/{studio-68n67094.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/studio-pm6hgy7r.js +4763 -0
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/studio-qahxvnan.js +111 -0
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-kjjsjak4.js → studio-rkstz940.js} +3661 -6136
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rpyah2ew.js +2805 -0
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/{studio-yxrkyv8a.js → studio-s6z853aq.js} +12108 -11766
- package/dist/chunks/{studio-sf7zjgv1.js → studio-sgdc5pfc.js} +8 -8
- package/dist/chunks/studio-tb3ev01j.js +763 -0
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-htsf0w6m.js → studio-vz68yn9e.js} +31 -154
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/{studio-eesa1myv.js → studio-x3rty6tr.js} +58 -58
- package/dist/chunks/studio-xsykpvsh.js +8448 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -0
- package/dist/chunks/swatch-group-t0n6h2rn.js +139 -0
- package/dist/chunks/tabs-wbp1cdws.js +156 -0
- package/dist/chunks/textfield-abk6qyee.js +73 -0
- package/dist/chunks/toast-780pvfbv.js +27 -0
- package/dist/chunks/toast-host-3sqv46sn.js +116 -0
- package/dist/chunks/toolbar-xbh5bhtr.js +194 -0
- package/dist/chunks/tooltip-eptb614w.js +369 -0
- package/dist/chunks/tree-a73p0pqm.js +367 -0
- package/dist/chunks/{tsMode-76kr53q0.js → tsMode-jy4m86rv.js} +83 -85
- package/dist/chunks/workspace-wrew8zk4.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1812 -698
- package/dist/manifest.json +7 -0
- package/dist/studio.js +52900 -36573
- package/dist/workers/editor.worker.js +1040 -1085
- package/dist/workers/json.worker.js +1946 -1991
- package/dist/workers/ts.worker.js +4960 -5005
- package/favicon.ico +0 -0
- package/index.html +2 -0
- package/package.json +22 -55
- package/src/about/about-modal.ts +73 -123
- package/src/browse/library-commands.ts +20 -49
- package/src/browse/library-layouts.ts +87 -218
- package/src/browse/library-pane.ts +406 -438
- package/src/canvas/canvas-helpers.ts +0 -49
- package/src/canvas/canvas-live-render.ts +25 -2
- package/src/canvas/canvas-render.ts +666 -231
- package/src/canvas/canvas-surface.ts +0 -1
- package/src/canvas/canvas-utils.ts +310 -117
- package/src/canvas/dialog-path.ts +76 -0
- package/src/canvas/dialog-state.ts +67 -0
- package/src/canvas/diff-marks.ts +252 -0
- package/src/canvas/diff-toolbar.ts +349 -0
- package/src/canvas/diff-view.ts +123 -0
- package/src/canvas/edit-width-drag.ts +187 -0
- package/src/canvas/edit-width.ts +150 -0
- package/src/canvas/iframe-entry.ts +125 -8
- package/src/canvas/iframe-host.ts +271 -15
- package/src/canvas/iframe-interaction.ts +133 -13
- package/src/canvas/iframe-patch.ts +7 -1
- package/src/canvas/iframe-position.ts +5 -6
- package/src/canvas/iframe-protocol.ts +106 -5
- package/src/canvas/iframe-render.ts +373 -5
- package/src/canvas/iframe-slash.ts +2 -2
- package/src/canvas/iframe-subtree.ts +5 -8
- package/src/canvas/path-mapping.ts +25 -3
- package/src/canvas/popover-path.ts +106 -0
- package/src/canvas/popover-state.ts +155 -0
- package/src/canvas/surface-registry.ts +21 -10
- package/src/collab/presence-chips.ts +51 -73
- package/src/commands/app-commands.ts +10 -0
- package/src/commands/budget.ts +12 -0
- package/src/commands/command-args.ts +369 -6
- package/src/commands/defaults.ts +44 -14
- package/src/commands/live-context.ts +11 -5
- package/src/commands/reference.ts +12 -2
- package/src/commands/registry.ts +165 -8
- package/src/content/entry-commands.ts +16 -23
- package/src/content/entry-editor.ts +144 -101
- package/src/editor/canvas-slash-bridge.ts +2 -2
- package/src/editor/context-menu.ts +49 -200
- package/src/editor/convert-to-component.ts +42 -82
- package/src/editor/convert-to-repeater.ts +132 -173
- package/src/editor/inline-edit.ts +11 -0
- package/src/editor/shortcuts.ts +65 -26
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +949 -664
- package/src/files/json-layout.ts +474 -0
- package/src/files/media-paths.ts +13 -42
- package/src/files/media-usage.ts +41 -131
- package/src/files/serialize-document.ts +8 -1
- package/src/format/convert-file.ts +16 -10
- package/src/format/format-host.ts +50 -1
- package/src/github/github-auth.ts +71 -29
- package/src/github/github-publish.ts +57 -65
- package/src/grid/cell-editors.ts +46 -4
- package/src/grid/cell-popovers.ts +65 -62
- package/src/grid/grid-open.ts +86 -64
- package/src/grid/grid-panel.ts +390 -469
- package/src/grid/redirects-grid.ts +40 -44
- package/src/hosting/document.ts +2 -0
- package/src/hosting/layout.ts +10 -0
- package/src/i18n/i18n-commands.ts +127 -62
- package/src/media/media-pane.ts +83 -133
- package/src/new-project/add-repo-modal.ts +125 -176
- package/src/new-project/import-tab.ts +201 -250
- package/src/new-project/location-fields.ts +101 -165
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- package/src/panels/activity-panel.ts +137 -104
- package/src/panels/ai-chat/chat-markdown.ts +15 -13
- package/src/panels/ai-chat/chat-view.ts +307 -472
- package/src/panels/ai-chat/composer.ts +175 -153
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +210 -185
- package/src/panels/block-action-bar.ts +437 -643
- package/src/panels/bottom-dock.ts +112 -47
- package/src/panels/chat-panel.ts +19 -14
- package/src/panels/data-explorer.ts +141 -102
- package/src/panels/data-grid.ts +183 -150
- package/src/panels/dnd.ts +75 -20
- package/src/panels/editors.ts +26 -19
- package/src/panels/elements-panel.ts +243 -186
- package/src/panels/empty-state.ts +26 -42
- package/src/panels/events-panel.ts +950 -729
- package/src/panels/formula-workspace.ts +434 -207
- package/src/panels/frontmatter-fields.ts +185 -153
- package/src/panels/frontmatter-panel.ts +411 -187
- package/src/panels/git-diff-open.ts +148 -0
- package/src/panels/git-panel.ts +679 -605
- package/src/panels/head-panel.ts +617 -435
- package/src/panels/i18n-panel.ts +153 -133
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +174 -147
- package/src/panels/layers-panel.ts +785 -671
- package/src/panels/left-panel.ts +166 -94
- package/src/panels/navigator-panels.ts +1 -1
- package/src/panels/pane-context.ts +529 -677
- package/src/panels/pane-grid.ts +265 -241
- package/src/panels/panel-registry.ts +15 -4
- package/src/panels/problems-panel.ts +177 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +217 -172
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +109 -646
- package/src/panels/settings-pane.ts +102 -86
- package/src/panels/signals-panel.ts +1318 -1172
- package/src/panels/statement-editor.ts +556 -428
- package/src/panels/style-panel.ts +1367 -630
- package/src/panels/style-utils.ts +36 -32
- package/src/panels/stylebook-doc.ts +30 -73
- package/src/panels/stylebook-layers-panel.ts +202 -109
- package/src/panels/stylebook-panel.ts +124 -88
- package/src/panels/tab-strip.ts +385 -287
- package/src/platforms/cloud.ts +347 -86
- package/src/platforms/devserver.ts +13 -0
- package/src/publish/deploy-checklist.ts +124 -78
- package/src/publish/publish-commands.ts +4 -12
- package/src/publish/publish-panel.ts +165 -299
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +468 -0
- package/src/services/ai-import-tools.ts +50 -12
- package/src/services/ai-models.ts +108 -1
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +110 -18
- package/src/services/ai-tools.ts +28 -143
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/context-manager.ts +12 -1
- package/src/services/document-assistant.ts +50 -2
- package/src/services/idle.ts +16 -14
- package/src/services/live-surfaces.ts +237 -0
- package/src/services/model-uri.ts +75 -0
- package/src/services/notify.ts +63 -6
- package/src/services/popover-report.ts +325 -0
- package/src/services/surface-registry.ts +56 -0
- package/src/services/tool-executor.ts +17 -0
- package/src/settings/contexts-section.ts +301 -299
- package/src/settings/contributed-section.ts +361 -222
- package/src/settings/css-vars-editor.ts +320 -325
- package/src/settings/defs-editor.ts +572 -535
- package/src/settings/dependencies-editor.ts +79 -107
- package/src/settings/extension-commands.ts +379 -0
- package/src/settings/extension-rows.ts +113 -0
- package/src/settings/extensions-section.ts +287 -0
- package/src/settings/general-settings.ts +130 -181
- package/src/settings/head-editor.ts +10 -305
- package/src/settings/locales-section.ts +146 -196
- package/src/settings/preferences-accounts.ts +193 -12
- package/src/settings/preferences-dialog.ts +384 -307
- package/src/settings/project-sections.ts +108 -181
- package/src/settings/schema-field-ui.ts +11 -399
- package/src/settings/section-registry.ts +8 -1
- package/src/settings/settings-document.ts +31 -29
- package/src/shell/tree.ts +42 -87
- package/src/shell.ts +48 -36
- package/src/studio.ts +90 -67
- package/src/style/token-ref.ts +0 -39
- package/src/surfaces/about.json +263 -0
- package/src/surfaces/about.ts +163 -0
- package/src/surfaces/add-repo.json +486 -0
- package/src/surfaces/add-repo.ts +236 -0
- package/src/surfaces/ai-chat.json +2185 -0
- package/src/surfaces/ai-chat.ts +549 -0
- package/src/surfaces/ai-credentials-form.json +332 -0
- package/src/surfaces/ai-credentials-form.ts +151 -0
- package/src/surfaces/ai-managed-connect.json +108 -0
- package/src/surfaces/ai-managed-connect.ts +123 -0
- package/src/surfaces/ai-model-picker.json +114 -0
- package/src/surfaces/ai-model-picker.ts +139 -0
- package/src/surfaces/block-action-bar.json +640 -0
- package/src/surfaces/block-action-bar.ts +368 -0
- package/src/surfaces/bottom-dock.json +154 -0
- package/src/surfaces/bottom-dock.ts +125 -0
- package/src/surfaces/canvas-stage.json +444 -0
- package/src/surfaces/canvas-stage.ts +253 -0
- package/src/surfaces/cf-account-picker.json +300 -0
- package/src/surfaces/cf-account-picker.ts +214 -0
- package/src/surfaces/commandbar.json +984 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +414 -389
- package/src/surfaces/convert-repeater.json +309 -0
- package/src/surfaces/convert-repeater.ts +276 -0
- package/src/surfaces/data-actions.json +157 -0
- package/src/surfaces/data-actions.ts +115 -0
- package/src/surfaces/dialog.json +289 -0
- package/src/surfaces/dialog.ts +343 -0
- package/src/surfaces/diff-toolbar.json +266 -0
- package/src/surfaces/diff-toolbar.ts +139 -0
- package/src/surfaces/doc-header.json +739 -0
- package/src/surfaces/doc-header.ts +223 -0
- package/src/surfaces/empty-state.json +152 -0
- package/src/surfaces/empty-state.ts +173 -0
- package/src/surfaces/entry-editor.json +281 -0
- package/src/surfaces/entry-editor.ts +191 -0
- package/src/surfaces/expression-editor.json +977 -0
- package/src/surfaces/expression-editor.ts +266 -0
- package/src/surfaces/files-panel.json +592 -0
- package/src/surfaces/files-panel.ts +301 -0
- package/src/surfaces/formula-palette.json +364 -0
- package/src/surfaces/formula-palette.ts +340 -0
- package/src/surfaces/git-panel.json +1822 -0
- package/src/surfaces/git-panel.ts +272 -0
- package/src/surfaces/github-auth.json +112 -0
- package/src/surfaces/github-auth.ts +139 -0
- package/src/surfaces/github-publish.json +206 -0
- package/src/surfaces/github-publish.ts +169 -0
- package/src/surfaces/grid-cell.json +218 -0
- package/src/surfaces/grid-cell.ts +120 -0
- package/src/surfaces/grid-open.json +147 -0
- package/src/surfaces/grid-open.ts +87 -0
- package/src/surfaces/grid-panel.json +706 -0
- package/src/surfaces/grid-panel.ts +206 -0
- package/src/surfaces/grid-replace.json +179 -0
- package/src/surfaces/grid-replace.ts +89 -0
- package/src/surfaces/grid-views.json +446 -0
- package/src/surfaces/grid-views.ts +172 -0
- package/src/surfaces/inspector-dock.json +187 -0
- package/src/surfaces/inspector-dock.ts +161 -0
- package/src/surfaces/jump-bar.json +243 -0
- package/src/surfaces/jump-bar.ts +129 -0
- package/src/surfaces/jxsuite-update.json +146 -0
- package/src/surfaces/jxsuite-update.ts +149 -0
- package/src/surfaces/library-pane.json +1509 -0
- package/src/surfaces/library-pane.ts +363 -0
- package/src/surfaces/logic-panel.json +1949 -0
- package/src/surfaces/logic-panel.ts +369 -0
- package/src/surfaces/logic-workspace.json +685 -0
- package/src/surfaces/logic-workspace.ts +238 -0
- package/src/surfaces/media-browser.json +303 -0
- package/src/surfaces/media-browser.ts +145 -0
- package/src/surfaces/media-field.json +163 -0
- package/src/surfaces/media-field.ts +116 -0
- package/src/surfaces/media-pane.json +513 -0
- package/src/surfaces/media-pane.ts +197 -0
- package/src/surfaces/menu.json +232 -0
- package/src/surfaces/menu.ts +375 -0
- package/src/surfaces/navigator-dock.json +113 -0
- package/src/surfaces/navigator-dock.ts +130 -0
- package/src/surfaces/new-project.json +1654 -0
- package/src/surfaces/new-project.ts +411 -0
- package/src/surfaces/palette.json +535 -0
- package/src/surfaces/pane-context.json +1497 -0
- package/src/surfaces/pane-context.ts +513 -0
- package/src/surfaces/pane-grid.json +188 -0
- package/src/surfaces/pane-grid.ts +250 -0
- package/src/surfaces/panel-activity.json +563 -0
- package/src/surfaces/panel-activity.ts +187 -0
- package/src/surfaces/panel-data.json +141 -0
- package/src/surfaces/panel-data.ts +156 -0
- package/src/surfaces/panel-deploy-checklist.json +283 -0
- package/src/surfaces/panel-deploy-checklist.ts +175 -0
- package/src/surfaces/panel-elements.json +367 -0
- package/src/surfaces/panel-elements.ts +175 -0
- package/src/surfaces/panel-i18n.json +569 -0
- package/src/surfaces/panel-i18n.ts +212 -0
- package/src/surfaces/panel-imports.json +780 -0
- package/src/surfaces/panel-imports.ts +209 -0
- package/src/surfaces/panel-outline.json +734 -0
- package/src/surfaces/panel-outline.ts +326 -0
- package/src/surfaces/panel-page.json +1017 -0
- package/src/surfaces/panel-page.ts +240 -0
- package/src/surfaces/panel-problems.json +497 -0
- package/src/surfaces/panel-problems.ts +157 -0
- package/src/surfaces/panel-signals.json +1973 -0
- package/src/surfaces/panel-signals.ts +436 -0
- package/src/surfaces/panel-stylebook-layers.json +317 -0
- package/src/surfaces/panel-stylebook-layers.ts +155 -0
- package/src/surfaces/preferences.json +850 -0
- package/src/surfaces/preferences.ts +332 -0
- package/src/surfaces/progress-modal.json +110 -0
- package/src/surfaces/progress-modal.ts +150 -0
- package/src/surfaces/properties-panel.json +1578 -0
- package/src/surfaces/properties-panel.ts +337 -0
- package/src/surfaces/publish.json +945 -0
- package/src/surfaces/publish.ts +392 -0
- package/src/surfaces/push-plan.json +110 -0
- package/src/surfaces/push-plan.ts +87 -0
- package/src/surfaces/rail.json +255 -0
- package/src/surfaces/rail.ts +206 -0
- package/src/surfaces/reference-field.json +191 -0
- package/src/surfaces/reference-field.ts +168 -0
- package/src/surfaces/schema-builder.json +1011 -0
- package/src/surfaces/schema-builder.ts +181 -0
- package/src/surfaces/schema-form.json +1013 -0
- package/src/surfaces/schema-form.ts +287 -0
- package/src/surfaces/secret-field.json +60 -0
- package/src/surfaces/secret-field.ts +146 -0
- package/src/surfaces/seo.json +932 -0
- package/src/surfaces/seo.ts +334 -0
- package/src/surfaces/settings-contexts.json +538 -0
- package/src/surfaces/settings-contexts.ts +196 -0
- package/src/surfaces/settings-contributed.json +489 -0
- package/src/surfaces/settings-contributed.ts +199 -0
- package/src/surfaces/settings-css-vars.json +820 -0
- package/src/surfaces/settings-css-vars.ts +199 -0
- package/src/surfaces/settings-defs.json +1363 -0
- package/src/surfaces/settings-defs.ts +232 -0
- package/src/surfaces/settings-deploy.json +108 -0
- package/src/surfaces/settings-deploy.ts +135 -0
- package/src/surfaces/settings-extensions.json +486 -0
- package/src/surfaces/settings-extensions.ts +201 -0
- package/src/surfaces/settings-head.json +779 -0
- package/src/surfaces/settings-head.ts +397 -0
- package/src/surfaces/settings-locales.json +420 -0
- package/src/surfaces/settings-locales.ts +137 -0
- package/src/surfaces/settings-overview.json +423 -0
- package/src/surfaces/settings-overview.ts +218 -0
- package/src/surfaces/settings-packages.json +549 -0
- package/src/surfaces/settings-packages.ts +158 -0
- package/src/surfaces/settings-pane.json +147 -0
- package/src/surfaces/settings-pane.ts +150 -0
- package/src/surfaces/settings-rawjson.json +104 -0
- package/src/surfaces/settings-rawjson.ts +107 -0
- package/src/surfaces/shell.json +99 -0
- package/src/surfaces/shell.ts +30 -0
- package/src/surfaces/slash-menu.json +180 -0
- package/src/surfaces/slash-menu.ts +272 -0
- package/src/surfaces/statements.json +607 -0
- package/src/surfaces/statements.ts +238 -0
- package/src/surfaces/statusbar.json +94 -0
- package/src/{panels → surfaces}/statusbar.ts +163 -90
- package/src/surfaces/style-panel.json +1643 -0
- package/src/surfaces/style-panel.ts +338 -0
- package/src/surfaces/stylebook-chrome.json +122 -0
- package/src/surfaces/stylebook-chrome.ts +122 -0
- package/src/surfaces/tab-strip.json +448 -0
- package/src/surfaces/tab-strip.ts +200 -0
- package/src/surfaces/target-line.json +419 -0
- package/src/surfaces/target-line.ts +349 -0
- package/src/surfaces/toasts.json +189 -0
- package/src/surfaces/welcome.json +571 -0
- package/src/surfaces/welcome.ts +338 -0
- package/src/tabs/project-config.ts +71 -15
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +49 -3
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +116 -49
- package/src/ui/ai-model-picker.ts +102 -47
- package/src/ui/cf-account-picker.ts +135 -0
- package/src/ui/color-selector.ts +80 -301
- package/src/ui/dynamic-slot.ts +43 -283
- package/src/ui/expression-editor.ts +797 -576
- package/src/ui/field-input.ts +8 -181
- package/src/ui/form-controls.ts +838 -366
- package/src/ui/formula-chips.ts +80 -85
- package/src/ui/kit.ts +33 -0
- package/src/ui/layers.ts +293 -593
- package/src/ui/media-picker.ts +203 -284
- package/src/ui/panel-resize.ts +251 -64
- package/src/ui/popover-surface.ts +153 -0
- package/src/ui/progress-modal.ts +22 -60
- package/src/ui/regions.ts +13 -7
- package/src/ui/schema-form.ts +906 -440
- package/src/ui/surface.ts +122 -0
- package/src/ui/unit-selector.ts +15 -131
- package/src/ui/value-source.ts +14 -0
- package/src/ui/virtual-window.ts +88 -9
- package/src/utils/canvas-media.ts +72 -0
- package/src/utils/edit-display.ts +7 -2
- package/src/utils/element-selectors.ts +69 -0
- package/src/utils/link-target.ts +2 -2
- package/src/utils/studio-utils.ts +0 -10
- package/src/view.ts +15 -0
- package/src/workspace/pane-derive.ts +36 -14
- package/src/workspace/workspace.ts +15 -6
- package/styles/canvas.css +72 -467
- package/styles/forced-colors.css +48 -82
- package/styles/forced-colors.json +41 -0
- package/styles/inspector.css +2 -1301
- package/styles/overlays.css +96 -2823
- package/styles/panels.css +6 -1423
- package/styles/shell-frame.css +272 -0
- package/styles/shell-frame.json +227 -0
- package/styles/shell.css +0 -1532
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-723bv0df.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-t88vb2dr.js +0 -49
- package/dist/chunks/convert-to-repeater-dhw1nrz9.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-6z6bhxg0.js +0 -46
- package/dist/chunks/extension-sections-3ydgjbdy.js +0 -311
- package/dist/chunks/file-ops-rskmhxyq.js +0 -48
- package/dist/chunks/files-0cratsr0.js +0 -92
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-ggawf1hy.js +0 -1024
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-tgcmfs4p.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-0yywyk76.js +0 -58
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8q2g05x1.js +0 -19
- package/dist/chunks/layers-panel-z3tqe5cd.js +0 -67
- package/dist/chunks/layers-q75tj2mf.js +0 -45
- package/dist/chunks/lit-html-j055mkh8.js +0 -22
- package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
- package/dist/chunks/notify-yjm79n4s.js +0 -30
- package/dist/chunks/parse-24d0gay3.js +0 -19
- package/dist/chunks/platform-ba1j1gbh.js +0 -16
- package/dist/chunks/publish-panel-54jvhskq.js +0 -28
- package/dist/chunks/quick-search-cgfmjwq5.js +0 -65
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-cqp8bc4v.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-yztmtrs1.js +0 -18
- package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
- package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
- package/dist/chunks/sp-tooltip.dev-xcvpnqr0.js +0 -15
- package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
- package/dist/chunks/studio-0a5qrh01.js +0 -3
- package/dist/chunks/studio-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1hbqnt19.js +0 -1823
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5rywrkxz.js +0 -1903
- package/dist/chunks/studio-7afd21nw.js +0 -67
- package/dist/chunks/studio-7nte2hj4.js +0 -613
- package/dist/chunks/studio-8jpzqk5s.js +0 -128
- package/dist/chunks/studio-8q517dfr.js +0 -24
- package/dist/chunks/studio-9c4k4vhv.js +0 -357
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahjfdy6e.js +0 -387
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bw5dz6km.js +0 -608
- package/dist/chunks/studio-cb12yz9w.js +0 -15055
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ex8zyp98.js +0 -1813
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-kyk2v92a.js +0 -659
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mmv72a27.js +0 -4344
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-pdfjntbk.js +0 -6939
- package/dist/chunks/studio-qq6jym04.js +0 -53
- package/dist/chunks/studio-r1r7afxx.js +0 -1066
- package/dist/chunks/studio-rdx8jcxy.js +0 -83
- package/dist/chunks/studio-rn9ta2mz.js +0 -111
- package/dist/chunks/studio-t7qb9db8.js +0 -665
- package/dist/chunks/studio-tmc5emrw.js +0 -8
- package/dist/chunks/studio-txwkm6p9.js +0 -12
- package/dist/chunks/studio-v38hmvx1.js +0 -390
- package/dist/chunks/studio-vadzgkrz.js +0 -318
- package/dist/chunks/studio-wx5609xd.js +0 -341
- package/dist/chunks/studio-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/workspace-xpres40v.js +0 -89
- package/src/panels/activity-bar.ts +0 -251
- package/src/panels/panel-scheduler.ts +0 -219
- package/src/panels/style-inputs.ts +0 -237
- package/src/panels/target-line.ts +0 -274
- package/src/panels/welcome-screen.ts +0 -346
- package/src/ui/button-group.ts +0 -102
- package/src/ui/choice-field.ts +0 -72
- package/src/ui/field-row.ts +0 -249
- package/src/ui/formula-palette.ts +0 -213
- package/src/ui/icons.ts +0 -52
- package/src/ui/jx-theme.ts +0 -130
- package/src/ui/spectrum.ts +0 -340
- package/src/ui/value-selector.ts +0 -174
- package/src/ui/widgets.ts +0 -172
- /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
- /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
- /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
- /package/dist/chunks/{tsMode-ef187txx.css → tsMode-hnxxb73h.css} +0 -0
package/src/files/media-usage.ts
CHANGED
|
@@ -1,164 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Media usage — "which pages use this image?", asked
|
|
2
|
+
* Media usage — "which pages use this image?", asked once.
|
|
3
3
|
*
|
|
4
|
-
* `services/references.ts`
|
|
5
|
-
* what every destructive confirmation says out loud. Media
|
|
6
|
-
*
|
|
7
|
-
* somewhere else.** `public/hero.jpg` is written `/hero.jpg`, which the compiler — and therefore
|
|
8
|
-
* the sweep — resolves to `hero.jpg`. Ask about the file and every reference to it is invisible;
|
|
9
|
-
* the query succeeds, returns zero, and the delete dialog says nothing else refers to it while
|
|
10
|
-
* seven pages break. A confident zero is the one answer a destructive dialog must never invent.
|
|
4
|
+
* `services/references.ts` answers "where is this used?" for every kind of file, and its answer is
|
|
5
|
+
* what every destructive confirmation says out loud. Media needs three things on top of it, and no
|
|
6
|
+
* longer needs the fourth this module was built for.
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* round trip), the same `invalidateUsages` on any filesystem event, the same `usageWarning`
|
|
17
|
-
* sentence in the confirmation, and the same `usageHeadline` wording on a panel.
|
|
8
|
+
* **What it still does.** A media path is normalized before it becomes a query (a leading `./` is
|
|
9
|
+
* not part of a file's identity), an empty path is a FAILURE rather than "nothing uses it", and
|
|
10
|
+
* {@link mediaUsageHeadline} renders the one line a media surface shows beside a file — where a
|
|
11
|
+
* failed query says **unknown**, which is a different fact from "unused" and has to read like one.
|
|
18
12
|
*
|
|
19
|
-
* **
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
13
|
+
* **What it no longer does, and why that matters.** A media file's authored reference usually
|
|
14
|
+
* resolves somewhere else: `public/hero.jpg` is written `/hero.jpg`, and a content asset is written
|
|
15
|
+
* `./images/hero.png` and republished at its collection's mount. `findReferences` used to resolve a
|
|
16
|
+
* rooted reference against the project root ALONE, so asking it about the file matched none of
|
|
17
|
+
* those and returned a confident zero — the one answer a destructive dialog must never invent. This
|
|
18
|
+
* module's answer was to enumerate every authored spelling of the file and union the results.
|
|
19
|
+
*
|
|
20
|
+
* That was a workaround in the wrong place. A client-side union can make a COUNT come out right and
|
|
21
|
+
* can do nothing at all about the REWRITE, which happens inside the engine — so the engine learned
|
|
22
|
+
* to resolve every lane itself (issue 239/241, `site-architecture.md` §9.3), and the union became a
|
|
23
|
+
* second implementation of a rule that now has one. It is gone: one path in, one query, one answer,
|
|
24
|
+
* and the lanes are the engine's business.
|
|
23
25
|
*
|
|
24
26
|
* @docs studio/projects/media
|
|
25
27
|
*/
|
|
26
28
|
|
|
27
|
-
import {
|
|
29
|
+
import { normalizeProjectPath } from "./media-paths";
|
|
28
30
|
import { loadUsages, peekUsages, retryUsages, usageHeadline } from "../services/references";
|
|
29
|
-
import type {
|
|
30
|
-
import type { ReferenceFile, ReferenceHit, ReferencesResult } from "../types";
|
|
31
|
+
import type { UsageState } from "../services/references";
|
|
31
32
|
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
*
|
|
35
|
-
* One per authored form. An empty list means there is no question to ask (an empty path), which
|
|
36
|
-
* {@link loadMediaUsages} reports as a failure rather than as "nothing uses it".
|
|
37
|
-
*/
|
|
38
|
-
export function mediaUsageQueries(path: string): UsageQuery[] {
|
|
39
|
-
return authoredRefTargets(path).map((target) => ({ path: target }));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Merge one file's hits into the accumulator, summing counts per `(refType, ref)`. */
|
|
43
|
-
function mergeFile(into: Map<string, ReferenceFile>, file: ReferenceFile): void {
|
|
44
|
-
const existing = into.get(file.path);
|
|
45
|
-
if (!existing) {
|
|
46
|
-
into.set(file.path, { count: file.count, path: file.path, refs: [...file.refs] });
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
for (const hit of file.refs) {
|
|
50
|
-
const same = existing.refs.find(
|
|
51
|
-
(candidate: ReferenceHit) => candidate.refType === hit.refType && candidate.ref === hit.ref,
|
|
52
|
-
);
|
|
53
|
-
if (same) {
|
|
54
|
-
same.count += hit.count;
|
|
55
|
-
} else {
|
|
56
|
-
existing.refs.push({ ...hit });
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
existing.count += file.count;
|
|
60
|
-
}
|
|
33
|
+
/** The state a caller gets for a path that names no file. */
|
|
34
|
+
const NO_FILE: UsageState = { message: "no media file to look for", status: "failed" };
|
|
61
35
|
|
|
62
36
|
/**
|
|
63
|
-
*
|
|
37
|
+
* The query for a media file, or null when the path names nothing.
|
|
64
38
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* whichever lane happened to be first.
|
|
39
|
+
* Normalizing here rather than at each call site is the whole of what this wrapper adds over
|
|
40
|
+
* `loadUsages`: the file tree, a drop handler and a library tile do not agree on whether a path
|
|
41
|
+
* carries a leading `./`, and two spellings of one file must not become two cache entries.
|
|
69
42
|
*/
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
for (const result of results) {
|
|
74
|
-
for (const file of result.files) {
|
|
75
|
-
mergeFile(files, file);
|
|
76
|
-
}
|
|
77
|
-
for (const error of result.errors) {
|
|
78
|
-
if (!errors.has(error.path)) {
|
|
79
|
-
errors.set(error.path, error);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
const merged = [...files.values()].toSorted((a, b) => a.path.localeCompare(b.path));
|
|
84
|
-
return {
|
|
85
|
-
errors: [...errors.values()],
|
|
86
|
-
files: merged,
|
|
87
|
-
filesReferencing: merged.length,
|
|
88
|
-
path,
|
|
89
|
-
refsTotal: merged.reduce((sum, file) => sum + file.count, 0),
|
|
90
|
-
tagName: null,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Reduce the lanes to one state.
|
|
96
|
-
*
|
|
97
|
-
* Precedence is strictly least-informative-wins, because every step down is a step away from a
|
|
98
|
-
* number the caller could act on: unsupported (the host cannot answer at all) beats failed (it
|
|
99
|
-
* tried and could not) beats pending beats a real union.
|
|
100
|
-
*/
|
|
101
|
-
function combine(path: string, states: readonly UsageState[]): UsageState {
|
|
102
|
-
if (states.some((state) => state.status === "unsupported")) {
|
|
103
|
-
return { status: "unsupported" };
|
|
104
|
-
}
|
|
105
|
-
const failure = states.find((state) => state.status === "failed");
|
|
106
|
-
if (failure) {
|
|
107
|
-
return failure;
|
|
108
|
-
}
|
|
109
|
-
if (states.some((state) => state.status === "pending")) {
|
|
110
|
-
return { status: "pending" };
|
|
111
|
-
}
|
|
112
|
-
return {
|
|
113
|
-
result: unionResults(
|
|
114
|
-
path,
|
|
115
|
-
states.map((state) => (state as { result: ReferencesResult }).result),
|
|
116
|
-
),
|
|
117
|
-
status: "ready",
|
|
118
|
-
};
|
|
43
|
+
function mediaQuery(path: string): { path: string } | null {
|
|
44
|
+
const normalized = normalizeProjectPath(path);
|
|
45
|
+
return normalized === "" ? null : { path: normalized };
|
|
119
46
|
}
|
|
120
47
|
|
|
121
48
|
/**
|
|
122
49
|
* The answer right now, WITHOUT starting a request — the synchronous read a lit template needs.
|
|
123
50
|
*
|
|
124
|
-
* `null` means
|
|
125
|
-
*
|
|
51
|
+
* `null` means the question has never been asked, and the caller decides whether this paint is the
|
|
52
|
+
* one that asks (see {@link loadMediaUsages}).
|
|
126
53
|
*/
|
|
127
54
|
export function peekMediaUsages(path: string): UsageState | null {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
const states: UsageState[] = [];
|
|
133
|
-
for (const query of queries) {
|
|
134
|
-
const state = peekUsages(query);
|
|
135
|
-
if (state === null) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
states.push(state);
|
|
139
|
-
}
|
|
140
|
-
return combine(path, states);
|
|
55
|
+
const query = mediaQuery(path);
|
|
56
|
+
return query === null ? null : peekUsages(query);
|
|
141
57
|
}
|
|
142
58
|
|
|
143
59
|
/**
|
|
144
|
-
* Ask
|
|
60
|
+
* Ask, or join the ask already in flight. Never rejects — a failure is a STATE, because the caller
|
|
145
61
|
* has to render something and "unknown" is the honest something.
|
|
146
62
|
*/
|
|
147
63
|
export async function loadMediaUsages(path: string): Promise<UsageState> {
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
return { message: "no media file to look for", status: "failed" };
|
|
151
|
-
}
|
|
152
|
-
return combine(path, await Promise.all(queries.map((query) => loadUsages(query))));
|
|
64
|
+
const query = mediaQuery(path);
|
|
65
|
+
return query === null ? NO_FILE : loadUsages(query);
|
|
153
66
|
}
|
|
154
67
|
|
|
155
|
-
/** Forget
|
|
68
|
+
/** Forget the answer and ask again — the Retry behind a failed media count. */
|
|
156
69
|
export async function retryMediaUsages(path: string): Promise<UsageState> {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
return { message: "no media file to look for", status: "failed" };
|
|
160
|
-
}
|
|
161
|
-
return combine(path, await Promise.all(queries.map((query) => retryUsages(query))));
|
|
70
|
+
const query = mediaQuery(path);
|
|
71
|
+
return query === null ? NO_FILE : retryUsages(query);
|
|
162
72
|
}
|
|
163
73
|
|
|
164
74
|
/**
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
formatSerialize,
|
|
20
20
|
loadFormats,
|
|
21
21
|
} from "../format/format-host";
|
|
22
|
+
import { serializeJson } from "./json-layout";
|
|
22
23
|
import type { Tab } from "../tabs/tab";
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -56,5 +57,11 @@ export async function serializeDocument(tab: Tab): Promise<string> {
|
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
/* Native JSON, in the layout the file was read in (`json-layout.ts`, issue 308).
|
|
61
|
+
`tab.doc.layout` is what the read recorded — which objects the author kept on one line, where
|
|
62
|
+
a blank line sits, which characters were escaped — and it is null for a document with no JSON
|
|
63
|
+
source, where every object expands and every array is laid by fit: the formatter's own answer
|
|
64
|
+
for stringified output. Either way the text ends with one newline, as every formatted file
|
|
65
|
+
does. */
|
|
66
|
+
return serializeJson(tab.doc.document, tab.doc.layout ?? null);
|
|
60
67
|
}
|
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
stringProperty,
|
|
28
28
|
} from "../commands/command-args";
|
|
29
29
|
import { convertTargetExtensions, convertTargets } from "./format-choices";
|
|
30
|
+
import { parseJsonDocument, serializeJson } from "../files/json-layout";
|
|
31
|
+
import type { JsonLayout } from "../files/json-layout";
|
|
30
32
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
31
33
|
|
|
32
34
|
/** What a conversion will do, resolved in full before the reader is asked to confirm it. */
|
|
@@ -97,7 +99,12 @@ async function writeDocument(
|
|
|
97
99
|
): Promise<string> {
|
|
98
100
|
const merged = { ...frontmatter, ...document };
|
|
99
101
|
if (targetExt === ".json") {
|
|
100
|
-
|
|
102
|
+
/* The same serializer a save uses (`files/json-layout.ts`), with NO layout: the source was
|
|
103
|
+
markdown or CSV, so there is no JSON text whose line breaks could be kept. Every object
|
|
104
|
+
expands and every short array stays on one line — which is exactly what the repository's
|
|
105
|
+
formatter would make of `JSON.stringify` output, so the converted file needs no reformat and
|
|
106
|
+
the tab it opens in reads its layout straight back. The newline is the serializer's own. */
|
|
107
|
+
return serializeJson(merged, null);
|
|
101
108
|
}
|
|
102
109
|
const { formatByExtension, formatSerialize } = await import("./format-host");
|
|
103
110
|
const format = formatByExtension(targetExt, "serialize");
|
|
@@ -368,12 +375,16 @@ async function rebuildTab(from: string, to: string, text: string): Promise<void>
|
|
|
368
375
|
const format = formatForPath(to);
|
|
369
376
|
let document: Record<string, unknown>;
|
|
370
377
|
let frontmatter: Record<string, unknown> | undefined;
|
|
378
|
+
// The layout of the JSON just written, as every other JSON reader records it (`files/files.ts`,
|
|
379
|
+
// `files/file-ops.ts`): the text is the serializer's own, so the record says what a layout-less
|
|
380
|
+
// Write would do anyway — but the tab reads its file rather than assuming it.
|
|
381
|
+
let layout: JsonLayout | null = null;
|
|
371
382
|
try {
|
|
372
383
|
if (format) {
|
|
373
384
|
const { parseSourceForPath } = await import("../files/file-ops");
|
|
374
385
|
({ document, frontmatter } = await parseSourceForPath(to, text));
|
|
375
386
|
} else {
|
|
376
|
-
document =
|
|
387
|
+
({ document, layout } = parseJsonDocument(text));
|
|
377
388
|
}
|
|
378
389
|
} catch {
|
|
379
390
|
// The bytes on disk are the ones just written and the conversion has already succeeded, so a
|
|
@@ -386,6 +397,7 @@ async function rebuildTab(from: string, to: string, text: string): Promise<void>
|
|
|
386
397
|
documentPath: to,
|
|
387
398
|
...(frontmatter === undefined ? {} : { frontmatter }),
|
|
388
399
|
id: to,
|
|
400
|
+
layout,
|
|
389
401
|
sourceFormat: format?.name ?? null,
|
|
390
402
|
});
|
|
391
403
|
}
|
|
@@ -485,14 +497,8 @@ export function fileFormatCommands(): AnyCommand[] {
|
|
|
485
497
|
// Nothing restores it: the file has moved and its references have been rewritten with it.
|
|
486
498
|
// The confirmation carrying the count is what stands in for an undo.
|
|
487
499
|
undo: "none",
|
|
488
|
-
aiTool:
|
|
489
|
-
|
|
490
|
-
"Convert a document between formats in place — Markdown to JSON and back. The file is " +
|
|
491
|
-
"renamed to the new extension and every reference to it is rewritten. Refused for " +
|
|
492
|
-
"layouts, for anything inside a content collection, and while the file is open with " +
|
|
493
|
-
"unsaved changes.",
|
|
494
|
-
name: "convert_file_format",
|
|
495
|
-
},
|
|
500
|
+
/* No `aiTool`, by §12.4's second deletion rule: `run` awaits a confirm dialog the person
|
|
501
|
+
answers. */
|
|
496
502
|
run: async (_ctx, args: Record<string, unknown>) => {
|
|
497
503
|
const target = typeof args.format === "string" ? args.format : undefined;
|
|
498
504
|
await convertFile(
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { setProjectSchemasForMonaco } from "../services/monaco-lazy";
|
|
11
11
|
import { getPlatform } from "../platform";
|
|
12
|
-
import type { ExtensionsInfo } from "../types";
|
|
12
|
+
import type { ExtensionCatalogEntry, ExtensionsInfo } from "../types";
|
|
13
13
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
14
14
|
|
|
15
15
|
export interface StudioFormatHints {
|
|
@@ -76,6 +76,8 @@ export function refreshFormats() {
|
|
|
76
76
|
_formats = [];
|
|
77
77
|
_extensionsLoaded = null;
|
|
78
78
|
_extensions = [];
|
|
79
|
+
_catalogLoaded = null;
|
|
80
|
+
_catalog = [];
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
/** Seed the registry directly (tests and hosts that preload format metadata). */
|
|
@@ -122,6 +124,50 @@ export function setExtensions(extensions: ExtensionsInfo[]) {
|
|
|
122
124
|
_extensionsLoaded = Promise.resolve(extensions);
|
|
123
125
|
}
|
|
124
126
|
|
|
127
|
+
// ─── Extension catalogue (specs/extensions.md §9.2) ──────────────────────────
|
|
128
|
+
/* The AVAILABLE half beside the ENABLED half above, cached the same way and for a sharper reason:
|
|
129
|
+
the Extensions section and the AI assistant's system prompt both need "what could this project
|
|
130
|
+
turn on", and `buildSystemPrompt` is synchronous. Two caches would be two answers to one
|
|
131
|
+
question, so there is one, loaded here and read synchronously by both. */
|
|
132
|
+
|
|
133
|
+
let _catalog: ExtensionCatalogEntry[] = [];
|
|
134
|
+
let _catalogLoaded: Promise<ExtensionCatalogEntry[]> | null = null;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Load (and cache) what this backend can offer. Backed by the optional `listExtensionCatalog`
|
|
138
|
+
* member; a platform without it (or a failure) degrades to an empty list, and the Extensions
|
|
139
|
+
* section falls back to a typed package name.
|
|
140
|
+
*
|
|
141
|
+
* @returns {Promise<ExtensionCatalogEntry[]>}
|
|
142
|
+
*/
|
|
143
|
+
export function loadExtensionCatalog(): Promise<ExtensionCatalogEntry[]> {
|
|
144
|
+
if (!_catalogLoaded) {
|
|
145
|
+
_catalogLoaded = (async () => {
|
|
146
|
+
try {
|
|
147
|
+
const platform = getPlatform() as {
|
|
148
|
+
listExtensionCatalog?: () => Promise<ExtensionCatalogEntry[]>;
|
|
149
|
+
};
|
|
150
|
+
_catalog = (await platform.listExtensionCatalog?.()) ?? [];
|
|
151
|
+
} catch {
|
|
152
|
+
_catalog = [];
|
|
153
|
+
}
|
|
154
|
+
return _catalog;
|
|
155
|
+
})();
|
|
156
|
+
}
|
|
157
|
+
return _catalogLoaded;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The last-loaded catalogue (synchronous access for render and prompt paths). */
|
|
161
|
+
export function getExtensionCatalog(): ExtensionCatalogEntry[] {
|
|
162
|
+
return _catalog;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Seed the catalogue directly (tests and hosts that preload it). */
|
|
166
|
+
export function setExtensionCatalog(catalog: ExtensionCatalogEntry[]) {
|
|
167
|
+
_catalog = catalog;
|
|
168
|
+
_catalogLoaded = Promise.resolve(catalog);
|
|
169
|
+
}
|
|
170
|
+
|
|
125
171
|
/**
|
|
126
172
|
* Fetch the active project's entry documents ONCE and hand the same payload to every consumer.
|
|
127
173
|
*
|
|
@@ -166,6 +212,9 @@ export function refreshExtensionUi(platform: {
|
|
|
166
212
|
fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;
|
|
167
213
|
}): void {
|
|
168
214
|
void shareProjectSchemas(platform);
|
|
215
|
+
// `installed` and `bundled` are per-project facts, so an install or a project switch can move
|
|
216
|
+
// Them even when the shipped half has not changed.
|
|
217
|
+
void loadExtensionCatalog();
|
|
169
218
|
void import("../settings/extension-sections")
|
|
170
219
|
.then(({ syncExtensionSettingsSections }) => syncExtensionSettingsSections())
|
|
171
220
|
.catch(() => {
|
|
@@ -34,16 +34,25 @@
|
|
|
34
34
|
* here — the browser withholds the reason on purpose — so the detail names both rather than
|
|
35
35
|
* guessing between them.
|
|
36
36
|
*
|
|
37
|
+
* **The waiting room is a document.** `surfaces/github-auth.json` draws the code, the link and the
|
|
38
|
+
* wait, over the kit's `jx-dialog`; this module keeps the client id, the poll loop, its failure
|
|
39
|
+
* budget and every report above. The dialog it replaced was an `<sp-dialog-wrapper>` whose one
|
|
40
|
+
* `@cancel`/`@close` handler both stopped the loop and resolved the promise, so "the reader
|
|
41
|
+
* dismissed this" and "GitHub answered" were the same code path — and the promise could be resolved
|
|
42
|
+
* a second time with `null` by the close that a successful sign-in itself provokes. Answering and
|
|
43
|
+
* closing are two steps now, in that order.
|
|
44
|
+
*
|
|
37
45
|
* The token is returned to callers and never rendered. In a browser it is stored in `localStorage`;
|
|
38
46
|
* on the desktop it is in the launcher's `0600` credential store and this module holds it only in
|
|
39
47
|
* memory for the session. `settings/preferences-accounts.ts` lists it as _stored or not_ and is the
|
|
40
48
|
* only place it can be revoked (`studio.md` §15 rule 1).
|
|
41
49
|
*/
|
|
42
50
|
|
|
43
|
-
import { html } from "lit-html";
|
|
44
51
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
45
52
|
import { notify } from "../services/notify";
|
|
46
|
-
import {
|
|
53
|
+
import { layerHost } from "../ui/layers";
|
|
54
|
+
import { openGithubAuthSurface } from "../surfaces/github-auth";
|
|
55
|
+
import type { GithubAuthSurfaceHandle } from "../surfaces/github-auth";
|
|
47
56
|
|
|
48
57
|
const CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
|
|
49
58
|
const STORAGE_KEY = "jx_github_token";
|
|
@@ -247,17 +256,52 @@ export async function authenticateGithub() {
|
|
|
247
256
|
|
|
248
257
|
const { device_code, user_code, verification_uri, interval = 5 } = codeData;
|
|
249
258
|
|
|
250
|
-
return
|
|
259
|
+
return new Promise<string | null>((resolve) => {
|
|
251
260
|
let cancelled = false;
|
|
252
261
|
let pollTimer: ReturnType<typeof setTimeout> | null = null;
|
|
253
262
|
let failures = 0;
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
let answered = false;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Stop the loop and answer, once.
|
|
267
|
+
*
|
|
268
|
+
* Separate from {@link done} because both ends arrive and either may be first: a token that
|
|
269
|
+
* lands closes the dialog, which raises `onClosed` behind it, and a dialog the reader dismisses
|
|
270
|
+
* raises `onClosed` with no token at all. Answering here and closing there is what keeps the
|
|
271
|
+
* second of those from overwriting the first with `null`.
|
|
272
|
+
*/
|
|
273
|
+
const settle = (token: string | null): void => {
|
|
274
|
+
if (answered) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
answered = true;
|
|
256
278
|
cancelled = true;
|
|
257
279
|
if (pollTimer) {
|
|
258
280
|
clearTimeout(pollTimer);
|
|
281
|
+
pollTimer = null;
|
|
282
|
+
}
|
|
283
|
+
resolve(token);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Take the dialog down, once.
|
|
288
|
+
*
|
|
289
|
+
* Guarded here rather than trusted to the handle, because closing is what RAISES `onClosed` —
|
|
290
|
+
* so a teardown that re-entered through it would call itself until the stack ran out.
|
|
291
|
+
*/
|
|
292
|
+
let closing = false;
|
|
293
|
+
const takeDown = (): void => {
|
|
294
|
+
if (closing) {
|
|
295
|
+
return;
|
|
259
296
|
}
|
|
260
|
-
|
|
297
|
+
closing = true;
|
|
298
|
+
handle.close();
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/** The poll's own exit: answer, then take the dialog down. */
|
|
302
|
+
const done = (token: string | null): void => {
|
|
303
|
+
settle(token);
|
|
304
|
+
takeDown();
|
|
261
305
|
};
|
|
262
306
|
|
|
263
307
|
const poll = async () => {
|
|
@@ -306,13 +350,11 @@ export async function authenticateGithub() {
|
|
|
306
350
|
? "The device code expired before it was entered."
|
|
307
351
|
: `GitHub answered "${tokenData.error ?? "an unrecognised response"}".`,
|
|
308
352
|
);
|
|
309
|
-
cancelled = true;
|
|
310
353
|
done(null);
|
|
311
354
|
} catch (error) {
|
|
312
355
|
failures += 1;
|
|
313
356
|
if (failures >= MAX_POLL_FAILURES) {
|
|
314
357
|
reportUnreachable(error);
|
|
315
|
-
cancelled = true;
|
|
316
358
|
done(null);
|
|
317
359
|
return;
|
|
318
360
|
}
|
|
@@ -320,27 +362,27 @@ export async function authenticateGithub() {
|
|
|
320
362
|
}
|
|
321
363
|
};
|
|
322
364
|
|
|
323
|
-
|
|
365
|
+
/*
|
|
366
|
+
* The dialog first, then the timer. `done` reaches for `handle`, and a poll that fired before
|
|
367
|
+
* the surface existed would find a binding that is not initialised yet — which a zero-second
|
|
368
|
+
* device interval makes reachable rather than theoretical.
|
|
369
|
+
*/
|
|
370
|
+
const handle: GithubAuthSurfaceHandle = openGithubAuthSurface({
|
|
371
|
+
layer: layerHost("dialog"),
|
|
372
|
+
onCancel: () => {
|
|
373
|
+
takeDown();
|
|
374
|
+
},
|
|
375
|
+
/* `done`, not `settle`: a `close` the flow did not ask for — Escape, or a dismissal the
|
|
376
|
+
platform allows — must ALSO take the document out of the dialog layer, or the surface
|
|
377
|
+
outlives the dialog it drew. `settle` is idempotent, so a close that follows a token
|
|
378
|
+
answers nothing and only cleans up. */
|
|
379
|
+
onClosed: () => {
|
|
380
|
+
done(null);
|
|
381
|
+
},
|
|
382
|
+
userCode: user_code,
|
|
383
|
+
verificationUri: verification_uri,
|
|
384
|
+
});
|
|
324
385
|
|
|
325
|
-
|
|
326
|
-
<sp-dialog-wrapper
|
|
327
|
-
open
|
|
328
|
-
headline="Sign in to GitHub"
|
|
329
|
-
cancel-label="Cancel"
|
|
330
|
-
@cancel=${stop}
|
|
331
|
-
@close=${stop}
|
|
332
|
-
>
|
|
333
|
-
<div class="github-auth-dialog">
|
|
334
|
-
<p>Enter this code on GitHub to authorize Jx Studio:</p>
|
|
335
|
-
<div class="github-auth-code">${user_code}</div>
|
|
336
|
-
<p>
|
|
337
|
-
<a href="${verification_uri}" target="_blank" rel="noopener"
|
|
338
|
-
>Open ${verification_uri}</a
|
|
339
|
-
>
|
|
340
|
-
</p>
|
|
341
|
-
<p class="github-auth-waiting">Waiting for authorization…</p>
|
|
342
|
-
</div>
|
|
343
|
-
</sp-dialog-wrapper>
|
|
344
|
-
`;
|
|
386
|
+
pollTimer = setTimeout(poll, interval * 1000);
|
|
345
387
|
});
|
|
346
388
|
}
|