@jxsuite/studio 2.0.1 → 2.1.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/canvas.html +21 -0
- package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
- package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
- package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
- package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
- package/dist/chunks/{components-799jpvhm.js → components-2bpqp4mq.js} +5 -7
- package/dist/chunks/{components-799jpvhm.js.map → components-2bpqp4mq.js.map} +1 -1
- package/dist/chunks/content-source-34gnkbnn.js +38 -0
- package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
- package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
- package/dist/chunks/extension-sections-6mqydz35.js +301 -0
- package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
- package/dist/chunks/files-8kn321h1.js +70 -0
- package/dist/chunks/files-8kn321h1.js.map +9 -0
- package/dist/chunks/{format-host-8jxwts2p.js → format-host-mkwsmt8d.js} +3 -3
- package/dist/chunks/git-panel-tjbr191d.js +51 -0
- package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
- package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
- package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
- package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
- package/dist/chunks/layers-panel-87pb25km.js +58 -0
- package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
- package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
- package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
- package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
- package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
- package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
- package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
- package/dist/chunks/right-panel-zpdxd98t.js +37 -0
- package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
- package/dist/chunks/section-registry-zmckaxf4.js +30 -0
- package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
- package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
- package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
- package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
- package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
- package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
- package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
- package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
- package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
- package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
- package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
- package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
- package/dist/chunks/studio-41exgzhq.js +6690 -0
- package/dist/chunks/studio-41exgzhq.js.map +38 -0
- package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
- package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
- package/dist/chunks/studio-50k77cca.js +1787 -0
- package/dist/chunks/studio-50k77cca.js.map +18 -0
- package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
- package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
- package/dist/chunks/studio-6f0am8f2.js +53 -0
- package/dist/chunks/studio-6f0am8f2.js.map +10 -0
- package/dist/chunks/studio-6nmjc5qk.js +7002 -0
- package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
- package/dist/chunks/studio-7afd21nw.js +67 -0
- package/dist/chunks/studio-7afd21nw.js.map +10 -0
- package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
- package/dist/chunks/studio-7bmdvzne.js.map +10 -0
- package/dist/chunks/studio-8jpzqk5s.js +128 -0
- package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
- package/dist/chunks/studio-94m77tgk.js +1482 -0
- package/dist/chunks/studio-94m77tgk.js.map +13 -0
- package/dist/chunks/studio-9je6w5sq.js +1000 -0
- package/dist/chunks/studio-9je6w5sq.js.map +16 -0
- package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
- package/dist/chunks/{studio-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
- package/dist/chunks/{studio-gs6kqdt1.js.map → studio-adn0z1k3.js.map} +3 -3
- package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
- package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
- package/dist/chunks/studio-bw5dz6km.js +608 -0
- package/dist/chunks/studio-bw5dz6km.js.map +21 -0
- package/dist/chunks/studio-c6s5getc.js +4232 -0
- package/dist/chunks/studio-c6s5getc.js.map +39 -0
- package/dist/chunks/studio-cjm7fdjf.js +451 -0
- package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
- package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
- package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
- package/dist/chunks/studio-dg7zyt5x.js +28 -0
- package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
- package/dist/chunks/studio-dzcyvvvz.js +166 -0
- package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
- package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
- package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
- package/dist/chunks/studio-f12h6177.js +411 -0
- package/dist/chunks/studio-f12h6177.js.map +13 -0
- package/dist/chunks/studio-hbp1s8m9.js +1817 -0
- package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
- package/dist/chunks/studio-k2sxjph5.js +15295 -0
- package/dist/chunks/studio-k2sxjph5.js.map +235 -0
- package/dist/chunks/studio-myje51t3.js +385 -0
- package/dist/chunks/studio-myje51t3.js.map +12 -0
- package/dist/chunks/studio-na6rwzhw.js +353 -0
- package/dist/chunks/studio-na6rwzhw.js.map +11 -0
- package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
- package/dist/chunks/studio-p471gg5n.js.map +14 -0
- package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
- package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
- package/dist/chunks/{studio-esrewxap.js → studio-s519zc99.js} +3 -3
- package/dist/chunks/studio-sas7mt3k.js +75 -0
- package/dist/chunks/studio-sas7mt3k.js.map +10 -0
- package/dist/chunks/studio-t5wqwzdh.js +74 -0
- package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
- package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
- package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
- package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
- package/dist/chunks/studio-tr20m8g8.js.map +9 -0
- package/dist/chunks/{studio-v7jkjqng.js → studio-v96qfnww.js} +5514 -4291
- package/dist/chunks/studio-v96qfnww.js.map +54 -0
- package/dist/chunks/studio-vcetc91k.js +659 -0
- package/dist/chunks/studio-vcetc91k.js.map +10 -0
- package/dist/chunks/{studio-jm0z592w.js → studio-vmymjefp.js} +2972 -4937
- package/dist/chunks/studio-vmymjefp.js.map +98 -0
- package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
- package/dist/chunks/studio-x9hmy5kr.js +390 -0
- package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
- package/dist/chunks/studio-xa0ce0n7.js +335 -0
- package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
- package/dist/chunks/studio-xm3dbxvn.js +378 -0
- package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
- package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
- package/dist/chunks/studio-zv37yrfa.js +1054 -0
- package/dist/chunks/studio-zv37yrfa.js.map +13 -0
- package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
- package/dist/chunks/ws-client-654ts66j.js.map +11 -0
- package/dist/iframe-entry.js +668 -230
- package/dist/studio.js +21080 -32585
- package/index.html +35 -4685
- package/package.json +17 -15
- package/src/about/about-modal.ts +42 -11
- package/src/browse/library-commands.ts +240 -0
- package/src/browse/library-layouts.ts +369 -0
- package/src/browse/library-model.ts +396 -0
- package/src/browse/library-pane.ts +1049 -0
- package/src/browse/library-preview.ts +252 -0
- package/src/browse/library-source.ts +150 -0
- package/src/canvas/canvas-helpers.ts +33 -9
- package/src/canvas/canvas-live-render.ts +45 -29
- package/src/canvas/canvas-patcher.ts +151 -31
- package/src/canvas/canvas-perf.ts +46 -7
- package/src/canvas/canvas-render.ts +1092 -220
- package/src/canvas/canvas-surface.ts +240 -0
- package/src/canvas/canvas-utils.ts +1166 -124
- package/src/canvas/iframe-drop.ts +2 -1
- package/src/canvas/iframe-entry.ts +241 -4
- package/src/canvas/iframe-host.ts +1226 -143
- package/src/canvas/iframe-inline-edit.ts +31 -0
- package/src/canvas/iframe-interaction.ts +76 -16
- package/src/canvas/iframe-keys.ts +107 -45
- package/src/canvas/iframe-overlay.ts +38 -1
- package/src/canvas/iframe-protocol.ts +137 -2
- package/src/canvas/iframe-render.ts +70 -2
- package/src/canvas/iframe-slash.ts +6 -0
- package/src/canvas/path-mapping.ts +56 -6
- package/src/canvas/surface-registry.ts +292 -0
- package/src/collab/collab-commands.ts +244 -0
- package/src/collab/collab-session.ts +198 -32
- package/src/collab/collab-state.ts +28 -2
- package/src/collab/presence-chips.ts +100 -9
- package/src/commands/active-registry.ts +42 -0
- package/src/commands/app-commands.ts +176 -0
- package/src/commands/budget.ts +158 -0
- package/src/commands/command-args.ts +253 -0
- package/src/commands/context.ts +387 -0
- package/src/commands/defaults.ts +580 -0
- package/src/commands/keymap.ts +571 -0
- package/src/commands/levels.ts +345 -0
- package/src/commands/live-context.ts +193 -0
- package/src/commands/reference.ts +227 -0
- package/src/commands/registry.ts +293 -0
- package/src/component-props.ts +3 -2
- package/src/content/draft-state.ts +106 -0
- package/src/content/entry-commands.ts +282 -0
- package/src/content/entry-editor.ts +327 -0
- package/src/content/entry-fields.ts +116 -0
- package/src/content/entry-model.ts +175 -0
- package/src/editor/canvas-context-menu.ts +17 -11
- package/src/editor/canvas-slash-bridge.ts +11 -4
- package/src/editor/context-menu.ts +804 -204
- package/src/editor/convert-to-component.ts +31 -10
- package/src/editor/convert-to-repeater.ts +3 -2
- package/src/editor/inline-edit-apply.ts +5 -5
- package/src/editor/inline-edit.ts +86 -50
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/shortcuts.ts +1043 -329
- package/src/editor/slash-menu.ts +1 -0
- package/src/files/elements.ts +166 -0
- package/src/files/file-ops.ts +178 -31
- package/src/files/files.ts +898 -268
- package/src/files/fs-events.ts +21 -0
- package/src/files/media-meta.ts +203 -0
- package/src/files/media-paths.ts +141 -0
- package/src/files/media-upload.ts +7 -3
- package/src/files/media-usage.ts +189 -0
- package/src/github/github-auth.ts +235 -33
- package/src/github/github-publish.ts +80 -21
- package/src/grid/grid-controller.ts +152 -12
- package/src/grid/grid-layout.ts +225 -20
- package/src/grid/grid-open.ts +120 -0
- package/src/grid/grid-panel.ts +554 -39
- package/src/grid/grid-source.ts +27 -1
- package/src/grid/redirects-grid.ts +599 -0
- package/src/grid/redirects.ts +398 -0
- package/src/grid/sources/content-source.ts +108 -2
- package/src/i18n/i18n-commands.ts +322 -0
- package/src/new-project/add-repo-modal.ts +8 -10
- package/src/new-project/import-tab.ts +7 -0
- package/src/new-project/location-fields.ts +9 -1
- package/src/new-project/new-project-modal.ts +221 -245
- package/src/packages/jxsuite-update.ts +97 -48
- package/src/packages/pull-package-sync.ts +18 -9
- package/src/page-params.ts +2 -1
- package/src/panels/activity-bar.ts +152 -91
- package/src/panels/activity-panel.ts +481 -0
- package/src/panels/ai-chat/chat-markdown.ts +8 -3
- package/src/panels/ai-chat/chat-view.ts +245 -18
- package/src/panels/ai-chat/composer.ts +31 -5
- package/src/panels/ai-chat/sessions-view.ts +17 -10
- package/src/panels/ai-panel.ts +279 -53
- package/src/panels/block-action-bar.ts +1115 -224
- package/src/panels/bottom-dock.ts +337 -0
- package/src/panels/canvas-dnd-bridge.ts +37 -8
- package/src/panels/chat-panel.ts +29 -12
- package/src/panels/data-explorer.ts +254 -112
- package/src/panels/data-grid.ts +10 -4
- package/src/panels/dnd.ts +28 -51
- package/src/panels/editors.ts +434 -107
- package/src/panels/elements-panel.ts +66 -2
- package/src/panels/empty-state.ts +112 -0
- package/src/panels/events-panel.ts +596 -82
- package/src/panels/formula-workspace.ts +408 -218
- package/src/panels/frontmatter-fields.ts +51 -10
- package/src/panels/frontmatter-panel.ts +357 -79
- package/src/panels/git-panel.ts +375 -164
- package/src/panels/head-panel.ts +791 -85
- package/src/panels/i18n-panel.ts +592 -0
- package/src/panels/imports-panel.ts +95 -85
- package/src/panels/jump-bar.ts +584 -0
- package/src/panels/layers-panel.ts +1106 -328
- package/src/panels/left-panel.ts +109 -204
- package/src/panels/navigator-panels.ts +131 -0
- package/src/panels/overlays.ts +7 -2
- package/src/panels/pane-context.ts +1477 -0
- package/src/panels/pane-grid.ts +406 -0
- package/src/panels/panel-registry.ts +340 -0
- package/src/panels/panel-scheduler.ts +75 -0
- package/src/panels/problems-panel.ts +234 -0
- package/src/panels/properties-panel.ts +946 -1139
- package/src/panels/provenance.ts +258 -0
- package/src/panels/quick-search.ts +791 -122
- package/src/panels/right-panel.ts +228 -102
- package/src/panels/seo-modal.ts +395 -0
- package/src/panels/settings-pane.ts +203 -0
- package/src/panels/signals-panel.ts +354 -137
- package/src/panels/statement-editor.ts +41 -25
- package/src/panels/statusbar.ts +342 -106
- package/src/panels/style-panel.ts +974 -463
- package/src/panels/style-utils.ts +3 -3
- package/src/panels/stylebook-doc.ts +4 -2
- package/src/panels/stylebook-layers-panel.ts +3 -2
- package/src/panels/stylebook-panel.ts +51 -26
- package/src/panels/tab-strip.ts +1058 -78
- package/src/panels/target-line.ts +274 -0
- package/src/panels/toolbar.ts +631 -484
- package/src/panels/welcome-screen.ts +301 -198
- package/src/platform-errors.ts +26 -3
- package/src/platform.ts +96 -2
- package/src/platforms/cloud.ts +71 -8
- package/src/platforms/devserver.ts +92 -29
- package/src/publish/deploy-checklist.ts +383 -0
- package/src/publish/pages-service.ts +10 -1
- package/src/publish/publish-commands.ts +218 -0
- package/src/publish/publish-panel.ts +110 -16
- package/src/recent-projects.ts +3 -2
- package/src/services/a11y-report.ts +505 -0
- package/src/services/ai-models.ts +30 -1
- package/src/services/ai-project-tools.ts +29 -10
- package/src/services/ai-system-prompt.ts +53 -14
- package/src/services/ai-tools.ts +39 -3
- package/src/services/ai-writes.ts +154 -0
- package/src/services/announce.ts +97 -0
- package/src/services/automation.ts +424 -175
- package/src/services/cem-export.ts +9 -4
- package/src/services/clock.ts +61 -0
- package/src/services/document-assistant.ts +36 -8
- package/src/services/idle.ts +179 -0
- package/src/services/import-client.ts +26 -0
- package/src/services/monaco-buffer.ts +627 -0
- package/src/services/monaco-lazy.ts +36 -0
- package/src/services/notify.ts +271 -0
- package/src/services/profile.ts +155 -0
- package/src/services/references.ts +0 -0
- package/src/services/token-lint.ts +3 -2
- package/src/services/tool-executor.ts +53 -7
- package/src/services/trusted-types.ts +123 -0
- package/src/settings/contexts-section.ts +427 -0
- package/src/settings/contributed-section.ts +149 -11
- package/src/settings/css-vars-editor.ts +306 -349
- package/src/settings/defs-editor.ts +93 -34
- package/src/settings/dependencies-editor.ts +7 -7
- package/src/settings/extension-sections.ts +37 -5
- package/src/settings/general-settings.ts +204 -121
- package/src/settings/locales-section.ts +347 -0
- package/src/settings/preferences-accounts.ts +140 -0
- package/src/settings/preferences-dialog.ts +620 -0
- package/src/settings/preferences-keymap.ts +270 -0
- package/src/settings/project-sections.ts +260 -0
- package/src/settings/section-registry.ts +169 -0
- package/src/settings/settings-document.ts +385 -0
- package/src/shell.ts +1549 -0
- package/src/site-context.ts +45 -20
- package/src/state.ts +14 -275
- package/src/store.ts +88 -43
- package/src/studio.ts +790 -346
- package/src/style/live-preview.ts +36 -0
- package/src/style/project-styles.ts +349 -0
- package/src/style/token-ref.ts +123 -0
- package/src/tabs/patch-ops.ts +16 -4
- package/src/tabs/project-config.ts +416 -0
- package/src/tabs/selection.ts +323 -0
- package/src/tabs/tab.ts +182 -47
- package/src/tabs/transact.ts +209 -28
- package/src/types.ts +68 -13
- package/src/ui/ai-credentials-form.ts +39 -35
- package/src/ui/ai-managed-connect.ts +7 -1
- package/src/ui/dynamic-slot.ts +224 -81
- package/src/ui/expression-editor.ts +71 -63
- package/src/ui/field-input.ts +4 -6
- package/src/ui/field-row.ts +215 -38
- package/src/ui/form-controls.ts +194 -7
- package/src/ui/layers.ts +492 -69
- package/src/ui/media-picker.ts +115 -25
- package/src/ui/panel-resize.ts +109 -91
- package/src/ui/progress-modal.ts +131 -50
- package/src/ui/regions.ts +462 -0
- package/src/ui/schema-form.ts +229 -45
- package/src/ui/spectrum.ts +24 -8
- package/src/ui/timing.ts +49 -0
- package/src/ui/value-selector.ts +20 -0
- package/src/ui/value-source.ts +348 -0
- package/src/ui/virtual-window.ts +400 -0
- package/src/utils/edit-display.ts +3 -2
- package/src/utils/inherited-style.ts +67 -37
- package/src/view.ts +64 -78
- package/src/workspace/pane-derive.ts +1258 -0
- package/src/workspace/session.ts +317 -0
- package/src/workspace/workspace.ts +1345 -23
- package/styles/canvas.css +653 -0
- package/styles/forced-colors.css +106 -0
- package/styles/inspector.css +1454 -0
- package/styles/overlays.css +2704 -0
- package/styles/panels.css +1701 -0
- package/styles/shell.css +1423 -0
- package/styles/tokens.css +151 -0
- package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
- package/dist/chunks/extension-sections-qr3drkkw.js +0 -531
- package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
- package/dist/chunks/files-j8a1t06k.js +0 -50
- package/dist/chunks/files-j8a1t06k.js.map +0 -9
- package/dist/chunks/git-panel-xtq5z81x.js +0 -28
- package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
- package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
- package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
- package/dist/chunks/settings-modal-17ttr96g.js +0 -29
- package/dist/chunks/settings-modal-17ttr96g.js.map +0 -9
- package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
- package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
- package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
- package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
- package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
- package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
- package/dist/chunks/studio-0xgs7xrs.js +0 -429
- package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
- package/dist/chunks/studio-4d8hzcz5.js +0 -3427
- package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
- package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
- package/dist/chunks/studio-9smfzqhc.js +0 -19
- package/dist/chunks/studio-9smfzqhc.js.map +0 -10
- package/dist/chunks/studio-jm0z592w.js.map +0 -115
- package/dist/chunks/studio-m2t4mdg5.js +0 -1854
- package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
- package/dist/chunks/studio-n4p11dfy.js +0 -853
- package/dist/chunks/studio-n4p11dfy.js.map +0 -12
- package/dist/chunks/studio-qkvt37c0.js.map +0 -9
- package/dist/chunks/studio-sjh1wt1a.js +0 -3744
- package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
- package/dist/chunks/studio-v7jkjqng.js.map +0 -46
- package/dist/chunks/studio-xq0t7n5t.js +0 -140
- package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
- package/dist/chunks/studio-xze4zrs1.js.map +0 -10
- package/dist/chunks/studio-yfcstdzy.js +0 -399
- package/dist/chunks/studio-yfcstdzy.js.map +0 -12
- package/dist/chunks/studio-zp7jncs8.js +0 -469
- package/dist/chunks/studio-zp7jncs8.js.map +0 -14
- package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
- package/src/browse/browse-modal.ts +0 -69
- package/src/browse/browse.ts +0 -904
- package/src/canvas/canvas-diff.ts +0 -216
- package/src/canvas/nested-site-style.ts +0 -58
- package/src/new-project/design-fields.ts +0 -264
- package/src/new-project/templates.ts +0 -61
- package/src/panels/tab-bar.ts +0 -548
- package/src/settings/settings-modal.ts +0 -203
- /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
- /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
- /package/dist/chunks/{format-host-8jxwts2p.js.map → format-host-mkwsmt8d.js.map} +0 -0
- /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
- /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
- /package/dist/chunks/{studio-esrewxap.js.map → studio-s519zc99.js.map} +0 -0
- /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
- /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/**
|
|
3
|
-
* New Project modal — a two-step wizard.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
3
|
+
* New Project modal — a two-step wizard.
|
|
4
|
+
*
|
|
5
|
+
* **Step 1 · Choose a starting point.** Starters lead: the first thing offered is a complete site
|
|
6
|
+
* you can look at. The gallery ends with one **Start from scratch** card — the minimal scaffold —
|
|
7
|
+
* because a first-run choice between four breakpoint presets described by media-query direction is
|
|
8
|
+
* a choice nobody can make. Two further sources sit on their own tabs: an **Import** of an existing
|
|
9
|
+
* site, and an **Agent** prompt.
|
|
10
|
+
*
|
|
11
|
+
* **Step 2 · Name your project.** Name and location, nothing else. A project's URL, deployment
|
|
12
|
+
* adapter and design tokens are settings, not creation-time decisions, so they live in the
|
|
13
|
+
* project's own settings surface where they can be changed more than once.
|
|
8
14
|
*
|
|
9
15
|
* Import and Agent need working AI, so both are gated until credentials exist — a key stored in
|
|
10
16
|
* this browser, or a backend that holds its own (managed cloud platforms, env-keyed dev servers).
|
|
11
17
|
* While gated they offer the same two paths as the assistant sidebar: connect Cloudflare for
|
|
12
18
|
* Workers AI, or bring a key.
|
|
19
|
+
*
|
|
20
|
+
* @docs studio/projects/create
|
|
13
21
|
*/
|
|
14
22
|
|
|
15
23
|
import { html } from "lit-html";
|
|
16
24
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
17
25
|
import { openModal } from "../ui/layers";
|
|
26
|
+
import { enumArg, enumProperty } from "../commands/command-args";
|
|
27
|
+
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
18
28
|
import { getPlatform } from "../platform";
|
|
19
29
|
import { installUrlOf } from "../platform-errors";
|
|
20
30
|
import { hasAiCredentials } from "../services/ai-models";
|
|
21
31
|
import { setPendingAgentPrompt } from "../services/agent-seed";
|
|
32
|
+
import { initProjectRepo } from "../files/files";
|
|
22
33
|
import { createAiCredentialsForm } from "../ui/ai-credentials-form";
|
|
23
34
|
import { createManagedConnect } from "../ui/ai-managed-connect";
|
|
24
|
-
import { PROJECT_TEMPLATES } from "./templates";
|
|
25
|
-
import { collectDesign, renderDesignFields, resetDesignFields } from "./design-fields";
|
|
26
35
|
import {
|
|
27
36
|
collectDestination,
|
|
28
37
|
loadLocationOptions,
|
|
@@ -44,28 +53,21 @@ import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
|
44
53
|
import type { CreateProjectDestination, StarterInfo } from "../types";
|
|
45
54
|
import type { ImportTabCtx } from "./import-tab";
|
|
46
55
|
|
|
47
|
-
type NewProjectTab =
|
|
56
|
+
type NewProjectTab = (typeof NEW_PROJECT_TABS)[number];
|
|
48
57
|
type WizardStep = "source" | "params";
|
|
49
58
|
|
|
50
59
|
let _handle: ReturnType<typeof openModal> | null = null;
|
|
51
60
|
|
|
52
|
-
let _form = {
|
|
53
|
-
adapter: "static",
|
|
54
|
-
description: "",
|
|
55
|
-
directory: "",
|
|
56
|
-
name: "",
|
|
57
|
-
url: "",
|
|
58
|
-
};
|
|
61
|
+
let _form = { directory: "", name: "" };
|
|
59
62
|
|
|
60
|
-
let _tab: NewProjectTab = "
|
|
63
|
+
let _tab: NewProjectTab = "starter";
|
|
61
64
|
let _step: WizardStep = "source";
|
|
62
|
-
|
|
65
|
+
/** The step-1 choice on the Starters tab: a starter id, or `""` for "Start from scratch". */
|
|
63
66
|
let _starter = "";
|
|
67
|
+
/** Set once the user picks a card, so an arriving starter list stops overriding their choice. */
|
|
68
|
+
let _starterTouched = false;
|
|
64
69
|
let _agentPrompt = "";
|
|
65
70
|
|
|
66
|
-
/** Which source the Parameters step was last seeded for — Back/Next keeps user edits intact. */
|
|
67
|
-
let _paramsSeededFor = "";
|
|
68
|
-
|
|
69
71
|
let _error = "";
|
|
70
72
|
|
|
71
73
|
/**
|
|
@@ -93,7 +95,7 @@ function focusNameField() {
|
|
|
93
95
|
|
|
94
96
|
let _creating = false;
|
|
95
97
|
|
|
96
|
-
/** Starter templates offered in the
|
|
98
|
+
/** Starter templates offered in the gallery (empty until loaded / on platforms without starters). */
|
|
97
99
|
let _starters: StarterInfo[] = [];
|
|
98
100
|
|
|
99
101
|
let _resolve: ((result: { root: string; config: ProjectConfig } | null) => void) | null = null;
|
|
@@ -144,28 +146,22 @@ function aiGateOpen(): boolean {
|
|
|
144
146
|
* Open the New Project modal. Returns a promise that resolves with the created project info (or
|
|
145
147
|
* null if cancelled).
|
|
146
148
|
*
|
|
149
|
+
* @param {{ tab?: NewProjectTab }} [options] Which source tab to open on; defaults to Starters.
|
|
147
150
|
* @returns {Promise<{ root: string; config: object } | null>}
|
|
148
151
|
*/
|
|
149
|
-
export function openNewProjectModal(options?: { tab?:
|
|
152
|
+
export function openNewProjectModal(options?: { tab?: NewProjectTab }): Promise<{
|
|
150
153
|
root: string;
|
|
151
154
|
config: ProjectConfig;
|
|
152
155
|
} | null> {
|
|
153
156
|
if (_handle) {
|
|
154
157
|
return Promise.resolve(null);
|
|
155
158
|
}
|
|
156
|
-
_form = {
|
|
157
|
-
|
|
158
|
-
description: "",
|
|
159
|
-
directory: "",
|
|
160
|
-
name: "",
|
|
161
|
-
url: "",
|
|
162
|
-
};
|
|
163
|
-
_tab = options?.tab ?? "template";
|
|
159
|
+
_form = { directory: "", name: "" };
|
|
160
|
+
_tab = options?.tab ?? "starter";
|
|
164
161
|
_step = "source";
|
|
165
|
-
_template = "blank";
|
|
166
162
|
_starter = "";
|
|
163
|
+
_starterTouched = false;
|
|
167
164
|
_agentPrompt = "";
|
|
168
|
-
_paramsSeededFor = "";
|
|
169
165
|
_error = "";
|
|
170
166
|
_nameError = "";
|
|
171
167
|
_errorInstallUrl = "";
|
|
@@ -173,12 +169,10 @@ export function openNewProjectModal(options?: { tab?: "template" | "starter" }):
|
|
|
173
169
|
_starters = [];
|
|
174
170
|
_dirDerived = true;
|
|
175
171
|
resetImportTab();
|
|
176
|
-
resetDesignFields();
|
|
177
172
|
resetLocationFields();
|
|
178
173
|
|
|
179
174
|
// Load the destination options (repo-mode owners) and starter templates in the background,
|
|
180
|
-
// Re-rendering when they arrive.
|
|
181
|
-
// Its empty note.
|
|
175
|
+
// Re-rendering when they arrive. A platform without starters shows the scratch card alone.
|
|
182
176
|
const platform = getPlatform();
|
|
183
177
|
loadLocationOptions(() => {
|
|
184
178
|
if (_handle) {
|
|
@@ -190,7 +184,8 @@ export function openNewProjectModal(options?: { tab?: "template" | "starter" }):
|
|
|
190
184
|
.listStarters()
|
|
191
185
|
.then((starters) => {
|
|
192
186
|
_starters = starters;
|
|
193
|
-
|
|
187
|
+
// Starters lead: the gallery opens with a real site selected, not an empty scaffold.
|
|
188
|
+
if (!_starterTouched) {
|
|
194
189
|
_starter = starters[0]?.id ?? "";
|
|
195
190
|
}
|
|
196
191
|
if (_handle) {
|
|
@@ -198,7 +193,7 @@ export function openNewProjectModal(options?: { tab?: "template" | "starter" }):
|
|
|
198
193
|
}
|
|
199
194
|
})
|
|
200
195
|
.catch(() => {
|
|
201
|
-
/* Non-fatal: the
|
|
196
|
+
/* Non-fatal: the gallery keeps the scratch card. */
|
|
202
197
|
});
|
|
203
198
|
}
|
|
204
199
|
|
|
@@ -208,10 +203,17 @@ export function openNewProjectModal(options?: { tab?: "template" | "starter" }):
|
|
|
208
203
|
});
|
|
209
204
|
}
|
|
210
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Dismiss the wizard. Available from every step, and from the underlay and Escape — a running
|
|
208
|
+
* import is aborted on the way out rather than trapping the user behind it.
|
|
209
|
+
*/
|
|
211
210
|
export function closeNewProjectModal() {
|
|
212
|
-
if (!_handle || _creating
|
|
211
|
+
if (!_handle || _creating) {
|
|
213
212
|
return;
|
|
214
213
|
}
|
|
214
|
+
if (isImportRunning()) {
|
|
215
|
+
cancelImport(importCtxFor(renderModal));
|
|
216
|
+
}
|
|
215
217
|
_handle.close();
|
|
216
218
|
_handle = null;
|
|
217
219
|
if (_resolve) {
|
|
@@ -233,6 +235,15 @@ function finish(result: { root: string; config: ProjectConfig }) {
|
|
|
233
235
|
}
|
|
234
236
|
}
|
|
235
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Every path out of the wizard that produced a project: initialise version control for it, then
|
|
240
|
+
* hand it to the caller. A scaffold is not a repository, and Delete and Rename are one click away.
|
|
241
|
+
*/
|
|
242
|
+
async function finishCreated(result: { root: string; config: ProjectConfig }) {
|
|
243
|
+
await initProjectRepo(result.root);
|
|
244
|
+
finish(result);
|
|
245
|
+
}
|
|
246
|
+
|
|
236
247
|
function deriveSlug(name: string): string {
|
|
237
248
|
return name
|
|
238
249
|
.toLowerCase()
|
|
@@ -240,12 +251,9 @@ function deriveSlug(name: string): string {
|
|
|
240
251
|
.replaceAll(/^-|-$/g, "");
|
|
241
252
|
}
|
|
242
253
|
|
|
243
|
-
/** The human label of the chosen source, shown as context on the
|
|
254
|
+
/** The human label of the chosen source, shown as context on the Name step. */
|
|
244
255
|
function sourceLabel(): string {
|
|
245
256
|
switch (_tab) {
|
|
246
|
-
case "starter": {
|
|
247
|
-
return `Starter Site · ${_starters.find((s) => s.id === _starter)?.name ?? _starter}`;
|
|
248
|
-
}
|
|
249
257
|
case "import": {
|
|
250
258
|
return "Import";
|
|
251
259
|
}
|
|
@@ -253,54 +261,79 @@ function sourceLabel(): string {
|
|
|
253
261
|
return "Agent";
|
|
254
262
|
}
|
|
255
263
|
default: {
|
|
256
|
-
return
|
|
264
|
+
return _starter
|
|
265
|
+
? `Starter site · ${_starters.find((s) => s.id === _starter)?.name ?? _starter}`
|
|
266
|
+
: "Start from scratch";
|
|
257
267
|
}
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
271
|
+
/** The import tab's context object — rebuilt per render so it closes over current state. */
|
|
272
|
+
function importCtxFor(rerender: () => void): ImportTabCtx {
|
|
273
|
+
return {
|
|
264
274
|
aiGateOpen,
|
|
265
275
|
credsForm: credsForm(),
|
|
266
276
|
form: _form,
|
|
267
277
|
managedConnect: managedConnect(),
|
|
268
|
-
onDone:
|
|
269
|
-
|
|
278
|
+
onDone: (result) => {
|
|
279
|
+
// See above: the discard is deliberate, and `void` as a statement is what says so.
|
|
280
|
+
void finishCreated(result);
|
|
281
|
+
},
|
|
282
|
+
rerender,
|
|
270
283
|
resolveDestination: () => validateParams(),
|
|
271
284
|
};
|
|
285
|
+
}
|
|
272
286
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Validate the Name step, returning the destination to create at (null when something is missing —
|
|
289
|
+
* the reason is already rendered inline and the modal re-drawn). The slug is derived from the name
|
|
290
|
+
* when left blank, but the destination itself is never guessed.
|
|
291
|
+
*/
|
|
292
|
+
function validateParams(): CreateProjectDestination | null {
|
|
293
|
+
if (!_form.name.trim()) {
|
|
294
|
+
_nameError = "Project name is required";
|
|
295
|
+
renderModal();
|
|
296
|
+
focusNameField();
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
if (!_form.directory.trim()) {
|
|
300
|
+
_form.directory = deriveSlug(_form.name);
|
|
301
|
+
}
|
|
302
|
+
const destination = collectDestination(_form.directory);
|
|
303
|
+
if (!destination) {
|
|
304
|
+
_nameError = "";
|
|
305
|
+
renderModal();
|
|
306
|
+
focusNameField();
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
return destination;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function renderModal() {
|
|
313
|
+
const platform = getPlatform();
|
|
314
|
+
const importCtx = importCtxFor(renderModal);
|
|
315
|
+
|
|
316
|
+
const onInput = (field: "name" | "directory") => (e: Event) => {
|
|
317
|
+
_form[field] = (e.target as HTMLInputElement).value;
|
|
318
|
+
if (field === "name") {
|
|
319
|
+
_nameError = "";
|
|
320
|
+
// Auto-derive the directory slug from the name while the user hasn't typed one.
|
|
321
|
+
if (!_form.directory) {
|
|
281
322
|
_dirDerived = true;
|
|
282
323
|
}
|
|
283
|
-
if (_dirDerived
|
|
324
|
+
if (_dirDerived) {
|
|
284
325
|
_form.directory = deriveSlug(_form.name);
|
|
285
326
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
renderModal();
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const onAdapterChange = (e: Event) => {
|
|
293
|
-
_form.adapter = (e.target as HTMLInputElement).value;
|
|
294
|
-
renderModal();
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
const selectTemplate = (id: string) => {
|
|
298
|
-
_template = id;
|
|
327
|
+
} else {
|
|
328
|
+
_dirDerived = false;
|
|
329
|
+
}
|
|
299
330
|
renderModal();
|
|
300
331
|
};
|
|
301
332
|
|
|
302
333
|
const selectStarter = (id: string) => {
|
|
303
334
|
_starter = id;
|
|
335
|
+
_starterTouched = true;
|
|
336
|
+
_error = "";
|
|
304
337
|
renderModal();
|
|
305
338
|
};
|
|
306
339
|
|
|
@@ -316,11 +349,6 @@ function renderModal() {
|
|
|
316
349
|
// ─── Step transitions ──────────────────────────────────────────────────────
|
|
317
350
|
|
|
318
351
|
const goNext = () => {
|
|
319
|
-
if (_tab === "starter" && !_starter) {
|
|
320
|
-
_error = "Choose a starter site";
|
|
321
|
-
renderModal();
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
352
|
if (_tab === "import" && !validateImportSource(importCtx)) {
|
|
325
353
|
return;
|
|
326
354
|
}
|
|
@@ -329,28 +357,6 @@ function renderModal() {
|
|
|
329
357
|
renderModal();
|
|
330
358
|
return;
|
|
331
359
|
}
|
|
332
|
-
|
|
333
|
-
// Seed the Parameters step from the chosen source — only when the source changed, so Back +
|
|
334
|
-
// Next round-trips keep the user's edits.
|
|
335
|
-
const seedKey = `${_tab}:${_template}:${_starter}`;
|
|
336
|
-
if (_paramsSeededFor !== seedKey) {
|
|
337
|
-
_paramsSeededFor = seedKey;
|
|
338
|
-
if (_tab === "starter") {
|
|
339
|
-
const meta = _starters.find((s) => s.id === _starter);
|
|
340
|
-
if (meta && !_form.description.trim()) {
|
|
341
|
-
_form.description = meta.tagline;
|
|
342
|
-
}
|
|
343
|
-
resetDesignFields({
|
|
344
|
-
...(meta?.accent ? { accent: meta.accent } : {}),
|
|
345
|
-
mediaNote: "Leave empty to keep the starter's breakpoints.",
|
|
346
|
-
});
|
|
347
|
-
} else if (_tab === "template" || _tab === "agent") {
|
|
348
|
-
const templateId = _tab === "agent" ? "blank" : _template;
|
|
349
|
-
const meta = PROJECT_TEMPLATES.find((t) => t.id === templateId);
|
|
350
|
-
resetDesignFields(meta ? { media: meta.media } : {});
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
360
|
_step = "params";
|
|
355
361
|
_error = "";
|
|
356
362
|
renderModal();
|
|
@@ -368,32 +374,11 @@ function renderModal() {
|
|
|
368
374
|
|
|
369
375
|
// ─── Submission ────────────────────────────────────────────────────────────
|
|
370
376
|
|
|
371
|
-
/**
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const validateParams = (): CreateProjectDestination | null => {
|
|
377
|
-
if (!_form.name.trim()) {
|
|
378
|
-
_nameError = "Project name is required";
|
|
379
|
-
renderModal();
|
|
380
|
-
focusNameField();
|
|
381
|
-
return null;
|
|
382
|
-
}
|
|
383
|
-
if (!_form.directory.trim()) {
|
|
384
|
-
_form.directory = deriveSlug(_form.name);
|
|
385
|
-
}
|
|
386
|
-
const destination = collectDestination(_form.directory);
|
|
387
|
-
if (!destination) {
|
|
388
|
-
_nameError = "";
|
|
389
|
-
renderModal();
|
|
390
|
-
focusNameField();
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
|
-
return destination;
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
const onSubmit = async () => {
|
|
377
|
+
/** Create the project from the chosen source, then run `after` with the result. */
|
|
378
|
+
const create = async (
|
|
379
|
+
source: { starter: string } | { template: string },
|
|
380
|
+
after: (result: { root: string; config: ProjectConfig }) => void | Promise<void>,
|
|
381
|
+
) => {
|
|
397
382
|
const destination = validateParams();
|
|
398
383
|
if (!destination) {
|
|
399
384
|
return;
|
|
@@ -405,14 +390,8 @@ function renderModal() {
|
|
|
405
390
|
renderModal();
|
|
406
391
|
|
|
407
392
|
try {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
..._form,
|
|
411
|
-
destination,
|
|
412
|
-
...(_tab === "starter" && _starter ? { starter: _starter } : { template: _template }),
|
|
413
|
-
...(design ? { design } : {}),
|
|
414
|
-
});
|
|
415
|
-
finish(result);
|
|
393
|
+
const result = await getPlatform().createProject({ ..._form, destination, ...source });
|
|
394
|
+
await after(result);
|
|
416
395
|
} catch (error) {
|
|
417
396
|
_creating = false;
|
|
418
397
|
captureError(error);
|
|
@@ -420,82 +399,54 @@ function renderModal() {
|
|
|
420
399
|
}
|
|
421
400
|
};
|
|
422
401
|
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
if (!destination) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
_creating = true;
|
|
430
|
-
_error = "";
|
|
431
|
-
_nameError = "";
|
|
432
|
-
renderModal();
|
|
402
|
+
const onSubmit = () =>
|
|
403
|
+
create(_starter ? { starter: _starter } : { template: "blank" }, finishCreated);
|
|
433
404
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const result = await getPlatform().createProject({
|
|
437
|
-
..._form,
|
|
438
|
-
destination,
|
|
439
|
-
template: "blank",
|
|
440
|
-
...(design ? { design } : {}),
|
|
441
|
-
});
|
|
405
|
+
const onAgentSubmit = () =>
|
|
406
|
+
create({ template: "blank" }, async (result) => {
|
|
442
407
|
// The window that opens the project consumes this and hands the prompt to the assistant.
|
|
443
408
|
setPendingAgentPrompt(result.root, _agentPrompt.trim());
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
_creating = false;
|
|
447
|
-
captureError(error);
|
|
448
|
-
renderModal();
|
|
449
|
-
}
|
|
450
|
-
};
|
|
409
|
+
await finishCreated(result);
|
|
410
|
+
});
|
|
451
411
|
|
|
452
412
|
// ─── Step 1: source selection ──────────────────────────────────────────────
|
|
453
413
|
|
|
454
|
-
const
|
|
414
|
+
const starterSourceTpl = () => html`
|
|
415
|
+
<div class="new-project-tab-intro">
|
|
416
|
+
Every starter is a complete site copied in as plain files you own — open it, look at it, then
|
|
417
|
+
make it yours.
|
|
418
|
+
</div>
|
|
455
419
|
<div class="new-project-templates">
|
|
456
|
-
${
|
|
457
|
-
(
|
|
420
|
+
${_starters.map(
|
|
421
|
+
(s) => html`
|
|
458
422
|
<button
|
|
459
423
|
type="button"
|
|
460
|
-
class="new-project-template ${
|
|
461
|
-
@click=${() =>
|
|
462
|
-
title=${
|
|
424
|
+
class="new-project-template ${_starter === s.id ? "selected" : ""}"
|
|
425
|
+
@click=${() => selectStarter(s.id)}
|
|
426
|
+
title=${s.description}
|
|
463
427
|
>
|
|
464
|
-
<
|
|
428
|
+
<img class="new-project-template-thumb" src=${s.thumbnail} alt="" />
|
|
465
429
|
<div class="new-project-template-body">
|
|
466
|
-
<div class="new-project-template-name">${
|
|
467
|
-
<div class="new-project-template-tag">${
|
|
430
|
+
<div class="new-project-template-name">${s.name}</div>
|
|
431
|
+
<div class="new-project-template-tag">${s.tagline}</div>
|
|
468
432
|
</div>
|
|
469
433
|
</button>
|
|
470
434
|
`,
|
|
471
435
|
)}
|
|
436
|
+
<button
|
|
437
|
+
type="button"
|
|
438
|
+
class="new-project-template new-project-scratch ${_starter === "" ? "selected" : ""}"
|
|
439
|
+
@click=${() => selectStarter("")}
|
|
440
|
+
>
|
|
441
|
+
<div class="new-project-template-blank">+</div>
|
|
442
|
+
<div class="new-project-template-body">
|
|
443
|
+
<div class="new-project-template-name">Start from scratch</div>
|
|
444
|
+
<div class="new-project-template-tag">An empty site with one page</div>
|
|
445
|
+
</div>
|
|
446
|
+
</button>
|
|
472
447
|
</div>
|
|
473
448
|
`;
|
|
474
449
|
|
|
475
|
-
const starterSourceTpl = () =>
|
|
476
|
-
_starters.length > 0
|
|
477
|
-
? html`
|
|
478
|
-
<div class="new-project-templates">
|
|
479
|
-
${_starters.map(
|
|
480
|
-
(s) => html`
|
|
481
|
-
<button
|
|
482
|
-
type="button"
|
|
483
|
-
class="new-project-template ${_starter === s.id ? "selected" : ""}"
|
|
484
|
-
@click=${() => selectStarter(s.id)}
|
|
485
|
-
title=${s.description}
|
|
486
|
-
>
|
|
487
|
-
<img class="new-project-template-thumb" src=${s.thumbnail} alt="" />
|
|
488
|
-
<div class="new-project-template-body">
|
|
489
|
-
<div class="new-project-template-name">${s.name}</div>
|
|
490
|
-
<div class="new-project-template-tag">${s.tagline}</div>
|
|
491
|
-
</div>
|
|
492
|
-
</button>
|
|
493
|
-
`,
|
|
494
|
-
)}
|
|
495
|
-
</div>
|
|
496
|
-
`
|
|
497
|
-
: html`<div class="new-project-tab-intro">No starter sites are available.</div>`;
|
|
498
|
-
|
|
499
450
|
const agentSourceTpl = () => {
|
|
500
451
|
if (!aiGateOpen()) {
|
|
501
452
|
return html`
|
|
@@ -532,9 +483,6 @@ function renderModal() {
|
|
|
532
483
|
|
|
533
484
|
const sourceBodyTpl = () => {
|
|
534
485
|
switch (_tab) {
|
|
535
|
-
case "starter": {
|
|
536
|
-
return starterSourceTpl();
|
|
537
|
-
}
|
|
538
486
|
case "import": {
|
|
539
487
|
return renderImportSource(importCtx);
|
|
540
488
|
}
|
|
@@ -542,14 +490,15 @@ function renderModal() {
|
|
|
542
490
|
return agentSourceTpl();
|
|
543
491
|
}
|
|
544
492
|
default: {
|
|
545
|
-
return
|
|
493
|
+
return starterSourceTpl();
|
|
546
494
|
}
|
|
547
495
|
}
|
|
548
496
|
};
|
|
549
497
|
|
|
550
|
-
// ─── Step 2:
|
|
498
|
+
// ─── Step 2: name + location ───────────────────────────────────────────────
|
|
551
499
|
|
|
552
|
-
const
|
|
500
|
+
const paramsBodyTpl = () => html`
|
|
501
|
+
<div class="new-project-step-context">${sourceLabel()}</div>
|
|
553
502
|
<label class="new-project-field">
|
|
554
503
|
<span class="new-project-label">Project Name *</span>
|
|
555
504
|
<sp-textfield
|
|
@@ -573,47 +522,14 @@ function renderModal() {
|
|
|
573
522
|
rerender: renderModal,
|
|
574
523
|
slug: _form.directory,
|
|
575
524
|
})}
|
|
576
|
-
`;
|
|
577
|
-
|
|
578
|
-
const paramsBodyTpl = () => html`
|
|
579
|
-
<div class="new-project-step-context">${sourceLabel()}</div>
|
|
580
|
-
<div class="new-project-step-heading">New Project Parameters</div>
|
|
581
|
-
${nameDirFieldsTpl()}
|
|
582
525
|
${
|
|
583
526
|
_tab === "import"
|
|
584
527
|
? renderImportStatus()
|
|
585
528
|
: html`
|
|
586
|
-
<
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
.value=${_form.description}
|
|
591
|
-
@input=${onInput("description")}
|
|
592
|
-
style="width: 100%"
|
|
593
|
-
></sp-textfield>
|
|
594
|
-
</label>
|
|
595
|
-
|
|
596
|
-
<label class="new-project-field">
|
|
597
|
-
<span class="new-project-label">Production URL</span>
|
|
598
|
-
<sp-textfield
|
|
599
|
-
placeholder="https://example.com"
|
|
600
|
-
.value=${_form.url}
|
|
601
|
-
@input=${onInput("url")}
|
|
602
|
-
style="width: 100%"
|
|
603
|
-
></sp-textfield>
|
|
604
|
-
</label>
|
|
605
|
-
|
|
606
|
-
<label class="new-project-field">
|
|
607
|
-
<span class="new-project-label">Deployment Adapter</span>
|
|
608
|
-
<sp-picker label="Adapter" .value=${_form.adapter} @change=${onAdapterChange}>
|
|
609
|
-
<sp-menu-item value="static">Static</sp-menu-item>
|
|
610
|
-
<sp-menu-item value="cloudflare-pages">Cloudflare Pages</sp-menu-item>
|
|
611
|
-
<sp-menu-item value="node">Node</sp-menu-item>
|
|
612
|
-
<sp-menu-item value="bun">Bun</sp-menu-item>
|
|
613
|
-
</sp-picker>
|
|
614
|
-
</label>
|
|
615
|
-
|
|
616
|
-
${renderDesignFields({ rerender: renderModal })}
|
|
529
|
+
<div class="new-project-tab-intro">
|
|
530
|
+
The site's address, deployment target and design tokens are project settings — set
|
|
531
|
+
them from Settings once the project is open.
|
|
532
|
+
</div>
|
|
617
533
|
`
|
|
618
534
|
}
|
|
619
535
|
`;
|
|
@@ -621,7 +537,14 @@ function renderModal() {
|
|
|
621
537
|
// ─── Footer ────────────────────────────────────────────────────────────────
|
|
622
538
|
|
|
623
539
|
const footerTpl = () => {
|
|
540
|
+
const cancel = html`
|
|
541
|
+
<sp-button variant="secondary" ?disabled=${_creating} @click=${closeNewProjectModal}>
|
|
542
|
+
Cancel
|
|
543
|
+
</sp-button>
|
|
544
|
+
`;
|
|
624
545
|
if (isImportRunning()) {
|
|
546
|
+
// One cancel, not two: the run's own Cancel is the step's Cancel, and dismissing the modal
|
|
547
|
+
// (Escape, the underlay, the header ✕) aborts the run on the way out.
|
|
625
548
|
return html`
|
|
626
549
|
<sp-button variant="secondary" @click=${() => cancelImport(importCtx)}>
|
|
627
550
|
Cancel Import
|
|
@@ -631,7 +554,7 @@ function renderModal() {
|
|
|
631
554
|
if (_step === "source") {
|
|
632
555
|
const gated = (_tab === "import" || _tab === "agent") && !aiGateOpen();
|
|
633
556
|
return html`
|
|
634
|
-
|
|
557
|
+
${cancel}
|
|
635
558
|
${gated ? "" : html`<sp-button variant="accent" @click=${goNext}>Next</sp-button>`}
|
|
636
559
|
`;
|
|
637
560
|
}
|
|
@@ -654,6 +577,7 @@ function renderModal() {
|
|
|
654
577
|
</sp-button>
|
|
655
578
|
`;
|
|
656
579
|
return html`
|
|
580
|
+
${cancel}
|
|
657
581
|
<sp-button variant="secondary" ?disabled=${_creating} @click=${goBack}>Back</sp-button>
|
|
658
582
|
${primary}
|
|
659
583
|
`;
|
|
@@ -668,16 +592,11 @@ function renderModal() {
|
|
|
668
592
|
|
|
669
593
|
const tpl = html`
|
|
670
594
|
<sp-underlay open @close=${closeNewProjectModal}></sp-underlay>
|
|
671
|
-
<div
|
|
672
|
-
class="new-project-modal"
|
|
673
|
-
@keydown=${(e: KeyboardEvent) => {
|
|
674
|
-
if (e.key === "Escape") {
|
|
675
|
-
closeNewProjectModal();
|
|
676
|
-
}
|
|
677
|
-
}}
|
|
678
|
-
>
|
|
595
|
+
<div class="new-project-modal" data-jx-region="overlay.dialog:new-project">
|
|
679
596
|
<div class="new-project-modal-header">
|
|
680
|
-
<h2 class="new-project-modal-title">
|
|
597
|
+
<h2 class="new-project-modal-title">
|
|
598
|
+
${_step === "source" ? "Choose a starting point" : "Name your project"}
|
|
599
|
+
</h2>
|
|
681
600
|
<sp-action-button quiet size="s" @click=${closeNewProjectModal} title="Close">
|
|
682
601
|
<sp-icon-close slot="icon"></sp-icon-close>
|
|
683
602
|
</sp-action-button>
|
|
@@ -687,8 +606,7 @@ function renderModal() {
|
|
|
687
606
|
? html`
|
|
688
607
|
<div class="new-project-tabs">
|
|
689
608
|
<sp-tabs selected=${_tab} quiet @change=${onTabChange}>
|
|
690
|
-
<sp-tab value="
|
|
691
|
-
<sp-tab value="starter" label="Starter Site"></sp-tab>
|
|
609
|
+
<sp-tab value="starter" label="Starters"></sp-tab>
|
|
692
610
|
${platform.importSite ? html`<sp-tab value="import" label="Import"></sp-tab>` : ""}
|
|
693
611
|
<sp-tab value="agent" label="Agent"></sp-tab>
|
|
694
612
|
</sp-tabs>
|
|
@@ -716,10 +634,68 @@ function renderModal() {
|
|
|
716
634
|
`;
|
|
717
635
|
|
|
718
636
|
if (!_handle) {
|
|
719
|
-
_handle = openModal(tpl);
|
|
637
|
+
_handle = openModal(tpl, { label: "New Project", onDismiss: closeNewProjectModal });
|
|
720
638
|
} else {
|
|
721
639
|
_handle.update(tpl);
|
|
722
640
|
}
|
|
723
641
|
}
|
|
724
642
|
|
|
725
643
|
let _dirDerived = true;
|
|
644
|
+
|
|
645
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
646
|
+
|
|
647
|
+
/** The wizard's source tabs, in strip order — the declared values of `project.new`'s `tab`. */
|
|
648
|
+
export const NEW_PROJECT_TABS = ["starter", "import", "agent"] as const;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Open the New Project wizard.
|
|
652
|
+
*
|
|
653
|
+
* `tab` is declared as an enum rather than passed through, because the two non-default tabs are AI
|
|
654
|
+
* gated: naming one that does not exist would open the wizard on Starters and a shot would record
|
|
655
|
+
* that as "the Import tab". The wizard resolves the returned promise when the project is created or
|
|
656
|
+
* dismissed; the command deliberately does not await it — opening a modal is the action, and
|
|
657
|
+
* blocking `run` until a human finishes a wizard would hold the palette open behind it.
|
|
658
|
+
*
|
|
659
|
+
* @returns {AnyCommand[]}
|
|
660
|
+
*/
|
|
661
|
+
export function newProjectCommands(): AnyCommand[] {
|
|
662
|
+
return [
|
|
663
|
+
{
|
|
664
|
+
args: {
|
|
665
|
+
additionalProperties: false,
|
|
666
|
+
properties: {
|
|
667
|
+
tab: enumProperty(NEW_PROJECT_TABS, "Which source tab to open on. Defaults to Starters."),
|
|
668
|
+
},
|
|
669
|
+
required: [],
|
|
670
|
+
type: "object",
|
|
671
|
+
},
|
|
672
|
+
category: "Project",
|
|
673
|
+
id: "project.new",
|
|
674
|
+
level: "application",
|
|
675
|
+
menus: ["commandbar/overflow", "palette"],
|
|
676
|
+
group: "1_file",
|
|
677
|
+
aiTool: {
|
|
678
|
+
description:
|
|
679
|
+
"Open the New Project wizard, optionally on the Starters, Import or Agent tab.",
|
|
680
|
+
name: "open_new_project",
|
|
681
|
+
},
|
|
682
|
+
run: (_commandCtx, args) => {
|
|
683
|
+
const tab =
|
|
684
|
+
(args as { tab?: unknown }).tab === undefined
|
|
685
|
+
? undefined
|
|
686
|
+
: enumArg("project.new", args, "tab", NEW_PROJECT_TABS);
|
|
687
|
+
void openNewProjectModal(tab === undefined ? {} : { tab });
|
|
688
|
+
},
|
|
689
|
+
title: "New Project…",
|
|
690
|
+
},
|
|
691
|
+
];
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Register the New Project verb.
|
|
696
|
+
*
|
|
697
|
+
* @param {CommandRegistry} registry
|
|
698
|
+
*/
|
|
699
|
+
export function registerNewProjectCommands(registry: CommandRegistry): void {
|
|
700
|
+
registry.registerAll(newProjectCommands());
|
|
701
|
+
}
|