@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
|
@@ -466,8 +466,10 @@ export async function resolveUsersWithCoverage(
|
|
|
466
466
|
}
|
|
467
467
|
|
|
468
468
|
const unresolvedUserIds = [...unresolvedUsers];
|
|
469
|
-
|
|
470
|
-
|
|
469
|
+
if (!directoryError) {
|
|
470
|
+
for (const id of unresolvedUserIds) {
|
|
471
|
+
results[id] = fallbackSlackUser(id);
|
|
472
|
+
}
|
|
471
473
|
}
|
|
472
474
|
|
|
473
475
|
// Resolve bot users from messages that have bot_id but no user
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
needsCorpusWorkflowForCoverageSensitiveRequest,
|
|
32
32
|
needsSourceRecordBodyWorkflowForCoverageSensitiveRequest,
|
|
33
33
|
registerGroundingActions,
|
|
34
|
+
stripInjectedAnalyticsGuardContext,
|
|
34
35
|
} from "../lib/real-data-actions";
|
|
35
36
|
|
|
36
37
|
// Which actions return real data-source evidence is a fact each action states
|
|
@@ -107,7 +108,10 @@ function hasPartialDashboardBuild(
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
export const BOUNDED_STRUCTURED_LOOKUP_GUIDANCE =
|
|
110
|
-
"BOUNDED STRUCTURED LOOKUP FAST PATH — Treat existing analytics work like an engineer treats existing code: grep before writing. For an ordinary count, aggregate, grouped metric, trend, or record lookup, first call `search-analytics-query-catalog` once with focused metric/entity terms. It searches accessible dashboard names, chart titles/descriptions/saved queries, shipped dashboard patterns, and data-dictionary definitions together. Prefer the strongest approved dictionary or saved-chart match, preserve its source and business logic, adapt only the requested filters and explicit time window, then run one bounded query against that source. A user-named source wins, but still use a matching saved definition when it supplies the source's proven query shape. If there is no useful match, inspect
|
|
111
|
+
"BOUNDED STRUCTURED LOOKUP FAST PATH — Treat existing analytics work like an engineer treats existing code: grep before writing. For an ordinary count, aggregate, grouped metric, trend, or record lookup, first call `search-analytics-query-catalog` once with focused metric/entity terms. It searches accessible dashboard names, chart titles/descriptions/saved queries, shipped dashboard patterns, and data-dictionary definitions together. Prefer the strongest approved dictionary or saved-chart match, preserve its source and business logic, adapt only the requested filters and explicit time window, then run one bounded query against that source. A user-named source wins, but still use a matching saved definition when it supplies the source's proven query shape. If there is no useful match, inspect the most likely source schema before asking a clarification about business meaning; do not ask the user to provide internal dataset, table, column, or SQL identifiers. Do not fan out across providers. Do not separately list every dashboard, call data-source status, browse the whole dictionary, load provider catalogs/corpus tools, or query a second source after a strong match. Once the query succeeds, answer immediately with its source, time window, filters, row count, and only necessary caveats. Do not enrich, cross-check, retry, or add breakdowns unless the user requested them, the first query failed, or its result conflicts with the known definition. The words `all`, `total`, or `exact` in a structured aggregate do not by themselves make it a corpus investigation. Never repeat an identical invalid or failed tool call; correct its arguments once or surface the error. This does not waive the real-data requirement: never answer from a guess, stale value, or unverified result. ";
|
|
112
|
+
|
|
113
|
+
export const INTERNAL_PRODUCT_USAGE_GUIDANCE =
|
|
114
|
+
"INTERNAL PRODUCT USAGE / CROSS-SOURCE ROUTING — Requests for product usage, AI credits, credit consumption, allowances, quotas, branch creation, branch creators, or user-level adoption by month are live data requests even when they say pull, export, or prepare a report. For workspace-wide internal Builder.io usage, route to Dispatch with `call-agent` and `list-dispatch-usage-metrics`; use its `monthlyByUser` and `workspaceAppCreationsByUserMonth` result. Do not ask for a user export or BigQuery schema on that path. For a named customer or account such as OCBC, preserve the customer scope and do not substitute workspace metrics. Start with `search-analytics-query-catalog`; if it has no usable definition, call `list-data-dictionary` with focused metric terms and `search-bigquery-schema` with the same terms. `search-bigquery-schema` can search the configured project without a dataset, so do not ask the user to name the dataset, table, columns, or SQL. Use the exact discovered schema in one bounded `bigquery` query, and resolve the named account identity before attributing rows to it. A table that contains limits, plans, or changelog metadata is not proof of actual consumption or creator identity. If the configured actions prove that the source or metric is unavailable, report that exact gap and the inspected coverage instead of asking the user to identify internal tables. ";
|
|
111
115
|
|
|
112
116
|
export const ANALYTICS_ACCOUNT_HEALTH_GUIDANCE =
|
|
113
117
|
"ACCOUNT HEALTH / CUSTOMER SCOPE GUARD — Use this for a named customer, organization ID, account-health, QBR, renewal, contract-usage, risk, or adoption request. Treat a prompt-supplied org ID as a lookup key, not proof of row ownership: resolve it against canonical account data first, carry the resolved customer name plus organization/root-organization identifiers through every usage query, and stop if results contain a different customer, mixed IDs, or an unresolved identity. Use the account-health skill. Account health is incomplete until verified usage queries cover each requested product or feature dimension separately. Before warehouse SQL, use the catalog/dictionary and schema metadata. Do not run definitions marked deprecated or retired, or use a source whose freshness cannot be verified; use the current approved definition instead. Do not call a current partial-period snapshot a completed period without proving the period/as-of row and freshness. Distinguish contract metrics from similarly named platform metrics, total distinct contracted users from DAU/WAU, and actual usage from contracted capacity. Always surface utilization at or above 100%, report adoption window and coverage, and state gaps instead of inferring them. ";
|
|
@@ -123,6 +127,7 @@ export const ANALYTICS_OBSERVABILITY_INCIDENT_GUIDANCE =
|
|
|
123
127
|
|
|
124
128
|
export const ANALYTICS_CROSS_APP_ROUTING_GUIDANCE =
|
|
125
129
|
"WORKSPACE APP ROUTING — Analytics is the sibling app for first-party product usage, app/template events, agent-native signups, conversions, and other curated product metrics. When another app delegates one of these questions with `call-agent`, answer it here using the built-in first-party source and query catalog; do not send the user back to another app or ask the caller to invent SQL. " +
|
|
130
|
+
'INTERNAL USAGE EXCEPTION — Builder.io or AI credit spend, LLM usage by workspace member or month, and workspace app or Builder branch creation history are Dispatch-owned internal metrics. For workspace-wide internal requests, call `call-agent` with agent `dispatch`, action `list-dispatch-usage-metrics`, and the exact read-only input `{ sinceDays, scope: "workspace" }` (add `userEmail` only when the user explicitly narrows the request). The result includes `monthlyByUser` and `workspaceAppCreationsByUserMonth` from the shared `token_usage` and Dispatch audit tables. Do not ask for a user export or BigQuery schema. A request scoped to a named customer or account, such as OCBC, is different: keep that customer scope and use the catalog, dictionary, configured warehouse schema, and one bounded query; do not substitute the current workspace metrics. ' +
|
|
126
131
|
"WORKSPACE APP ROUTING — Brain is the sibling app that owns company knowledge and indexed Slack context. Brain is not an Analytics extension and will not appear in `list-extensions`. When the user asks about company knowledge, decisions, meeting context, or Slack messages/context such as a named channel or thread, use `call-agent` with agent `brain` and a narrow natural-language question. Use `describe-workspace-apps` only when you need to confirm the sibling capability. Do not use `list-extensions` to find Brain, and do not use `provider-api-request` to call Brain. If Brain reports an access or source error, preserve that exact error; do not infer that the Slack bot is absent from a channel or tell the user to re-invite it. Stay in Analytics for metrics and aggregates over a named provider. ";
|
|
127
132
|
|
|
128
133
|
export const NON_ANALYTICS_REQUEST_GUIDANCE =
|
|
@@ -156,6 +161,7 @@ export function analyticsSourceGuidanceOpening(): string {
|
|
|
156
161
|
// Measured in production: this ran in under 1% of data threads while the
|
|
157
162
|
// equivalent instruction sat ~7000 words deep. Threads that did call it used
|
|
158
163
|
// roughly a third the tool calls. Keep it first and keep it imperative.
|
|
164
|
+
"INTERNAL USAGE OVERRIDE — For workspace-wide Builder.io or AI credit spend, LLM usage by workspace member or month, or workspace app/Builder branch creation history, your FIRST tool call is `call-agent` for Dispatch with action `list-dispatch-usage-metrics`, scope `workspace`, and the requested `sinceDays`. Do not start with a user list, `search-bigquery-schema`, or a request for dataset/table/column names. If the request names a customer or account such as OCBC, preserve that customer scope and use the Analytics catalog/warehouse path instead of substituting workspace metrics. " +
|
|
159
165
|
"START HERE — For an ordinary metric, cohort, list, count, or trend question, your FIRST tool call is `search-analytics-query-catalog`. For a request to replicate, clone, or adapt an existing dashboard, your FIRST tool call is `search-dashboard-references` instead; inspect the returned dashboard before choosing a source or writing anything. The catalog path is the analytics equivalent of grepping a codebase before writing new code: someone has very likely already built and saved the query you need, and its saved SQL tells you the exact source, table, and column names so you do not have to discover them. Adapt the closest saved query to the requested filters and time window, run it once, and stop. Only fall back to schema discovery or provider catalogs when the catalog search returns nothing usable — and never run more than one schema-discovery pass before querying. " +
|
|
160
166
|
ANALYTICS_CROSS_APP_ROUTING_GUIDANCE +
|
|
161
167
|
'ONE BOUNDED CALL — List, filter, count, and cohort questions ("which X, excluding Y") are a single query, not a loop. Express the include filter, the exclude filter, and the aggregation in one SQL statement or one `run-code` script that filters server-side. Never page through a cohort across separate tool calls and never fan out per item to apply a filter; that is what turns a ten-second answer into a twenty-minute one. ' +
|
|
@@ -163,6 +169,7 @@ export function analyticsSourceGuidanceOpening(): string {
|
|
|
163
169
|
NON_ANALYTICS_REQUEST_GUIDANCE +
|
|
164
170
|
DASHBOARD_REFERENCE_GUIDANCE +
|
|
165
171
|
BOUNDED_STRUCTURED_LOOKUP_GUIDANCE +
|
|
172
|
+
INTERNAL_PRODUCT_USAGE_GUIDANCE +
|
|
166
173
|
ANALYTICS_ACCOUNT_HEALTH_GUIDANCE +
|
|
167
174
|
BUILT_IN_FIRST_PARTY_SOURCE_GUIDANCE +
|
|
168
175
|
ANALYTICS_OBSERVABILITY_INCIDENT_GUIDANCE +
|
|
@@ -171,9 +178,18 @@ export function analyticsSourceGuidanceOpening(): string {
|
|
|
171
178
|
);
|
|
172
179
|
}
|
|
173
180
|
|
|
181
|
+
const SCHEMA_DETAILS_REQUEST_PATTERN =
|
|
182
|
+
/\b(?:could you|can you|would you|please\s+(?:provide|share|send|tell)|provide|share|send(?: me)?|tell me|i need(?: you to)?|what (?:is|are)|which)\b[\s\S]{0,260}\b(?:bigquery\s+)?(?:dataset(?: name)?s?|table(?: name)?s?|column(?: name)?s?|field(?: name)?s?|schema|sql query)\b/i;
|
|
183
|
+
|
|
184
|
+
function looksLikeSchemaDetailsRequest(text: string): boolean {
|
|
185
|
+
return SCHEMA_DETAILS_REQUEST_PATTERN.test(
|
|
186
|
+
stripInjectedAnalyticsGuardContext(String(text ?? "")),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
174
190
|
export function analyticsDataDictionaryRoutingContext(): string {
|
|
175
191
|
return `<data-dictionary-routing>
|
|
176
|
-
Data-dictionary definitions are available through \`search-analytics-query-catalog\`, which combines focused dictionary lookup with a search over existing dashboard/chart SQL. Use that combined catalog search as the normal preflight for a bounded metric lookup. Call \`list-data-dictionary\` separately
|
|
192
|
+
Data-dictionary definitions are available through \`search-analytics-query-catalog\`, which combines focused dictionary lookup with a search over existing dashboard/chart SQL. Use that combined catalog search as the normal preflight for a bounded metric lookup. Call \`list-data-dictionary\` separately when the catalog has no usable match or when the user asks to browse definitions or filter them by department. Treat approved entries as canonical, verify unreviewed human entries when stakes are high, and treat AI-generated unapproved entries as suggestions only. After the catalog identifies one source and query shape, query that source once and stop on success. If no matching definition or chart exists, inspect the most likely source schema before asking a clarification about business meaning. Never ask the user to supply internal dataset, table, column, or SQL identifiers that the configured Analytics actions can discover.
|
|
177
193
|
</data-dictionary-routing>`;
|
|
178
194
|
}
|
|
179
195
|
|
|
@@ -782,8 +798,22 @@ export function realDataFinalGuard(
|
|
|
782
798
|
};
|
|
783
799
|
}
|
|
784
800
|
|
|
785
|
-
if (dataQueryAttempted) return null;
|
|
786
801
|
const failedQueryMessage = failedDataQueryAttemptMessage(context.toolResults);
|
|
802
|
+
if (looksLikeSchemaDetailsRequest(context.text)) {
|
|
803
|
+
const failedQueryRecovery = failedQueryMessage
|
|
804
|
+
? ` ${failedQueryMessage}`
|
|
805
|
+
: "";
|
|
806
|
+
return {
|
|
807
|
+
retryMessage:
|
|
808
|
+
"The draft asks the user to supply internal dataset, table, column, or SQL details. Do not ask the user for warehouse schema identifiers. Use the configured Analytics tools now: call `search-analytics-query-catalog`, then `list-data-dictionary` and `search-bigquery-schema` with focused metric terms when the catalog has no usable definition, and run one authoritative `bigquery` query using the exact discovered references. `search-bigquery-schema` searches the configured project without a dataset. For a named customer, verify identity and distinguish actual consumption from limits or changelog metadata. If the tools prove the source or metric is unavailable, state that exact evidence gap instead of asking the user to name internal tables." +
|
|
809
|
+
failedQueryRecovery,
|
|
810
|
+
fallbackMessage:
|
|
811
|
+
"I couldn't complete that lookup from the configured Analytics sources yet. Please retry and I'll inspect the catalog and warehouse schema directly rather than asking you to provide internal table names.",
|
|
812
|
+
maxRetries: 2,
|
|
813
|
+
expandToolSurface: true,
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
if (dataQueryAttempted) return null;
|
|
787
817
|
// Whether the built-in source is worth trying is decided by tool evidence,
|
|
788
818
|
// not by how the draft is worded, so it is asked once for every draft shape.
|
|
789
819
|
// A source that already failed this turn is not an untried source: steering
|
|
@@ -14,7 +14,12 @@ export default mergeConfig(
|
|
|
14
14
|
},
|
|
15
15
|
test: {
|
|
16
16
|
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
-
exclude: [
|
|
17
|
+
exclude: [
|
|
18
|
+
"**/node_modules/**",
|
|
19
|
+
"**/.git/**",
|
|
20
|
+
"**/dist/**",
|
|
21
|
+
"**/.react-router/**",
|
|
22
|
+
],
|
|
18
23
|
},
|
|
19
24
|
}),
|
|
20
25
|
);
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -20,11 +20,13 @@ import {
|
|
|
20
20
|
} from "@agent-native/core/client/host";
|
|
21
21
|
import { useT } from "@agent-native/core/client/i18n";
|
|
22
22
|
import {
|
|
23
|
-
AGENT_NATIVE_EMBED_MESSAGE_TYPES,
|
|
24
|
-
createAgentNativeEmbedEnvelope,
|
|
25
23
|
createEmbeddedAppBridge,
|
|
26
24
|
type EmbeddedAppBridge,
|
|
27
|
-
} from "@agent-native/core/embedding";
|
|
25
|
+
} from "@agent-native/core/embedding/bridge";
|
|
26
|
+
import {
|
|
27
|
+
AGENT_NATIVE_EMBED_MESSAGE_TYPES,
|
|
28
|
+
createAgentNativeEmbedEnvelope,
|
|
29
|
+
} from "@agent-native/core/embedding/protocol";
|
|
28
30
|
import {
|
|
29
31
|
EMBED_MODE_QUERY_PARAM,
|
|
30
32
|
EMBED_TOKEN_QUERY_PARAM,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type RouteConfig } from "@react-router/dev/routes";
|
|
2
2
|
import { flatRoutes } from "@react-router/fs-routes";
|
|
3
3
|
|
|
4
|
-
export default flatRoutes(
|
|
4
|
+
export default flatRoutes({
|
|
5
|
+
ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
6
|
+
}) satisfies RouteConfig;
|
|
@@ -14,7 +14,12 @@ export default mergeConfig(
|
|
|
14
14
|
},
|
|
15
15
|
test: {
|
|
16
16
|
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
-
exclude: [
|
|
17
|
+
exclude: [
|
|
18
|
+
"**/node_modules/**",
|
|
19
|
+
"**/.git/**",
|
|
20
|
+
"**/dist/**",
|
|
21
|
+
"**/.react-router/**",
|
|
22
|
+
],
|
|
18
23
|
},
|
|
19
24
|
}),
|
|
20
25
|
);
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@agent-native/toolkit/ui/pointer-lock";
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
} from "@/components/ui/dropdown-menu";
|
|
68
68
|
import { Input } from "@/components/ui/input";
|
|
69
69
|
import { Label } from "@/components/ui/label";
|
|
70
|
+
import { afterBodyPointerUnlock } from "@/components/ui/pointer-lock";
|
|
70
71
|
import { Progress } from "@/components/ui/progress";
|
|
71
72
|
import {
|
|
72
73
|
Select,
|
|
@@ -2253,7 +2254,11 @@ export default function SourcesRoute() {
|
|
|
2253
2254
|
result,
|
|
2254
2255
|
sourceKey: form.sourceKey,
|
|
2255
2256
|
});
|
|
2256
|
-
|
|
2257
|
+
setSetupOpen(false);
|
|
2258
|
+
if (handoff) {
|
|
2259
|
+
afterBodyPointerUnlock(() => setIngestHandoff(handoff));
|
|
2260
|
+
}
|
|
2261
|
+
return;
|
|
2257
2262
|
}
|
|
2258
2263
|
setSetupOpen(false);
|
|
2259
2264
|
}
|
|
@@ -2360,7 +2365,7 @@ export default function SourcesRoute() {
|
|
|
2360
2365
|
: undefined
|
|
2361
2366
|
}
|
|
2362
2367
|
onSync={() => syncSource.mutate({ sourceId: source.id })}
|
|
2363
|
-
onTune={() => openEdit(source)}
|
|
2368
|
+
onTune={() => afterBodyPointerUnlock(() => openEdit(source))}
|
|
2364
2369
|
onImportMarkdown={() => setMarkdownImportSource(source)}
|
|
2365
2370
|
onArchive={() => setArchiveSource(source)}
|
|
2366
2371
|
/>
|
|
@@ -2451,7 +2456,7 @@ export default function SourcesRoute() {
|
|
|
2451
2456
|
}
|
|
2452
2457
|
onAddSource={(provider) => {
|
|
2453
2458
|
setAdvancedOpen(false);
|
|
2454
|
-
openCreate(provider);
|
|
2459
|
+
afterBodyPointerUnlock(() => openCreate(provider));
|
|
2455
2460
|
}}
|
|
2456
2461
|
/>
|
|
2457
2462
|
</div>
|
|
@@ -643,8 +643,33 @@ export async function ensureManualSource(title = "Manual imports") {
|
|
|
643
643
|
}
|
|
644
644
|
|
|
645
645
|
function isUniqueConflict(error: unknown): boolean {
|
|
646
|
-
|
|
647
|
-
|
|
646
|
+
if (!error || typeof error !== "object") {
|
|
647
|
+
return /unique constraint|duplicate key|duplicate entry|unique/i.test(
|
|
648
|
+
String(error),
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const candidate = error as {
|
|
653
|
+
code?: unknown;
|
|
654
|
+
message?: unknown;
|
|
655
|
+
cause?: unknown;
|
|
656
|
+
};
|
|
657
|
+
if (
|
|
658
|
+
candidate.code === "23505" ||
|
|
659
|
+
candidate.code === "SQLITE_CONSTRAINT_UNIQUE"
|
|
660
|
+
) {
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
663
|
+
if (typeof candidate.message === "string") {
|
|
664
|
+
if (
|
|
665
|
+
/unique constraint|duplicate key|duplicate entry|unique violation|unique/i.test(
|
|
666
|
+
candidate.message,
|
|
667
|
+
)
|
|
668
|
+
) {
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
return candidate.cause !== error && isUniqueConflict(candidate.cause);
|
|
648
673
|
}
|
|
649
674
|
|
|
650
675
|
const UPSTREAM_DELETED_POLICY_VERSION = "upstream-deleted-v1";
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -1,21 +1,100 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
getRequestOrgId,
|
|
4
|
+
getRequestUserEmail,
|
|
5
|
+
} from "@agent-native/core/server/request-context";
|
|
6
|
+
import {
|
|
7
|
+
accessFilter,
|
|
8
|
+
ROLE_RANK,
|
|
9
|
+
type ShareRole,
|
|
10
|
+
} from "@agent-native/core/sharing";
|
|
11
|
+
import { and, desc, eq, inArray, or, sql } from "drizzle-orm";
|
|
4
12
|
import { z } from "zod";
|
|
5
13
|
|
|
6
14
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
15
|
import { rowToBookingLink } from "../server/lib/booking-link-utils.js";
|
|
8
16
|
|
|
17
|
+
type EffectiveRole = "owner" | ShareRole;
|
|
18
|
+
|
|
19
|
+
function normalizeEmail(email: string | undefined): string | null {
|
|
20
|
+
const normalized = email?.trim().toLowerCase();
|
|
21
|
+
return normalized || null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function strongerRole(current: ShareRole | null, next: ShareRole): ShareRole {
|
|
25
|
+
if (!current || ROLE_RANK[next] > ROLE_RANK[current]) return next;
|
|
26
|
+
return current;
|
|
27
|
+
}
|
|
28
|
+
|
|
9
29
|
export default defineAction({
|
|
10
30
|
description: "List all booking links",
|
|
11
31
|
schema: z.object({}),
|
|
12
32
|
http: { method: "GET" },
|
|
13
33
|
run: async () => {
|
|
14
|
-
const
|
|
34
|
+
const db = getDb();
|
|
35
|
+
const userEmail = normalizeEmail(getRequestUserEmail());
|
|
36
|
+
const orgId = getRequestOrgId();
|
|
37
|
+
const rows = await db
|
|
15
38
|
.select()
|
|
16
39
|
.from(schema.bookingLinks)
|
|
17
40
|
.where(accessFilter(schema.bookingLinks, schema.bookingLinkShares))
|
|
18
41
|
.orderBy(desc(schema.bookingLinks.updatedAt));
|
|
19
|
-
|
|
42
|
+
|
|
43
|
+
if (rows.length === 0) return [];
|
|
44
|
+
|
|
45
|
+
const principalClauses: NonNullable<ReturnType<typeof and>>[] = [];
|
|
46
|
+
if (userEmail) {
|
|
47
|
+
principalClauses.push(
|
|
48
|
+
and(
|
|
49
|
+
eq(schema.bookingLinkShares.principalType, "user"),
|
|
50
|
+
sql`lower(${schema.bookingLinkShares.principalId}) = ${userEmail}`,
|
|
51
|
+
)!,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (orgId) {
|
|
55
|
+
principalClauses.push(
|
|
56
|
+
and(
|
|
57
|
+
eq(schema.bookingLinkShares.principalType, "org"),
|
|
58
|
+
eq(schema.bookingLinkShares.principalId, orgId),
|
|
59
|
+
)!,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const shareRoleById = new Map<string, ShareRole>();
|
|
64
|
+
if (principalClauses.length > 0) {
|
|
65
|
+
const shareRows = await db
|
|
66
|
+
.select({
|
|
67
|
+
resourceId: schema.bookingLinkShares.resourceId,
|
|
68
|
+
role: schema.bookingLinkShares.role,
|
|
69
|
+
})
|
|
70
|
+
.from(schema.bookingLinkShares)
|
|
71
|
+
.where(
|
|
72
|
+
and(
|
|
73
|
+
inArray(
|
|
74
|
+
schema.bookingLinkShares.resourceId,
|
|
75
|
+
rows.map((row) => row.id),
|
|
76
|
+
),
|
|
77
|
+
or(...principalClauses),
|
|
78
|
+
),
|
|
79
|
+
);
|
|
80
|
+
for (const share of shareRows) {
|
|
81
|
+
shareRoleById.set(
|
|
82
|
+
share.resourceId,
|
|
83
|
+
strongerRole(shareRoleById.get(share.resourceId) ?? null, share.role),
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return rows.map((row) => {
|
|
89
|
+
let role: EffectiveRole = shareRoleById.get(row.id) ?? "viewer";
|
|
90
|
+
if (
|
|
91
|
+
userEmail &&
|
|
92
|
+
normalizeEmail(row.ownerEmail) === userEmail &&
|
|
93
|
+
(!row.orgId || row.orgId === orgId)
|
|
94
|
+
) {
|
|
95
|
+
role = "owner";
|
|
96
|
+
}
|
|
97
|
+
return { ...rowToBookingLink(row), accessRole: role };
|
|
98
|
+
});
|
|
20
99
|
},
|
|
21
100
|
});
|
|
@@ -57,7 +57,7 @@ export default defineAction({
|
|
|
57
57
|
isActive: z.boolean().optional().describe("Whether the link is active"),
|
|
58
58
|
}),
|
|
59
59
|
run: async (args) => {
|
|
60
|
-
await assertAccess("booking-link", args.id, "editor");
|
|
60
|
+
const access = await assertAccess("booking-link", args.id, "editor");
|
|
61
61
|
|
|
62
62
|
const durationInput = normalizeBookingDurationInput({
|
|
63
63
|
duration: args.duration,
|
|
@@ -90,6 +90,7 @@ export default defineAction({
|
|
|
90
90
|
.select({
|
|
91
91
|
slug: schema.bookingLinks.slug,
|
|
92
92
|
ownerEmail: schema.bookingLinks.ownerEmail,
|
|
93
|
+
isActive: schema.bookingLinks.isActive,
|
|
93
94
|
})
|
|
94
95
|
.from(schema.bookingLinks)
|
|
95
96
|
.where(eq(schema.bookingLinks.id, args.id));
|
|
@@ -116,7 +117,7 @@ export default defineAction({
|
|
|
116
117
|
? JSON.stringify(args.conferencing)
|
|
117
118
|
: null,
|
|
118
119
|
color: args.color ? args.color.trim() : null,
|
|
119
|
-
isActive: args.isActive ??
|
|
120
|
+
isActive: args.isActive ?? current.isActive,
|
|
120
121
|
updatedAt: new Date().toISOString(),
|
|
121
122
|
})
|
|
122
123
|
.where(eq(schema.bookingLinks.id, args.id));
|
|
@@ -140,6 +141,6 @@ export default defineAction({
|
|
|
140
141
|
.where(eq(schema.bookingLinks.id, args.id));
|
|
141
142
|
|
|
142
143
|
if (!updated) throw new Error("Booking link not found");
|
|
143
|
-
return rowToBookingLink(updated);
|
|
144
|
+
return { ...rowToBookingLink(updated), accessRole: access.role };
|
|
144
145
|
},
|
|
145
146
|
});
|
|
@@ -74,6 +74,7 @@ interface EventDetailPanelProps {
|
|
|
74
74
|
onClose: () => void;
|
|
75
75
|
onDelete: (eventId: string) => void;
|
|
76
76
|
onTitleSave?: (eventId: string, title: string, accountEmail?: string) => void;
|
|
77
|
+
timezone?: string;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
function formatDuration(start: string, end: string): string {
|
|
@@ -121,6 +122,7 @@ export function EventDetailPanel({
|
|
|
121
122
|
onClose,
|
|
122
123
|
onDelete,
|
|
123
124
|
onTitleSave,
|
|
125
|
+
timezone,
|
|
124
126
|
}: EventDetailPanelProps) {
|
|
125
127
|
const t = useT();
|
|
126
128
|
const workingLocationLabels = createWorkingLocationDisplayLabels(t);
|
|
@@ -451,7 +453,9 @@ export function EventDetailPanel({
|
|
|
451
453
|
{format(
|
|
452
454
|
getDisplayDateInTimezone(
|
|
453
455
|
event.start,
|
|
454
|
-
|
|
456
|
+
timezone ??
|
|
457
|
+
event.startTimeZone ??
|
|
458
|
+
event.endTimeZone,
|
|
455
459
|
),
|
|
456
460
|
"h:mm a",
|
|
457
461
|
)}
|
|
@@ -459,7 +463,9 @@ export function EventDetailPanel({
|
|
|
459
463
|
{format(
|
|
460
464
|
getDisplayDateInTimezone(
|
|
461
465
|
event.end,
|
|
462
|
-
|
|
466
|
+
timezone ??
|
|
467
|
+
event.endTimeZone ??
|
|
468
|
+
event.startTimeZone,
|
|
463
469
|
),
|
|
464
470
|
"h:mm a",
|
|
465
471
|
)}
|
|
@@ -471,7 +477,9 @@ export function EventDetailPanel({
|
|
|
471
477
|
{format(
|
|
472
478
|
getDisplayDateInTimezone(
|
|
473
479
|
event.start,
|
|
474
|
-
|
|
480
|
+
timezone ??
|
|
481
|
+
event.startTimeZone ??
|
|
482
|
+
event.endTimeZone,
|
|
475
483
|
),
|
|
476
484
|
"EEE MMM d",
|
|
477
485
|
)}
|
|
@@ -489,7 +489,7 @@ export function EventDetailPopover({
|
|
|
489
489
|
const t = useT();
|
|
490
490
|
const workingLocationLabels = createWorkingLocationDisplayLabels(t);
|
|
491
491
|
const isMobile = useIsMobile();
|
|
492
|
-
const eventTimezone = event.startTimeZone ||
|
|
492
|
+
const eventTimezone = timezone || event.startTimeZone || getLocalTimezone();
|
|
493
493
|
const [open, setOpen] = useState(defaultOpen);
|
|
494
494
|
const [editingTitle, setEditingTitle] = useState(
|
|
495
495
|
defaultOpen ? getEditableEventTitle(event) : "",
|