@jxsuite/studio 6.1.0 → 6.1.2
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/dist/chunks/2020-f2gkpy8d.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-5g0ag7c0.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-pxg4ap1e.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-qbj760tx.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-anyrgzvb.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-v2bvmbjj.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-txjjzrsm.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-cpxkgjrj.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/studio-y64hrt8p.js +12 -0
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -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-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/tsMode-sf49ee9x.js +14 -0
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +98 -98
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +11 -11
- 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/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +66 -42
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +163 -64
- 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 +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +203 -118
- package/src/canvas/iframe-inline-edit.ts +69 -32
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +37 -26
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +15 -16
- package/src/canvas/iframe-render.ts +41 -36
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- 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/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -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/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/defaults.ts +4 -1
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +10 -8
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- 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 +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +87 -47
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +6 -1
- package/src/files/serialize-document.ts +2 -2
- 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 +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- 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 +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- 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 +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- 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 +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- 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 +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +55 -22
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +254 -216
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +174 -127
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- 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 +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- 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 +18 -12
- 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 +8 -7
- 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 +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +39 -77
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- 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.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- 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/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- 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/git-panel.ts +7 -15
- 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.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +25 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -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.ts +5 -6
- 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.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -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.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +126 -73
- package/src/surfaces/rail.ts +38 -12
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- 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.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- 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 +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/tabs/typing.ts +31 -0
- package/src/types.ts +32 -17
- 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 +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- 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 +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +103 -74
- 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/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 +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +47 -36
- package/dist/chunks/2020-nkxms0ay.js +0 -4
- package/dist/chunks/adapter-m948ab5f.js +0 -4
- package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
- package/dist/chunks/cf-settings-356xdtne.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-yk3t844e.js +0 -4
- package/dist/chunks/content-source-bawmyc09.js +0 -4
- package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-6sc8nacq.js +0 -4
- package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
- package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
- package/dist/chunks/file-ops-gye0qw56.js +0 -4
- package/dist/chunks/files-dmc2xvcq.js +0 -4
- package/dist/chunks/format-host-t76b53f8.js +0 -4
- package/dist/chunks/fs-events-cg4tpz06.js +0 -4
- package/dist/chunks/git-panel-yef7bshy.js +0 -4
- package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
- package/dist/chunks/icons-qbh8akb1.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-tmz30gfp.js +0 -4
- package/dist/chunks/index-nag78a9h.js +0 -4
- package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
- package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
- package/dist/chunks/layers-fvz99859.js +0 -4
- package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-9agdspkt.js +0 -4
- package/dist/chunks/media-picker-rhjvyy00.js +0 -4
- package/dist/chunks/menu-2e4y9j7b.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
- package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
- package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
- package/dist/chunks/notify-h3www560.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-hz34wcd7.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
- package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
- package/dist/chunks/references-2cgdxnb8.js +0 -4
- package/dist/chunks/right-panel-jf856w5w.js +0 -4
- package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0f55h9ye.js +0 -5
- package/dist/chunks/studio-0sqdhnew.js +0 -12
- package/dist/chunks/studio-19x1c75w.js +0 -5
- package/dist/chunks/studio-2sqcndak.js +0 -5
- package/dist/chunks/studio-3aey7dd3.js +0 -5
- package/dist/chunks/studio-3bpdkq2s.js +0 -5
- package/dist/chunks/studio-47y6fbpf.js +0 -5
- package/dist/chunks/studio-4m3826v2.js +0 -5
- package/dist/chunks/studio-4nx2dj1g.js +0 -4
- package/dist/chunks/studio-4xv5s47r.js +0 -9
- package/dist/chunks/studio-5g4t8v6w.js +0 -5
- package/dist/chunks/studio-5py436sf.js +0 -5
- package/dist/chunks/studio-77kt594t.js +0 -5
- package/dist/chunks/studio-8f87n763.js +0 -10
- package/dist/chunks/studio-8mb00b84.js +0 -5
- package/dist/chunks/studio-8p51gq2h.js +0 -6
- package/dist/chunks/studio-954ds834.js +0 -5
- package/dist/chunks/studio-9ft45c83.js +0 -9
- package/dist/chunks/studio-a2138x5k.js +0 -7
- package/dist/chunks/studio-a9yzstqj.js +0 -5
- package/dist/chunks/studio-acdksxx6.js +0 -5
- package/dist/chunks/studio-ar8jcf2y.js +0 -5
- package/dist/chunks/studio-bmn4mn9j.js +0 -7
- package/dist/chunks/studio-e7xxa0sj.js +0 -5
- package/dist/chunks/studio-ecaz25vk.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-fzdywr6p.js +0 -9
- package/dist/chunks/studio-g5fmf0c1.js +0 -5
- package/dist/chunks/studio-g7nse7zb.js +0 -5
- package/dist/chunks/studio-geq1ea6k.js +0 -14
- package/dist/chunks/studio-ghkb32r8.js +0 -5
- package/dist/chunks/studio-ghrhy2y7.js +0 -5
- package/dist/chunks/studio-grawhey1.js +0 -5
- package/dist/chunks/studio-h0xgswew.js +0 -5
- package/dist/chunks/studio-h9c4p2tx.js +0 -5
- package/dist/chunks/studio-jyzj5cxs.js +0 -5
- package/dist/chunks/studio-mgx8yhnz.js +0 -64
- package/dist/chunks/studio-mpb04y1d.js +0 -6
- package/dist/chunks/studio-n17mty64.js +0 -5
- package/dist/chunks/studio-nwh2eqsk.js +0 -6
- package/dist/chunks/studio-q1h883bt.js +0 -16
- package/dist/chunks/studio-q4tv82h7.js +0 -9
- package/dist/chunks/studio-qpqa7vk3.js +0 -5
- package/dist/chunks/studio-qqz8e5gk.js +0 -5
- package/dist/chunks/studio-qvasen3f.js +0 -5
- package/dist/chunks/studio-rggdb3hm.js +0 -5
- package/dist/chunks/studio-sghy936h.js +0 -4
- package/dist/chunks/studio-skprc6ef.js +0 -5
- package/dist/chunks/studio-tt2nactf.js +0 -5
- package/dist/chunks/studio-tyasmc39.js +0 -5
- package/dist/chunks/studio-vk9ezads.js +0 -5
- package/dist/chunks/studio-vzacdfsc.js +0 -4
- package/dist/chunks/studio-w4c0xmrw.js +0 -5
- package/dist/chunks/studio-wfjqhhbk.js +0 -5
- package/dist/chunks/studio-wgh5kxpj.js +0 -5
- package/dist/chunks/studio-xasj0796.js +0 -5
- package/dist/chunks/studio-y78s8r2n.js +0 -5
- package/dist/chunks/studio-z8w183sh.js +0 -5
- package/dist/chunks/studio-zscd9ty4.js +0 -928
- package/dist/chunks/studio-zxp13sss.js +0 -7
- package/dist/chunks/studio-zygnmm01.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-gr0m4dzr.js +0 -14
- package/dist/chunks/workspace-m15qtcqp.js +0 -4
- package/dist/chunks/ws-client-nf61frr1.js +0 -4
|
@@ -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,10 +3,10 @@
|
|
|
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
|
*
|
|
@@ -19,11 +19,12 @@ import type { JxDocument } from "@jxsuite/schema/types";
|
|
|
19
19
|
/**
|
|
20
20
|
* Translate a render-time error into an actionable message the model can fix.
|
|
21
21
|
*
|
|
22
|
-
* @param {
|
|
22
|
+
* @param {unknown} cause What the render threw — an Error in practice; anything else is printed
|
|
23
|
+
* as-is.
|
|
23
24
|
* @returns {string}
|
|
24
25
|
*/
|
|
25
|
-
function translateRenderError(
|
|
26
|
-
const msg =
|
|
26
|
+
function translateRenderError(cause: unknown): string {
|
|
27
|
+
const msg = (cause instanceof Error && cause.message) || String(cause);
|
|
27
28
|
|
|
28
29
|
if (msg.includes("is not defined") || msg.includes("Cannot read properties of")) {
|
|
29
30
|
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.`;
|
|
@@ -64,7 +65,7 @@ export async function renderCheck(
|
|
|
64
65
|
|
|
65
66
|
return { ok: true };
|
|
66
67
|
} catch (error) {
|
|
67
|
-
return { ok: false, error: translateRenderError(error
|
|
68
|
+
return { ok: false, error: translateRenderError(error) };
|
|
68
69
|
} finally {
|
|
69
70
|
// Dispose all effects created synchronously by renderNode via the RUNTIME's runScoped — scope
|
|
70
71
|
// Collection is per @vue/reactivity module instance, so a studio effectScope here would collect
|
|
@@ -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();
|
|
@@ -26,23 +26,43 @@
|
|
|
26
26
|
* @docs studio/ai/chat
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
import { isSealContent } from "@jxsuite/ai/messages";
|
|
29
|
+
import { SEAL_RELOADED, isSealContent } from "@jxsuite/ai/messages";
|
|
30
30
|
import type { ToolResult } from "@jxsuite/ai/tools";
|
|
31
|
+
import { isBoolean, isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
31
32
|
import type { PersistedMessage } from "./ai-session-store";
|
|
32
|
-
import { UNANSWERED_TOOL_RESULT } from "./context-manager";
|
|
33
33
|
|
|
34
34
|
/** The tool that suspends a turn on the author (services/ai-ask.ts). */
|
|
35
|
-
const ASK_TOOL = "ask_user";
|
|
35
|
+
export const ASK_TOOL = "ask_user";
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
|
|
37
|
+
/**
|
|
38
|
+
* The outcome of an ordinary call that never ran to completion — the seal's own words: the object
|
|
39
|
+
* `context-manager.ts`'s `UNANSWERED_TOOL_RESULT` serializes, built from the same sentence.
|
|
40
|
+
*/
|
|
41
|
+
const NEVER_COMPLETED: ToolResult = { success: false, error: SEAL_RELOADED };
|
|
39
42
|
|
|
40
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* A tool-call record as persisted: `id` and `name` are what pairing and the chip read. Every member
|
|
45
|
+
* is optional and unchecked, because the records come back out of storage; each is narrowed where
|
|
46
|
+
* it is read.
|
|
47
|
+
*/
|
|
41
48
|
interface PersistedToolCall {
|
|
42
49
|
id?: unknown;
|
|
43
50
|
name?: unknown;
|
|
44
51
|
result?: unknown;
|
|
45
|
-
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Whether a persisted `toolCalls` entry is a record at all. Any object qualifies — every member of
|
|
56
|
+
* {@link PersistedToolCall} is optional — and a primitive (a corrupt or foreign payload) is passed
|
|
57
|
+
* through untouched by both directions.
|
|
58
|
+
*/
|
|
59
|
+
function isToolCallRecord(value: unknown): value is PersistedToolCall {
|
|
60
|
+
return isNonNullObject(value);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Whether a parsed tool message is a `ToolResult`: an object whose `success` is a boolean. */
|
|
64
|
+
function isToolResult(value: unknown): value is ToolResult {
|
|
65
|
+
return isNonNullObject(value) && "success" in value && isBoolean(value.success);
|
|
46
66
|
}
|
|
47
67
|
|
|
48
68
|
/**
|
|
@@ -61,28 +81,29 @@ export function stripToolResults(messages: readonly PersistedMessage[]): Persist
|
|
|
61
81
|
return {
|
|
62
82
|
...message,
|
|
63
83
|
toolCalls: message.toolCalls.map((call) => {
|
|
64
|
-
if (!call
|
|
84
|
+
if (!isToolCallRecord(call)) {
|
|
65
85
|
return call;
|
|
66
86
|
}
|
|
67
|
-
const { result: _result, ...rest } = call
|
|
87
|
+
const { result: _result, ...rest } = call;
|
|
68
88
|
return rest;
|
|
69
89
|
}),
|
|
70
90
|
};
|
|
71
91
|
});
|
|
72
92
|
}
|
|
73
93
|
|
|
74
|
-
/**
|
|
75
|
-
|
|
76
|
-
|
|
94
|
+
/**
|
|
95
|
+
* A tool message's content as a `ToolResult`, or null when it is not one.
|
|
96
|
+
*
|
|
97
|
+
* The content is re-checked as a string although {@link PersistedMessage} declares one: the message
|
|
98
|
+
* came back out of storage, where a corrupt or foreign payload can hold anything.
|
|
99
|
+
*/
|
|
100
|
+
function parseToolResult(content: string): ToolResult | null {
|
|
101
|
+
if (!isString(content)) {
|
|
77
102
|
return null;
|
|
78
103
|
}
|
|
79
104
|
try {
|
|
80
|
-
const parsed = JSON.parse(content)
|
|
81
|
-
return parsed
|
|
82
|
-
typeof parsed === "object" &&
|
|
83
|
-
typeof (parsed as ToolResult).success === "boolean"
|
|
84
|
-
? (parsed as ToolResult)
|
|
85
|
-
: null;
|
|
105
|
+
const parsed: unknown = JSON.parse(content);
|
|
106
|
+
return isToolResult(parsed) ? parsed : null;
|
|
86
107
|
} catch {
|
|
87
108
|
return null;
|
|
88
109
|
}
|
|
@@ -114,7 +135,7 @@ export function backfillToolResults(messages: readonly PersistedMessage[]): Pers
|
|
|
114
135
|
break;
|
|
115
136
|
}
|
|
116
137
|
const result = parseToolResult(reply.content);
|
|
117
|
-
if (
|
|
138
|
+
if (isString(reply.toolCallId) && result && !replies.has(reply.toolCallId)) {
|
|
118
139
|
replies.set(reply.toolCallId, result);
|
|
119
140
|
if (isSealContent(reply.content)) {
|
|
120
141
|
sealed.add(reply.toolCallId);
|
|
@@ -123,12 +144,11 @@ export function backfillToolResults(messages: readonly PersistedMessage[]): Pers
|
|
|
123
144
|
}
|
|
124
145
|
return {
|
|
125
146
|
...message,
|
|
126
|
-
toolCalls: message.toolCalls.map((
|
|
127
|
-
if (!
|
|
128
|
-
return
|
|
147
|
+
toolCalls: message.toolCalls.map((record) => {
|
|
148
|
+
if (!isToolCallRecord(record)) {
|
|
149
|
+
return record;
|
|
129
150
|
}
|
|
130
|
-
const
|
|
131
|
-
const id = typeof record.id === "string" ? record.id : undefined;
|
|
151
|
+
const id = isString(record.id) ? record.id : undefined;
|
|
132
152
|
const answered = id === undefined ? undefined : replies.get(id);
|
|
133
153
|
if (record.name === ASK_TOOL) {
|
|
134
154
|
/* A question's only outcomes are an answer or none: a seal is not an answer, and a
|
|
@@ -22,6 +22,20 @@
|
|
|
22
22
|
* @docs studio/interface/problems-and-progress
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* A W3C `TrustedHTML`: opaque to script, accepted by an injection sink, and stringifying to the
|
|
27
|
+
* markup it wraps. This TypeScript's `lib.dom` does not declare it, so it is declared here with the
|
|
28
|
+
* one member a reader can rely on.
|
|
29
|
+
*/
|
|
30
|
+
export interface TrustedHtml {
|
|
31
|
+
toString: () => string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The policy object `createPolicy` answers with, narrowed to the one factory the shell calls. */
|
|
35
|
+
export interface StudioPolicy {
|
|
36
|
+
createHTML: (input: string) => TrustedHtml;
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
/** The subset of the Trusted Types API this module uses — typed here so no DOM lib is required. */
|
|
26
40
|
interface TrustedTypesApi {
|
|
27
41
|
createPolicy: (
|
|
@@ -31,7 +45,7 @@ interface TrustedTypesApi {
|
|
|
31
45
|
createScript?: (input: string) => string;
|
|
32
46
|
createScriptURL?: (input: string) => string;
|
|
33
47
|
},
|
|
34
|
-
) =>
|
|
48
|
+
) => StudioPolicy;
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
/** The policy name, which a CSP `trusted-types` directive would have to allow. */
|
|
@@ -75,18 +89,21 @@ export function assertSanitized(value: string): string {
|
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
/** Created once. A second `createPolicy` with the same name throws when policies are restricted. */
|
|
78
|
-
let policy:
|
|
92
|
+
let policy: StudioPolicy | null = null;
|
|
79
93
|
|
|
80
94
|
/**
|
|
81
95
|
* The shell's Trusted Types policy, or null where the API does not exist.
|
|
82
96
|
*
|
|
83
|
-
* @returns {
|
|
97
|
+
* @returns {StudioPolicy | null}
|
|
84
98
|
*/
|
|
85
|
-
export function studioPolicy():
|
|
99
|
+
export function studioPolicy(): StudioPolicy | null {
|
|
86
100
|
if (policy) {
|
|
87
101
|
return policy;
|
|
88
102
|
}
|
|
89
|
-
|
|
103
|
+
/* SAFETY: `trustedTypes` is the member Trusted Types adds to the global scope, which this
|
|
104
|
+
`lib.dom` predates; the intersection only names it, typed as possibly absent, and an absent
|
|
105
|
+
member (a browser without Trusted Types, and the tests) is the `undefined` handled below. */
|
|
106
|
+
const api = (globalThis as typeof globalThis & { trustedTypes?: TrustedTypesApi }).trustedTypes;
|
|
90
107
|
if (!api) {
|
|
91
108
|
return null;
|
|
92
109
|
}
|
|
@@ -110,9 +127,9 @@ export function studioPolicy(): { createHTML: (input: string) => unknown } | nul
|
|
|
110
127
|
* guard that only fires under Trusted Types would be a guard that never fires in the tests.
|
|
111
128
|
*
|
|
112
129
|
* @param {string} value Markup from `markdownToHtml`.
|
|
113
|
-
* @returns {
|
|
130
|
+
* @returns {TrustedHtml | string} A `TrustedHTML`, or the asserted string.
|
|
114
131
|
*/
|
|
115
|
-
export function trustedHtml(value: string):
|
|
132
|
+
export function trustedHtml(value: string): TrustedHtml | string {
|
|
116
133
|
const active = studioPolicy();
|
|
117
134
|
return active ? active.createHTML(value) : assertSanitized(value);
|
|
118
135
|
}
|
|
@@ -76,6 +76,12 @@ export interface ContextEntry {
|
|
|
76
76
|
kind: ContextKind;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/** A `$media` map, split: the base width, and every other entry classified. */
|
|
80
|
+
export interface ContextSplit {
|
|
81
|
+
base: string;
|
|
82
|
+
entries: ContextEntry[];
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
/**
|
|
80
86
|
* Which kind of context an entry is.
|
|
81
87
|
*
|
|
@@ -98,12 +104,9 @@ export function contextKindOf(query: string): ContextKind {
|
|
|
98
104
|
* Split a `$media` map into the base width and the three context groups.
|
|
99
105
|
*
|
|
100
106
|
* @param {Record<string, string> | undefined} media
|
|
101
|
-
* @returns {
|
|
107
|
+
* @returns {ContextSplit}
|
|
102
108
|
*/
|
|
103
|
-
export function splitContexts(media?: Record<string, string> | undefined): {
|
|
104
|
-
base: string;
|
|
105
|
-
entries: ContextEntry[];
|
|
106
|
-
} {
|
|
109
|
+
export function splitContexts(media?: Record<string, string> | undefined): ContextSplit {
|
|
107
110
|
const source = media ?? {};
|
|
108
111
|
const entries: ContextEntry[] = [];
|
|
109
112
|
for (const [key, raw] of Object.entries(source)) {
|
|
@@ -232,11 +235,11 @@ export function contextsError(container: HTMLElement): { target: string; message
|
|
|
232
235
|
* a projection, which makes reading through to the store the thing that keeps them honest.
|
|
233
236
|
*/
|
|
234
237
|
function currentConfig(): ProjectConfig {
|
|
235
|
-
return
|
|
238
|
+
return projectState?.projectConfig ?? {};
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
function currentMedia(): Record<string, string> {
|
|
239
|
-
return
|
|
242
|
+
return currentConfig().$media ?? {};
|
|
240
243
|
}
|
|
241
244
|
|
|
242
245
|
// ─── Writing ──────────────────────────────────────────────────────────────────
|
|
@@ -271,7 +274,7 @@ async function persistMedia(
|
|
|
271
274
|
target: ErrorTarget,
|
|
272
275
|
): Promise<void> {
|
|
273
276
|
const config = currentConfig();
|
|
274
|
-
const candidate = { ...config, $media: next }
|
|
277
|
+
const candidate: ProjectConfig = { ...config, $media: next };
|
|
275
278
|
let schemaErrors: string[] = [];
|
|
276
279
|
let inherited: string[] = [];
|
|
277
280
|
try {
|