@jxsuite/studio 6.1.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/color-area-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/listbox-c421cf8c.js +4 -0
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/menu-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/studio-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/studio-bbe4c90a.js +5 -0
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/ws-client-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { activeTab } from "../workspace/workspace";
|
|
25
25
|
import { clearProblems, notify, problemFindings } from "./notify";
|
|
26
|
+
import type { NotifyOptions } from "./notify";
|
|
26
27
|
import {
|
|
27
28
|
findPopoverDefects,
|
|
28
29
|
popoverDisplayRepair,
|
|
@@ -39,7 +40,8 @@ import {
|
|
|
39
40
|
} from "../tabs/transact";
|
|
40
41
|
import { getNodeAtPath } from "../state";
|
|
41
42
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
42
|
-
import type {
|
|
43
|
+
import type { CommandArgValues } from "../commands/command-args";
|
|
44
|
+
import type { JxElement } from "@jxsuite/schema/types";
|
|
43
45
|
import type { JxPath } from "../state";
|
|
44
46
|
import type { PopoverFix, PopoverPath } from "@jxsuite/schema/overlays";
|
|
45
47
|
|
|
@@ -100,7 +102,7 @@ export function reportPopoverProblems(doc: JxElement, path?: string): number {
|
|
|
100
102
|
const defects = findPopoverDefects(doc, KIT_SCOPE);
|
|
101
103
|
for (const defect of defects) {
|
|
102
104
|
const action = defect.fix === undefined ? undefined : REPAIR_COMMAND[defect.fix];
|
|
103
|
-
|
|
105
|
+
const options: NotifyOptions = {
|
|
104
106
|
detail: defect.detail,
|
|
105
107
|
/* Keyed by RULE AND PATH, not by rule alone: a header with two popovers can carry the same
|
|
106
108
|
defect twice, and a key that collapsed them would report one and silently drop the other.
|
|
@@ -109,32 +111,45 @@ export function reportPopoverProblems(doc: JxElement, path?: string): number {
|
|
|
109
111
|
key: problemKey(seen, "popover", defect.rule, defect.path),
|
|
110
112
|
source: POPOVER_PROBLEM_SOURCE,
|
|
111
113
|
tier: "problem",
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
};
|
|
115
|
+
if (action !== undefined) {
|
|
116
|
+
options.action = action;
|
|
117
|
+
options.actionArgs = { path: defect.path };
|
|
118
|
+
}
|
|
119
|
+
if (path !== undefined) {
|
|
120
|
+
options.path = path;
|
|
121
|
+
}
|
|
122
|
+
notify(defect.severity, defect.message, options);
|
|
115
123
|
}
|
|
116
124
|
/* The dialog and invoker-command rules (`spec.md` §8.7) file under the same source: one report
|
|
117
125
|
for everything the platform overlays. They carry no repair button yet — the popover repairs
|
|
118
126
|
move `display` into `:popover-open`, and a dialog's open rule is a different selector. */
|
|
119
127
|
const dialogDefects = findDialogDefects(doc, KIT_SCOPE);
|
|
120
128
|
for (const defect of dialogDefects) {
|
|
121
|
-
|
|
129
|
+
const options: NotifyOptions = {
|
|
122
130
|
detail: defect.detail,
|
|
123
131
|
key: problemKey(seen, "dialog", defect.rule, defect.path),
|
|
124
132
|
source: POPOVER_PROBLEM_SOURCE,
|
|
125
133
|
tier: "problem",
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
};
|
|
135
|
+
if (path !== undefined) {
|
|
136
|
+
options.path = path;
|
|
137
|
+
}
|
|
138
|
+
notify(defect.severity, defect.message, options);
|
|
128
139
|
}
|
|
129
140
|
return defects.length + dialogDefects.length;
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
/** Read the path argument a repair command was invoked with, or throw naming the command. */
|
|
133
|
-
function repairPath(id: string, args:
|
|
144
|
+
function repairPath(id: string, args: CommandArgValues | undefined): JxPath {
|
|
134
145
|
const path = args?.path;
|
|
135
146
|
if (!Array.isArray(path)) {
|
|
136
147
|
throw new RangeError(`command "${id}" needs a "path" argument naming the popover`);
|
|
137
148
|
}
|
|
149
|
+
/* SAFETY: every repair record below declares `path` as an array whose items are
|
|
150
|
+
`["string", "number"]`, which `coerceArgs` reads as a path argument and checks segment by
|
|
151
|
+
segment (`pathArg`) before `run` is called — so an array that reached here holds only string
|
|
152
|
+
keys and numeric indexes. */
|
|
138
153
|
return path as JxPath;
|
|
139
154
|
}
|
|
140
155
|
|
|
@@ -217,7 +232,7 @@ export function popoverCommands(): AnyCommand[] {
|
|
|
217
232
|
const id = "document.repairPopoverDisplay";
|
|
218
233
|
const tab = repairTab(id);
|
|
219
234
|
const path = repairPath(id, args);
|
|
220
|
-
const node = getNodeAtPath(tab.doc.document, path)
|
|
235
|
+
const node = getNodeAtPath(tab.doc.document, path);
|
|
221
236
|
const repair = popoverDisplayRepair(node?.style);
|
|
222
237
|
if (!repair) {
|
|
223
238
|
throw new RangeError(`command "${id}": nothing to move — this popover sets no display`);
|
|
@@ -10,12 +10,15 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { evaluateExpression, isMutating } from "@jxsuite/runtime/expression";
|
|
13
|
+
import { isNonNullObject } from "@jxsuite/schema/guards";
|
|
13
14
|
import { toRaw } from "../reactivity";
|
|
14
15
|
// Imported for local use AND re-exported below so existing consumers keep their import site.
|
|
15
16
|
// oxlint-disable-next-line unicorn/prefer-export-from
|
|
16
17
|
import { formatPreviewValue } from "../utils/preview-format";
|
|
18
|
+
import type { PreviewValue } from "../utils/preview-format";
|
|
17
19
|
|
|
18
|
-
import type {
|
|
20
|
+
import type { JxScope } from "@jxsuite/runtime/types";
|
|
21
|
+
import type { JxExpressionNode, JxExpressionOperand } from "@jxsuite/schema/types";
|
|
19
22
|
|
|
20
23
|
export interface ExpressionPreview {
|
|
21
24
|
/** Path-keyed display values: "" is the root node, "value/target" a nested operand, etc. */
|
|
@@ -36,14 +39,14 @@ export { formatPreviewValue };
|
|
|
36
39
|
* (canvas not yet rendered) — the editor renders no badges rather than wrong ones.
|
|
37
40
|
*/
|
|
38
41
|
export function previewExpression(
|
|
39
|
-
node:
|
|
40
|
-
scope?:
|
|
42
|
+
node: JxExpressionOperand | undefined,
|
|
43
|
+
scope?: JxScope | null,
|
|
41
44
|
): ExpressionPreview | null {
|
|
42
|
-
if (!scope || !node ||
|
|
45
|
+
if (!scope || !isNonNullObject(node) || !("operator" in node)) {
|
|
43
46
|
return null;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
let state:
|
|
49
|
+
let state: JxScope;
|
|
47
50
|
try {
|
|
48
51
|
// Callers hand over tab.session.canvas.scope, which the reactive session tree wraps in a
|
|
49
52
|
// Proxy — structuredClone rejects proxies, so unwrap to the raw snapshot first.
|
|
@@ -54,11 +57,20 @@ export function previewExpression(
|
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
const values = new Map<string, string>();
|
|
57
|
-
|
|
60
|
+
/* SAFETY: an operand object carrying `operator` is the expression-node member of the operand
|
|
61
|
+
union (the plain-object member is an options bag, which has no operator), and a node whose
|
|
62
|
+
other members are malformed throws inside `evaluateExpression`, which this preview reports
|
|
63
|
+
as its `error` rather than trusting. */
|
|
64
|
+
const expr = node as JxExpressionNode;
|
|
58
65
|
let errorMessage: string | null = null;
|
|
59
66
|
try {
|
|
60
|
-
evaluateExpression(expr, state, null, undefined, {
|
|
61
|
-
report: (path, value) =>
|
|
67
|
+
void evaluateExpression(expr, state, null, undefined, {
|
|
68
|
+
report: (path, value) => {
|
|
69
|
+
/* SAFETY: the trace reports raw runtime values, and PreviewValue names every category a JS
|
|
70
|
+
value falls in (primitive, bigint, symbol, function, array, record); formatting relies on
|
|
71
|
+
nothing beyond what JSON.stringify and String() accept for any value. */
|
|
72
|
+
values.set(path.join("/"), formatPreviewValue(value as PreviewValue));
|
|
73
|
+
},
|
|
62
74
|
});
|
|
63
75
|
} catch (error) {
|
|
64
76
|
errorMessage = error instanceof Error ? error.message : String(error);
|
package/src/services/profile.ts
CHANGED
|
@@ -40,7 +40,7 @@ export interface StartupProfile {
|
|
|
40
40
|
* `default` is not a no-op by omission — it is a named state, so "the app started normally" and
|
|
41
41
|
* "the profile was unrecognised" are different outcomes and the second one is loud.
|
|
42
42
|
*/
|
|
43
|
-
export const STARTUP_PROFILES
|
|
43
|
+
export const STARTUP_PROFILES = {
|
|
44
44
|
default: {
|
|
45
45
|
description: "Resume whatever was persisted — layout, recents, settings, chat history.",
|
|
46
46
|
id: "default",
|
|
@@ -51,7 +51,10 @@ export const STARTUP_PROFILES: Readonly<Record<string, StartupProfile>> = {
|
|
|
51
51
|
id: "fresh",
|
|
52
52
|
reset: "app-state",
|
|
53
53
|
},
|
|
54
|
-
}
|
|
54
|
+
} satisfies Readonly<Record<string, StartupProfile>>;
|
|
55
|
+
|
|
56
|
+
/** {@link STARTUP_PROFILES} by id, for a lookup whose id arrives from the query string. */
|
|
57
|
+
const PROFILES_BY_ID = new Map<string, StartupProfile>(Object.entries(STARTUP_PROFILES));
|
|
55
58
|
|
|
56
59
|
export const DEFAULT_PROFILE_ID = "default";
|
|
57
60
|
|
|
@@ -77,7 +80,8 @@ export function isStudioStorageKey(key: string): boolean {
|
|
|
77
80
|
* @returns The keys removed, so a caller (Preferences, a test) can report what it did.
|
|
78
81
|
*/
|
|
79
82
|
export function clearStudioStorage(): string[] {
|
|
80
|
-
|
|
83
|
+
// `localStorage` is absent outside a browser realm (Bun without a DOM shim), whatever lib.dom says.
|
|
84
|
+
const store = typeof localStorage === "undefined" ? undefined : localStorage;
|
|
81
85
|
if (!store) {
|
|
82
86
|
return [];
|
|
83
87
|
}
|
|
@@ -105,10 +109,10 @@ export function clearStudioStorage(): string[] {
|
|
|
105
109
|
* `default` would start the app in the state the caller was trying to avoid.
|
|
106
110
|
*/
|
|
107
111
|
export function applyProfile(id: string): StartupProfile {
|
|
108
|
-
const profile =
|
|
112
|
+
const profile = PROFILES_BY_ID.get(id);
|
|
109
113
|
if (!profile) {
|
|
110
114
|
throw new RangeError(
|
|
111
|
-
`unknown startup profile "${id}"; declared: ${
|
|
115
|
+
`unknown startup profile "${id}"; declared: ${[...PROFILES_BY_ID.keys()].join(", ")}`,
|
|
112
116
|
);
|
|
113
117
|
}
|
|
114
118
|
if (profile.reset === "app-state") {
|
|
@@ -137,7 +141,10 @@ export function applyStartupProfile(search?: string): StartupState {
|
|
|
137
141
|
if (_startup) {
|
|
138
142
|
return _startup;
|
|
139
143
|
}
|
|
140
|
-
|
|
144
|
+
// `location` is absent outside a browser realm, which is why the tests pass `search` themselves.
|
|
145
|
+
const query = new URLSearchParams(
|
|
146
|
+
search ?? (typeof location === "undefined" ? "" : location.search),
|
|
147
|
+
);
|
|
141
148
|
const profile = applyProfile(query.get("profile") ?? DEFAULT_PROFILE_ID);
|
|
142
149
|
const clockParam = query.get("clock");
|
|
143
150
|
_startup = { clock: clockParam === null ? null : pinClock(clockParam), profile };
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
* Project-path.ts — the containment check the assistant's file tools run before they touch disk.
|
|
3
3
|
*
|
|
4
4
|
* `ai.md` §4: a file tool refuses a path outside the open project itself, rather than leaving the
|
|
5
|
-
* server to. `list_files`, `read_file` and `write_file` always refused one; `create_component`
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* server to. `list_files`, `read_file` and `write_file` always refused one; `create_component` and
|
|
6
|
+
* `create_page` took the model's path as given and handed it to the platform write. One module, so
|
|
7
|
+
* the two sets of tools cannot disagree about what "inside the project" means, and a leaf, because
|
|
8
|
+
* the document tools and the project tools already import each other's neighbours.
|
|
9
9
|
*
|
|
10
|
-
* @docs studio/ai/chat
|
|
11
10
|
* @license MIT
|
|
11
|
+
* @docs studio/ai/chat
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
15
|
+
import type { JsonValue } from "@jxsuite/schema/types";
|
|
14
16
|
import type { ToolResult } from "@jxsuite/ai/tools";
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -18,11 +20,12 @@ import type { ToolResult } from "@jxsuite/ai/tools";
|
|
|
18
20
|
* `..` segments, drive letters, a home directory). The server re-checks; this keeps the error
|
|
19
21
|
* actionable.
|
|
20
22
|
*
|
|
21
|
-
* @param {
|
|
23
|
+
* @param {JsonValue | undefined} path A tool argument as the model sent it — any JSON value, or
|
|
24
|
+
* absent.
|
|
22
25
|
* @returns {string | null}
|
|
23
26
|
*/
|
|
24
|
-
export function normalizeRelPath(path:
|
|
25
|
-
if (
|
|
27
|
+
export function normalizeRelPath(path: JsonValue | undefined): string | null {
|
|
28
|
+
if (!isString(path) || !path.trim()) {
|
|
26
29
|
return null;
|
|
27
30
|
}
|
|
28
31
|
let p = path.trim().replaceAll("\\", "/");
|
|
@@ -42,10 +45,10 @@ export function normalizeRelPath(path: unknown): string | null {
|
|
|
42
45
|
* The refusal a tool returns for a path {@link normalizeRelPath} rejected, quoting what the model
|
|
43
46
|
* sent so it can see what to change.
|
|
44
47
|
*
|
|
45
|
-
* @param {
|
|
48
|
+
* @param {JsonValue | undefined} path The tool argument as the model sent it.
|
|
46
49
|
* @returns {ToolResult}
|
|
47
50
|
*/
|
|
48
|
-
export function invalidPathResult(path:
|
|
51
|
+
export function invalidPathResult(path: JsonValue | undefined): ToolResult {
|
|
49
52
|
return {
|
|
50
53
|
success: false,
|
|
51
54
|
error: `Invalid path ${JSON.stringify(path)} — use a path relative to the project root (no leading "/", no "..").`,
|
|
Binary file
|
|
@@ -3,27 +3,36 @@
|
|
|
3
3
|
*
|
|
4
4
|
* After a mutation passes schema validation, this module attempts a lightweight headless render
|
|
5
5
|
* (buildScope → renderNode into a throwaway div) and reports render-time errors back through the
|
|
6
|
-
* same { ok, error } shape that applyAndValidate consumes. The model can then self-correct
|
|
7
|
-
*
|
|
6
|
+
* same { ok, error } shape that applyAndValidate consumes. The model can then self-correct within
|
|
7
|
+
* the round budget instead of the user discovering a blank canvas.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* V1 scope: catches render throws only (missing $ref, malformed Function body, bad template
|
|
10
10
|
* expressions). Does NOT detect empty/zero-node output or deep-render custom element internals
|
|
11
11
|
* (connectedCallback doesn't fire on detached nodes).
|
|
12
12
|
*
|
|
13
13
|
* @license MIT
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
buildScope,
|
|
18
|
+
renderNode,
|
|
19
|
+
runScoped,
|
|
20
|
+
setResolveToken,
|
|
21
|
+
setSkipServerFunctions,
|
|
22
|
+
setTemplateErrorHandler,
|
|
23
|
+
} from "@jxsuite/runtime";
|
|
17
24
|
import type { JxDocument } from "@jxsuite/schema/types";
|
|
25
|
+
import { hostResolveToken } from "../canvas/canvas-origin";
|
|
18
26
|
|
|
19
27
|
/**
|
|
20
28
|
* Translate a render-time error into an actionable message the model can fix.
|
|
21
29
|
*
|
|
22
|
-
* @param {
|
|
30
|
+
* @param {unknown} cause What the render threw — an Error in practice; anything else is printed
|
|
31
|
+
* as-is.
|
|
23
32
|
* @returns {string}
|
|
24
33
|
*/
|
|
25
|
-
function translateRenderError(
|
|
26
|
-
const msg =
|
|
34
|
+
function translateRenderError(cause: unknown): string {
|
|
35
|
+
const msg = (cause instanceof Error && cause.message) || String(cause);
|
|
27
36
|
|
|
28
37
|
if (msg.includes("is not defined") || msg.includes("Cannot read properties of")) {
|
|
29
38
|
return `Render error: ${msg}\n → Fix: A $ref or template expression references a name that doesn't exist in state. Check that all $ref paths and \${...} expressions match entries in the document's "state" object.`;
|
|
@@ -51,8 +60,17 @@ export async function renderCheck(
|
|
|
51
60
|
doc: JxDocument,
|
|
52
61
|
): Promise<{ ok: true } | { ok: false; error: string }> {
|
|
53
62
|
let stopRender: (() => void) | null = null;
|
|
63
|
+
/* A binding that throws no longer unwinds the render (spec.md §6.1) — it renders empty and waits
|
|
64
|
+
for its data — so the throw is collected here instead. The first one is the verdict: a page
|
|
65
|
+
whose template can never evaluate is exactly what this check exists to refuse. */
|
|
66
|
+
const bindingErrors: Error[] = [];
|
|
67
|
+
setTemplateErrorHandler((error) => {
|
|
68
|
+
bindingErrors.push(error);
|
|
69
|
+
});
|
|
54
70
|
try {
|
|
55
71
|
setSkipServerFunctions(true);
|
|
72
|
+
// The desktop dev proxy refuses a class resolve without the token the canvas carries.
|
|
73
|
+
setResolveToken(hostResolveToken());
|
|
56
74
|
|
|
57
75
|
const state = await buildScope(doc, {});
|
|
58
76
|
|
|
@@ -62,10 +80,12 @@ export async function renderCheck(
|
|
|
62
80
|
});
|
|
63
81
|
stopRender = stop;
|
|
64
82
|
|
|
65
|
-
|
|
83
|
+
const [first] = bindingErrors;
|
|
84
|
+
return first ? { ok: false, error: translateRenderError(first) } : { ok: true };
|
|
66
85
|
} catch (error) {
|
|
67
|
-
return { ok: false, error: translateRenderError(error
|
|
86
|
+
return { ok: false, error: translateRenderError(error) };
|
|
68
87
|
} finally {
|
|
88
|
+
setTemplateErrorHandler(null);
|
|
69
89
|
// Dispose all effects created synchronously by renderNode via the RUNTIME's runScoped — scope
|
|
70
90
|
// Collection is per @vue/reactivity module instance, so a studio effectScope here would collect
|
|
71
91
|
// Nothing. Effects from the async buildScope (prototype/computed setup) still escape the scope;
|
|
@@ -2,23 +2,23 @@
|
|
|
2
2
|
* The settings registry — every application setting Studio holds, declared once.
|
|
3
3
|
*
|
|
4
4
|
* Before this table the answer to "which settings roam, and what is each one's default" lived in
|
|
5
|
-
* four places: a `PERSISTED_SETTINGS_KEYS` array, a private `const` per key in each
|
|
6
|
-
* a bespoke getter/setter pair beside it, and whatever the getter's `||` happened
|
|
7
|
-
* Adding a roaming setting meant editing all four and hoping; the key strings
|
|
8
|
-
* duplicated between the array and the module that owned them.
|
|
5
|
+
* four places: a `PERSISTED_SETTINGS_KEYS` array, a private `const` per key in each
|
|
6
|
+
* `*-settings.ts`, a bespoke getter/setter pair beside it, and whatever the getter's `||` happened
|
|
7
|
+
* to fall back to. Adding a roaming setting meant editing all four and hoping; the key strings
|
|
8
|
+
* themselves were duplicated between the array and the module that owned them.
|
|
9
9
|
*
|
|
10
10
|
* Two properties of this table are load-bearing rather than tidy:
|
|
11
11
|
*
|
|
12
|
-
* 1.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* 2.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
12
|
+
* 1. **Scope is declared, not inferred.** {@link USER_SETTINGS} is DERIVED from it, so a setting roams
|
|
13
|
+
* because it says `scope: "user"` — not because someone remembered to add its key to a second
|
|
14
|
+
* list. `device` is the honest name for the rest: panel geometry and a palette's MRU describe
|
|
15
|
+
* _this window_, and a user with two windows open wants them to differ.
|
|
16
|
+
* 2. **A default is not a value.** The default is what a _reader_ sees when nothing is stored; it is
|
|
17
|
+
* never itself stored. `getModel()` used to mask unset as `"gpt-4o"` with `||`, a form prefilled
|
|
18
|
+
* from it, and Save wrote the mask back — which is how an install whose owner had configured an
|
|
19
|
+
* entirely different provider was left holding `jx.ai.model: "gpt-4o"` and nothing else.
|
|
20
|
+
* {@link readSetting} and {@link readStoredSetting} in `kernel.ts` are two functions for exactly
|
|
21
|
+
* this reason.
|
|
22
22
|
*
|
|
23
23
|
* @license MIT
|
|
24
24
|
*/
|
|
@@ -144,6 +144,17 @@ export const SETTINGS = {
|
|
|
144
144
|
normalize: trimmed,
|
|
145
145
|
scope: "user",
|
|
146
146
|
},
|
|
147
|
+
/**
|
|
148
|
+
* Whether the Design rail draws the developer panels — Files and Packages (`specs/studio.md`
|
|
149
|
+
* §5.1). Unset, the default, keeps them off the rail; `settings/developer-panels.ts` reads it.
|
|
150
|
+
* Roams, for the reason `showIgnoredFiles` does: it is a way of working, not a window's.
|
|
151
|
+
*/
|
|
152
|
+
developerPanels: {
|
|
153
|
+
default: "",
|
|
154
|
+
key: "jx.panels.developer",
|
|
155
|
+
normalize: trimmed,
|
|
156
|
+
scope: "user",
|
|
157
|
+
},
|
|
147
158
|
cfAccountId: {
|
|
148
159
|
default: "",
|
|
149
160
|
key: "jx.cf.accountId",
|
|
@@ -35,13 +35,22 @@ import type { SettingsPatch } from "./write-queue";
|
|
|
35
35
|
/** The synchronous source of truth. Absent key means unset — which is not the same as `""`. */
|
|
36
36
|
const values = new Map<string, string>();
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* The cache, when this realm has one. `lib.dom` declares `localStorage` unconditionally, but a
|
|
40
|
+
* realm without a DOM (Bun under test, a worker) has none — so it is looked up on every use, inside
|
|
41
|
+
* the caller's `try`, where an access that throws (storage disabled) is already handled.
|
|
42
|
+
*/
|
|
43
|
+
function cacheStorage(): Storage | undefined {
|
|
44
|
+
return typeof localStorage === "undefined" ? undefined : localStorage;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
/** Mirror a value into the cache, so the next boot is correct before the backend answers. */
|
|
39
48
|
function writeCache(key: string, value: string | null): void {
|
|
40
49
|
try {
|
|
41
50
|
if (value === null) {
|
|
42
|
-
|
|
51
|
+
cacheStorage()?.removeItem(key);
|
|
43
52
|
} else {
|
|
44
|
-
|
|
53
|
+
cacheStorage()?.setItem(key, value);
|
|
45
54
|
}
|
|
46
55
|
} catch {
|
|
47
56
|
/* Storage unavailable (private mode) — the Map still serves this session. */
|
|
@@ -60,7 +69,7 @@ function writeCache(key: string, value: string | null): void {
|
|
|
60
69
|
*/
|
|
61
70
|
try {
|
|
62
71
|
for (const definition of ALL_SETTINGS) {
|
|
63
|
-
const cached =
|
|
72
|
+
const cached = cacheStorage()?.getItem(definition.key);
|
|
64
73
|
if (cached !== null && cached !== undefined) {
|
|
65
74
|
values.set(definition.key, cached);
|
|
66
75
|
}
|
|
@@ -120,7 +129,7 @@ function announce(keys: readonly string[]): void {
|
|
|
120
129
|
// ─── Writing ──────────────────────────────────────────────────────────────────
|
|
121
130
|
|
|
122
131
|
const queue = createWriteQueue({
|
|
123
|
-
onError(error
|
|
132
|
+
onError(error) {
|
|
124
133
|
notify("error", "Your settings could not be saved.", {
|
|
125
134
|
detail: error instanceof Error ? error.message : String(error),
|
|
126
135
|
key: "settings-write",
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
* A coalescing, serializing write queue.
|
|
3
3
|
*
|
|
4
4
|
* The defect it exists to make unrepresentable: saving a provider mutates three settings through
|
|
5
|
-
* three setters, and each setter used to fire its own whole-map write. Three overlapping writes
|
|
6
|
-
* out against one file, each reading storage at a different moment, with no ordering between
|
|
7
|
-
* so whichever landed last won. That was observed in the wild as a settings file holding
|
|
5
|
+
* three setters, and each setter used to fire its own whole-map write. Three overlapping writes
|
|
6
|
+
* went out against one file, each reading storage at a different moment, with no ordering between
|
|
7
|
+
* them — so whichever landed last won. That was observed in the wild as a settings file holding
|
|
8
8
|
* `{"jx.ai.model": "gpt-4o"}`: the SECOND of three snapshots, landing last, a state storage itself
|
|
9
9
|
* never rested in.
|
|
10
10
|
*
|
|
11
11
|
* Two rules, and they are different guarantees:
|
|
12
12
|
*
|
|
13
|
-
* 1.
|
|
14
|
-
*
|
|
15
|
-
* 2.
|
|
16
|
-
*
|
|
13
|
+
* 1. **Coalesce.** Every mutation in one synchronous burst merges into a single patch, sent once the
|
|
14
|
+
* burst has finished. N setters produce one write, not N.
|
|
15
|
+
* 2. **Serialize.** At most one send is in flight. A mutation made while one is out waits for it
|
|
16
|
+
* rather than racing it, so the order the app made changes in is the order the store sees them.
|
|
17
17
|
*
|
|
18
18
|
* Generic over the transport so the kernel can hand it a platform call and a test can hand it an
|
|
19
19
|
* array. `schedule` is injectable for the same reason.
|
|
@@ -34,7 +34,7 @@ export interface WriteQueueOptions {
|
|
|
34
34
|
/** Deliver one merged patch. Rejection is reported through {@link WriteQueueOptions.onError}. */
|
|
35
35
|
send: (patch: SettingsPatch) => Promise<void>;
|
|
36
36
|
/** Called with the failure and the patch that did not land. */
|
|
37
|
-
onError?: (
|
|
37
|
+
onError?: (cause: unknown, patch: SettingsPatch) => void;
|
|
38
38
|
/**
|
|
39
39
|
* Defer to the end of the current burst. Defaults to `queueMicrotask`.
|
|
40
40
|
*
|
|
@@ -89,7 +89,7 @@ export function createWriteQueue(opts: WriteQueueOptions): WriteQueue {
|
|
|
89
89
|
}
|
|
90
90
|
tail = tail
|
|
91
91
|
.then(() => opts.send(patch))
|
|
92
|
-
.catch((error
|
|
92
|
+
.catch((error) => {
|
|
93
93
|
opts.onError?.(error, patch);
|
|
94
94
|
});
|
|
95
95
|
return tail;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
9
|
-
import { displayTagName } from "@jxsuite/schema/guards";
|
|
9
|
+
import { displayTagName, isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
10
10
|
|
|
11
11
|
interface TokenLintFinding {
|
|
12
12
|
path: string;
|
|
@@ -25,7 +25,8 @@ interface TokenLintFinding {
|
|
|
25
25
|
function buildTokenIndex(projectStyle: Record<string, string>) {
|
|
26
26
|
const index = new Map<string, string>();
|
|
27
27
|
for (const [key, value] of Object.entries(projectStyle)) {
|
|
28
|
-
|
|
28
|
+
// The style object comes from `project.json`, where a key can also hold a nested block.
|
|
29
|
+
if (!key.startsWith("--") || !isString(value)) {
|
|
29
30
|
continue;
|
|
30
31
|
}
|
|
31
32
|
const norm = value.toLowerCase().trim();
|
|
@@ -43,7 +44,7 @@ function buildTokenIndex(projectStyle: Record<string, string>) {
|
|
|
43
44
|
* @returns {boolean}
|
|
44
45
|
*/
|
|
45
46
|
function isTokenRef(value: string) {
|
|
46
|
-
return
|
|
47
|
+
return value.includes("var(--");
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
@@ -53,7 +54,7 @@ function isTokenRef(value: string) {
|
|
|
53
54
|
* @returns {boolean}
|
|
54
55
|
*/
|
|
55
56
|
function isTemplate(value: string) {
|
|
56
|
-
return
|
|
57
|
+
return value.includes("${");
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
@@ -78,18 +79,19 @@ export function flagHardcodedTokens(
|
|
|
78
79
|
|
|
79
80
|
const findings: TokenLintFinding[] = [];
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
/* Every member is re-checked rather than trusted: callers hand over model output parsed from
|
|
83
|
+
JSON, so a "node" may be a primitive, a `style` may be a string, and a child may be anything. */
|
|
84
|
+
function walk(el: JxMutableNode, pathPrefix: string) {
|
|
85
|
+
if (!isNonNullObject(el)) {
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
85
|
-
const el = node as JxMutableNode;
|
|
86
88
|
|
|
87
|
-
if (el.style
|
|
89
|
+
if (isNonNullObject(el.style)) {
|
|
88
90
|
for (const [prop, val] of Object.entries(el.style)) {
|
|
89
91
|
if (prop.startsWith("@")) {
|
|
90
92
|
continue;
|
|
91
93
|
}
|
|
92
|
-
if (
|
|
94
|
+
if (!isString(val)) {
|
|
93
95
|
continue;
|
|
94
96
|
}
|
|
95
97
|
if (isTokenRef(val) || isTemplate(val)) {
|
|
@@ -112,7 +114,7 @@ export function flagHardcodedTokens(
|
|
|
112
114
|
if (Array.isArray(el.children)) {
|
|
113
115
|
for (let i = 0; i < el.children.length; i++) {
|
|
114
116
|
const child = el.children[i];
|
|
115
|
-
if (child
|
|
117
|
+
if (isNonNullObject(child)) {
|
|
116
118
|
walk(child, `${pathPrefix} > ${displayTagName(child.tagName) || `[${i}]`}`);
|
|
117
119
|
}
|
|
118
120
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
import type { createChatState } from "@jxsuite/ai/chat-state";
|
|
22
22
|
import { DEFAULT_TURN_POLICY, runTurn } from "@jxsuite/ai/harness";
|
|
23
|
-
import type { TurnRun } from "@jxsuite/ai/harness";
|
|
23
|
+
import type { TurnInput, TurnRun } from "@jxsuite/ai/harness";
|
|
24
24
|
import { toChatMessages, toOpenAITools } from "@jxsuite/ai/messages";
|
|
25
25
|
import type { StreamingClient } from "@jxsuite/ai/streaming-client";
|
|
26
26
|
import { createSessionFacts } from "@jxsuite/ai/tools";
|
|
@@ -36,6 +36,9 @@ import { studioTurnHooks } from "./harness/turn-hooks";
|
|
|
36
36
|
/** What a turn that drew nothing says: the model answered with neither text nor a tool call. */
|
|
37
37
|
export const EMPTY_TURN_TEXT = DEFAULT_TURN_POLICY.emptyText;
|
|
38
38
|
|
|
39
|
+
/** {@link TurnInput} while this module assembles it: read-only to `runTurn`, not to its builder. */
|
|
40
|
+
type TurnInputDraft = { -readonly [K in keyof TurnInput]: TurnInput[K] };
|
|
41
|
+
|
|
39
42
|
interface RunAgentLoopOptions {
|
|
40
43
|
chatState: ReturnType<typeof createChatState>;
|
|
41
44
|
streamingClient: StreamingClient;
|
|
@@ -94,7 +97,7 @@ export async function runAgentLoop({
|
|
|
94
97
|
let superseded = false;
|
|
95
98
|
let run: TurnRun | undefined;
|
|
96
99
|
try {
|
|
97
|
-
|
|
100
|
+
const input: TurnInputDraft = {
|
|
98
101
|
history,
|
|
99
102
|
system: [{ text: systemPrompt }],
|
|
100
103
|
/* Projected from the chat store, the transcript of record. The streaming client is read on
|
|
@@ -104,13 +107,15 @@ export async function runAgentLoop({
|
|
|
104
107
|
chatState.toMessagesArray(),
|
|
105
108
|
toOpenAITools(request.tools),
|
|
106
109
|
systemPrompt,
|
|
110
|
+
/* SAFETY: the one production caller, `document-assistant.ts`, always passes its turn
|
|
111
|
+
controller's signal; only tests that drive the loop directly omit it, and their stream
|
|
112
|
+
doubles record the absent signal rather than reading it — which the agent-trace
|
|
113
|
+
goldens (`signal: "none"`) pin. */
|
|
107
114
|
signal as AbortSignal,
|
|
108
115
|
),
|
|
109
116
|
modelInfo: { family: "openai-compat", model: chatState.model },
|
|
110
117
|
tools: toolRegistry,
|
|
111
|
-
...(signal ? { signal } : {}),
|
|
112
118
|
turnId: ledger.turnId,
|
|
113
|
-
...(placeholder ? { firstMessageId: placeholder.id } : {}),
|
|
114
119
|
policy: { estimateTokens: estimatePromptTokens },
|
|
115
120
|
hooks: studioTurnHooks({
|
|
116
121
|
superseded: () =>
|
|
@@ -128,7 +133,14 @@ export async function runAgentLoop({
|
|
|
128
133
|
applyHarnessEvent(chatState, event);
|
|
129
134
|
}
|
|
130
135
|
},
|
|
131
|
-
}
|
|
136
|
+
};
|
|
137
|
+
if (signal) {
|
|
138
|
+
input.signal = signal;
|
|
139
|
+
}
|
|
140
|
+
if (placeholder) {
|
|
141
|
+
input.firstMessageId = placeholder.id;
|
|
142
|
+
}
|
|
143
|
+
run = runTurn(input);
|
|
132
144
|
await run.outcome;
|
|
133
145
|
} finally {
|
|
134
146
|
endBatch();
|