@jxsuite/studio 5.3.0 → 5.4.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/data/css-meta.json +28 -27
- package/dist/chunks/{cf-account-picker-nwnwdm6p.js → cf-account-picker-3f08rry6.js} +21 -18
- package/dist/chunks/{cf-settings-adg74qsk.js → cf-settings-m79r7p5y.js} +4 -4
- package/dist/chunks/{components-5y78e05d.js → components-xm826zjw.js} +3 -3
- package/dist/chunks/{content-source-4rzvmp0m.js → content-source-jt7rbcbc.js} +22 -22
- package/dist/chunks/{convert-to-repeater-jxsv62v7.js → convert-to-repeater-vg38bq99.js} +22 -22
- package/dist/chunks/{editor-3qhbg51x.js → editor-ddy019sn.js} +2 -2
- package/dist/chunks/entry-commands-64nb2a9a.js +42 -0
- package/dist/chunks/{extension-sections-2mrptyek.js → extension-sections-r73an5s6.js} +30 -29
- package/dist/chunks/{file-ops-knfqshrm.js → file-ops-3xan8mnj.js} +21 -21
- package/dist/chunks/{files-y6fr4he9.js → files-egsb0ry8.js} +28 -28
- package/dist/chunks/{format-host-1k4qrcqd.js → format-host-mym8qnd0.js} +3 -3
- package/dist/chunks/{fs-events-3y6y0nrm.js → fs-events-z2gg8qjt.js} +4 -4
- package/dist/chunks/{git-panel-2rkrsjva.js → git-panel-a05atk6q.js} +20 -20
- package/dist/chunks/{grid-view-1p6hsyjx.css → grid-view-3g1h2re8.css} +956 -139
- package/dist/chunks/{grid-view-a7b87n2c.js → grid-view-qaqer9kr.js} +24 -24
- package/dist/chunks/{icons-yy10wk9r.js → icons-drxq9q10.js} +8 -2
- package/dist/chunks/{iframe-host-scpw01h8.js → iframe-host-psetcv20.js} +11 -11
- package/dist/chunks/{index-n4j7qxyr.js → index-9yjae3hz.js} +4 -4
- package/dist/chunks/{javascript-4abzjcy9.css → javascript-bc9z461d.css} +688 -54
- package/dist/chunks/{javascript-xvrfrpkb.js → javascript-hr5sg57n.js} +2 -2
- package/dist/chunks/{jsonMode-vvmpmk34.css → jsonMode-qqd9nm1t.css} +1120 -303
- package/dist/chunks/{jsonMode-tyx2kj6p.js → jsonMode-zs88v0wr.js} +4 -4
- package/dist/chunks/layers-panel-83a16ytx.js +41 -0
- package/dist/chunks/{layers-jnvdbqva.js → layers-s6mc01ry.js} +3 -3
- package/dist/chunks/{media-picker-f66nav16.js → media-picker-nhn6rv4w.js} +11 -11
- package/dist/chunks/{menu-1dfhry4s.js → menu-8j4qxjrp.js} +4 -4
- package/dist/chunks/{monaco-binding-sw6en4dw.js → monaco-binding-e8d9wzyk.js} +3 -3
- package/dist/chunks/{monaco-buffer-pykwbm92.js → monaco-buffer-jaq1t9zj.js} +2 -2
- package/dist/chunks/{monaco-setup-8vbyqnhr.css → monaco-setup-ey9cjcm3.css} +954 -137
- package/dist/chunks/{monaco-setup-km6abc6q.js → monaco-setup-gsjdysze.js} +6 -6
- package/dist/chunks/{platform-ts9cg1a4.js → platform-fnchmhy7.js} +5 -3
- package/dist/chunks/publish-panel-ak6hxfma.js +27 -0
- package/dist/chunks/quick-search-c63mkt3b.js +47 -0
- package/dist/chunks/{references-h69xp9zz.js → references-f7bdv3z5.js} +3 -3
- package/dist/chunks/right-panel-t5n8wttg.js +45 -0
- package/dist/chunks/{studio-ze46gzjh.js → studio-01269reb.js} +7 -7
- package/dist/chunks/{studio-rnyf3f8e.js → studio-0a4gncx0.js} +3 -3
- package/dist/chunks/{studio-e1f24eff.js → studio-0d4p4wxj.js} +6778 -2993
- package/dist/chunks/{studio-4wbb9ct0.js → studio-1tejxvba.js} +3006 -1855
- package/dist/chunks/{studio-d1n2bykn.js → studio-3nprwbd9.js} +117 -25
- package/dist/chunks/{studio-4c041r8y.js → studio-40z39dme.js} +3 -3
- package/dist/chunks/{studio-151w0xnh.js → studio-482eeazk.js} +20 -20
- package/dist/chunks/{studio-cgprcdxn.js → studio-4998spet.js} +10 -9
- package/dist/chunks/{studio-nq5yf5mp.js → studio-557bmn0x.js} +2 -2
- package/dist/chunks/{studio-rtskkm43.js → studio-5w26wza5.js} +3 -3
- package/dist/chunks/{studio-6nzaktvy.js → studio-6pwn9j8c.js} +6 -3
- package/dist/chunks/{studio-wnsyffg1.js → studio-6vg0x5fz.js} +3 -2
- package/dist/chunks/{studio-vn5hske5.js → studio-7d3c1m59.js} +12 -5
- package/dist/chunks/{studio-6gryj0sg.js → studio-9vsvz7w7.js} +6 -6
- package/dist/chunks/{studio-50wfwy44.js → studio-9wm0xzpf.js} +19 -19
- package/dist/chunks/{studio-0j7r7s9g.js → studio-ag3z6shb.js} +10 -4
- package/dist/chunks/studio-aj9drheq.js +177 -0
- package/dist/chunks/{studio-xajk70w0.js → studio-apv9x70c.js} +189 -130
- package/dist/chunks/{studio-c04nzbby.js → studio-b9q3znz8.js} +2 -2
- package/dist/chunks/{studio-nfx354t1.js → studio-bh47w0cy.js} +9 -10
- package/dist/chunks/{studio-gk2twyh4.js → studio-dgdm6vvt.js} +264 -52
- package/dist/chunks/{studio-gtfq1dkz.js → studio-dwdcr2e8.js} +4 -4
- package/dist/chunks/{studio-nqgawfks.js → studio-fbcyz234.js} +146 -139
- package/dist/chunks/{studio-27q131j3.js → studio-fqpkpq1t.js} +7 -4
- package/dist/chunks/{studio-c0qgc3tn.js → studio-fy320dfc.js} +62 -68
- package/dist/chunks/{studio-zjjde71a.js → studio-gjj4bbfx.js} +2 -2
- package/dist/chunks/{studio-g33v4fe9.js → studio-jfhxy8h3.js} +7 -7
- package/dist/chunks/{studio-ab87phj1.js → studio-kwewmhhq.js} +4 -4
- package/dist/chunks/{studio-7rrb1esn.js → studio-m58xn8at.js} +25 -24
- package/dist/chunks/{studio-fzjx96t2.js → studio-mfkh1q8d.js} +17 -17
- package/dist/chunks/{studio-drg8qj9k.js → studio-mrh0a92f.js} +17 -17
- package/dist/chunks/{studio-jt27ta6x.js → studio-mt79tn56.js} +3 -3
- package/dist/chunks/{studio-b66rsh78.js → studio-ne593z1j.js} +38 -31
- package/dist/chunks/{studio-h4nvnjvz.js → studio-ptfcxkz5.js} +418 -232
- package/dist/chunks/{studio-dd1qqkry.js → studio-qxye31h7.js} +7 -7
- package/dist/chunks/{studio-ye9drbk8.js → studio-rav5bpmp.js} +73 -52
- package/dist/chunks/{studio-6kvgrkrp.js → studio-rwmmbrth.js} +6 -6
- package/dist/chunks/{studio-b7xacrwe.js → studio-sceg8ws0.js} +8 -8
- package/dist/chunks/{studio-msc1ee1m.js → studio-sjas5b3a.js} +19 -13
- package/dist/chunks/{studio-a65w20ex.js → studio-vd67b66d.js} +3 -3
- package/dist/chunks/{studio-7144epdr.js → studio-w475cbf9.js} +10 -10
- package/dist/chunks/{studio-4f3psrk1.js → studio-w7gpcvfj.js} +9 -9
- package/dist/chunks/{studio-nsgw7dbk.js → studio-xrbfdxgk.js} +7 -7
- package/dist/chunks/{studio-ke09tn9k.js → studio-y49b6mjv.js} +35 -35
- package/dist/chunks/{studio-j0w60gft.js → studio-ygvr9e4q.js} +10 -10
- package/dist/chunks/{studio-z2smx5ce.js → studio-yxmmjy2a.js} +9 -6
- package/dist/chunks/{tsMode-jy4m86rv.js → tsMode-ay4c78ne.js} +4 -4
- package/dist/chunks/{tsMode-hnxxb73h.css → tsMode-c72wyz27.css} +954 -137
- package/dist/chunks/{workspace-np10mayv.js → workspace-b9k2frks.js} +5 -5
- package/dist/chunks/{ws-client-ny4zc51r.js → ws-client-erze4czt.js} +356 -20
- package/dist/codicon.ttf +0 -0
- package/dist/iframe-entry.js +18 -16
- package/dist/studio.css +956 -139
- package/dist/studio.js +1453 -830
- package/dist/workers/editor.worker.js +196 -107
- package/dist/workers/json.worker.js +196 -107
- package/dist/workers/ts.worker.js +196 -107
- package/package.json +15 -14
- package/src/about/about-modal.ts +4 -3
- package/src/browse/library-commands.ts +15 -13
- package/src/browse/library-pane.ts +2 -2
- package/src/canvas/canvas-render.ts +97 -83
- package/src/canvas/canvas-surface.ts +2 -2
- package/src/canvas/canvas-utils.ts +42 -32
- package/src/canvas/diff-toolbar.ts +21 -2
- package/src/canvas/diff-view.ts +30 -6
- package/src/canvas/iframe-entry.ts +2 -2
- package/src/canvas/iframe-host.ts +5 -5
- package/src/canvas/iframe-interaction.ts +7 -6
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-protocol.ts +6 -5
- package/src/canvas/iframe-render.ts +3 -3
- package/src/canvas/popover-state.ts +1 -1
- package/src/canvas/stage-scrollbar.ts +112 -0
- package/src/canvas/surface-registry.ts +9 -2
- package/src/collab/collab-commands.ts +8 -6
- package/src/collab/collab-session.ts +4 -4
- package/src/collab/collab-state.ts +4 -4
- package/src/collab/presence-chips.ts +3 -3
- package/src/commands/app-commands.ts +7 -7
- package/src/commands/budget.ts +17 -16
- package/src/commands/command-args.ts +10 -9
- package/src/commands/context.ts +20 -10
- package/src/commands/defaults.ts +30 -29
- package/src/commands/levels.ts +8 -6
- package/src/commands/live-context.ts +12 -10
- package/src/commands/reference.ts +5 -5
- package/src/commands/registry.ts +2 -2
- package/src/content/draft-state.ts +9 -8
- package/src/content/entry-commands.ts +16 -14
- package/src/content/entry-editor.ts +2 -2
- package/src/content/entry-fields.ts +1 -1
- package/src/editor/context-menu.ts +4 -4
- package/src/editor/convert-to-component.ts +6 -5
- package/src/editor/inline-edit.ts +3 -3
- package/src/editor/shortcuts.ts +88 -20
- package/src/editor/slash-menu.ts +11 -10
- package/src/files/elements.ts +4 -5
- package/src/files/file-ops.ts +1 -1
- package/src/files/files.ts +21 -17
- package/src/files/serialize-document.ts +1 -1
- package/src/format/convert-file.ts +5 -5
- package/src/github/github-auth-status.ts +107 -0
- package/src/github/github-auth.ts +18 -82
- package/src/github/github-publish.ts +7 -6
- package/src/grid/cell-editors.ts +8 -7
- package/src/grid/grid-layout.ts +1 -1
- package/src/grid/grid-open.ts +6 -5
- package/src/grid/grid-panel.ts +13 -12
- package/src/grid/redirects-grid.ts +14 -11
- package/src/grid/redirects.ts +10 -5
- package/src/grid/sources/content-source.ts +10 -9
- package/src/hosting/document.ts +28 -1
- package/src/hosting/stage.ts +15 -4
- package/src/i18n/i18n-commands.ts +9 -7
- package/src/new-project/location-fields.ts +16 -3
- package/src/new-project/new-project-modal.ts +23 -7
- package/src/page-params.ts +6 -6
- package/src/panels/activity-panel.ts +11 -10
- package/src/panels/ai-chat/chat-view.ts +27 -14
- package/src/panels/ai-chat/composer.ts +10 -3
- package/src/panels/ai-panel.ts +87 -29
- package/src/panels/block-action-bar.ts +59 -33
- package/src/panels/bottom-dock.ts +22 -22
- package/src/panels/data-explorer.ts +9 -9
- package/src/panels/data-grid.ts +1 -1
- package/src/panels/editors.ts +8 -8
- package/src/panels/elements-panel.ts +7 -8
- package/src/panels/empty-state.ts +1 -1
- package/src/panels/events-panel.ts +13 -12
- package/src/panels/formula-workspace.ts +8 -5
- package/src/panels/frontmatter-fields.ts +4 -1
- package/src/panels/frontmatter-panel.ts +18 -18
- package/src/panels/git-panel.ts +19 -13
- package/src/panels/head-panel.ts +9 -10
- package/src/panels/i18n-panel.ts +6 -4
- package/src/panels/imports-panel.ts +1 -1
- package/src/panels/jump-bar.ts +20 -18
- package/src/panels/layers-panel.ts +19 -17
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/navigator-panels.ts +8 -8
- package/src/panels/overlays.ts +1 -1
- package/src/panels/pane-context.ts +56 -28
- package/src/panels/pane-grid.ts +9 -8
- package/src/panels/panel-registry.ts +47 -19
- package/src/panels/problems-panel.ts +11 -12
- package/src/panels/properties-panel.ts +21 -20
- package/src/panels/provenance.ts +3 -3
- package/src/panels/quick-search.ts +15 -11
- package/src/panels/right-panel.ts +4 -3
- package/src/panels/seo-modal.ts +5 -4
- package/src/panels/settings-menu.ts +9 -9
- package/src/panels/settings-pane.ts +3 -3
- package/src/panels/signals-panel.ts +16 -9
- package/src/panels/statement-editor.ts +12 -9
- package/src/panels/style-panel.ts +45 -41
- package/src/panels/stylebook-panel.ts +0 -1
- package/src/panels/tab-strip.ts +26 -23
- package/src/platform-errors.ts +2 -2
- package/src/platform.ts +44 -4
- package/src/platforms/cloud.ts +11 -1
- package/src/platforms/default-platform.ts +141 -4
- package/src/platforms/devserver.ts +23 -3
- package/src/publish/deploy-checklist.ts +11 -10
- package/src/publish/publish-commands.ts +9 -8
- package/src/services/a11y-report.ts +1 -1
- package/src/services/ai-ask.ts +39 -16
- package/src/services/ai-command-tools.ts +28 -14
- package/src/services/ai-import-tools.ts +43 -29
- package/src/services/ai-project-tools.ts +20 -38
- package/src/services/ai-settings.ts +55 -2
- package/src/services/ai-tools.ts +69 -58
- package/src/services/ai-write-report.ts +4 -4
- package/src/services/ai-writes.ts +74 -55
- package/src/services/automation.ts +12 -12
- package/src/services/clock.ts +2 -1
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +69 -6
- package/src/services/directory-picker.ts +93 -27
- package/src/services/document-assistant.ts +86 -17
- package/src/services/gated-registry.ts +4 -3
- package/src/services/idle.ts +5 -4
- package/src/services/live-surfaces.ts +2 -1
- package/src/services/notify.ts +9 -7
- package/src/services/popover-report.ts +3 -3
- package/src/services/preview-eval.ts +1 -1
- package/src/services/project-adoption.ts +34 -1
- package/src/services/project-path.ts +53 -0
- package/src/services/settings/kernel.ts +13 -2
- package/src/services/tool-executor.ts +135 -30
- package/src/services/tool-outcomes.ts +143 -0
- package/src/settings/contexts-section.ts +8 -8
- package/src/settings/contributed-section.ts +6 -6
- package/src/settings/css-vars-editor.ts +6 -5
- package/src/settings/extension-commands.ts +19 -18
- package/src/settings/extension-sections.ts +7 -7
- package/src/settings/extensions-section.ts +3 -3
- package/src/settings/general-settings.ts +21 -18
- package/src/settings/preferences-accounts.ts +3 -3
- package/src/settings/preferences-dialog.ts +9 -8
- package/src/settings/preferences-sections.ts +1 -1
- package/src/settings/project-sections.ts +2 -2
- package/src/settings/section-registry.ts +7 -6
- package/src/settings/settings-document.ts +41 -43
- package/src/shell/tree.ts +29 -0
- package/src/shell.ts +63 -55
- package/src/site-context.ts +1 -1
- package/src/store.ts +2 -2
- package/src/studio.ts +46 -28
- package/src/style/live-preview.ts +8 -8
- package/src/style/project-styles.ts +8 -9
- package/src/style/token-ref.ts +2 -2
- package/src/surfaces/about.json +6 -2
- package/src/surfaces/add-repo.json +2 -2
- package/src/surfaces/add-repo.ts +2 -2
- package/src/surfaces/ai-chat.json +14 -6
- package/src/surfaces/ai-chat.ts +4 -2
- package/src/surfaces/ai-credentials-form.json +53 -49
- package/src/surfaces/ai-credentials-form.ts +18 -4
- package/src/surfaces/ai-managed-connect.json +4 -4
- package/src/surfaces/block-action-bar.json +4 -4
- package/src/surfaces/block-action-bar.ts +3 -3
- package/src/surfaces/boot-failure.json +228 -0
- package/src/surfaces/boot-failure.ts +156 -0
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/canvas-stage.json +9 -40
- package/src/surfaces/canvas-stage.ts +9 -9
- package/src/surfaces/cf-account-picker.json +11 -8
- package/src/surfaces/commandbar.ts +11 -10
- package/src/surfaces/convert-repeater.ts +3 -2
- package/src/surfaces/dialog.json +7 -1
- package/src/surfaces/dialog.ts +2 -2
- package/src/surfaces/doc-header.json +6 -13
- package/src/surfaces/doc-header.ts +4 -5
- package/src/surfaces/entry-editor.json +1 -1
- package/src/surfaces/entry-editor.ts +2 -1
- package/src/surfaces/expression-editor.json +5 -5
- package/src/surfaces/files-panel.json +4 -3
- package/src/surfaces/files-panel.ts +1 -1
- package/src/surfaces/formula-palette.json +2 -2
- package/src/surfaces/formula-palette.ts +1 -1
- package/src/surfaces/git-panel.json +167 -109
- package/src/surfaces/git-panel.ts +2 -2
- package/src/surfaces/github-auth.json +2 -1
- package/src/surfaces/github-publish.ts +3 -3
- package/src/surfaces/grid-open.json +1 -1
- package/src/surfaces/grid-panel.json +2 -2
- package/src/surfaces/grid-views.json +1 -1
- package/src/surfaces/inspector-dock.json +2 -2
- package/src/surfaces/jump-bar.json +1 -1
- package/src/surfaces/jump-bar.ts +1 -1
- package/src/surfaces/library-pane.ts +2 -1
- package/src/surfaces/logic-panel.json +7 -7
- package/src/surfaces/logic-panel.ts +6 -4
- package/src/surfaces/logic-workspace.json +2 -2
- package/src/surfaces/logic-workspace.ts +2 -2
- package/src/surfaces/media-browser.ts +3 -3
- package/src/surfaces/media-pane.ts +2 -1
- package/src/surfaces/menu.ts +5 -5
- package/src/surfaces/new-project.json +1 -1
- package/src/surfaces/pane-context.json +86 -57
- package/src/surfaces/pane-context.ts +2 -1
- package/src/surfaces/pane-grid.json +3 -3
- package/src/surfaces/panel-activity.json +2 -1
- package/src/surfaces/panel-deploy-checklist.json +1 -1
- package/src/surfaces/panel-elements.ts +2 -1
- package/src/surfaces/panel-i18n.ts +2 -1
- package/src/surfaces/panel-outline.json +1 -1
- package/src/surfaces/panel-outline.ts +4 -3
- package/src/surfaces/panel-page.json +2 -2
- package/src/surfaces/panel-page.ts +4 -1
- package/src/surfaces/panel-problems.json +4 -3
- package/src/surfaces/panel-problems.ts +2 -2
- package/src/surfaces/panel-signals.json +23 -8
- package/src/surfaces/panel-signals.ts +5 -1
- package/src/surfaces/panel-stylebook-layers.json +1 -1
- package/src/surfaces/panel-stylebook-layers.ts +2 -2
- package/src/surfaces/preferences.json +21 -8
- package/src/surfaces/preferences.ts +9 -1
- package/src/surfaces/properties-panel.json +4 -4
- package/src/surfaces/properties-panel.ts +2 -2
- package/src/surfaces/publish.json +1 -1
- package/src/surfaces/publish.ts +2 -1
- package/src/surfaces/push-plan.json +4 -3
- package/src/surfaces/rail.json +2 -2
- package/src/surfaces/rail.ts +10 -4
- package/src/surfaces/reference-field.json +1 -1
- package/src/surfaces/schema-form.json +2 -2
- package/src/surfaces/schema-form.ts +1 -1
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +2 -2
- package/src/surfaces/settings-contributed.ts +2 -1
- package/src/surfaces/settings-css-vars.json +4 -4
- package/src/surfaces/settings-deploy.json +4 -4
- package/src/surfaces/settings-deploy.ts +2 -1
- package/src/surfaces/settings-extensions.json +6 -6
- package/src/surfaces/settings-extensions.ts +6 -2
- package/src/surfaces/settings-locales.json +4 -4
- package/src/surfaces/settings-overview.ts +2 -1
- package/src/surfaces/settings-pane.ts +3 -2
- package/src/surfaces/settings-rawjson.ts +1 -1
- package/src/surfaces/slash-menu.ts +4 -4
- package/src/surfaces/statements.json +3 -3
- package/src/surfaces/statusbar.ts +23 -23
- package/src/surfaces/style-panel.json +9 -5
- package/src/surfaces/style-panel.ts +3 -3
- package/src/surfaces/tab-strip.json +2 -2
- package/src/surfaces/target-line.json +1 -1
- package/src/surfaces/target-line.ts +12 -10
- package/src/surfaces/welcome.json +7 -2
- package/src/tabs/doc-op-apply.ts +5 -5
- package/src/tabs/patch-ops.ts +3 -3
- package/src/tabs/project-config.ts +10 -10
- package/src/tabs/selection.ts +1 -1
- package/src/tabs/tab.ts +13 -14
- package/src/tabs/transact.ts +18 -24
- package/src/types.ts +27 -3
- package/src/ui/ai-credentials-form.ts +74 -16
- package/src/ui/ai-managed-connect.ts +68 -19
- package/src/ui/color-selector.ts +1 -1
- package/src/ui/expression-editor.ts +3 -3
- package/src/ui/form-controls.ts +6 -5
- package/src/ui/formula-catalog.ts +4 -4
- package/src/ui/formula-chips.ts +2 -2
- package/src/ui/layers.ts +20 -18
- package/src/ui/panel-resize.ts +5 -5
- package/src/ui/popover-surface.ts +2 -2
- package/src/ui/progress-modal.ts +3 -3
- package/src/ui/regions.ts +14 -9
- package/src/ui/schema-form.ts +10 -9
- package/src/ui/timing.ts +9 -7
- package/src/ui/value-source.ts +4 -4
- package/src/ui/virtual-window.ts +1 -1
- package/src/utils/base64.ts +20 -1
- package/src/utils/canvas-media.ts +1 -1
- package/src/utils/studio-utils.ts +0 -31
- package/src/view.ts +4 -3
- package/src/workspace/pane-derive.ts +14 -13
- package/src/workspace/session.ts +7 -6
- package/src/workspace/workspace.ts +49 -39
- package/styles/canvas.css +1 -27
- package/styles/inspector.css +4 -3
- package/styles/overlays.css +1 -1
- package/styles/tokens.css +17 -1
- package/styles/tokens.json +6 -1
- package/dist/chunks/entry-commands-1wnsqn5d.js +0 -42
- package/dist/chunks/layers-panel-73gfkcga.js +0 -41
- package/dist/chunks/publish-panel-z1zd2da1.js +0 -27
- package/dist/chunks/quick-search-zdv7h8ht.js +0 -47
- package/dist/chunks/right-panel-889vbnm5.js +0 -45
- package/dist/chunks/studio-727xh0e3.js +0 -76
- package/src/files/json-layout.ts +0 -474
- package/src/services/ai-turn-signal.ts +0 -70
package/src/ui/progress-modal.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
* The one surface in Studio that still BLOCKS while it works — and now the only one (
|
|
3
|
+
* The one surface in Studio that still BLOCKS while it works — and now the only one (§16.4).
|
|
4
4
|
*
|
|
5
5
|
* What changed. This modal used to be four things at once: the running state, the error view, the
|
|
6
6
|
* log and the operation's entire memory. It blocked the whole app, offered no way out, and took all
|
|
7
7
|
* four with it when it closed — so a failed `bun install` could be read exactly once, and a hung
|
|
8
|
-
* one could not be escaped at all. §
|
|
8
|
+
* one could not be escaped at all. §16.4 splits those apart:
|
|
9
9
|
*
|
|
10
10
|
* - The **record** moves to `panels/activity-panel.ts`, which keeps the entry, its steps and its log
|
|
11
11
|
* after the modal is gone;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - And the **exit** arrives twice: `Run in the background` hands the app back while the operation
|
|
16
16
|
* keeps going in Activity, and an operation that passed a `cancel` gets a real Cancel button.
|
|
17
17
|
*
|
|
18
|
-
* What did NOT change is which operations block. §
|
|
18
|
+
* What did NOT change is which operations block. §16.4 keeps blocking for dependency install and
|
|
19
19
|
* nothing else, and this module's four call sites are exactly that — `packages/ensure-deps.ts`,
|
|
20
20
|
* `packages/pull-package-sync.ts`, `packages/jxsuite-update.ts` and
|
|
21
21
|
* `settings/dependencies-editor.ts`. Every other long operation calls `beginActivity` directly and
|
package/src/ui/regions.ts
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* restoration after a toast or a Problems jump, and the screenshot pipeline, which today addresses
|
|
10
10
|
* the shell through sixteen CSS selectors, seven of which name nodes the shell redesign deletes.
|
|
11
11
|
*
|
|
12
|
-
* **The grammar** (
|
|
12
|
+
* **The grammar** (scripts/screenshots/README.md, "The region grammar") is
|
|
13
|
+
* `<surface>[.<instance>][/<part>]`:
|
|
13
14
|
*
|
|
14
15
|
* ```text
|
|
15
16
|
* navigator the Navigator dock
|
|
@@ -38,7 +39,10 @@ import type { FocusRegion } from "../shell";
|
|
|
38
39
|
/** The attribute every region carries. One attribute, one grammar, one resolver. */
|
|
39
40
|
export const REGION_ATTR = "data-jx-region";
|
|
40
41
|
|
|
41
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The eight surfaces the region grammar declares (`scripts/screenshots/README.md`). A region id
|
|
44
|
+
* always begins with one of these.
|
|
45
|
+
*/
|
|
42
46
|
export const REGION_SURFACES = [
|
|
43
47
|
"rail",
|
|
44
48
|
"navigator",
|
|
@@ -377,12 +381,12 @@ export function inspectorStatementsRegion(eventKey: string): string {
|
|
|
377
381
|
* Region id for a Bottom dock tab, derived from the panel's own id.
|
|
378
382
|
*
|
|
379
383
|
* The third member of the derived-region family, and the one that shows the grammar was worth
|
|
380
|
-
* specifying before the surface existed: `dock.bottom`
|
|
381
|
-
* whose NAME contains the instance separator, which is why {@link DOTTED_SURFACES}
|
|
382
|
-
* resolved to nothing, because nothing hosted it. `panels/bottom-dock.ts` stamps this
|
|
383
|
-
* the same id `view.setBottomTab` accepts, so the dock
|
|
384
|
-
* authoring an id — and the host itself carries the bare `dock.bottom` only while it
|
|
385
|
-
* closed dock resolves to nothing rather than to an invisible box.
|
|
384
|
+
* specifying before the surface existed: `dock.bottom` parsed before the dock was built (it is the
|
|
385
|
+
* only surface whose NAME contains the instance separator, which is why {@link DOTTED_SURFACES}
|
|
386
|
+
* exists) and resolved to nothing, because nothing hosted it. `panels/bottom-dock.ts` stamps this
|
|
387
|
+
* once, from the same id `view.setBottomTab` accepts, so every tab the dock hosts is addressable
|
|
388
|
+
* without anyone authoring an id — and the host itself carries the bare `dock.bottom` only while it
|
|
389
|
+
* is open, so a closed dock resolves to nothing rather than to an invisible box.
|
|
386
390
|
*/
|
|
387
391
|
export function bottomPanelRegion(panelId: string): string {
|
|
388
392
|
return `dock.bottom/panel:${panelId}`;
|
|
@@ -419,7 +423,8 @@ export function overlayRegion(
|
|
|
419
423
|
}
|
|
420
424
|
|
|
421
425
|
/**
|
|
422
|
-
* `regions` — the
|
|
426
|
+
* `regions` — the resolver behind the region grammar (`scripts/screenshots/README.md`), gathered so
|
|
427
|
+
* a consumer imports one thing.
|
|
423
428
|
*
|
|
424
429
|
* `probe.regions` is a projection of this; nothing here knows the camera exists.
|
|
425
430
|
*/
|
package/src/ui/schema-form.ts
CHANGED
|
@@ -162,7 +162,7 @@ export interface RenderFormOptions {
|
|
|
162
162
|
ui?: Record<string, { control?: string; enum?: unknown }> | undefined;
|
|
163
163
|
rerender?: (() => void) | undefined;
|
|
164
164
|
/**
|
|
165
|
-
* Externally-produced diagnostics, keyed by property name — §
|
|
165
|
+
* Externally-produced diagnostics, keyed by property name — §16.1's inline tier, sourced.
|
|
166
166
|
*
|
|
167
167
|
* This is how a validator that runs over the WHOLE document reaches the one field it is about:
|
|
168
168
|
* `jx-validate`'s `project.json` errors, Monaco's markers for the same file open in the code
|
|
@@ -177,7 +177,7 @@ export interface RenderFormOptions {
|
|
|
177
177
|
/** How many times each field has been refused in a row; drives the row's repeat counter. */
|
|
178
178
|
errorCounts?: Record<string, number> | undefined;
|
|
179
179
|
/**
|
|
180
|
-
* Report required-but-empty fields inline. Off by default, and that default is §
|
|
180
|
+
* Report required-but-empty fields inline. Off by default, and that default is §16.5's rule
|
|
181
181
|
* literally applied: a form the user has not touched yet has not committed anything, so painting
|
|
182
182
|
* every required field red the moment it renders is telling them they got something wrong before
|
|
183
183
|
* they did anything. Required-ness is already shown — the row carries the required mark. A host
|
|
@@ -313,7 +313,7 @@ function asText(value: unknown): string {
|
|
|
313
313
|
return typeof value === "object" ? JSON.stringify(value, null, 2) : String(value);
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
// ─── Field validation (§
|
|
316
|
+
// ─── Field validation (§16.1, inline tier) ───────────────────────────────────
|
|
317
317
|
|
|
318
318
|
/**
|
|
319
319
|
* Why this value is not acceptable for this property schema, or `""` when it is.
|
|
@@ -670,7 +670,7 @@ function createController(): FormController {
|
|
|
670
670
|
return raw;
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
-
/** The rung picker: every source this position permits, one action away (§6.
|
|
673
|
+
/** The rung picker: every source this position permits, one action away (§6.6). */
|
|
674
674
|
function openSourceMenu(key: string, anchor: HTMLElement): void {
|
|
675
675
|
const plan = plans.get(key);
|
|
676
676
|
if (!plan?.ladder) {
|
|
@@ -985,11 +985,12 @@ function deriveField(prop: string, ps: JsonSchema, args: DeriveArgs): SchemaForm
|
|
|
985
985
|
}
|
|
986
986
|
|
|
987
987
|
/* A relationship to another collection (`$ref: "#/content/<type>"`) is the registered `reference`
|
|
988
|
-
control, wherever the form is drawn — §
|
|
989
|
-
`registerFormControl("reference", …)` in `ui/form-controls.ts`. It is
|
|
990
|
-
the choices are entry files on disk, so they are read asynchronously
|
|
991
|
-
schema `enum` is a closed set the document itself declares. When the
|
|
992
|
-
(a bare-Bun import of this engine), the field falls through to the
|
|
988
|
+
control, wherever the form is drawn — site-architecture.md §7.4's one entry picker is this
|
|
989
|
+
dispatch plus the single `registerFormControl("reference", …)` in `ui/form-controls.ts`. It is
|
|
990
|
+
deliberately NOT an enum: the choices are entry files on disk, so they are read asynchronously
|
|
991
|
+
and can be stale, and a schema `enum` is a closed set the document itself declares. When the
|
|
992
|
+
control is not registered (a bare-Bun import of this engine), the field falls through to the
|
|
993
|
+
plain text control below. */
|
|
993
994
|
if (referenceTarget(ps) !== null) {
|
|
994
995
|
const reference = controlRegistry.get("reference");
|
|
995
996
|
if (reference) {
|
package/src/ui/timing.ts
CHANGED
|
@@ -13,16 +13,17 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Text/style input debounce — the §4.4 standard. Long enough that a normal
|
|
17
|
-
* one commit per pause rather than one per keystroke, short enough that the
|
|
18
|
-
* live.
|
|
16
|
+
* Text/style input debounce — the studio-ui-guidelines.md §4.4 standard. Long enough that a normal
|
|
17
|
+
* typing cadence produces one commit per pause rather than one per keystroke, short enough that the
|
|
18
|
+
* canvas still feels live.
|
|
19
19
|
*/
|
|
20
20
|
export const INPUT_DEBOUNCE = 400;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Code and expression textareas — the §4.4 standard. Longer than
|
|
24
|
-
* each commit re-parses source (or re-lints), and because half-typed
|
|
25
|
-
* committing eagerly just burns work on states the user is about to
|
|
23
|
+
* Code and expression textareas — the studio-ui-guidelines.md §4.4 standard. Longer than
|
|
24
|
+
* {@link INPUT_DEBOUNCE} because each commit re-parses source (or re-lints), and because half-typed
|
|
25
|
+
* code is usually invalid, so committing eagerly just burns work on states the user is about to
|
|
26
|
+
* leave.
|
|
26
27
|
*/
|
|
27
28
|
export const CODE_DEBOUNCE = 500;
|
|
28
29
|
|
|
@@ -38,7 +39,8 @@ export const LIVE_PREVIEW = 350;
|
|
|
38
39
|
* `STATUS_MESSAGE = 3000` used to live here: how long a transient message stayed in the status bar
|
|
39
40
|
* before it erased itself. It had one reader, `statusMessage`, which is deleted — the bar carries
|
|
40
41
|
* ambient state now and outcomes go to `services/notify.ts`, whose `TOAST_LIFETIME_MS` is per
|
|
41
|
-
* SEVERITY (
|
|
42
|
+
* SEVERITY (4s, or 8s for a warning or an error: studio-ui-guidelines.md §13.2) rather than one
|
|
43
|
+
* number for a failure and a save alike.
|
|
42
44
|
*/
|
|
43
45
|
|
|
44
46
|
/**
|
package/src/ui/value-source.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Value Source — the one vocabulary for "how is this value produced", and the derivation that says
|
|
3
|
-
* which productions a given document position actually permits (
|
|
3
|
+
* which productions a given document position actually permits (§6.6).
|
|
4
4
|
*
|
|
5
5
|
* Six controls used to answer that question in six dialects: `abc / $ref / ${} / fx` on the dynamic
|
|
6
6
|
* slot, `inline / $expression / ref` on the Events tab, `lit / $ref / expr` on every expression
|
|
7
7
|
* operand, and `Static value / route param / Custom…` in the schema-driven forms. They are the same
|
|
8
|
-
* four rungs of the Rule of Least Power ladder (spec §2.2) wearing four costumes, and a user who
|
|
8
|
+
* four rungs of the Rule of Least Power ladder (spec.md §2.2) wearing four costumes, and a user who
|
|
9
9
|
* learned one learned none of the others. {@link VALUE_SOURCE_LABELS} is the single vocabulary;
|
|
10
10
|
* every surface that offers the choice spells it the same way.
|
|
11
11
|
*
|
|
@@ -48,11 +48,11 @@ import { isFunctionDef, isRef, isTemplateString } from "@jxsuite/schema/guards";
|
|
|
48
48
|
/** A rung of the value ladder — one way a document position can produce its value. */
|
|
49
49
|
export type SlotMode = "literal" | "ref" | "template" | "expression" | "function";
|
|
50
50
|
|
|
51
|
-
/** Ladder order, least powerful first (spec §2.2). Every rung list is sorted by this. */
|
|
51
|
+
/** Ladder order, least powerful first (spec.md §2.2). Every rung list is sorted by this. */
|
|
52
52
|
export const SLOT_MODE_ORDER: SlotMode[] = ["literal", "ref", "template", "expression", "function"];
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* The user-facing name of each rung — the whole point of §6.
|
|
55
|
+
* The user-facing name of each rung — the whole point of §6.6. `ref` keeps its ellipsis because
|
|
56
56
|
* choosing it opens a picker rather than committing a value.
|
|
57
57
|
*/
|
|
58
58
|
export const VALUE_SOURCE_LABELS: Record<SlotMode, string> = {
|
package/src/ui/virtual-window.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* project. The two trees pay a smaller version of the same bill — a 5 000-node page drew 5 000
|
|
10
10
|
* rows, each an `sp-icon` custom element — and they now pay it through this file.
|
|
11
11
|
*
|
|
12
|
-
* **It lives in `ui/`, not in `browse/`.**
|
|
12
|
+
* **It lives in `ui/`, not in `browse/`.** The shell redesign promised "one virtual-list primitive
|
|
13
13
|
* behind the Files tree and the Outline tree, reused by the Library grid", and what shipped sat
|
|
14
14
|
* inside the Library and was imported by the Library alone. A primitive two surfaces share cannot
|
|
15
15
|
* live inside one of them: the next surface that needs it either reaches across a feature boundary
|
package/src/utils/base64.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
* Base64 encoding for binary
|
|
3
|
+
* Base64 encoding for binary payloads that cross an RPC boundary.
|
|
4
4
|
*
|
|
5
5
|
* `StudioPlatform.uploadFile` accepts `string | File | Blob | ArrayBuffer`, but the RPC platforms
|
|
6
6
|
* (electrobun, chromium) JSON-serialize their params — a `File`/`Blob` becomes `{}` on the wire.
|
|
7
7
|
* Those platforms encode here before the call; the HTTP platforms (dev server, cloud) post the
|
|
8
8
|
* binary body directly and must NOT use this.
|
|
9
|
+
*
|
|
10
|
+
* {@link base64ToBytes} is the same boundary in the other direction, for `readFileBytes`: the RPC
|
|
11
|
+
* backends answer a base64 string for the same reason they accept one, and the caller wants bytes.
|
|
9
12
|
*/
|
|
10
13
|
|
|
11
14
|
/** Bytes per `String.fromCodePoint` call — spreading a whole large file blows the call stack. */
|
|
@@ -31,3 +34,19 @@ export async function toBase64(data: string | File | Blob | ArrayBuffer): Promis
|
|
|
31
34
|
const buffer = data instanceof ArrayBuffer ? data : await data.arrayBuffer();
|
|
32
35
|
return bytesToBase64(new Uint8Array(buffer));
|
|
33
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Decode a base64 string to raw bytes — the inverse of {@link bytesToBase64}.
|
|
40
|
+
*
|
|
41
|
+
* The RPC platforms' `readFileBytes` answers base64 because their params and results are JSON, so
|
|
42
|
+
* this is where a JPEG becomes a JPEG again. `atob` yields one character per byte, and reading the
|
|
43
|
+
* code point back out is what keeps a byte above 0x7F from being re-encoded as UTF-8 — the exact
|
|
44
|
+
* corruption that makes `readFile` useless for an image.
|
|
45
|
+
*
|
|
46
|
+
* `Uint8Array.from` with a mapper rather than an index loop, because `atob`'s output is latin1: one
|
|
47
|
+
* code unit per byte, none of them a surrogate, so iterating characters and iterating bytes are the
|
|
48
|
+
* same walk and the index never has to be reasoned about.
|
|
49
|
+
*/
|
|
50
|
+
export function base64ToBytes(base64: string): Uint8Array {
|
|
51
|
+
return Uint8Array.from(atob(base64), (char) => char.codePointAt(0) ?? 0);
|
|
52
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { pureSchemeOf } from "@jxsuite/runtime";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* True when a feature query participates in the forced-scheme contract (spec §9.5) — a pure
|
|
8
|
+
* True when a feature query participates in the forced-scheme contract (spec.md §9.5) — a pure
|
|
9
9
|
* prefers-color-scheme query. These surface as the Auto/Light/Dark control, not generic toggles.
|
|
10
10
|
*
|
|
11
11
|
* @param {string} query
|
|
@@ -76,37 +76,6 @@ export function attrLabel(
|
|
|
76
76
|
return camelToLabel(attr);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
/**
|
|
80
|
-
* Abbreviate a CSS value for button-group display
|
|
81
|
-
*
|
|
82
|
-
* @param {string} val
|
|
83
|
-
* @returns {string}
|
|
84
|
-
*/
|
|
85
|
-
export function abbreviateValue(val: string) {
|
|
86
|
-
const map: Record<string, string> = {
|
|
87
|
-
baseline: "base",
|
|
88
|
-
column: "col",
|
|
89
|
-
"column-reverse": "col-r",
|
|
90
|
-
contents: "cnt",
|
|
91
|
-
"flex-end": "end",
|
|
92
|
-
"flex-start": "start",
|
|
93
|
-
"flow-root": "flow",
|
|
94
|
-
inline: "inl",
|
|
95
|
-
"inline-block": "i-blk",
|
|
96
|
-
"inline-flex": "i-flx",
|
|
97
|
-
"inline-grid": "i-grd",
|
|
98
|
-
normal: "norm",
|
|
99
|
-
nowrap: "no-wr",
|
|
100
|
-
"row-reverse": "row-r",
|
|
101
|
-
"space-around": "arnd",
|
|
102
|
-
"space-between": "betw",
|
|
103
|
-
"space-evenly": "even",
|
|
104
|
-
stretch: "str",
|
|
105
|
-
"wrap-reverse": "wr-rev",
|
|
106
|
-
};
|
|
107
|
-
return map[val] || val;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
79
|
/**
|
|
111
80
|
* True when a schema `format` names a MEDIA reference.
|
|
112
81
|
*
|
package/src/view.ts
CHANGED
|
@@ -23,9 +23,10 @@ import type { Tab } from "./tabs/tab";
|
|
|
23
23
|
* different modules, torn down by different events and written into by different continuations —
|
|
24
24
|
* and each of those differences used to justify its own spelling of the same two ideas ("ignore the
|
|
25
25
|
* change my own `setValue` is about to fire" and "cancel the work armed over this buffer"). The
|
|
26
|
-
* function editor got a canceller in
|
|
27
|
-
* timer survived three disposal sites and stayed able to replace a
|
|
28
|
-
* `services/monaco-buffer.ts` owns the rule; this is the storage it
|
|
26
|
+
* function editor got a canceller in the shell redesign's panes phase and the source view did not,
|
|
27
|
+
* which is exactly how a 600ms timer survived three disposal sites and stayed able to replace a
|
|
28
|
+
* page with an empty parse. `services/monaco-buffer.ts` owns the rule; this is the storage it
|
|
29
|
+
* needs.
|
|
29
30
|
*/
|
|
30
31
|
/**
|
|
31
32
|
* A comparison's Monaco diff editor.
|
|
@@ -171,10 +171,10 @@ export const PRESET_LABELS: Readonly<Record<DerivePreset, string>> = {
|
|
|
171
171
|
diff: "Diff vs HEAD",
|
|
172
172
|
layout: "Layout",
|
|
173
173
|
/* An UNFINISHED sentence, like `breakpoint`'s, because the row and the chip both finish it with
|
|
174
|
-
the locale's own autonym — "Same page in français". Jx has no message catalogue
|
|
175
|
-
translation is a different file in a different directory, so
|
|
176
|
-
rather than re-rendering this one, and the label says "the same
|
|
177
|
-
rather than about the text on screen. */
|
|
174
|
+
the locale's own autonym — "Same page in français". Jx has no message catalogue
|
|
175
|
+
(site-architecture.md §13.3): a translation is a different file in a different directory, so
|
|
176
|
+
this preset opens that file rather than re-rendering this one, and the label says "the same
|
|
177
|
+
page" about the document rather than about the text on screen. */
|
|
178
178
|
locale: "Same page in",
|
|
179
179
|
};
|
|
180
180
|
|
|
@@ -1029,9 +1029,9 @@ export function presetRefusal(
|
|
|
1029
1029
|
if (i18n === null || i18n.locales.length < 2) {
|
|
1030
1030
|
return "a project that declares more than one locale — see Project Settings › Locales";
|
|
1031
1031
|
}
|
|
1032
|
-
/* A PATH, because a translation is a FILE (§13.3) rather than a rendering:
|
|
1033
|
-
has nowhere for its sibling to be, and `translationPathFor` would answer
|
|
1034
|
-
frame later with a sentence about locales instead of about saving. */
|
|
1032
|
+
/* A PATH, because a translation is a FILE (site-architecture.md §13.3) rather than a rendering:
|
|
1033
|
+
an unsaved document has nowhere for its sibling to be, and `translationPathFor` would answer
|
|
1034
|
+
null for it one frame later with a sentence about locales instead of about saving. */
|
|
1035
1035
|
if (source.documentPath === null) {
|
|
1036
1036
|
return "a document that has been saved";
|
|
1037
1037
|
}
|
|
@@ -1082,10 +1082,11 @@ function derivationFor(
|
|
|
1082
1082
|
media: string | null,
|
|
1083
1083
|
locale: string | null = null,
|
|
1084
1084
|
): PaneDerivation {
|
|
1085
|
-
/* A COMPANION, because the French copy of this page is a different FILE —
|
|
1086
|
-
catalogue, so there is no rendering of this document that is the
|
|
1087
|
-
be a second copy of the same page under a chip naming another
|
|
1088
|
-
this module's own header warns about: a projection that changes
|
|
1085
|
+
/* A COMPANION, because the French copy of this page is a different FILE — Jx has no message
|
|
1086
|
+
catalogue (site-architecture.md §13.3), so there is no rendering of this document that is the
|
|
1087
|
+
French one. A lens here would be a second copy of the same page under a chip naming another
|
|
1088
|
+
language, which is the defect this module's own header warns about: a projection that changes
|
|
1089
|
+
only the chip. */
|
|
1089
1090
|
if (preset === "locale") {
|
|
1090
1091
|
return {
|
|
1091
1092
|
kind: "companion",
|
|
@@ -1213,8 +1214,8 @@ export function derivationCommands(deps: DerivationDeps): AnyCommand[] {
|
|
|
1213
1214
|
enablement: () => deriveRefusal(activePane().id) === null,
|
|
1214
1215
|
requires: DERIVE_REQUIRES,
|
|
1215
1216
|
undo: "none",
|
|
1216
|
-
/* No `aiTool`, by §12.4's first deletion rule: chrome — it arranges
|
|
1217
|
-
looking at. */
|
|
1217
|
+
/* No `aiTool`, by studio-ui-guidelines.md §12.4's first deletion rule: chrome — it arranges
|
|
1218
|
+
what the person is looking at. */
|
|
1218
1219
|
run: (_ctx, args) => {
|
|
1219
1220
|
const preset = enumArg("pane.derive", args, "preset", DERIVE_PRESETS);
|
|
1220
1221
|
/* `??`, not `||`. `optionalStringArg` answers `undefined` or a non-empty string — it is
|
package/src/workspace/session.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session.ts — what a project looked like when you left it, and how it looks that way again.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* tab, per-tab editor kind / view / zoom / rendering context
|
|
6
|
-
* consequence plainly: **the session survives a relaunch
|
|
7
|
-
* held `layouts` and `activeLayout` and nothing else, its interface said
|
|
8
|
-
*
|
|
9
|
-
* nine open documents, a split, and the breakpoint you were checking were lost every
|
|
4
|
+
* The shell redesign promised that session state persists **per project root** — open tabs and
|
|
5
|
+
* order per pane, active tab, per-tab editor kind / view / zoom / rendering context — and stated
|
|
6
|
+
* the consequence plainly: **the session survives a relaunch** (§14.8). Neither shipped. The
|
|
7
|
+
* per-project record held `layouts` and `activeLayout` and nothing else, its interface said session
|
|
8
|
+
* state would "grow into this shape", and reopening a project landed on the home page with an empty
|
|
9
|
+
* strip — so nine open documents, a split, and the breakpoint you were checking were lost every
|
|
10
|
+
* time.
|
|
10
11
|
*
|
|
11
12
|
* **Paths, not tab ids.** A tab id is minted per open and means nothing across a reload; the
|
|
12
13
|
* document's path is the identity the workspace already dedupes on (`openFileInTab` scans
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { computed, reactive, toRaw } from "../reactivity";
|
|
2
2
|
import { commitTabBuffers } from "../services/monaco-buffer";
|
|
3
|
+
import { resetAiWrites } from "../services/ai-writes";
|
|
3
4
|
import { ensureCollab, rekeyCollab } from "../collab/collab-session";
|
|
4
5
|
import { createTab, disposeTab } from "../tabs/tab";
|
|
5
6
|
import { projectState } from "../state";
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
} from "../commands/command-args";
|
|
13
14
|
import { EDITOR_KIND_LABELS } from "../commands/context";
|
|
14
15
|
import type { Tab, TabOrigin } from "../tabs/tab";
|
|
15
|
-
import type { JsonLayout } from "
|
|
16
|
+
import type { JsonLayout } from "@jxsuite/schema/json-layout";
|
|
16
17
|
|
|
17
18
|
import type { ComponentEntry } from "../files/components";
|
|
18
19
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
@@ -35,11 +36,11 @@ export interface ClosedTabRecord {
|
|
|
35
36
|
const CLOSED_TAB_LIMIT = 20;
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
|
-
* One editor pane — the unit of split, focus and zoom (§
|
|
39
|
+
* One editor pane — the unit of split, focus and zoom (§18.1).
|
|
39
40
|
*
|
|
40
41
|
* A tab BELONGS to a pane, and the pane is what splits; the tab strip is per-pane for the same
|
|
41
|
-
* reason.
|
|
42
|
-
*
|
|
42
|
+
* reason. The model is deliberately minimal, an ordered list and an active id; derived panes and
|
|
43
|
+
* their follow behaviour (§18.4) sit beside it in `derived` rather than in either.
|
|
43
44
|
*/
|
|
44
45
|
export interface Pane {
|
|
45
46
|
id: string;
|
|
@@ -357,10 +358,10 @@ export function focusOtherPane() {
|
|
|
357
358
|
* `session.ui.canvasMode`), one picked the replacement kind, and two narrowed what the controls
|
|
358
359
|
* offered so no dropdown could contain an entry the app would refuse.
|
|
359
360
|
*
|
|
360
|
-
* The cap existed because a second LIVE canvas host was unaffordable, and it is gone because
|
|
361
|
-
*
|
|
362
|
-
* flipped a splitting Design tab to `source` before focus moved, so `⌘\` on a page
|
|
363
|
-
* designing silently became "open this as Code somewhere else".
|
|
361
|
+
* The cap existed because a second LIVE canvas host was unaffordable, and it is gone because render
|
|
362
|
+
* fan-out (§18.2) made it affordable — see {@link MAX_PANES}. Its LAST act was a bug:
|
|
363
|
+
* `capToPaneKind` flipped a splitting Design tab to `source` before focus moved, so `⌘\` on a page
|
|
364
|
+
* you were designing silently became "open this as Code somewhere else".
|
|
364
365
|
*
|
|
365
366
|
* What replaces them is `tabs/tab.ts`'s `editorKindsOf` — the kinds a DOCUMENT declares — which is
|
|
366
367
|
* the only narrowing left and the only one that was ever about the document rather than about what
|
|
@@ -371,7 +372,7 @@ export function focusOtherPane() {
|
|
|
371
372
|
* Split the grid and move a tab into the new pane, which becomes focused.
|
|
372
373
|
*
|
|
373
374
|
* Moves rather than duplicates: one tab is one document with one undo history and one collab
|
|
374
|
-
* session, and two strips claiming the same id is the duplicate-`repeat`-key bug §
|
|
375
|
+
* session, and two strips claiming the same id is the duplicate-`repeat`-key bug §14.1 describes.
|
|
375
376
|
*
|
|
376
377
|
* The subject is `tabId` when given, else the focused pane's active tab. The drag resolver names
|
|
377
378
|
* the tab it is carrying — the gesture points at a chip, not at whatever the keyboard is in — and
|
|
@@ -607,11 +608,11 @@ export function paneIsEmpty(pane: Pane): boolean {
|
|
|
607
608
|
return pane.tabOrder.length === 0 && pane.derived === null;
|
|
608
609
|
}
|
|
609
610
|
|
|
610
|
-
/* No `togglePaneZoom`.
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
611
|
+
/* No `togglePaneZoom`. It was removed when the shell still handed one stage between panes: the
|
|
612
|
+
focused pane already filled the shell, so the state existed, both commands wrote it, and nothing
|
|
613
|
+
that draws ever read it — a control whose only observable effect is on itself. There is a grid of
|
|
614
|
+
live panes now (§18.3), so a zoom is buildable, but no section of studio.md asks for one; it
|
|
615
|
+
comes back with the section that does, and not one release earlier. */
|
|
615
616
|
|
|
616
617
|
/**
|
|
617
618
|
* Remove a tab id from whichever pane holds it, without touching the tab itself.
|
|
@@ -696,6 +697,13 @@ function defaultSlot(pane: Pane, tabId: string): number {
|
|
|
696
697
|
* @param {object | null} [config]
|
|
697
698
|
*/
|
|
698
699
|
export function setWorkspaceProject(root: string | null, config: object | null = null) {
|
|
700
|
+
/* Leaving a project drops the assistant's record of what each turn changed (ai.md §3.2). It
|
|
701
|
+
names project-relative paths, and its Restore undoes the active tab, so carried into another
|
|
702
|
+
project it would list files that are not there and undo a document the turn never touched.
|
|
703
|
+
Adopting a project from none keeps it: a bootstrap conversation follows the project it made. */
|
|
704
|
+
if (workspace.projectRoot && root !== workspace.projectRoot) {
|
|
705
|
+
resetAiWrites();
|
|
706
|
+
}
|
|
699
707
|
workspace.projectRoot = root;
|
|
700
708
|
workspace.projectConfig = config;
|
|
701
709
|
}
|
|
@@ -820,12 +828,12 @@ function setActiveTab(tabId: string, opts: { cycling?: boolean; focus?: boolean
|
|
|
820
828
|
* keys. Callers that mean "show me this file" should use `files/files.ts`'s `openFileInTab`, which
|
|
821
829
|
* activates the existing tab instead.
|
|
822
830
|
*
|
|
823
|
-
* `preview: true` opens a DISPOSABLE tab (
|
|
824
|
-
* browsing, and browsing must not litter, so the next preview open in
|
|
825
|
-
* It is opt-in rather than the default because only the CALLER knows
|
|
826
|
-
* browsing or committing — an author who typed a new file name has
|
|
827
|
-
* discarding that tab on their next click is the one failure a preview tab
|
|
828
|
-
* {@link promoteTab} records a commitment made after the fact.
|
|
831
|
+
* `preview: true` opens a DISPOSABLE tab (docs/studio/interface/tabs.md): single-clicking through
|
|
832
|
+
* the tree or the palette is browsing, and browsing must not litter, so the next preview open in
|
|
833
|
+
* the same pane takes its slot. It is opt-in rather than the default because only the CALLER knows
|
|
834
|
+
* whether the author was browsing or committing — an author who typed a new file name has
|
|
835
|
+
* committed, and silently discarding that tab on their next click is the one failure a preview tab
|
|
836
|
+
* must never have. {@link promoteTab} records a commitment made after the fact.
|
|
829
837
|
*
|
|
830
838
|
* `paneId` says WHERE, and `focus` says whether the keyboard goes with it. Both default to today's
|
|
831
839
|
* answer — the focused pane, and yes — because "open this document" has always meant "in front of
|
|
@@ -1383,12 +1391,12 @@ export function tabCommands(deps: TabCommandDeps): AnyCommand[] {
|
|
|
1383
1391
|
"Use it when the user should SEE the page, or for iterative visual refinement after " +
|
|
1384
1392
|
"creating a page or component.",
|
|
1385
1393
|
name: "open_document",
|
|
1386
|
-
/* The person's own read: `activeTab` is what the tab strip highlights, and `editor.kind`
|
|
1387
|
-
|
|
1394
|
+
/* The person's own read: `activeTab` is what the tab strip highlights, and `editor.kind` is
|
|
1395
|
+
the fact the document-tree tier is gated on. Both are named so the model learns in one
|
|
1388
1396
|
round whether the tree tools reach the file it opened — a `.csv` lands in the Grid, a
|
|
1389
1397
|
`.png` in the Media viewer, and neither is an element tree. The `.value` read is module
|
|
1390
|
-
state, which a projected `report` may close over (§12.4); `after`
|
|
1391
|
-
document is active. */
|
|
1398
|
+
state, which a projected `report` may close over (studio-ui-guidelines.md §12.4); `after`
|
|
1399
|
+
alone cannot say WHICH document is active. */
|
|
1392
1400
|
report: ({ after, args }) => {
|
|
1393
1401
|
const path = stringArg("document.open", args, "path");
|
|
1394
1402
|
const active = activeTab.value?.documentPath ?? null;
|
|
@@ -1402,11 +1410,12 @@ export function tabCommands(deps: TabCommandDeps): AnyCommand[] {
|
|
|
1402
1410
|
return `"${path}" is the active document, ${where}.`;
|
|
1403
1411
|
},
|
|
1404
1412
|
},
|
|
1405
|
-
/* Refuses by THROWING (§12.4's first review rule). `openFileInTab`
|
|
1406
|
-
open as a Problem and returns normally — the right answer for a
|
|
1407
|
-
where the toast is in front of the person — so the record has to
|
|
1408
|
-
The hand tool this replaced read `getTab()` after the open and
|
|
1409
|
-
success, so a missing file left the PREVIOUS document active and
|
|
1413
|
+
/* Refuses by THROWING (studio-ui-guidelines.md §12.4's first review rule). `openFileInTab`
|
|
1414
|
+
reports a file it cannot open as a Problem and returns normally — the right answer for a
|
|
1415
|
+
click in the Files tree, where the toast is in front of the person — so the record has to
|
|
1416
|
+
look for the tab itself. The hand tool this replaced read `getTab()` after the open and
|
|
1417
|
+
called whatever it found a success, so a missing file left the PREVIOUS document active and
|
|
1418
|
+
reported "Switched to". */
|
|
1410
1419
|
run: async (_ctx, args) => {
|
|
1411
1420
|
const path = stringArg("document.open", args, "path");
|
|
1412
1421
|
await deps.openFile(path);
|
|
@@ -1435,8 +1444,9 @@ export function tabCommands(deps: TabCommandDeps): AnyCommand[] {
|
|
|
1435
1444
|
group: "1_file",
|
|
1436
1445
|
when: (ctx) => ctx.project.open,
|
|
1437
1446
|
requires: "an open project",
|
|
1438
|
-
/* No `aiTool`, by §12.4's first deletion rule: chrome — it arranges
|
|
1439
|
-
looking at. No `undo`: opening a tab is not a state the undo stack
|
|
1447
|
+
/* No `aiTool`, by studio-ui-guidelines.md §12.4's first deletion rule: chrome — it arranges
|
|
1448
|
+
what the person is looking at. No `undo`: opening a tab is not a state the undo stack
|
|
1449
|
+
owns. */
|
|
1440
1450
|
undo: "none",
|
|
1441
1451
|
/* The non-drag equivalent of dragging a file row onto the other pane's strip (SC 2.5.7): the
|
|
1442
1452
|
same `receivingPane` the drag resolver uses, so a file tree row and this command can never
|
|
@@ -1550,12 +1560,12 @@ export function tabCommands(deps: TabCommandDeps): AnyCommand[] {
|
|
|
1550
1560
|
* The pane commands.
|
|
1551
1561
|
*
|
|
1552
1562
|
* They live beside the pane model for the same reason the tab commands do, and they are the whole
|
|
1553
|
-
* user-facing surface of §
|
|
1563
|
+
* user-facing surface of the pane transport (§18.1): split, focus, unsplit, zoom.
|
|
1554
1564
|
*
|
|
1555
1565
|
* `⌘0` and `⌘⌥0` are a PAIR, and they are both bound. `⌘0` was `canvas.zoomReset`, which held it
|
|
1556
|
-
* for the one verb of the zoom cluster that also has a button in the floating zoom pod
|
|
1557
|
-
*
|
|
1558
|
-
*
|
|
1566
|
+
* for the one verb of the zoom cluster that also has a button in the floating zoom pod — so the
|
|
1567
|
+
* chord was the second way to reach a control that is already on screen, while focusing a pane had
|
|
1568
|
+
* no way at all. The zoom keeps its pod button and gives up the key.
|
|
1559
1569
|
*
|
|
1560
1570
|
* @param {TabCommandDeps} deps
|
|
1561
1571
|
* @returns {AnyCommand[]}
|
|
@@ -1604,13 +1614,13 @@ export function paneCommands(deps: TabCommandDeps): AnyCommand[] {
|
|
|
1604
1614
|
/* This is NOT `pane.derive`, and the distinction is the whole reason both exist. `derive`
|
|
1605
1615
|
shows a projection OF THIS PANE — its Code, its diff, the same page at another breakpoint —
|
|
1606
1616
|
and follows it. `compareWith` puts THAT DOCUMENT beside this one and then leaves it alone.
|
|
1607
|
-
Collapsing them would give "open a second document in the other pane" two definition
|
|
1608
|
-
|
|
1617
|
+
Collapsing them would give "open a second document in the other pane" two definition sites,
|
|
1618
|
+
which is how the shell redesign's two names for it came to disagree in the first place. */
|
|
1609
1619
|
enablement: () => workspace.activeTabId !== null,
|
|
1610
1620
|
requires: "an open document",
|
|
1611
1621
|
undo: "none",
|
|
1612
|
-
/* No `aiTool`, by §12.4's first deletion rule: chrome — it arranges
|
|
1613
|
-
looking at. */
|
|
1622
|
+
/* No `aiTool`, by studio-ui-guidelines.md §12.4's first deletion rule: chrome — it arranges
|
|
1623
|
+
what the person is looking at. */
|
|
1614
1624
|
run: async (_ctx, args) => {
|
|
1615
1625
|
const path = stringArg("pane.compareWith", args, "path");
|
|
1616
1626
|
const here = activePane();
|
package/styles/canvas.css
CHANGED
|
@@ -18,32 +18,6 @@
|
|
|
18
18
|
min-height: 0;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/* ─── Document Header card ─────────────────────
|
|
22
|
-
Region ⑧: the artefact's own header, drawn IN the stage. `#frontmatter-panel` — a fourth
|
|
23
|
-
full-width band up to 40vh that appeared and vanished as a side effect of the canvas mode — is
|
|
24
|
-
gone, grid row and all.
|
|
25
|
-
|
|
26
|
-
Two placements, because the stage draws a page two ways. In Edit the card is `in-column`: a block
|
|
27
|
-
of the document's own centered column that scrolls with it, so it is part of the artefact rather
|
|
28
|
-
than a strip above it. In Design the artboards are under a pan/zoom transform, and a form drawn
|
|
29
|
-
at 40% is a picture of a form — so the card is `pinned` above the surface at 1:1, and that is the
|
|
30
|
-
one placement that still needs a cap. */
|
|
31
|
-
.doc-header-host[hidden] {
|
|
32
|
-
display: none;
|
|
33
|
-
}
|
|
34
|
-
.doc-header-host.in-column {
|
|
35
|
-
display: block;
|
|
36
|
-
padding-bottom: 16px;
|
|
37
|
-
}
|
|
38
|
-
.doc-header-host.pinned {
|
|
39
|
-
flex-shrink: 0;
|
|
40
|
-
max-height: 40vh;
|
|
41
|
-
overflow-y: auto;
|
|
42
|
-
}
|
|
43
|
-
.doc-header-host.pinned .doc-header {
|
|
44
|
-
border-width: 0 0 1px;
|
|
45
|
-
border-radius: 0;
|
|
46
|
-
}
|
|
47
21
|
/* ─── Content edit mode canvas ─────────────── */
|
|
48
22
|
.content-edit-canvas {
|
|
49
23
|
width: 100%;
|
|
@@ -201,7 +175,7 @@
|
|
|
201
175
|
.overlay-coselection-group {
|
|
202
176
|
display: contents;
|
|
203
177
|
}
|
|
204
|
-
/* The other members of a multi-selection (§6.
|
|
178
|
+
/* The other members of a multi-selection (§6.7). Same accent, thinner: one box is the primary —
|
|
205
179
|
what the Inspector, the block action bar and the status bar address — and the rest are along for
|
|
206
180
|
the batch. A selection of one draws no co-selection boxes at all. */
|
|
207
181
|
.overlay-coselection {
|