@jxsuite/studio 5.2.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-h4dab9bq.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-sgg1sv6n.js → content-source-jt7rbcbc.js} +22 -22
- package/dist/chunks/{convert-to-repeater-mf1cxgfn.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-c6zwzbre.js → extension-sections-r73an5s6.js} +31 -30
- package/dist/chunks/{file-ops-vrpq1jjk.js → file-ops-3xan8mnj.js} +21 -21
- package/dist/chunks/{files-msaf95y6.js → files-egsb0ry8.js} +30 -29
- package/dist/chunks/{format-host-f64fnesp.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-bv5e22j0.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-paj67nr5.js → grid-view-qaqer9kr.js} +24 -24
- package/dist/chunks/{icons-yy10wk9r.js → icons-drxq9q10.js} +8 -2
- package/dist/chunks/{iframe-host-dh5np8vk.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/{jx-validate-j0wxk72w.js → jx-validate-epp2z3s3.js} +2 -2
- package/dist/chunks/layers-panel-83a16ytx.js +41 -0
- package/dist/chunks/{layers-1vcfdbet.js → layers-s6mc01ry.js} +3 -3
- package/dist/chunks/{listbox-6v2ac08j.js → listbox-b7jxnhq1.js} +19 -3
- package/dist/chunks/{media-picker-p49nhqhs.js → media-picker-nhn6rv4w.js} +11 -11
- package/dist/chunks/{menu-qht48vnc.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-8r62fj6y.js → monaco-setup-gsjdysze.js} +7 -7
- 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/{split-g7nm1rgb.js → split-4cz4b6ef.js} +14 -3
- package/dist/chunks/{studio-sar8g54p.js → studio-01269reb.js} +8 -8
- 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-p6pmwkvh.js → studio-3nprwbd9.js} +147 -28
- package/dist/chunks/{studio-4c041r8y.js → studio-40z39dme.js} +3 -3
- package/dist/chunks/{studio-68fydsrj.js → studio-482eeazk.js} +20 -20
- package/dist/chunks/{studio-y4f9fdge.js → studio-4998spet.js} +10 -9
- package/dist/chunks/{studio-nq5yf5mp.js → studio-557bmn0x.js} +2 -2
- package/dist/chunks/{studio-hdc2jt3z.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-28vs5k2y.js → studio-9vsvz7w7.js} +7 -7
- package/dist/chunks/{studio-t3adrr56.js → studio-9wm0xzpf.js} +19 -19
- package/dist/chunks/{studio-38emantv.js → studio-a5h5j33a.js} +19 -5
- package/dist/chunks/{studio-ympe0n7a.js → studio-ag3z6shb.js} +10 -4
- package/dist/chunks/studio-aj9drheq.js +177 -0
- package/dist/chunks/{studio-vt0tj32j.js → studio-apv9x70c.js} +189 -130
- package/dist/chunks/{studio-c04nzbby.js → studio-b9q3znz8.js} +2 -2
- package/dist/chunks/{studio-2mdbbc76.js → studio-bh47w0cy.js} +9 -10
- package/dist/chunks/{studio-ez11dmdh.js → studio-dgdm6vvt.js} +264 -52
- package/dist/chunks/{studio-5nz00bhh.js → studio-dwdcr2e8.js} +4 -4
- package/dist/chunks/{studio-nqgawfks.js → studio-fbcyz234.js} +146 -139
- package/dist/chunks/{studio-kcgff4r0.js → studio-fgmfksz8.js} +2 -2
- package/dist/chunks/{studio-x72j58vw.js → studio-fqpkpq1t.js} +7 -4
- package/dist/chunks/{studio-15f3kxqe.js → studio-fy320dfc.js} +62 -68
- package/dist/chunks/{studio-zjjde71a.js → studio-gjj4bbfx.js} +2 -2
- package/dist/chunks/{studio-66arbpc2.js → studio-jfhxy8h3.js} +16 -15
- package/dist/chunks/{studio-d0300636.js → studio-ks2zzth2.js} +17 -2
- package/dist/chunks/{studio-c07s5ckd.js → studio-kwewmhhq.js} +4 -4
- package/dist/chunks/{studio-01jeck2y.js → studio-m58xn8at.js} +26 -25
- package/dist/chunks/{studio-mpzwze9x.js → studio-mfkh1q8d.js} +17 -17
- package/dist/chunks/{studio-etvx9s2g.js → studio-mrh0a92f.js} +17 -17
- package/dist/chunks/{studio-qa7fzxan.js → studio-mt79tn56.js} +3 -3
- package/dist/chunks/{studio-hhskq2mr.js → studio-ne593z1j.js} +39 -32
- package/dist/chunks/{studio-h4nvnjvz.js → studio-ptfcxkz5.js} +418 -232
- package/dist/chunks/{studio-4xmjcrg3.js → studio-qxye31h7.js} +7 -7
- package/dist/chunks/{studio-a1pswps3.js → studio-rav5bpmp.js} +81 -59
- package/dist/chunks/{studio-ncn9e189.js → studio-rwmmbrth.js} +6 -6
- package/dist/chunks/{studio-en82c639.js → studio-sceg8ws0.js} +8 -8
- package/dist/chunks/{studio-wjpgxywa.js → studio-sjas5b3a.js} +19 -13
- package/dist/chunks/{studio-4r14yzyy.js → studio-vd67b66d.js} +3 -3
- package/dist/chunks/{studio-14d9tq4d.js → studio-w475cbf9.js} +10 -10
- package/dist/chunks/{studio-ctm7bhx5.js → studio-w7gpcvfj.js} +9 -9
- package/dist/chunks/{studio-9j6sfeba.js → studio-xrbfdxgk.js} +7 -7
- package/dist/chunks/{studio-x10fp4tp.js → studio-y49b6mjv.js} +35 -35
- package/dist/chunks/{studio-5t7ena5z.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-bnw54cha.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 +20 -18
- package/dist/studio.css +956 -139
- package/dist/studio.js +1511 -851
- 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 +18 -17
- 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/chat-panel.ts +40 -5
- 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/module-preloads.ts +67 -0
- 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 +52 -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 +10 -9
- package/src/surfaces/formula-palette.ts +11 -7
- 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/palette.json +8 -7
- 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 +8 -28
- 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 +58 -5
- 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-w9qsxa6q.js +0 -42
- package/dist/chunks/layers-panel-fksbdg4q.js +0 -40
- package/dist/chunks/publish-panel-vz23wwmg.js +0 -27
- package/dist/chunks/quick-search-e9rp74m8.js +0 -46
- package/dist/chunks/right-panel-j97t2yvy.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
|
@@ -37,7 +37,7 @@ import { PROJECT_CONFIG_PATH } from "../tabs/tab";
|
|
|
37
37
|
import type { TransactOrigin } from "../tabs/transact";
|
|
38
38
|
import type { TransactionRecord } from "../tabs/patch-ops";
|
|
39
39
|
import type { Tab } from "../tabs/tab";
|
|
40
|
-
import type { JxDocOp } from "@jxsuite/
|
|
40
|
+
import type { JxDocOp } from "@jxsuite/schema/doc-ops";
|
|
41
41
|
import type { CollabHandle } from "@jxsuite/collab/provider";
|
|
42
42
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
43
43
|
import type * as CollabNS from "@jxsuite/collab";
|
|
@@ -664,7 +664,7 @@ export function ensureCollab(tab: Tab): void {
|
|
|
664
664
|
|
|
665
665
|
/**
|
|
666
666
|
* Join or leave this document's collaboration session — the idempotent setter behind `Collaborate:
|
|
667
|
-
* Share this document` and `Collaborate: Stop sharing` (§
|
|
667
|
+
* Share this document` and `Collaborate: Stop sharing` (collab.md §4).
|
|
668
668
|
*
|
|
669
669
|
* Leaving sets a flag the watcher effect reads rather than calling `detachSession` directly, so the
|
|
670
670
|
* effect remains the one owner of the session lifecycle and re-joining is the same call with the
|
|
@@ -709,7 +709,7 @@ async function attachSession(tab: Tab): Promise<void> {
|
|
|
709
709
|
const platform = maybePlatform();
|
|
710
710
|
if (!path || !platform?.collab) {
|
|
711
711
|
/* Not a failure and not a session: this build/platform has no collaboration to offer. Saying
|
|
712
|
-
so is the difference between "nobody else is here" and "something broke" (§
|
|
712
|
+
so is the difference between "nobody else is here" and "something broke" (collab.md §4). */
|
|
713
713
|
collabState(tab).status = "unavailable";
|
|
714
714
|
return;
|
|
715
715
|
}
|
|
@@ -753,7 +753,7 @@ async function attachSession(tab: Tab): Promise<void> {
|
|
|
753
753
|
} catch (error) {
|
|
754
754
|
/* An attach that threw is a FAILURE, and it used to be reported as "detached" — the same
|
|
755
755
|
value a solo document carries. A relay that is down, a token that expired and a document
|
|
756
|
-
nobody shared were one indistinguishable state (§
|
|
756
|
+
nobody shared were one indistinguishable state (collab.md §4). */
|
|
757
757
|
state.status = "failed";
|
|
758
758
|
state.active = false;
|
|
759
759
|
state.attachError = error instanceof Error ? error.message : String(error);
|
|
@@ -13,9 +13,9 @@ import type { CollabAwarenessState } from "@jxsuite/collab/awareness-types";
|
|
|
13
13
|
*
|
|
14
14
|
* `"detached"` used to mean three different things at once and say none of them: this build has no
|
|
15
15
|
* collaboration at all, this project has collaboration but this tab is solo, and the attach was
|
|
16
|
-
* tried and it FAILED.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* tried and it FAILED. A freeze was indistinguishable from a bug, and so was a broken connection
|
|
17
|
+
* (collab.md §4). `"unavailable"` and `"failed"` split the third and first cases out, so the chip
|
|
18
|
+
* can say which one it is.
|
|
19
19
|
*/
|
|
20
20
|
export type CollabTabStatus =
|
|
21
21
|
| "unavailable"
|
|
@@ -42,7 +42,7 @@ export interface TabCollabState {
|
|
|
42
42
|
* surfaces soft-freeze and the canvas previews the source reconciler's parses.
|
|
43
43
|
*
|
|
44
44
|
* The freeze is real and it is brief, and until now its only rendering was a grey line for three
|
|
45
|
-
* seconds — which is exactly what a bug looks like. It gets an indicator (§
|
|
45
|
+
* seconds — which is exactly what a bug looks like. It gets an indicator (collab.md §4).
|
|
46
46
|
*/
|
|
47
47
|
sourceCanonical: boolean;
|
|
48
48
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Presence chips — who else is in this co-editing session, the sync-status pill that replaces the
|
|
3
|
-
* dirty dot for collab tabs, and the two states co-editing had no way to announce (§
|
|
3
|
+
* dirty dot for collab tabs, and the two states co-editing had no way to announce (collab.md §4).
|
|
4
4
|
*
|
|
5
5
|
* Pure projections of `collabState(tab)`: the Command Bar surface draws the cluster and the pane's
|
|
6
6
|
* own chrome draws the banner, and both are documents, so nothing here renders.
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
*
|
|
23
23
|
* **Undo says what it does.** The Y.UndoManager is constructed with `trackedOrigins:
|
|
24
24
|
* {LOCAL_ORIGIN}`, so ⌘Z reaches your own actions and never a peer's. That is the correct behaviour
|
|
25
|
-
* and it is also surprising, so the status pill's title states it
|
|
26
|
-
*
|
|
25
|
+
* and it is also surprising, so the status pill's title states it (collab.md §4). The scoping is
|
|
26
|
+
* deliberate: silently undoing someone else's work is worse than not undoing.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { collabState } from "./collab-state";
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* process with no DOM and no bootstrap, and each looks for one export — `defaultCommandSet()`.
|
|
9
9
|
*
|
|
10
10
|
* Without this module those three checks see only `commands/defaults.ts`'s sixteen records, which
|
|
11
|
-
* is why
|
|
12
|
-
*
|
|
13
|
-
* load the record that declares the enum.
|
|
14
|
-
* `document` and no `localStorage` write, which
|
|
15
|
-
* and the test beside it asserts exactly that, so
|
|
16
|
-
* rather than in CI.
|
|
11
|
+
* is why the screenshot gate's headline promise (`scripts/screenshots/README.md`, "The gate") was
|
|
12
|
+
* not yet true: a manifest step naming `view.setActivity` with a panel id the registry does not
|
|
13
|
+
* declare sailed through Lane 1, because Lane 1 could not load the record that declares the enum.
|
|
14
|
+
* Every module gathered below imports cleanly with no `document` and no `localStorage` write, which
|
|
15
|
+
* is the ONLY property this file requires of them — and the test beside it asserts exactly that, so
|
|
16
|
+
* a future DOM read at module scope fails here rather than in CI.
|
|
17
17
|
*
|
|
18
18
|
* **Deps are the no-op set.** Nothing here runs a command; the checks read `id`, `level`, `menus`
|
|
19
19
|
* and `args`. Passing real implementations would mean importing the app.
|
|
@@ -136,7 +136,7 @@ export function appCommandSet(): AnyCommand[] {
|
|
|
136
136
|
// And none reached the palette, because they were registered ONLY into the private registry
|
|
137
137
|
// `editor/context-menu.ts` builds for its popover — a registry whose own docstring said it
|
|
138
138
|
// Existed "until a bootstrap composes every contribution point into a single app-wide
|
|
139
|
-
// Registry". This is that bootstrap; it has existed since
|
|
139
|
+
// Registry". This is that bootstrap; it has existed since the command registry landed.
|
|
140
140
|
...liveElementCommands(),
|
|
141
141
|
...dataExplorerCommands({ renderLeftPanel: NO_OP }),
|
|
142
142
|
...signalsCommands(),
|
package/src/commands/budget.ts
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Budget.ts — chrome is earned by frequency and capped by a build check.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* most four tabs per dock. `scripts/check-chrome-budget.ts` fails
|
|
6
|
-
* "we should keep the toolbar small" from a code-review opinion
|
|
4
|
+
* The chrome budget, studio-ui-guidelines.md §12.2: at most five commands may declare `menus:
|
|
5
|
+
* ["commandbar/primary"]`, and at most four tabs per dock. `scripts/check-chrome-budget.ts` fails
|
|
6
|
+
* CI otherwise, which is what turns "we should keep the toolbar small" from a code-review opinion
|
|
7
|
+
* into a build error.
|
|
7
8
|
*
|
|
8
9
|
* The cap is not arbitrary. The toolbar's own CSS already admits it is over budget — a container
|
|
9
10
|
* query at 1140px strips every `.tb-label` rather than conceding there are too many controls — and
|
|
10
11
|
* an unlabelled icon is a control the user has to hover to identify. A hard number is what makes
|
|
11
12
|
* "retire this control, keep its name and its chord" the cheap option.
|
|
12
13
|
*
|
|
13
|
-
* The dock/tab sets used to be a flat declaration — written out from
|
|
14
|
-
* did not exist. It does now, so the two `rail/*` rows are
|
|
15
|
-
* ({@link dockTabs}) and adding a ninth rail panel fails this
|
|
16
|
-
* update a list. The two rows that remain declared are the two
|
|
17
|
-
* cannot see from a bare Bun process: the Inspector's four come
|
|
18
|
-
* `INSPECTOR_TABS` (a query in all but name), and the Bottom dock's
|
|
19
|
-
* `panels/bottom-dock.ts`, which renders lit templates and therefore cannot be
|
|
20
|
-
* `tests/bottom-dock.test.ts` asserts the declared row and the registered set are
|
|
21
|
-
* titles, so the copy cannot drift — the same bargain `tests/right-panel.test.ts`
|
|
22
|
-
* Inspector. Both become real queries the day `scripts/check-chrome-budget.ts`
|
|
23
|
-
* it already joins the rail.
|
|
14
|
+
* The dock/tab sets used to be a flat declaration — written out by hand from the shell redesign's
|
|
15
|
+
* region table, because `registerPanel()` did not exist. It does now, so the two `rail/*` rows are
|
|
16
|
+
* a QUERY over `railDeclarations()` ({@link dockTabs}) and adding a ninth rail panel fails this
|
|
17
|
+
* check without anyone remembering to update a list. The two rows that remain declared are the two
|
|
18
|
+
* docks whose tab sets this module cannot see from a bare Bun process: the Inspector's four come
|
|
19
|
+
* from `commands/defaults.ts`'s `INSPECTOR_TABS` (a query in all but name), and the Bottom dock's
|
|
20
|
+
* four are records in `panels/bottom-dock.ts`, which renders lit templates and therefore cannot be
|
|
21
|
+
* imported here. `tests/bottom-dock.test.ts` asserts the declared row and the registered set are
|
|
22
|
+
* the same four titles, so the copy cannot drift — the same bargain `tests/right-panel.test.ts`
|
|
23
|
+
* strikes for the Inspector. Both become real queries the day `scripts/check-chrome-budget.ts`
|
|
24
|
+
* joins them the way it already joins the rail.
|
|
24
25
|
*/
|
|
25
26
|
|
|
26
27
|
import { INSPECTOR_TABS } from "./defaults";
|
|
@@ -46,7 +47,7 @@ export const CHROME_BUDGET = {
|
|
|
46
47
|
*
|
|
47
48
|
* A prompt is chrome for a model: every tool costs attention, and issue 273's finding was that a
|
|
48
49
|
* naive projection of every declaration would have taken the list from 22 to 67. Thirty is
|
|
49
|
-
* headroom over today's
|
|
50
|
+
* headroom over today's 29 (18 hand + 11 projected), not a target. Asserted in
|
|
50
51
|
* `tests/ai-command-tools.test.ts` rather than `scripts/check-chrome-budget.ts`, because the hand
|
|
51
52
|
* table lives in `ai-system-prompt.ts`, which imports `../store.js` and is not bare-Bun loadable;
|
|
52
53
|
* the number lives here either way, and raising it is a design decision.
|
|
@@ -56,7 +57,7 @@ export const CHROME_BUDGET = {
|
|
|
56
57
|
|
|
57
58
|
/** One tabbed region and what it currently hosts. */
|
|
58
59
|
export interface DockDeclaration {
|
|
59
|
-
/** Region key
|
|
60
|
+
/** Region key. Rail groups count separately — they are separate placements. */
|
|
60
61
|
dock: string;
|
|
61
62
|
tabs: readonly string[];
|
|
62
63
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Command-args.ts — loud coercion for the arguments a command record declares.
|
|
3
3
|
*
|
|
4
|
-
* Every scriptable command carries an `args` JSON Schema (
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Every scriptable command carries an `args` JSON Schema (studio.md §13.1): the palette prompts
|
|
5
|
+
* from it, the AI tool's parameters are it, and `scripts/check-shot-contract.ts` validates every
|
|
6
|
+
* manifest step against it in the `checks` job. This module is the RUNTIME half of that same
|
|
7
7
|
* declaration, twice over: the typed readers a `run` body calls (`stringArg(...)` and its family),
|
|
8
8
|
* and {@link coerceArgs}, which `registry.run` applies to the received record BEFORE `run` for
|
|
9
9
|
* every caller — the palette, `__jxAutomation`, the assistant and a chord alike. The coercion
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
* 1. **Reject loudly, never clamp.** An unknown panel id, a mode the tab cannot enter, a selection
|
|
17
17
|
* path that is not in the document — each throws. A no-op would photograph the previous state
|
|
18
18
|
* and a docs build would accept it; a clamp would photograph a state the caller did not ask for.
|
|
19
|
-
*
|
|
19
|
+
* The shot contract (`scripts/screenshots/README.md`, `steps`) makes this a tested property.
|
|
20
20
|
* 2. **The failure names the fix.** `{@link enumArg}` prints the declared values, which is what makes
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* this file matters as much as
|
|
21
|
+
* the screenshot gate's headline failure (`scripts/screenshots/README.md`, "The gate") —
|
|
22
|
+
* _manifest shot "properties-bar" names panel "head"; the registry declares "page"_ — a sentence
|
|
23
|
+
* a reader can act on rather than a stack trace. Nothing else in this file matters as much as
|
|
24
|
+
* that message.
|
|
24
25
|
*
|
|
25
26
|
* `RangeError` (not a bespoke class) because `services/profile.ts` already throws it for exactly
|
|
26
27
|
* this — an id outside a declared set — and one refusal shape is easier to catch than two.
|
|
@@ -185,7 +186,7 @@ export function nullablePathArg(
|
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
/**
|
|
188
|
-
* A LIST of document paths — the whole selection set (§6.
|
|
189
|
+
* A LIST of document paths — the whole selection set (§6.7).
|
|
189
190
|
*
|
|
190
191
|
* Every element is validated as a path, so a caller that passes one bare path by mistake
|
|
191
192
|
* (`["children", 0]` rather than `[["children", 0]]`) is refused by name instead of selecting two
|
|
@@ -218,7 +219,7 @@ export function pathListArg(
|
|
|
218
219
|
|
|
219
220
|
// ─── Schema fragments ─────────────────────────────────────────────────────────
|
|
220
221
|
// The readers above are what a `run` body calls; these are the same facts in the form the palette
|
|
221
|
-
// Prompt, the AI tool's parameter list and
|
|
222
|
+
// Prompt, the AI tool's parameter list and the shot-contract check read. The pair used to be kept
|
|
222
223
|
// Adjacent so a reviewer could see that a schema agreed with its coercion; `coerceArgs` below made
|
|
223
224
|
// Them ONE call site, so a schema that disagrees with its coercion is now a refusal rather than a
|
|
224
225
|
// Defect a reviewer has to spot — which is what this module exists to prevent.
|
package/src/commands/context.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context.ts — the record every `when` / `enablement` predicate closes over.
|
|
3
3
|
*
|
|
4
|
-
* One flat-ish record of the facts a command can be gated on (
|
|
4
|
+
* One flat-ish record of the facts a command can be gated on (specs/studio.md §13.4). Predicates
|
|
5
5
|
* are plain closures over this record — the shape `services/gated-registry.ts` already ships for
|
|
6
|
-
* the AI's tools — not a serialisable string DSL
|
|
7
|
-
* && editor.kind == 'canvas'"` grammar needs a tokenizer, a parser and a reactive
|
|
8
|
-
* serialisability nothing in Studio consumes.
|
|
6
|
+
* the AI's tools — not a serialisable string DSL, which the shell redesign rejected explicitly: a
|
|
7
|
+
* `"project.open && editor.kind == 'canvas'"` grammar needs a tokenizer, a parser and a reactive
|
|
8
|
+
* evaluator to buy serialisability nothing in Studio consumes.
|
|
9
9
|
*
|
|
10
10
|
* This module owns the SHAPE and a pure builder. It deliberately imports nothing from the state
|
|
11
11
|
* modules: the registry takes a `getContext()` thunk, so wiring the live sources (the reactive
|
|
@@ -32,6 +32,9 @@ export const CAPABILITIES = [
|
|
|
32
32
|
"dataRows",
|
|
33
33
|
"windowControls",
|
|
34
34
|
"findReferences",
|
|
35
|
+
/* The image editor's gate. A backend that cannot hand Studio a project file's raw bytes cannot
|
|
36
|
+
decode one, so the Image mode is not offered at all rather than offered and then failing. */
|
|
37
|
+
"readFileBytes",
|
|
35
38
|
] as const;
|
|
36
39
|
|
|
37
40
|
export type Capability = (typeof CAPABILITIES)[number];
|
|
@@ -182,7 +185,7 @@ export interface CommandContext {
|
|
|
182
185
|
selection: {
|
|
183
186
|
count: number;
|
|
184
187
|
/**
|
|
185
|
-
* The selected document paths, in selection order — `[]` when nothing is selected (§6.
|
|
188
|
+
* The selected document paths, in selection order — `[]` when nothing is selected (§6.7).
|
|
186
189
|
*
|
|
187
190
|
* The context is what `probe.state()` answers with, so this is how a script, a screenshot step
|
|
188
191
|
* or the assistant READS a multi-selection back. `count` is its length; the last entry is the
|
|
@@ -237,13 +240,19 @@ export interface CommandContext {
|
|
|
237
240
|
};
|
|
238
241
|
ai: {
|
|
239
242
|
configured: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* A turn is in flight: from an accepted send until its loop ends, with its tools, its questions
|
|
245
|
+
* and its imports included (specs/ai.md §3.0). Not the token stream, which the chat's own
|
|
246
|
+
* status reports and which reads idle whenever the turn's tools are running.
|
|
247
|
+
*/
|
|
240
248
|
streaming: boolean;
|
|
241
249
|
/**
|
|
242
250
|
* A turn is suspended on an `ask_user` question.
|
|
243
251
|
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
252
|
+
* Always inside a turn, so `streaming` holds too. Kept as its own fact for `when` predicates
|
|
253
|
+
* and the live-context probe: while a question waits, a send is its answer rather than a new
|
|
254
|
+
* turn (the composer reads the same fact straight from `panels/ai-panel.ts`). Stop's union with
|
|
255
|
+
* it is the same thing as `streaming`.
|
|
247
256
|
*/
|
|
248
257
|
waiting: boolean;
|
|
249
258
|
};
|
|
@@ -309,6 +318,7 @@ export function emptyContext(): CommandContext {
|
|
|
309
318
|
dataRows: false,
|
|
310
319
|
windowControls: false,
|
|
311
320
|
findReferences: false,
|
|
321
|
+
readFileBytes: false,
|
|
312
322
|
},
|
|
313
323
|
};
|
|
314
324
|
}
|
|
@@ -358,8 +368,8 @@ const GLOBAL_STACK: readonly KeyScope[] = ["global"];
|
|
|
358
368
|
/**
|
|
359
369
|
* The scope stack for the current context, narrowest scope first.
|
|
360
370
|
*
|
|
361
|
-
* The ladder is `caret > grid/code engine > focused dock > global` (
|
|
362
|
-
*
|
|
371
|
+
* The ladder is `caret > grid/code engine > focused dock > global` (§13.3), and the whole point is
|
|
372
|
+
* that a scope which is not on the stack cannot fire AT ALL. Three hand-written guards collapse
|
|
363
373
|
* into it:
|
|
364
374
|
*
|
|
365
375
|
* - The blanket modal return → the `palette`-only stack;
|
package/src/commands/defaults.ts
CHANGED
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* print — one sentence, three consumers.
|
|
22
22
|
*
|
|
23
23
|
* The primary Command Bar cluster is capped at five by `scripts/check-chrome-budget.ts`; four are
|
|
24
|
-
* spent here (Save, Undo, Redo, Open in Browser) exactly
|
|
24
|
+
* spent here (Save, Undo, Redo, Open in Browser), exactly the four studio-ui-guidelines.md §12.1
|
|
25
|
+
* admits to `commandbar/primary` at document level.
|
|
25
26
|
*/
|
|
26
27
|
|
|
27
28
|
import { isSpliceablePath } from "../tabs/selection";
|
|
@@ -41,10 +42,10 @@ import type { CommandContext } from "./context";
|
|
|
41
42
|
export type DockId = "navigator" | "inspector" | "bottom";
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
|
-
* Palette modes, echoed as a removable chip in the input
|
|
45
|
+
* Palette modes, echoed as a removable chip in the input.
|
|
45
46
|
*
|
|
46
47
|
* The value space is the palette's namespace, declared once here so a new mode is a new member
|
|
47
|
-
* rather than a new widget:
|
|
48
|
+
* rather than a new widget: a Problems mode or a content search slots in beside these.
|
|
48
49
|
*/
|
|
49
50
|
export type PaletteMode = "picker" | "files" | "commands" | "nodes" | "projects";
|
|
50
51
|
|
|
@@ -68,15 +69,14 @@ export interface RailPanel {
|
|
|
68
69
|
when?: (ctx: CommandContext) => boolean;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
/** How many rail panels get a ⌘N
|
|
72
|
+
/** How many rail panels get a ⌘N: the Navigator rail (§5.1) spends four per level group. */
|
|
72
73
|
export const RAIL_CHORD_LIMIT = 8;
|
|
73
74
|
|
|
74
75
|
/**
|
|
75
|
-
* The Inspector's four tabs, in the order §
|
|
76
|
+
* The Inspector's four tabs, in the order §6 names them — which is the order ⌘⇧1–4 follow.
|
|
76
77
|
*
|
|
77
|
-
* `"assistant"` is a
|
|
78
|
-
*
|
|
79
|
-
* same run of four, because a user counting tabs does not know that.
|
|
78
|
+
* `"assistant"` is the fourth tab, not a dock of its own (there is no assistant column, §3.1), so
|
|
79
|
+
* it is one of `shell.ts`'s `INSPECTOR_TAB_IDS` like the other three.
|
|
80
80
|
*/
|
|
81
81
|
export interface InspectorTab {
|
|
82
82
|
/** The stored `session.ui.rightTab` value, or `"assistant"` for the assistant dock. */
|
|
@@ -130,9 +130,9 @@ export interface CommandDeps {
|
|
|
130
130
|
*/
|
|
131
131
|
panelRoster: readonly RailPanel[];
|
|
132
132
|
/**
|
|
133
|
-
* Toggle-FOCUS a panel
|
|
134
|
-
*
|
|
135
|
-
*
|
|
133
|
+
* Toggle-FOCUS a panel: reveal it and take focus, or — when it already has focus — collapse the
|
|
134
|
+
* dock hosting it and hand focus back to the pane. Deliberately not toggle-visible: ⌘1 pressed
|
|
135
|
+
* from the canvas must land you in Files, not close it.
|
|
136
136
|
*/
|
|
137
137
|
focusPanel: (panelId: string) => void;
|
|
138
138
|
/** Show an Inspector tab and focus the dock. `"assistant"` addresses the assistant dock. */
|
|
@@ -202,11 +202,11 @@ const structurallyEditable = (ctx: CommandContext) =>
|
|
|
202
202
|
/**
|
|
203
203
|
* The one sentence for {@link structurallyEditable}, read by Delete and Duplicate both.
|
|
204
204
|
*
|
|
205
|
-
* It names the gate the predicate actually has (§12.4's corollary): the old
|
|
206
|
-
* document root" and "has a sibling position" for a gate that also refuses
|
|
207
|
-
* and a `$switch` case, which sent a reader who had selected a template
|
|
208
|
-
* records with one predicate carry one sentence, because the tooltip, the
|
|
209
|
-
* assistant's refusal are all this string.
|
|
205
|
+
* It names the gate the predicate actually has (studio-ui-guidelines.md §12.4's corollary): the old
|
|
206
|
+
* sentences said "not the document root" and "has a sibling position" for a gate that also refuses
|
|
207
|
+
* a repeater's template and a `$switch` case, which sent a reader who had selected a template
|
|
208
|
+
* looking for a root. Two records with one predicate carry one sentence, because the tooltip, the
|
|
209
|
+
* palette subtitle and the assistant's refusal are all this string.
|
|
210
210
|
*/
|
|
211
211
|
const SPLICEABLE_SELECTION =
|
|
212
212
|
"an element selected on the canvas that has a sibling position: not the document root, a " +
|
|
@@ -278,7 +278,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
278
278
|
* the build keeps a command of its own rather than disappearing with the coupling.
|
|
279
279
|
*
|
|
280
280
|
* `commandbar/overflow` rather than `commandbar/primary`: the primary row is budgeted at five
|
|
281
|
-
* and is document-level by frequency (studio-ui-guidelines §12), and a build is neither
|
|
281
|
+
* and is document-level by frequency (studio-ui-guidelines.md §12), and a build is neither
|
|
282
282
|
* frequent nor about the document in front of you. No default chord for the same reason.
|
|
283
283
|
*/
|
|
284
284
|
id: "project.buildSite",
|
|
@@ -373,10 +373,11 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
373
373
|
enablement: (ctx) => structurallyEditable(ctx) && !ctx.selection.isRepeater,
|
|
374
374
|
requires: "an element with a sibling position that is not already a repeater",
|
|
375
375
|
/*
|
|
376
|
-
* No `aiTool`, by §12.4's second deletion rule: `run` waits on a
|
|
377
|
-
* collection, and a projected call would suspend the agent's
|
|
378
|
-
* the round as work; a cancel returns nothing a report could
|
|
379
|
-
* `collection` argument that skips the dialog would be the way back
|
|
376
|
+
* No `aiTool`, by studio-ui-guidelines.md §12.4's second deletion rule: `run` waits on a
|
|
377
|
+
* person. The dialog picks the collection, and a projected call would suspend the agent's
|
|
378
|
+
* turn on it while the loop counts the round as work; a cancel returns nothing a report could
|
|
379
|
+
* describe. A record with a `collection` argument that skips the dialog would be the way back
|
|
380
|
+
* in, and is a UX call.
|
|
380
381
|
*
|
|
381
382
|
* The one record here whose implementation is not injected, and the reason is a property of
|
|
382
383
|
* the implementation rather than of this record: `convertToRepeater()` is self-contained —
|
|
@@ -540,11 +541,11 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
540
541
|
/*
|
|
541
542
|
* The other half of multi-window, and the half that had no door.
|
|
542
543
|
*
|
|
543
|
-
* "Open a project ELSEWHERE" is reachable from Open Project and from Recents
|
|
544
|
-
* an EMPTY window" was reachable only from the ElectroBun
|
|
545
|
-
* — so on a launcher whose window has no menu bar,
|
|
546
|
-
* could not be run. Gated on the same capability
|
|
547
|
-
* with one window does not offer it.
|
|
544
|
+
* "Open a project ELSEWHERE" is reachable from Open Project and from Recents
|
|
545
|
+
* (desktop.md §4.2a); "open an EMPTY window" was reachable only from the ElectroBun
|
|
546
|
+
* launcher's native application menu — so on a launcher whose window has no menu bar,
|
|
547
|
+
* `newWindow` existed on the platform and could not be run. Gated on the same capability
|
|
548
|
+
* every other multi-window verb is, so a host with one window does not offer it.
|
|
548
549
|
*/
|
|
549
550
|
id: "view.newWindow",
|
|
550
551
|
title: "New Window",
|
|
@@ -559,7 +560,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
559
560
|
},
|
|
560
561
|
{
|
|
561
562
|
// The no-project palette stops being a hidden domain swap on `!projectState` and becomes a
|
|
562
|
-
// NAMED mode that works either way
|
|
563
|
+
// NAMED mode that works either way — same trigger, same chrome, stated feature.
|
|
563
564
|
id: "project.openRecent",
|
|
564
565
|
title: "Open Recent…",
|
|
565
566
|
category: "Project",
|
|
@@ -569,7 +570,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
569
570
|
run: () => deps.openPalette("projects"),
|
|
570
571
|
},
|
|
571
572
|
|
|
572
|
-
// ── Direct keys
|
|
573
|
+
// ── Direct keys ──
|
|
573
574
|
...panelFocusCommands(deps),
|
|
574
575
|
...inspectorFocusCommands(deps),
|
|
575
576
|
{
|
|
@@ -602,7 +603,7 @@ export function defaultCommands(deps: CommandDeps): AnyCommand[] {
|
|
|
602
603
|
* Generated rather than written out eight times for the reason the whole registry exists: the rail,
|
|
603
604
|
* the chord, the palette row and the generated shortcut sheet are then four renderings of one list.
|
|
604
605
|
* Only the first eight get a chord; a ninth panel keeps its name and its palette row, which is the
|
|
605
|
-
* cost §2
|
|
606
|
+
* cost studio-ui-guidelines.md §12.2 puts on chrome.
|
|
606
607
|
*/
|
|
607
608
|
export function panelFocusCommands(deps: CommandDeps): AnyCommand[] {
|
|
608
609
|
let chordsSpent = 0;
|
package/src/commands/levels.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Levels.ts — the containment taxonomy and the level × placement matrix.
|
|
3
3
|
*
|
|
4
|
-
* Two vocabularies live here, and keeping them apart is the whole point (
|
|
4
|
+
* Two vocabularies live here, and keeping them apart is the whole point (specs/studio.md
|
|
5
|
+
* §13.2–§13.3):
|
|
5
6
|
*
|
|
6
7
|
* - {@link Level} answers WHAT a record acts on. It governs placement and is CI-checked.
|
|
7
8
|
* - {@link KeyScope} answers WHERE a chord is live. It governs keyboard dispatch only.
|
|
@@ -150,9 +151,10 @@ export const PLACEMENT_MATRIX: Readonly<Record<Placement, PlacementRule>> = {
|
|
|
150
151
|
/**
|
|
151
152
|
* Every surface a Panel record may occupy.
|
|
152
153
|
*
|
|
153
|
-
* The rail's two level groups are SEPARATE placements, not one "mixed" region —
|
|
154
|
-
*
|
|
155
|
-
* prints that panel's level in its header,
|
|
154
|
+
* The rail's two level groups are SEPARATE placements, not one "mixed" region — the whole point of
|
|
155
|
+
* the level × placement matrix (studio-ui-guidelines.md §12.1). `navigator` is the dock body below
|
|
156
|
+
* them, which hosts whichever panel the rail selected and prints that panel's level in its header,
|
|
157
|
+
* so it is the one panel placement admitting two levels.
|
|
156
158
|
*/
|
|
157
159
|
export const PANEL_PLACEMENTS = [
|
|
158
160
|
"rail/project",
|
|
@@ -169,7 +171,7 @@ export type PanelPlacement = (typeof PANEL_PLACEMENTS)[number];
|
|
|
169
171
|
* `studio-ui-guidelines.md` §12 beside {@link PLACEMENT_MATRIX}.
|
|
170
172
|
*
|
|
171
173
|
* The rail rows are what stop it re-accreting: a panel cannot be filed in the PROJECT group because
|
|
172
|
-
* "it feels project-ish", only because the state it WRITES is the project's (
|
|
174
|
+
* "it feels project-ish", only because the state it WRITES is the project's (§13.2).
|
|
173
175
|
*/
|
|
174
176
|
export const PANEL_PLACEMENT_MATRIX: Readonly<Record<PanelPlacement, PlacementRule>> = {
|
|
175
177
|
"rail/project": {
|
|
@@ -215,7 +217,7 @@ function dockPlacement(dock: PlaceablePanel["dock"]): PanelPlacement {
|
|
|
215
217
|
* Every placement a Panel record occupies: its dock body, plus its rail group when it has a button.
|
|
216
218
|
*
|
|
217
219
|
* The rail group is DERIVED from the level rather than declared, which is what makes "grouped by
|
|
218
|
-
* level with a divider" (§
|
|
220
|
+
* level with a divider" (§5.1) a property of the data instead of an ordering convention in the
|
|
219
221
|
* rail's template. A rail panel whose level has no group (`application`, `selection`) therefore
|
|
220
222
|
* names a placement the matrix does not contain, and is rejected below.
|
|
221
223
|
*/
|
|
@@ -65,7 +65,7 @@ export function isTextEntryFocused(doc: Document = document): boolean {
|
|
|
65
65
|
export interface LiveContextSources {
|
|
66
66
|
/** `studio.ts`'s `getCanvasMode()` — the per-tab preview toggle already composed in. */
|
|
67
67
|
canvasMode: () => string;
|
|
68
|
-
/** `canvas/iframe-host.ts`'s bridge-derived caret flag (
|
|
68
|
+
/** `canvas/iframe-host.ts`'s bridge-derived caret flag (§10). */
|
|
69
69
|
isCaretActive: () => boolean;
|
|
70
70
|
/** `ui/layers.ts`'s `isModalOpen()`. */
|
|
71
71
|
isModalOpen: () => boolean;
|
|
@@ -74,8 +74,9 @@ export interface LiveContextSources {
|
|
|
74
74
|
/** Whether the assistant has usable credentials (`services/ai-models`). */
|
|
75
75
|
aiConfigured: () => boolean;
|
|
76
76
|
/**
|
|
77
|
-
* Whether
|
|
78
|
-
* private, so
|
|
77
|
+
* Whether an assistant turn is in flight, tools and questions included. `panels/ai-panel.ts`
|
|
78
|
+
* keeps its `DocumentAssistant` module-private, so the caller passes its probe
|
|
79
|
+
* (`isAssistantStreaming`).
|
|
79
80
|
*/
|
|
80
81
|
aiStreaming?: () => boolean;
|
|
81
82
|
/** Whether a turn is suspended on an `ask_user` question (`panels/ai-panel.ts`). */
|
|
@@ -93,6 +94,7 @@ function capabilities(platform: StudioPlatform | null): CommandContext["capabili
|
|
|
93
94
|
gitClone: has("gitClone"),
|
|
94
95
|
importSite: has("importSite"),
|
|
95
96
|
openProjectInNewWindow: has("openProjectInNewWindow"),
|
|
97
|
+
readFileBytes: has("readFileBytes"),
|
|
96
98
|
// Multi-window is a desktop-only family; `newWindow` is the one every member implies.
|
|
97
99
|
windowControls: has("newWindow"),
|
|
98
100
|
};
|
|
@@ -138,13 +140,13 @@ export function createLiveContext(sources: LiveContextSources): () => CommandCon
|
|
|
138
140
|
|
|
139
141
|
ctx.editor.kind = tab ? editorKindForMode(mode) : "none";
|
|
140
142
|
ctx.canvas.view = canvasViewForMode(mode);
|
|
141
|
-
/* The grid, counted from the grid. This read spent two phases saying
|
|
142
|
-
|
|
143
|
-
and through
|
|
144
|
-
FOCUSED pane's strip, so it could never answer 2 and
|
|
145
|
-
while a pane with no tab is still a pane. `derived` was
|
|
146
|
-
`services/automation.ts` publishes this whole record as
|
|
147
|
-
pipeline and the assistant were both reading it.
|
|
143
|
+
/* The grid, counted from the grid. This read spent two phases saying that until panes landed
|
|
144
|
+
the grid was one pane showing the focused tab — through the shell redesign's chrome phase,
|
|
145
|
+
which built the pane model, and through its panes phase, which gave every pane a live stage.
|
|
146
|
+
It counted `workspace.tabOrder`, the FOCUSED pane's strip, so it could never answer 2 and
|
|
147
|
+
answered 0 whenever no tab was open, while a pane with no tab is still a pane. `derived` was
|
|
148
|
+
declared and never assigned at all. `services/automation.ts` publishes this whole record as
|
|
149
|
+
`probe.state()`, so the screenshot pipeline and the assistant were both reading it.
|
|
148
150
|
|
|
149
151
|
`derived` is ASSIGNED now, and it means "the grid contains a derived pane" — the fact the two
|
|
150
152
|
predicates that need it actually ask. A third phase of a declared-never-assigned context key
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reference.ts — the registry, projected into the two generated documentation pages.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* `docs/studio/interface/shortcuts.md` and `docs/studio/interface/commands.md` are **generated from
|
|
5
|
+
* the registry at build time**, the last of the renderings §13 derives from it: with the chrome,
|
|
6
|
+
* the keymap, the palette, the menus and the automation surface all rendering the same records, a
|
|
7
|
+
* hand-maintained shortcut sheet is the only place left for the app's keyboard and its
|
|
8
|
+
* documentation to disagree.
|
|
9
9
|
*
|
|
10
10
|
* This module is the projection, not the generator. It takes a command set — `appCommandSet()`, the
|
|
11
11
|
* one bare-Bun-importable export the three CI checks already load — and returns ROWS plus the
|
package/src/commands/registry.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* default chord, and the surfaces it belongs in. Every surface — Command Bar, palette, rail,
|
|
7
7
|
* context menus, the block action bar, the keymap, `__jxAutomation` and the assistant's tools —
|
|
8
8
|
* becomes a RENDERING of these records. A surface may choose whether to show a command; it may
|
|
9
|
-
* never decide what it is called, when it is available, or what it does (
|
|
9
|
+
* never decide what it is called, when it is available, or what it does (§13).
|
|
10
10
|
*
|
|
11
11
|
* Four things fail loudly at registration rather than degrading into a surface disagreement:
|
|
12
12
|
*
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* `when` / `enablement` are `(ctx) => boolean` closures, modelled on the shipped
|
|
24
24
|
* `services/gated-registry.ts` `ToolAvailability`, and `requires` is ONE string with three
|
|
25
25
|
* consumers: the disabled control's tooltip, the palette row's grey subtitle and the agent's
|
|
26
|
-
* refusal message.
|
|
26
|
+
* refusal message. §13.1 rejects a serialisable string DSL; do not add one.
|
|
27
27
|
*
|
|
28
28
|
* The registry takes its context by injection (`getContext`), so nothing here imports a state
|
|
29
29
|
* module. That is what lets the CI checks import the command set in a bare Bun process and lets
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The draft axis (§7.6) — what a draft IS, and whether drafts are listed. One
|
|
2
|
+
* The draft axis (site-architecture.md §7.6) — what a draft IS, and whether drafts are listed. One
|
|
3
|
+
* place, every list.
|
|
3
4
|
*
|
|
4
5
|
* It is deliberately its own module rather than a field on a pane's state and rather than a section
|
|
5
6
|
* of `entry-model.ts`. Two reasons, and the second is why the definitions live here beside the
|
|
@@ -20,17 +21,17 @@
|
|
|
20
21
|
import { reactive } from "../reactivity";
|
|
21
22
|
import type { ContentTypeSchema } from "@jxsuite/schema/types";
|
|
22
23
|
|
|
23
|
-
/** The conventional
|
|
24
|
+
/** The conventional frontmatter boolean that marks an entry a draft (site-architecture.md §7.6). */
|
|
24
25
|
export const DRAFT_FIELD = "draft";
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* What a draft IS, in one sentence, for every surface that shows the pill.
|
|
28
29
|
*
|
|
29
|
-
* Deliberately does not say "excluded from production builds" —
|
|
30
|
-
* intent the build does not implement yet (`packages/compiler`'s `site/site-build.ts`
|
|
31
|
-
* beside `$sitemap`), and a badge that promises a file will not ship when it will is the
|
|
32
|
-
* class of confident-wrong statement §16 exists to end. When the compiler learns to drop
|
|
33
|
-
* this constant changes and every surface changes with it.
|
|
30
|
+
* Deliberately does not say "excluded from production builds" — site-architecture.md §7.6's bullet
|
|
31
|
+
* describes an intent the build does not implement yet (`packages/compiler`'s `site/site-build.ts`
|
|
32
|
+
* says so beside `$sitemap`), and a badge that promises a file will not ship when it will is the
|
|
33
|
+
* exact class of confident-wrong statement §16 exists to end. When the compiler learns to drop
|
|
34
|
+
* drafts, this constant changes and every surface changes with it.
|
|
34
35
|
*/
|
|
35
36
|
export const DRAFT_MEANING =
|
|
36
37
|
"Marked a draft. Studio filters drafts out of its own lists; the build does not exclude them yet.";
|
|
@@ -82,7 +83,7 @@ export function includingDrafts(): boolean {
|
|
|
82
83
|
*
|
|
83
84
|
* A setter, never a toggle: `content.setIncludeDrafts` names the STATE it reaches, so a manifest
|
|
84
85
|
* step, an assistant call and a checkbox all land on the same value however many times they run
|
|
85
|
-
* (
|
|
86
|
+
* (§13.5's idempotence rule, which `tests/app-commands.test.ts` enforces).
|
|
86
87
|
*
|
|
87
88
|
* Setting the flag is all this does. Repainting the lists that read it belongs to the command — see
|
|
88
89
|
* `content/entry-commands.ts` — because a data module may not reach into the workspace.
|