@agent-native/core 0.169.0 → 0.170.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/agent-native.eject.json +4 -1
- package/bin/agent-native.js +23 -5
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/analytics/actions/bigquery-table-info.ts +3 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/search-bigquery-schema.ts +130 -4
- package/corpus/templates/analytics/agent-native.config.ts +1 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +36 -23
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/lib/dashboard-visibility.ts +41 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +34 -9
- package/corpus/templates/analytics/app/routes/$.tsx +10 -0
- package/corpus/templates/analytics/app/routes.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-08-21-dashboard-filters-keep-other-users-dashboards-out-of-mine.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
- package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
- package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
- package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +14 -3
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +33 -3
- package/corpus/templates/analytics/vitest.config.ts +6 -1
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/assets/app/routes/library.tsx +5 -3
- package/corpus/templates/assets/app/routes.ts +3 -1
- package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
- package/corpus/templates/assets/vitest.config.ts +6 -1
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/brain/app/routes/sources.tsx +8 -3
- package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
- package/corpus/templates/brain/server/lib/brain.ts +27 -2
- package/corpus/templates/brain/vitest.config.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
- package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
- package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
- package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
- package/corpus/templates/calendar/app/routes.ts +3 -1
- package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
- package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
- package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
- package/corpus/templates/calendar/server/onboarding.ts +85 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/calendar/shared/api.ts +9 -1
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/chat/app/routes.ts +3 -1
- package/corpus/templates/chat/vitest.config.ts +8 -0
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/clips/actions/get-meeting.ts +9 -4
- package/corpus/templates/clips/actions/list-recordings.ts +16 -3
- package/corpus/templates/clips/actions/search-meetings.ts +1 -0
- package/corpus/templates/clips/actions/stop-meeting-recording.ts +87 -6
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -1
- package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
- package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
- package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
- package/corpus/templates/clips/desktop/src/app.tsx +53 -24
- package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
- package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
- package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
- package/corpus/templates/clips/server/lib/emails.ts +17 -33
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
- package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
- package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
- package/corpus/templates/content/app/i18n-data.ts +25 -0
- package/corpus/templates/content/app/routes.ts +3 -1
- package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
- package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
- package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
- package/corpus/templates/content/vitest.config.ts +7 -1
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1386 -92
- package/corpus/templates/design/actions/generate-design.ts +98 -47
- package/corpus/templates/design/actions/get-design-system.ts +6 -1
- package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
- package/corpus/templates/design/app/components/design/EditPanel.tsx +15 -47
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2060 -144
- package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
- package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -8
- package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +13 -8
- package/corpus/templates/design/app/i18n-data.ts +11 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
- package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +99 -57
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +39 -8
- package/corpus/templates/design/app/pages/DesignSystems.tsx +137 -43
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- package/corpus/templates/design/app/pages/Templates.tsx +0 -10
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
- package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
- package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
- package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
- package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
- package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
- package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
- package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
- package/corpus/templates/design/app/pages/design-editor/preview-navigation.ts +25 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
- package/corpus/templates/design/app/routes.ts +3 -1
- package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
- package/corpus/templates/design/package.json +2 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
- package/corpus/templates/design/shared/canvas-math.ts +612 -206
- package/corpus/templates/design/shared/pen-path.ts +37 -0
- package/corpus/templates/design/vitest.config.ts +7 -1
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
- package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
- package/corpus/templates/dispatch/app/routes.ts +3 -1
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/factory/.env.example +2 -7
- package/corpus/templates/factory/AGENTS.md +3 -0
- package/corpus/templates/factory/README.md +5 -3
- package/corpus/templates/factory/actions/create-factory.ts +16 -3
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
- package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
- package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
- package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
- package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
- package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
- package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
- package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
- package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
- package/corpus/templates/factory/app/routes/factory.tsx +84 -11
- package/corpus/templates/factory/app/routes.ts +3 -1
- package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
- package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
- package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
- package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
- package/corpus/templates/factory/vitest.config.ts +17 -2
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
- package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
- package/corpus/templates/forms/vitest.config.ts +1 -0
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/macros/app/routes.ts +3 -1
- package/corpus/templates/macros/vitest.config.ts +6 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
- package/corpus/templates/mail/app/hooks/use-emails.ts +13 -3
- package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
- package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
- package/corpus/templates/mail/app/routes/$.tsx +9 -0
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
- package/corpus/templates/mail/app/routes/$view.tsx +47 -1
- package/corpus/templates/mail/app/routes.ts +3 -1
- package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
- package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
- package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
- package/corpus/templates/mail/server/onboarding.ts +66 -18
- package/corpus/templates/mail/vitest.config.ts +6 -1
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/plan/app/routes/settings.tsx +4 -1
- package/corpus/templates/plan/app/routes.ts +3 -1
- package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/plan/netlify.toml +1 -1
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/slides/actions/patch-deck.ts +79 -10
- package/corpus/templates/slides/actions/update-slide.ts +11 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
- package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
- package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/slides/app/routes.ts +3 -1
- package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
- package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/slides/tsconfig.json +5 -0
- package/corpus/templates/slides/vitest.config.ts +6 -1
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
- package/corpus/templates/tasks/app/routes.ts +3 -1
- package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/tasks/vitest.config.ts +7 -1
- package/dist/action.d.ts +91 -0
- package/dist/action.js +50 -0
- package/dist/agent/abort-reasons.d.ts +38 -0
- package/dist/agent/abort-reasons.js +49 -0
- package/dist/agent/engine/ai-sdk-engine.js +8 -5
- package/dist/agent/engine/anthropic-engine.js +7 -5
- package/dist/agent/engine/credential-errors.d.ts +1 -1
- package/dist/agent/engine/credential-errors.js +2 -2
- package/dist/agent/engine/first-event-timeout.d.ts +42 -17
- package/dist/agent/engine/first-event-timeout.js +67 -25
- package/dist/agent/production-agent.d.ts +23 -0
- package/dist/agent/production-agent.js +107 -102
- package/dist/agent/run-loop-with-resume.d.ts +2 -28
- package/dist/agent/run-loop-with-resume.js +25 -40
- package/dist/agent/run-manager.js +5 -4
- package/dist/agent/run-store.d.ts +55 -0
- package/dist/agent/run-store.js +124 -1
- package/dist/agent/tool-search.js +2 -1
- package/dist/agent/types.d.ts +9 -4
- package/dist/app-config/configuration-error.d.ts +11 -0
- package/dist/app-config/configuration-error.js +14 -0
- package/dist/app-config/index.d.ts +1 -0
- package/dist/app-config/index.js +1 -0
- package/dist/app-config/integrations.d.ts +1 -0
- package/dist/app-config/integrations.js +10 -0
- package/dist/app-config/plugins.d.ts +34 -0
- package/dist/app-config/plugins.js +39 -0
- package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
- package/dist/app-config/run-lifecycle-invariants.js +18 -25
- package/dist/app-config/schema.d.ts +16 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/chat-threads/schema-migrations.js +20 -0
- package/dist/chat-threads/store.js +21 -4
- package/dist/cli/native-dependencies.d.ts +4 -0
- package/dist/cli/native-dependencies.js +15 -0
- package/dist/client/AssistantChat.js +47 -15
- package/dist/client/ConnectBuilderCard.d.ts +3 -1
- package/dist/client/ConnectBuilderCard.js +6 -3
- package/dist/client/EnvironmentBadge.d.ts +1 -1
- package/dist/client/EnvironmentBadge.js +40 -5
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.js +35 -14
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +2 -1
- package/dist/client/agent-page/use-jobs.js +3 -5
- package/dist/client/agent-sidebar-state.js +3 -1
- package/dist/client/blocks/library/code-tabs.js +5 -0
- package/dist/client/blocks/library/code.js +1 -0
- package/dist/client/chat/message-components.d.ts +7 -0
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/run-recovery.js +5 -2
- package/dist/client/chat/tool-call-display.js +9 -3
- package/dist/client/chat-first/apps-rail.js +2 -2
- package/dist/client/chat-model-groups.d.ts +12 -0
- package/dist/client/chat-model-groups.js +3 -2
- package/dist/client/error-format.js +12 -0
- package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
- package/dist/client/integrations/GoogleProductLogo.js +45 -0
- package/dist/client/integrations/index.d.ts +2 -0
- package/dist/client/integrations/index.js +2 -0
- package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
- package/dist/client/integrations/workspace-provider-oauth.js +13 -0
- package/dist/client/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/route-state.js +6 -0
- package/dist/client/settings/SettingsTabsPage.js +10 -6
- package/dist/client/sharing/ShareButton.js +11 -2
- package/dist/client/use-chat-models.d.ts +6 -0
- package/dist/client/use-chat-models.js +10 -0
- package/dist/client/use-db-sync.js +27 -9
- package/dist/client/workspace-app-navigation.d.ts +10 -0
- package/dist/client/workspace-app-navigation.js +38 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +111 -9
- package/dist/connections/catalog.js +86 -30
- package/dist/db/create-get-db.js +18 -0
- package/dist/db/ddl-guard.d.ts +0 -4
- package/dist/db/ddl-guard.js +46 -0
- package/dist/deploy/build.d.ts +32 -0
- package/dist/deploy/build.js +241 -16
- package/dist/deploy/function-bundle.d.ts +45 -0
- package/dist/deploy/function-bundle.js +337 -0
- package/dist/deploy/workspace-deploy.js +19 -1
- package/dist/eject/workspace-connections.js +4 -0
- package/dist/email-catalog/registry.d.ts +4 -0
- package/dist/email-catalog/registry.js +79 -14
- package/dist/extensions/content-patch.js +14 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/plugin.d.ts +10 -0
- package/dist/integrations/plugin.js +40 -6
- package/dist/jobs/actions/run-automation-now.d.ts +2 -1
- package/dist/jobs/actions/run-automation-now.js +11 -5
- package/dist/jobs/frontmatter.js +53 -2
- package/dist/jobs/run-now.d.ts +11 -1
- package/dist/jobs/run-now.js +42 -7
- package/dist/jobs/scheduler.d.ts +1 -0
- package/dist/jobs/scheduler.js +2 -1
- package/dist/localization/core-messages/ar-SA.js +4 -1
- package/dist/localization/core-messages/de-DE.js +4 -1
- package/dist/localization/core-messages/en-US.d.ts +4 -1
- package/dist/localization/core-messages/en-US.js +4 -1
- package/dist/localization/core-messages/es-ES.js +4 -1
- package/dist/localization/core-messages/fr-FR.js +4 -1
- package/dist/localization/core-messages/hi-IN.js +4 -1
- package/dist/localization/core-messages/ja-JP.js +4 -1
- package/dist/localization/core-messages/ko-KR.js +4 -1
- package/dist/localization/core-messages/pt-BR.js +4 -1
- package/dist/localization/core-messages/zh-CN.js +4 -1
- package/dist/localization/core-messages/zh-TW.js +4 -1
- package/dist/localization/core-messages.d.ts +4 -1
- package/dist/localization/default-messages.d.ts +2 -5
- package/dist/localization/default-messages.js +2 -5
- package/dist/mcp/build-server.d.ts +9 -0
- package/dist/mcp/build-server.js +37 -8
- package/dist/mcp-client/oauth-client.d.ts +7 -0
- package/dist/mcp-client/oauth-client.js +12 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/lifecycle.d.ts +11 -0
- package/dist/oauth-tokens/lifecycle.js +17 -0
- package/dist/oauth-tokens/store.js +7 -0
- package/dist/observability/posthog-ai.d.ts +15 -1
- package/dist/observability/posthog-ai.js +24 -12
- package/dist/observability/traces.js +158 -28
- package/dist/onboarding/app-profile.js +2 -2
- package/dist/onboarding/plugin.js +10 -2
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/scripts/db/check-scoping.js +9 -6
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
- package/dist/server/agent-chat/action-filters-a2a.js +48 -9
- package/dist/server/agent-chat-plugin.js +36 -9
- package/dist/server/agent-discovery.js +43 -20
- package/dist/server/auth.js +18 -16
- package/dist/server/beta-opt-out-html.js +45 -4
- package/dist/server/better-auth-instance.d.ts +2 -1
- package/dist/server/better-auth-instance.js +23 -7
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.js +23 -1
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.js +87 -6
- package/dist/server/builder-oauth.d.ts +1 -7
- package/dist/server/builder-oauth.js +80 -163
- package/dist/server/core-routes-plugin.d.ts +29 -0
- package/dist/server/core-routes-plugin.js +113 -21
- package/dist/server/default-plugins.d.ts +18 -0
- package/dist/server/default-plugins.js +22 -0
- package/dist/server/edge.d.ts +1 -0
- package/dist/server/edge.js +1 -0
- package/dist/server/framework-request-handler.js +31 -3
- package/dist/server/google-oauth.d.ts +3 -0
- package/dist/server/google-oauth.js +3 -0
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +3 -3
- package/dist/server/onboarding-html.js +37 -3
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.js +72 -20
- package/dist/shared/agent-sidebar-url.d.ts +1 -0
- package/dist/shared/agent-sidebar-url.js +1 -0
- package/dist/shared/environment-lanes.d.ts +2 -0
- package/dist/shared/environment-lanes.js +3 -1
- package/dist/shared/index.d.ts +3 -1
- package/dist/shared/index.js +3 -1
- package/dist/shared/surface-visibility.d.ts +31 -0
- package/dist/shared/surface-visibility.js +57 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/chat/app/routes.ts +3 -1
- package/dist/templates/chat/vitest.config.ts +8 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/default/app/routes.ts +3 -1
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/tracking/registry.d.ts +11 -0
- package/dist/tracking/registry.js +5 -2
- package/dist/triggers/actions.js +10 -3
- package/dist/usage/store.js +23 -3
- package/dist/user-profile/actions/get-auth-methods.js +18 -5
- package/dist/vite/client.js +24 -5
- package/docs/content/actions-access-control.mdx +43 -4
- package/docs/content/actions-defining.mdx +16 -0
- package/docs/content/template-clips-capture-everywhere.mdx +29 -30
- package/docs/content/template-clips-developers.mdx +4 -4
- package/docs/content/template-clips.mdx +3 -1
- package/package.json +3 -3
- package/src/eject/workspace-connections.ts +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/chat/app/routes.ts +3 -1
- package/src/templates/chat/vitest.config.ts +8 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/default/app/routes.ts +3 -1
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- /package/corpus/templates/dispatch/app/routes/{apps.$appId.tsx → apps.$appId.$.tsx} +0 -0
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
useCallback,
|
|
27
27
|
useEffect,
|
|
28
28
|
useMemo,
|
|
29
|
+
useRef,
|
|
29
30
|
useState,
|
|
30
31
|
type ReactNode,
|
|
31
32
|
} from "react";
|
|
@@ -72,6 +73,12 @@ import {
|
|
|
72
73
|
} from "@/lib/design-system-preview";
|
|
73
74
|
|
|
74
75
|
import { QueryErrorState } from "../components/QueryErrorState";
|
|
76
|
+
import {
|
|
77
|
+
builderRefreshKey,
|
|
78
|
+
parseDesignSystemData,
|
|
79
|
+
shouldRefreshBuilderDesignSystem,
|
|
80
|
+
type DesignSystemData,
|
|
81
|
+
} from "../lib/design-system-data";
|
|
75
82
|
|
|
76
83
|
interface DesignSystem {
|
|
77
84
|
id: string;
|
|
@@ -88,29 +95,21 @@ interface DesignSystem {
|
|
|
88
95
|
updatedAt?: string;
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
};
|
|
107
|
-
spacing?: Record<string, unknown>;
|
|
108
|
-
borders?: Record<string, unknown>;
|
|
109
|
-
logos?: Array<{ url?: string; name?: string; variant?: string }>;
|
|
110
|
-
defaults?: Record<string, unknown>;
|
|
111
|
-
notes?: unknown;
|
|
112
|
-
/** The source system's own named vocabulary; absent on kits predating it. */
|
|
113
|
-
tokens?: unknown;
|
|
98
|
+
type BuilderRefreshResult = {
|
|
99
|
+
synced: boolean;
|
|
100
|
+
status?: string;
|
|
101
|
+
rejectedTokenCount?: number;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
function isTerminalBuilderStatus(status?: string): boolean {
|
|
105
|
+
return (
|
|
106
|
+
status === "ready" ||
|
|
107
|
+
status === "complete" ||
|
|
108
|
+
status === "completed" ||
|
|
109
|
+
status === "error" ||
|
|
110
|
+
status === "failed" ||
|
|
111
|
+
status === "cancelled"
|
|
112
|
+
);
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
export default function DesignSystems() {
|
|
@@ -132,6 +131,19 @@ export default function DesignSystems() {
|
|
|
132
131
|
const setDefaultMutation = useActionMutation("set-default-design-system");
|
|
133
132
|
const deleteMutation = useActionMutation("delete-design-system");
|
|
134
133
|
const updateMutation = useActionMutation("update-design-system");
|
|
134
|
+
const refreshBuilderSystemMutation = useActionMutation<
|
|
135
|
+
BuilderRefreshResult,
|
|
136
|
+
{ id: string }
|
|
137
|
+
>("refresh-design-system-with-builder", {
|
|
138
|
+
skipActionQueryInvalidation: true,
|
|
139
|
+
});
|
|
140
|
+
const refreshBuilderSystemRef = useRef(
|
|
141
|
+
refreshBuilderSystemMutation.mutateAsync,
|
|
142
|
+
);
|
|
143
|
+
refreshBuilderSystemRef.current = refreshBuilderSystemMutation.mutateAsync;
|
|
144
|
+
const settledBuilderRefreshesRef = useRef(new Set<string>());
|
|
145
|
+
const stoppedBuilderRefreshesRef = useRef(new Set<string>());
|
|
146
|
+
const activeBuilderRefreshesRef = useRef(new Set<string>());
|
|
135
147
|
|
|
136
148
|
const designSystems = data?.designSystems ?? [];
|
|
137
149
|
const selectedDesignSystemId = searchParams.get("designSystemId");
|
|
@@ -362,13 +374,107 @@ export default function DesignSystems() {
|
|
|
362
374
|
});
|
|
363
375
|
}, [selectedSystemIds, queryClient, exitSelectionMode, deleteMutation, t]);
|
|
364
376
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
377
|
+
useEffect(() => {
|
|
378
|
+
const builderSystemEntries = designSystems
|
|
379
|
+
.filter(shouldRefreshBuilderDesignSystem)
|
|
380
|
+
.map((system) => ({
|
|
381
|
+
id: system.id,
|
|
382
|
+
key: builderRefreshKey(system),
|
|
383
|
+
}))
|
|
384
|
+
.filter(
|
|
385
|
+
({ key }) =>
|
|
386
|
+
!settledBuilderRefreshesRef.current.has(key) &&
|
|
387
|
+
!stoppedBuilderRefreshesRef.current.has(key) &&
|
|
388
|
+
!activeBuilderRefreshesRef.current.has(key),
|
|
389
|
+
);
|
|
390
|
+
if (builderSystemEntries.length === 0) return;
|
|
391
|
+
|
|
392
|
+
let disposed = false;
|
|
393
|
+
const timers: Array<ReturnType<typeof setTimeout>> = [];
|
|
394
|
+
const maxAttempts = 5;
|
|
395
|
+
const maxPolls = 3;
|
|
396
|
+
const retryDelayMs = 5_000;
|
|
397
|
+
const retryPollDelayMs = 30_000;
|
|
398
|
+
|
|
399
|
+
const scheduleRetry = (
|
|
400
|
+
entry: { id: string; key: string },
|
|
401
|
+
delayMs: number,
|
|
402
|
+
attempt: number,
|
|
403
|
+
pollCount: number,
|
|
404
|
+
): void => {
|
|
405
|
+
if (disposed) return;
|
|
406
|
+
timers.push(
|
|
407
|
+
setTimeout(() => {
|
|
408
|
+
void refresh(entry, attempt, pollCount);
|
|
409
|
+
}, delayMs),
|
|
410
|
+
);
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
const refresh = async (
|
|
414
|
+
entry: { id: string; key: string },
|
|
415
|
+
attempt: number,
|
|
416
|
+
pollCount: number,
|
|
417
|
+
): Promise<void> => {
|
|
418
|
+
try {
|
|
419
|
+
const result = await refreshBuilderSystemRef.current({ id: entry.id });
|
|
420
|
+
if (disposed) return;
|
|
421
|
+
if (result.synced) {
|
|
422
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
423
|
+
settledBuilderRefreshesRef.current.add(entry.key);
|
|
424
|
+
await queryClient.invalidateQueries({
|
|
425
|
+
queryKey: ["action", "list-design-systems"],
|
|
426
|
+
});
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (result.status === "conflict") {
|
|
430
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
431
|
+
stoppedBuilderRefreshesRef.current.add(entry.key);
|
|
432
|
+
await queryClient.invalidateQueries({
|
|
433
|
+
queryKey: ["action", "list-design-systems"],
|
|
434
|
+
});
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (result.status === "incomplete" || result.rejectedTokenCount) {
|
|
438
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
439
|
+
stoppedBuilderRefreshesRef.current.add(entry.key);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (isTerminalBuilderStatus(result.status)) {
|
|
443
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
444
|
+
settledBuilderRefreshesRef.current.add(entry.key);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
} catch {
|
|
448
|
+
if (disposed) return;
|
|
449
|
+
}
|
|
450
|
+
if (disposed) return;
|
|
451
|
+
const exhausted = attempt >= maxAttempts;
|
|
452
|
+
if (exhausted && pollCount >= maxPolls) {
|
|
453
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
454
|
+
stoppedBuilderRefreshesRef.current.add(entry.key);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
scheduleRetry(
|
|
458
|
+
entry,
|
|
459
|
+
exhausted ? retryPollDelayMs : retryDelayMs,
|
|
460
|
+
exhausted ? 0 : attempt + 1,
|
|
461
|
+
exhausted ? pollCount + 1 : pollCount,
|
|
462
|
+
);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
for (const entry of builderSystemEntries) {
|
|
466
|
+
activeBuilderRefreshesRef.current.add(entry.key);
|
|
467
|
+
void refresh(entry, 0, 0);
|
|
370
468
|
}
|
|
371
|
-
|
|
469
|
+
|
|
470
|
+
return () => {
|
|
471
|
+
disposed = true;
|
|
472
|
+
for (const timer of timers) clearTimeout(timer);
|
|
473
|
+
for (const entry of builderSystemEntries) {
|
|
474
|
+
activeBuilderRefreshesRef.current.delete(entry.key);
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
}, [designSystems, queryClient]);
|
|
372
478
|
|
|
373
479
|
useSetPageTitle(t("navigation.designSystems"));
|
|
374
480
|
|
|
@@ -486,7 +592,7 @@ export default function DesignSystems() {
|
|
|
486
592
|
|
|
487
593
|
{/* Design system cards */}
|
|
488
594
|
{designSystems.map((ds) => {
|
|
489
|
-
const parsed =
|
|
595
|
+
const parsed = parseDesignSystemData(ds.data);
|
|
490
596
|
const colors = parsed?.colors;
|
|
491
597
|
const primaryColor = getCssColorToken(colors?.primary);
|
|
492
598
|
const secondaryColor = getCssColorToken(colors?.secondary);
|
|
@@ -699,7 +805,7 @@ export default function DesignSystems() {
|
|
|
699
805
|
</AlertDialogCancel>
|
|
700
806
|
<AlertDialogAction
|
|
701
807
|
onClick={bulkDeleteOpen ? handleBulkDelete : handleDelete}
|
|
702
|
-
className="bg-
|
|
808
|
+
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 cursor-pointer"
|
|
703
809
|
>
|
|
704
810
|
{t("designSystems.actions.delete")}
|
|
705
811
|
</AlertDialogAction>
|
|
@@ -997,18 +1103,6 @@ function EmptyPreviewLine({
|
|
|
997
1103
|
);
|
|
998
1104
|
}
|
|
999
1105
|
|
|
1000
|
-
function parseDesignSystemData(dataStr: string): DesignSystemData | null {
|
|
1001
|
-
try {
|
|
1002
|
-
const parsed = JSON.parse(dataStr);
|
|
1003
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1004
|
-
return null;
|
|
1005
|
-
}
|
|
1006
|
-
return parsed as DesignSystemData;
|
|
1007
|
-
} catch {
|
|
1008
|
-
return null;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
1106
|
function parseDesignSystemAssets(
|
|
1013
1107
|
assetsStr?: string | null,
|
|
1014
1108
|
): Array<{ name?: string; url?: string; variant?: string }> {
|
|
@@ -864,6 +864,7 @@ export default function Index() {
|
|
|
864
864
|
value={search}
|
|
865
865
|
onChange={(e) => handleSearchChange(e.target.value)}
|
|
866
866
|
placeholder={t("home.searchPlaceholder")}
|
|
867
|
+
aria-label={t("home.searchPlaceholder")}
|
|
867
868
|
className="ps-8 h-8 w-48 bg-accent/50 border-border text-sm text-foreground/90 placeholder:text-muted-foreground/70"
|
|
868
869
|
/>
|
|
869
870
|
</div>
|
|
@@ -1232,7 +1233,7 @@ export default function Index() {
|
|
|
1232
1233
|
</AlertDialogCancel>
|
|
1233
1234
|
<AlertDialogAction
|
|
1234
1235
|
onClick={bulkDeleteOpen ? handleBulkDelete : handleDelete}
|
|
1235
|
-
className="bg-
|
|
1236
|
+
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 cursor-pointer"
|
|
1236
1237
|
>
|
|
1237
1238
|
{t("home.delete")}
|
|
1238
1239
|
</AlertDialogAction>
|
|
@@ -1262,6 +1263,7 @@ export default function Index() {
|
|
|
1262
1263
|
}
|
|
1263
1264
|
}}
|
|
1264
1265
|
placeholder={t("home.designName")}
|
|
1266
|
+
aria-label={t("home.designName")}
|
|
1265
1267
|
className="h-9 text-sm"
|
|
1266
1268
|
/>
|
|
1267
1269
|
<AlertDialogFooter>
|
|
@@ -302,16 +302,6 @@ export default function Templates() {
|
|
|
302
302
|
</p>
|
|
303
303
|
</div>
|
|
304
304
|
|
|
305
|
-
<div className="relative mb-6 md:hidden">
|
|
306
|
-
<IconSearch className="absolute start-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground/70" />
|
|
307
|
-
<Input
|
|
308
|
-
value={search}
|
|
309
|
-
onChange={(event) => setSearch(event.target.value)}
|
|
310
|
-
placeholder={t("templatesPage.searchPlaceholder")}
|
|
311
|
-
className="h-9 w-full bg-accent/50 ps-8 text-sm"
|
|
312
|
-
/>
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
305
|
{isLoading ? (
|
|
316
306
|
<TemplateGridSkeleton />
|
|
317
307
|
) : isError ? (
|
|
@@ -1134,6 +1134,16 @@ export function removeEmptyGeneratedGroupWrappers(
|
|
|
1134
1134
|
candidateParentAttrIds: ReadonlySet<string>,
|
|
1135
1135
|
): string {
|
|
1136
1136
|
if (candidateParentAttrIds.size === 0) return content;
|
|
1137
|
+
// Both are necessary conditions for isGeneratedGroupWrapperNode to ever
|
|
1138
|
+
// match. Checking them on the raw string first keeps a document with no
|
|
1139
|
+
// generated groups — the common case — from paying for a full projection of
|
|
1140
|
+
// post-edit content on every structural edit.
|
|
1141
|
+
if (
|
|
1142
|
+
!content.includes("data-agent-native-layer-name") ||
|
|
1143
|
+
!content.includes("Group")
|
|
1144
|
+
) {
|
|
1145
|
+
return content;
|
|
1146
|
+
}
|
|
1137
1147
|
let next = content;
|
|
1138
1148
|
// Loop: removing one empty wrapper can itself empty out ITS parent (e.g.
|
|
1139
1149
|
// ungrouping down a chain of nested generated groups), so keep sweeping
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { shouldUseLiveFileContent } from "@shared/html-content";
|
|
2
|
+
import DiffMatchPatch from "diff-match-patch";
|
|
3
|
+
import type * as Y from "yjs";
|
|
4
|
+
|
|
5
|
+
const { DIFF_DELETE, DIFF_EQUAL } = DiffMatchPatch;
|
|
2
6
|
|
|
3
7
|
export function shouldRebaseCollabDocFromStoredContent({
|
|
4
8
|
liveContent,
|
|
@@ -56,3 +60,49 @@ export function shouldApplyRemotePreviewContent({
|
|
|
56
60
|
}): boolean {
|
|
57
61
|
return !isLocalEdit && nextContent !== previousContent;
|
|
58
62
|
}
|
|
63
|
+
|
|
64
|
+
const diffMatchPatch = new DiffMatchPatch();
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Replace the collab document's text with `next` as the smallest set of
|
|
68
|
+
* disjoint splices, and report whether anything changed.
|
|
69
|
+
*
|
|
70
|
+
* Never `delete(0, length) + insert(0, next)`. That shape ships the whole
|
|
71
|
+
* document on every edit, the UndoManager pins every replaced copy so the doc
|
|
72
|
+
* grows without bound within a session, and it is wrong under concurrency:
|
|
73
|
+
* two peers each rewriting the whole text merge into a duplicated document
|
|
74
|
+
* instead of both edits.
|
|
75
|
+
*
|
|
76
|
+
* Disjoint rather than one prefix/suffix splice, because a single splice spans
|
|
77
|
+
* everything between the first and last changed character. An agent rewrite
|
|
78
|
+
* touching two ends of a screen would delete the untouched middle and take a
|
|
79
|
+
* concurrent edit inside it with it. This mirrors the server's own
|
|
80
|
+
* `applyTextToYDoc`, which has always diffed this way.
|
|
81
|
+
*/
|
|
82
|
+
export function writeCollabText(
|
|
83
|
+
ydoc: Y.Doc,
|
|
84
|
+
ytext: Y.Text,
|
|
85
|
+
next: string,
|
|
86
|
+
origin: unknown,
|
|
87
|
+
): boolean {
|
|
88
|
+
const current = ytext.toString();
|
|
89
|
+
if (current === next) return false;
|
|
90
|
+
// No cleanup pass: diff_cleanupEfficiency merges edits across equal runs
|
|
91
|
+
// shorter than Diff_EditCost (4), which deletes up to three untouched
|
|
92
|
+
// characters and takes any concurrent edit anchored in them along with it.
|
|
93
|
+
const diffs = diffMatchPatch.diff_main(current, next);
|
|
94
|
+
ydoc.transact(() => {
|
|
95
|
+
let cursor = 0;
|
|
96
|
+
for (const [operation, text] of diffs) {
|
|
97
|
+
if (operation === DIFF_EQUAL) {
|
|
98
|
+
cursor += text.length;
|
|
99
|
+
} else if (operation === DIFF_DELETE) {
|
|
100
|
+
ytext.delete(cursor, text.length);
|
|
101
|
+
} else {
|
|
102
|
+
ytext.insert(cursor, text);
|
|
103
|
+
cursor += text.length;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, origin);
|
|
107
|
+
return true;
|
|
108
|
+
}
|
package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface ApplyDesignEditorCommandArgs {
|
|
|
37
37
|
overviewScreens: OverviewScreen[];
|
|
38
38
|
setActiveFileId: Dispatch<SetStateAction<string | null>>;
|
|
39
39
|
setActiveInspectorTab: Dispatch<SetStateAction<InspectorTab>>;
|
|
40
|
-
setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel>>;
|
|
40
|
+
setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel | null>>;
|
|
41
41
|
setActiveTool: Dispatch<SetStateAction<DesignTool>>;
|
|
42
42
|
setDrawMode: Dispatch<SetStateAction<boolean>>;
|
|
43
43
|
setInteractDeviceName: Dispatch<SetStateAction<string>>;
|
package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts
CHANGED
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
waitForShaderWriteToSettle,
|
|
11
11
|
} from "@/components/design/inspector/GlslShaderPanel";
|
|
12
12
|
import type { ClipboardContentMutationPublication } from "@/lib/clipboard-content-lineage";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
resolveScreenCollabSyncTarget,
|
|
15
|
+
writeCollabText,
|
|
16
|
+
} from "@/pages/design-editor/collab-sync";
|
|
14
17
|
import { TAB_ID } from "@/pages/design-editor/editor-session";
|
|
15
18
|
import type { FileContentSaveRequest } from "@/pages/design-editor/editor-state";
|
|
16
19
|
import type { ContentHistoryEntry } from "@/pages/design-editor/history";
|
|
@@ -218,13 +221,12 @@ export function runApplyFileContentUpdate(
|
|
|
218
221
|
overviewDocConnected: !!(overviewYdoc && overviewIsSynced),
|
|
219
222
|
});
|
|
220
223
|
if (writeLiveDoc && overviewYdoc) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
overviewYdoc.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
224
|
+
writeCollabText(
|
|
225
|
+
overviewYdoc,
|
|
226
|
+
overviewYdoc.getText("content"),
|
|
227
|
+
nextContent,
|
|
228
|
+
TAB_ID,
|
|
229
|
+
);
|
|
228
230
|
}
|
|
229
231
|
if (options.persist === false) {
|
|
230
232
|
cancelQueuedFileContentSave(fileId);
|
package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts
CHANGED
|
@@ -7,6 +7,7 @@ import * as Y from "yjs";
|
|
|
7
7
|
|
|
8
8
|
import { trace } from "@/components/design/design-trace";
|
|
9
9
|
import type { ClipboardContentMutationPublication } from "@/lib/clipboard-content-lineage";
|
|
10
|
+
import { writeCollabText } from "@/pages/design-editor/collab-sync";
|
|
10
11
|
import {
|
|
11
12
|
LOCAL_EDIT_ORIGIN,
|
|
12
13
|
TAB_ID,
|
|
@@ -289,17 +290,16 @@ export function runApplyLocalContentUpdate(
|
|
|
289
290
|
const ytext = ydoc.getText("content");
|
|
290
291
|
if (ytext.toString() !== nextContent) {
|
|
291
292
|
if (!yjsHistoryAvailable) {
|
|
292
|
-
// Untracked
|
|
293
|
+
// Untracked write (recordHistory:false callers such as the
|
|
293
294
|
// code-layer id-stamping effect, or history-suppressed replays) —
|
|
294
295
|
// see U1 note above: clear the undo stack so a stale tracked
|
|
295
296
|
// delta can't be replayed against content it no longer matches.
|
|
296
297
|
undoManagerRef.current?.clear(true, false);
|
|
297
298
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
},
|
|
299
|
+
writeCollabText(
|
|
300
|
+
ydoc,
|
|
301
|
+
ytext,
|
|
302
|
+
nextContent,
|
|
303
303
|
yjsHistoryAvailable ? LOCAL_EDIT_ORIGIN : TAB_ID,
|
|
304
304
|
);
|
|
305
305
|
}
|
|
@@ -50,7 +50,7 @@ export interface ApplyPendingVisualStylesWithAgentArgs {
|
|
|
50
50
|
pendingStructureVerificationStatus: PendingStructureVerificationStatus;
|
|
51
51
|
pendingVisualStyleEdits: PendingVisualStyleEdit[];
|
|
52
52
|
pendingVisualStylePrompt: string;
|
|
53
|
-
setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel>>;
|
|
53
|
+
setActiveLeftPanel: Dispatch<SetStateAction<DesignLeftPanel | null>>;
|
|
54
54
|
setApplyingViaHost: Dispatch<SetStateAction<boolean>>;
|
|
55
55
|
setPendingAgentHandoffBusy: Dispatch<SetStateAction<boolean>>;
|
|
56
56
|
setPendingStructureAckRequest: Dispatch<
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
resolveCodeLayerTargetFromBridge,
|
|
26
26
|
resolveCodeLayerTargetFromElementInfo,
|
|
27
27
|
} from "@/pages/design-editor/code-layer-state";
|
|
28
|
+
import { writeCollabText } from "@/pages/design-editor/collab-sync";
|
|
28
29
|
import type {
|
|
29
30
|
LiveScreenSnapshot,
|
|
30
31
|
PatchProofState,
|
|
@@ -176,6 +177,9 @@ export function runCommitVisualStyles(
|
|
|
176
177
|
elementInfo?: ElementInfo;
|
|
177
178
|
/** Pre-gesture values, for the pending-edit revert stack. */
|
|
178
179
|
originalStyles?: Record<string, string>;
|
|
180
|
+
/** The write is a side effect of a gesture on another element, so it must
|
|
181
|
+
* not move the selection onto the element it touched. */
|
|
182
|
+
preserveSelection?: boolean;
|
|
179
183
|
} = {},
|
|
180
184
|
) {
|
|
181
185
|
trace("persist", "commit-styles", {
|
|
@@ -657,17 +661,16 @@ export function runCommitVisualStyles(
|
|
|
657
661
|
const ytext = ydoc.getText("content");
|
|
658
662
|
if (ytext.toString() !== resolvedNextContent) {
|
|
659
663
|
if (!yjsHistoryAvailable) {
|
|
660
|
-
// Untracked
|
|
664
|
+
// Untracked write (overview mode with a still-live
|
|
661
665
|
// single-mode UndoManager, or history-suppressed replay) —
|
|
662
666
|
// see U1 note: clear the undo stack so a stale tracked delta
|
|
663
667
|
// can't be replayed against content it no longer matches.
|
|
664
668
|
undoManagerRef.current?.clear(true, false);
|
|
665
669
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
},
|
|
670
|
+
writeCollabText(
|
|
671
|
+
ydoc,
|
|
672
|
+
ytext,
|
|
673
|
+
resolvedNextContent,
|
|
671
674
|
yjsHistoryAvailable ? LOCAL_EDIT_ORIGIN : TAB_ID,
|
|
672
675
|
);
|
|
673
676
|
}
|
|
@@ -687,7 +690,15 @@ export function runCommitVisualStyles(
|
|
|
687
690
|
setContentRenderRevision((revision) => revision + 1);
|
|
688
691
|
}
|
|
689
692
|
}
|
|
690
|
-
if (
|
|
693
|
+
if (options.preserveSelection) return;
|
|
694
|
+
// A commit must never shrink the selection: a group transform commits one
|
|
695
|
+
// style change per member, so selecting the committed node keeps only the
|
|
696
|
+
// member that happened to commit last.
|
|
697
|
+
if (resolvedNode) {
|
|
698
|
+
setSelectedLayerIdsState((current) =>
|
|
699
|
+
current.includes(resolvedNode.id) ? current : [resolvedNode.id],
|
|
700
|
+
);
|
|
701
|
+
}
|
|
691
702
|
setSelectedElement((prev) => {
|
|
692
703
|
if (options.elementInfo) return options.elementInfo;
|
|
693
704
|
if (!prev) return prev;
|
|
@@ -1,33 +1,13 @@
|
|
|
1
|
-
import type { CodeLayerNode, CodeLayerTreeNode } from "@shared/code-layer";
|
|
2
1
|
import type { Dispatch, RefObject, SetStateAction } from "react";
|
|
3
2
|
|
|
4
3
|
import type { ElementInfo } from "@/components/design/types";
|
|
5
|
-
import {
|
|
6
|
-
collectCodeLayerAncestors,
|
|
7
|
-
elementInfoFromCodeLayerNode,
|
|
8
|
-
} from "@/pages/design-editor/code-layer-state";
|
|
9
|
-
import {
|
|
10
|
-
hasSelectableCodeLayerParent,
|
|
11
|
-
resolveEscapePopSelectionAction,
|
|
12
|
-
shouldEscapeToOverview,
|
|
13
|
-
} from "@/pages/design-editor/selection-state";
|
|
4
|
+
import { shouldEscapeToOverview } from "@/pages/design-editor/selection-state";
|
|
14
5
|
import type { DesignTool, EditorMode } from "@/pages/design-editor/types";
|
|
15
6
|
|
|
16
7
|
export interface EscapeHotkeyArgs {
|
|
17
8
|
activeBreakpointWidthStateRef: RefObject<number | undefined>;
|
|
18
9
|
activeTool: DesignTool;
|
|
19
10
|
cancelActiveEditorDrag: () => boolean;
|
|
20
|
-
codeLayerOwnerByNodeIdRef: RefObject<
|
|
21
|
-
Map<
|
|
22
|
-
string,
|
|
23
|
-
{
|
|
24
|
-
fileId: string;
|
|
25
|
-
node: CodeLayerNode;
|
|
26
|
-
tree: CodeLayerTreeNode[];
|
|
27
|
-
runtimeOnly: boolean;
|
|
28
|
-
}
|
|
29
|
-
>
|
|
30
|
-
>;
|
|
31
11
|
drawMode: boolean;
|
|
32
12
|
enterOverviewFromZoom: (nextMode?: EditorMode) => void;
|
|
33
13
|
focusedAnnotationSending: boolean;
|
|
@@ -40,11 +20,8 @@ export interface EscapeHotkeyArgs {
|
|
|
40
20
|
overviewAnnotationSending: boolean;
|
|
41
21
|
pinMode: boolean;
|
|
42
22
|
selectedElement: ElementInfo | null;
|
|
43
|
-
selectedLayerIdsState: string[];
|
|
44
|
-
setActiveFileId: Dispatch<SetStateAction<string | null>>;
|
|
45
23
|
setActiveTool: Dispatch<SetStateAction<DesignTool>>;
|
|
46
24
|
setDrawMode: Dispatch<SetStateAction<boolean>>;
|
|
47
|
-
setExpandedLayerIds: Dispatch<SetStateAction<string[]>>;
|
|
48
25
|
setHoveredElement: Dispatch<SetStateAction<ElementInfo | null>>;
|
|
49
26
|
setMode: Dispatch<SetStateAction<EditorMode>>;
|
|
50
27
|
setOverviewClearSelectionRequest: Dispatch<SetStateAction<number>>;
|
|
@@ -59,7 +36,6 @@ export function runEscapeHotkey({
|
|
|
59
36
|
activeBreakpointWidthStateRef,
|
|
60
37
|
activeTool,
|
|
61
38
|
cancelActiveEditorDrag,
|
|
62
|
-
codeLayerOwnerByNodeIdRef,
|
|
63
39
|
drawMode,
|
|
64
40
|
enterOverviewFromZoom,
|
|
65
41
|
focusedAnnotationSending,
|
|
@@ -72,11 +48,8 @@ export function runEscapeHotkey({
|
|
|
72
48
|
overviewAnnotationSending,
|
|
73
49
|
pinMode,
|
|
74
50
|
selectedElement,
|
|
75
|
-
selectedLayerIdsState,
|
|
76
|
-
setActiveFileId,
|
|
77
51
|
setActiveTool,
|
|
78
52
|
setDrawMode,
|
|
79
|
-
setExpandedLayerIds,
|
|
80
53
|
setHoveredElement,
|
|
81
54
|
setMode,
|
|
82
55
|
setOverviewClearSelectionRequest,
|
|
@@ -133,68 +106,9 @@ export function runEscapeHotkey({
|
|
|
133
106
|
enterOverviewFromZoom();
|
|
134
107
|
return;
|
|
135
108
|
}
|
|
136
|
-
// Figma
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
// The decision itself is a pure, unit-tested function
|
|
140
|
-
// (resolveEscapePopSelectionAction in design-editor/selection-state.ts);
|
|
141
|
-
// this reuses the same codeLayerOwnerByNodeIdRef/parentId ancestor walk
|
|
142
|
-
// handleSelectParentLayer (Shift+Enter / "\\") already uses, inlined
|
|
143
|
-
// here (rather than calling selectCodeLayerNodesForHotkey directly)
|
|
144
|
-
// since that helper is declared later in this component and referencing
|
|
145
|
-
// it from this callback's deps would hit its temporal-dead-zone before
|
|
146
|
-
// this render's declarations run.
|
|
147
|
-
const escapeSelectedLayerId =
|
|
148
|
-
selectedLayerIdsState[selectedLayerIdsState.length - 1];
|
|
149
|
-
const escapeOwner = escapeSelectedLayerId
|
|
150
|
-
? codeLayerOwnerByNodeIdRef.current.get(escapeSelectedLayerId)
|
|
151
|
-
: undefined;
|
|
152
|
-
// BUG-ESCAPE-SHELL: the flat codeLayerOwnerByNodeIdRef map (built from
|
|
153
|
-
// projection.nodes) still contains <html>/<body> entries with real
|
|
154
|
-
// parentId links even though the VISUAL layers tree collapses them away
|
|
155
|
-
// (shared/code-layer.ts's isCollapsibleDocumentShellNode). A bare
|
|
156
|
-
// Boolean(escapeOwner?.node.parentId) check treats a top-level layer's
|
|
157
|
-
// collapsed <body> ancestor as a selectable parent, so popping from the
|
|
158
|
-
// screen root would select <body> then <html> instead of stopping at the
|
|
159
|
-
// screen/frame level. hasSelectableCodeLayerParent excludes those shell
|
|
160
|
-
// nodes so the pop walk matches what the layers panel shows.
|
|
161
|
-
const escapeParentOwner = escapeOwner?.node.parentId
|
|
162
|
-
? codeLayerOwnerByNodeIdRef.current.get(escapeOwner.node.parentId)
|
|
163
|
-
: undefined;
|
|
164
|
-
const popAction = resolveEscapePopSelectionAction({
|
|
165
|
-
hasSelectedLayer: Boolean(escapeOwner),
|
|
166
|
-
hasLayerParent: hasSelectableCodeLayerParent({
|
|
167
|
-
parentNode: escapeParentOwner?.node,
|
|
168
|
-
}),
|
|
169
|
-
viewMode,
|
|
170
|
-
});
|
|
171
|
-
if (popAction.kind === "pop-to-parent-layer" && escapeOwner) {
|
|
172
|
-
const parentOwner = escapeParentOwner;
|
|
173
|
-
if (parentOwner && parentOwner.fileId === escapeOwner.fileId) {
|
|
174
|
-
setActiveFileId(parentOwner.fileId);
|
|
175
|
-
setOverviewSelectedScreenIds([]);
|
|
176
|
-
setSelectedLayerIdsState([parentOwner.node.id]);
|
|
177
|
-
setSelectedElement(elementInfoFromCodeLayerNode(parentOwner.node));
|
|
178
|
-
setExpandedLayerIds((current) => {
|
|
179
|
-
const next = new Set(current);
|
|
180
|
-
next.add(parentOwner.fileId);
|
|
181
|
-
collectCodeLayerAncestors(
|
|
182
|
-
parentOwner.tree,
|
|
183
|
-
parentOwner.node.id,
|
|
184
|
-
).forEach((ancestorId) => next.add(ancestorId));
|
|
185
|
-
return next.size === current.length ? current : Array.from(next);
|
|
186
|
-
});
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
// Parent couldn't be resolved (e.g. cross-file) — fall through to a
|
|
190
|
-
// full deselect below rather than silently doing nothing.
|
|
191
|
-
} else if (popAction.kind === "pop-to-screen-frame" && escapeOwner) {
|
|
192
|
-
setSelectedElement(null);
|
|
193
|
-
setSelectedLayerIdsState([]);
|
|
194
|
-
setOverviewSelectedScreenIds([escapeOwner.fileId]);
|
|
195
|
-
setOverviewClearSelectionRequest((request) => request + 1);
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
109
|
+
// Figma's Esc is "select none". Walking up one ancestor per press belongs to
|
|
110
|
+
// Shift+Enter / "\\" (handleSelectParentLayer) — Escape must never leave
|
|
111
|
+
// something selected, or there is no keystroke that reaches an empty canvas.
|
|
198
112
|
setSelectedElement(null);
|
|
199
113
|
setHoveredElement(null);
|
|
200
114
|
setOverviewSelectedScreenIds([]);
|
package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isScreenRootElementInfo,
|
|
16
16
|
shouldClearBridgeSelectionOnEmptyMarquee,
|
|
17
17
|
} from "@/pages/design-editor/selection-state";
|
|
18
|
+
import { resolveToolAfterSelection } from "@/pages/design-editor/tool-state";
|
|
18
19
|
import type { DesignTool, EditorMode } from "@/pages/design-editor/types";
|
|
19
20
|
|
|
20
21
|
export interface LayerMarqueeSelectionChangeArgs {
|
|
@@ -158,6 +159,6 @@ export function runLayerMarqueeSelectionChange(
|
|
|
158
159
|
setOverviewClearSelectionRequest((request) => request + 1);
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
setActiveTool(
|
|
162
|
+
setActiveTool(resolveToolAfterSelection);
|
|
162
163
|
setMode("edit");
|
|
163
164
|
}
|