@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
package/agent-native.eject.json
CHANGED
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
"common-room",
|
|
41
41
|
"exa",
|
|
42
42
|
"gong",
|
|
43
|
-
"google-workspace",
|
|
44
43
|
"grafana",
|
|
45
44
|
"intercom",
|
|
46
45
|
"monday",
|
|
@@ -70,7 +69,11 @@
|
|
|
70
69
|
"figma",
|
|
71
70
|
"notion",
|
|
72
71
|
"gmail",
|
|
72
|
+
"google_calendar",
|
|
73
|
+
"google_docs",
|
|
73
74
|
"google_drive",
|
|
75
|
+
"google_sheets",
|
|
76
|
+
"google_slides",
|
|
74
77
|
"hubspot",
|
|
75
78
|
"salesforce",
|
|
76
79
|
"jira",
|
package/bin/agent-native.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
5
6
|
import { dirname, join } from "node:path";
|
|
6
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
8
|
|
|
@@ -62,14 +63,31 @@ if (!useSourceFallback) {
|
|
|
62
63
|
|
|
63
64
|
await import(pathToFileURL(distEntry).href);
|
|
64
65
|
} else {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
// Resolve tsx from this package instead of trusting PATH: the fallback is
|
|
67
|
+
// also reached through `node packages/core/bin/agent-native.js`, which runs
|
|
68
|
+
// without node_modules/.bin on PATH.
|
|
69
|
+
let tsxCli;
|
|
70
|
+
try {
|
|
71
|
+
tsxCli = createRequire(import.meta.url).resolve("tsx/cli");
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(
|
|
74
|
+
`agent-native CLI source fallback could not resolve tsx (${error.message}). Run \`pnpm --filter @agent-native/core build\` and try again.`,
|
|
75
|
+
);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const child = spawn(
|
|
80
|
+
process.execPath,
|
|
81
|
+
[tsxCli, sourceEntry, ...process.argv.slice(2)],
|
|
82
|
+
{
|
|
83
|
+
stdio: "inherit",
|
|
84
|
+
env: process.env,
|
|
85
|
+
},
|
|
86
|
+
);
|
|
69
87
|
|
|
70
88
|
child.on("error", (error) => {
|
|
71
89
|
console.error(
|
|
72
|
-
`agent-native CLI
|
|
90
|
+
`agent-native CLI source fallback failed: ${error.message}. Run \`pnpm --filter @agent-native/core build\` and try again.`,
|
|
73
91
|
);
|
|
74
92
|
process.exit(1);
|
|
75
93
|
});
|
package/corpus/README.md
CHANGED
|
@@ -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
|
|
|
@@ -9,12 +9,12 @@ Use these sources of truth instead:
|
|
|
9
9
|
|
|
10
10
|
- \`list-data-dictionary\` for approved metric, table, column, join, and caveat definitions configured by this organization.
|
|
11
11
|
- \`data-source-status --key bigquery\` to confirm whether BigQuery credentials and a project are configured.
|
|
12
|
-
- \`search-bigquery-schema\` to
|
|
12
|
+
- \`search-bigquery-schema\` to search the configured project by dataset, table, or column term, or inspect exact table columns before writing SQL.
|
|
13
13
|
- The configured warehouse's \`INFORMATION_SCHEMA.COLUMNS\` tables when you need to discover actual datasets, tables, and columns.
|
|
14
14
|
- \`@app_events\` as an optional placeholder for a default application events table in query-metrics examples. It defaults to \`<BIGQUERY_PROJECT_ID>.analytics.events_partitioned\` and can be overridden with \`ANALYTICS_BIGQUERY_EVENTS_TABLE\`; it is not the BigQuery connection status or a table catalog.
|
|
15
15
|
- \`@project\` as the configured BigQuery project placeholder for fully-qualified table references.
|
|
16
16
|
|
|
17
|
-
If no data-dictionary entry exists
|
|
17
|
+
If no data-dictionary entry exists, search the configured project before asking about business meaning. Ask the user for a metric definition only after the configured schema and query actions prove that the source or metric is unavailable. Never ask the user to provide internal dataset, table, or column names that the schema action can discover, and never invent table names, column names, joins, or numbers.
|
|
18
18
|
|
|
19
19
|
Preferred schema discovery:
|
|
20
20
|
|
|
@@ -22,6 +22,7 @@ Preferred schema discovery:
|
|
|
22
22
|
pnpm action search-bigquery-schema
|
|
23
23
|
pnpm action search-bigquery-schema --dataset=<dataset>
|
|
24
24
|
pnpm action search-bigquery-schema --table=<dataset.table>
|
|
25
|
+
pnpm action search-bigquery-schema --search=<metric-or-column-term>
|
|
25
26
|
\`\`\`
|
|
26
27
|
|
|
27
28
|
Example schema discovery query:
|
|
@@ -48,7 +48,7 @@ function toDataTableResult(result: {
|
|
|
48
48
|
|
|
49
49
|
export default defineAction({
|
|
50
50
|
description:
|
|
51
|
-
"Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track), compact daily rollups updated transactionally with new ingest, identifiable user-day rollups, and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. Prefer analytics_event_daily_rollups for event counts and analytics_user_days for active-user or retention questions. On the Builder.io production organization after the explicit BigQuery cutover, event and rollup reads use partitioned BigQuery tables/views while session_recordings remains in the SQL store; cross-backend joins are not supported. Before a large or historical query, call get-first-party-analytics-health and use a configured external backend when it recommends one: BigQuery supports warehouse SQL and historical analysis, while Amplitude supports product analytics, funnels, and retention. Connecting a backend does not automatically reroute /track events or copy existing Neon events; the migration action performs that explicit prepare, backfill, and cutover sequence. Aggregate, project only needed columns, use bounded recent drill-downs, and add a LIMIT for raw or high-cardinality reads; do not issue an unbounded raw-event scan or paginate a large cohort. An explicit all-time or lifetime request remains all-time, so do not invent a default lower time bound. Safe scoped results are cached for up to five minutes for this agent action. analytics_events columns include event_name, timestamp, event_date, user_id, anonymous_id, user_key, session_id, app, template, signed_in, url, path, hostname, referrer, properties, and context. analytics_event_daily_rollups columns include tenant_key, owner_email, org_id, event_date, event_name, app, template, and event_count. analytics_user_days columns include tenant_key, owner_email, org_id, event_date, and user_key. LLM observability events use event_name = '$ai_generation'; useful properties include $ai_trace_id/run_id, $ai_session_id/thread_id, $ai_model/model, $ai_provider/provider, $ai_input_tokens/input_tokens, $ai_output_tokens/output_tokens, cache_read_tokens, cache_write_tokens, cost_cents_x100, $ai_total_cost_usd/cost_usd, duration_ms
|
|
51
|
+
"Query the built-in first-party Analytics source: events recorded through this app's analytics collector endpoint (/track), compact daily rollups updated transactionally with new ingest, identifiable user-day rollups, and session replay summaries recorded through /api/analytics/replay. This source does not require an external provider connection. Use it for questions about app/site traffic, product events, template/app usage, conversions, session recordings, LLM/agent observability, model cost, token volume, latency, and other first-party data collected by this analytics app. Use source-specific actions such as BigQuery, GA4, Mixpanel, PostHog, or Amplitude when the user asks for those sources or the relevant data lives there. SQL may read analytics_events, analytics_event_daily_rollups, analytics_user_days, and session_recordings; session_replay_chunks is intentionally unavailable, and reads are automatically scoped to the current user/org. Prefer analytics_event_daily_rollups for event counts and analytics_user_days for active-user or retention questions. On the Builder.io production organization after the explicit BigQuery cutover, event and rollup reads use partitioned BigQuery tables/views while session_recordings remains in the SQL store; cross-backend joins are not supported. Before a large or historical query, call get-first-party-analytics-health and use a configured external backend when it recommends one: BigQuery supports warehouse SQL and historical analysis, while Amplitude supports product analytics, funnels, and retention. Connecting a backend does not automatically reroute /track events or copy existing Neon events; the migration action performs that explicit prepare, backfill, and cutover sequence. Aggregate, project only needed columns, use bounded recent drill-downs, and add a LIMIT for raw or high-cardinality reads; do not issue an unbounded raw-event scan or paginate a large cohort. An explicit all-time or lifetime request remains all-time, so do not invent a default lower time bound. Safe scoped results are cached for up to five minutes for this agent action. analytics_events columns include event_name, timestamp, event_date, user_id, anonymous_id, user_key, session_id, app, template, signed_in, url, path, hostname, referrer, properties, and context. analytics_event_daily_rollups columns include tenant_key, owner_email, org_id, event_date, event_name, app, template, and event_count. analytics_user_days columns include tenant_key, owner_email, org_id, event_date, and user_key. LLM observability events use event_name = '$ai_generation'; useful properties include $ai_trace_id/run_id, $ai_session_id/thread_id, $ai_model/model, $ai_provider/provider, $ai_input_tokens/input_tokens, $ai_output_tokens/output_tokens, cache_read_tokens, cache_write_tokens, cost_cents_x100, $ai_total_cost_usd/cost_usd, duration_ms (full run, milliseconds), $ai_latency (model time in seconds, run minus tool time), status, tool_calls, successful_tools, failed_tools, tools, tools_truncated, delegated, delegation_protocol, caller_app, delegation_task_id, a2a_task_id, parent_run_id, parent_turn_id, and error_message/$ai_error. Agent Teams child runs use delegation_protocol = 'agent-team' and retain their own run_id while linking to the launching run through parent_run_id. The bounded tools array contains names, relative start times, durations, statuses, and coarse error classes only, never args or results; failed runs and interrupted tools remain queryable. session_recordings columns include id, session_id, user_id, anonymous_id, user_key, started_at, ended_at, duration_ms, chunk_count, event_count, page_count, error_count, rage_click_count, app, template, status, first_url, last_url, path, hostname, referrer, and metadata.",
|
|
52
52
|
schema: z.object({
|
|
53
53
|
sql: z
|
|
54
54
|
.string()
|
|
@@ -35,6 +35,15 @@ interface TableListResponse {
|
|
|
35
35
|
}>;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
interface BigQueryTableSummary {
|
|
39
|
+
projectId?: string;
|
|
40
|
+
datasetId?: string;
|
|
41
|
+
tableId?: string;
|
|
42
|
+
type?: string;
|
|
43
|
+
friendlyName?: string;
|
|
44
|
+
labels?: Record<string, string>;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
interface TableMetadata {
|
|
39
48
|
tableReference?: {
|
|
40
49
|
projectId?: string;
|
|
@@ -54,6 +63,9 @@ interface TableMetadata {
|
|
|
54
63
|
|
|
55
64
|
const PROJECT_RE = /^[A-Za-z][A-Za-z0-9-]{4,61}[A-Za-z0-9]$/;
|
|
56
65
|
const ID_RE = /^[A-Za-z0-9_]+$/;
|
|
66
|
+
const GLOBAL_SEARCH_DATASET_LIMIT = 100;
|
|
67
|
+
const GLOBAL_SEARCH_TABLE_LIMIT = 250;
|
|
68
|
+
const GLOBAL_SEARCH_METADATA_BATCH_SIZE = 20;
|
|
57
69
|
|
|
58
70
|
function assertIdentifier(
|
|
59
71
|
label: string,
|
|
@@ -183,7 +195,12 @@ function compactTable(meta: TableMetadata, includeColumns: boolean) {
|
|
|
183
195
|
}
|
|
184
196
|
|
|
185
197
|
function matchesSearch(meta: TableMetadata, search: string): boolean {
|
|
186
|
-
const
|
|
198
|
+
const terms = search
|
|
199
|
+
.toLowerCase()
|
|
200
|
+
.replace(/[._-]+/g, " ")
|
|
201
|
+
.split(/\s+/)
|
|
202
|
+
.filter(Boolean);
|
|
203
|
+
if (!terms.length) return true;
|
|
187
204
|
const ref = meta.tableReference ?? {};
|
|
188
205
|
const haystack = [
|
|
189
206
|
ref.projectId,
|
|
@@ -199,8 +216,9 @@ function matchesSearch(meta: TableMetadata, search: string): boolean {
|
|
|
199
216
|
]
|
|
200
217
|
.filter(Boolean)
|
|
201
218
|
.join(" ")
|
|
202
|
-
.toLowerCase()
|
|
203
|
-
|
|
219
|
+
.toLowerCase()
|
|
220
|
+
.replace(/[._-]+/g, " ");
|
|
221
|
+
return terms.every((term) => haystack.includes(term));
|
|
204
222
|
}
|
|
205
223
|
|
|
206
224
|
async function listDatasets(projectId: string, limit: number, search: string) {
|
|
@@ -245,6 +263,111 @@ async function listTables(projectId: string, datasetId: string, limit: number) {
|
|
|
245
263
|
}));
|
|
246
264
|
}
|
|
247
265
|
|
|
266
|
+
async function searchAcrossDatasets(
|
|
267
|
+
projectId: string,
|
|
268
|
+
search: string,
|
|
269
|
+
limit: number,
|
|
270
|
+
) {
|
|
271
|
+
const datasets = await listDatasets(
|
|
272
|
+
projectId,
|
|
273
|
+
GLOBAL_SEARCH_DATASET_LIMIT + 1,
|
|
274
|
+
"",
|
|
275
|
+
);
|
|
276
|
+
const scannableDatasets = datasets.slice(0, GLOBAL_SEARCH_DATASET_LIMIT);
|
|
277
|
+
const tables: BigQueryTableSummary[] = [];
|
|
278
|
+
const datasetCount = scannableDatasets.filter(
|
|
279
|
+
(dataset) => typeof dataset.datasetId === "string" && dataset.datasetId,
|
|
280
|
+
).length;
|
|
281
|
+
let datasetsScanned = 0;
|
|
282
|
+
let truncated = datasets.length > GLOBAL_SEARCH_DATASET_LIMIT;
|
|
283
|
+
|
|
284
|
+
for (const dataset of scannableDatasets) {
|
|
285
|
+
const datasetId = dataset.datasetId;
|
|
286
|
+
if (!datasetId) continue;
|
|
287
|
+
if (tables.length >= GLOBAL_SEARCH_TABLE_LIMIT) {
|
|
288
|
+
truncated = true;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
datasetsScanned += 1;
|
|
293
|
+
const remaining = GLOBAL_SEARCH_TABLE_LIMIT - tables.length;
|
|
294
|
+
const listed = await listTables(
|
|
295
|
+
projectId,
|
|
296
|
+
datasetId,
|
|
297
|
+
Math.min(remaining, GLOBAL_SEARCH_TABLE_LIMIT),
|
|
298
|
+
);
|
|
299
|
+
tables.push(...listed);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (datasetsScanned < datasetCount) truncated = true;
|
|
303
|
+
|
|
304
|
+
// Inspect table metadata in bounded batches so a search can match columns,
|
|
305
|
+
// not only table names, without issuing an unbounded burst of requests.
|
|
306
|
+
const matches: ReturnType<typeof compactTable>[] = [];
|
|
307
|
+
const errors: Array<{
|
|
308
|
+
projectId?: string;
|
|
309
|
+
datasetId?: string;
|
|
310
|
+
tableId?: string;
|
|
311
|
+
error: string;
|
|
312
|
+
}> = [];
|
|
313
|
+
|
|
314
|
+
for (
|
|
315
|
+
let offset = 0;
|
|
316
|
+
offset < tables.length;
|
|
317
|
+
offset += GLOBAL_SEARCH_METADATA_BATCH_SIZE
|
|
318
|
+
) {
|
|
319
|
+
const batch = tables.slice(
|
|
320
|
+
offset,
|
|
321
|
+
offset + GLOBAL_SEARCH_METADATA_BATCH_SIZE,
|
|
322
|
+
);
|
|
323
|
+
const settled = await Promise.allSettled(
|
|
324
|
+
batch.map(async (table) => {
|
|
325
|
+
if (!table.datasetId || !table.tableId) return null;
|
|
326
|
+
const metadata = await getTableMetadata(
|
|
327
|
+
projectId,
|
|
328
|
+
table.datasetId,
|
|
329
|
+
table.tableId,
|
|
330
|
+
);
|
|
331
|
+
return matchesSearch(metadata, search)
|
|
332
|
+
? compactTable(metadata, true)
|
|
333
|
+
: null;
|
|
334
|
+
}),
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
settled.forEach((result, index) => {
|
|
338
|
+
const table = batch[index];
|
|
339
|
+
if (result.status === "fulfilled") {
|
|
340
|
+
if (result.value) matches.push(result.value);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
errors.push({
|
|
344
|
+
projectId: table?.projectId ?? projectId,
|
|
345
|
+
datasetId: table?.datasetId,
|
|
346
|
+
tableId: table?.tableId,
|
|
347
|
+
error:
|
|
348
|
+
result.reason instanceof Error
|
|
349
|
+
? result.reason.message
|
|
350
|
+
: String(result.reason),
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
mode: "table-search",
|
|
357
|
+
projectId,
|
|
358
|
+
search,
|
|
359
|
+
datasetsScanned,
|
|
360
|
+
tablesScanned: tables.length,
|
|
361
|
+
truncated,
|
|
362
|
+
tables: matches.slice(0, limit),
|
|
363
|
+
...(errors.length
|
|
364
|
+
? { errors: errors.slice(0, 12), errorCount: errors.length }
|
|
365
|
+
: {}),
|
|
366
|
+
nextStep:
|
|
367
|
+
"Use table=dataset.table for full metadata. Global search is bounded; pass a returned dataset/table reference for a complete inspection.",
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
248
371
|
async function getTableMetadata(
|
|
249
372
|
projectId: string,
|
|
250
373
|
datasetId: string,
|
|
@@ -256,7 +379,7 @@ async function getTableMetadata(
|
|
|
256
379
|
|
|
257
380
|
export default defineAction({
|
|
258
381
|
description:
|
|
259
|
-
"Search or describe BigQuery metadata for the configured warehouse. Use before writing SQL when the data dictionary does not already name the dataset, table, and columns. With no args, lists datasets. With dataset, lists tables. With dataset + table or a dataset.table value, returns columns for that table.",
|
|
382
|
+
"Search or describe BigQuery metadata for the configured warehouse. Use before writing SQL when the data dictionary does not already name the dataset, table, and columns. With no args, lists datasets. With search and no dataset, searches accessible tables and columns across the configured project so the user does not need to provide internal table names. With dataset, lists tables. With dataset + table or a dataset.table value, returns columns for that table.",
|
|
260
383
|
schema: z.object({
|
|
261
384
|
dataset: z
|
|
262
385
|
.string()
|
|
@@ -307,6 +430,9 @@ export default defineAction({
|
|
|
307
430
|
}
|
|
308
431
|
|
|
309
432
|
if (!args.dataset) {
|
|
433
|
+
if (search) {
|
|
434
|
+
return searchAcrossDatasets(configuredProjectId, search, limit);
|
|
435
|
+
}
|
|
310
436
|
return {
|
|
311
437
|
mode: "datasets",
|
|
312
438
|
projectId: configuredProjectId,
|
|
@@ -46,6 +46,11 @@ import { toast } from "sonner";
|
|
|
46
46
|
|
|
47
47
|
import { useAuth } from "@/components/auth/AuthProvider";
|
|
48
48
|
import { ANALYTICS_CHAT_STORAGE_KEY } from "@/lib/chat-handoff";
|
|
49
|
+
import {
|
|
50
|
+
matchesDashboardVisibilityFilter,
|
|
51
|
+
type DashboardVisibility,
|
|
52
|
+
type DashboardVisibilityFilter,
|
|
53
|
+
} from "@/lib/dashboard-visibility";
|
|
49
54
|
import { cn, shortcutModifierLabel } from "@/lib/utils";
|
|
50
55
|
import {
|
|
51
56
|
dashboards,
|
|
@@ -63,6 +68,7 @@ type SidebarDashboard = {
|
|
|
63
68
|
source: "static" | "sql" | "analysis";
|
|
64
69
|
resourceId?: string;
|
|
65
70
|
visibility?: Visibility;
|
|
71
|
+
ownerEmail?: string | null;
|
|
66
72
|
/** Id of the dashboard this one nests under in the sidebar, if any. */
|
|
67
73
|
parentId?: string;
|
|
68
74
|
};
|
|
@@ -162,7 +168,7 @@ const SIDEBAR_SKELETON_CLASS =
|
|
|
162
168
|
"bg-sidebar-foreground/12 dark:bg-sidebar-foreground/10";
|
|
163
169
|
|
|
164
170
|
type SidebarSortMode = "most-used" | "alphabetical" | "manual";
|
|
165
|
-
type SidebarVisibilityFilter =
|
|
171
|
+
type SidebarVisibilityFilter = DashboardVisibilityFilter;
|
|
166
172
|
|
|
167
173
|
import {
|
|
168
174
|
DndContext,
|
|
@@ -258,14 +264,11 @@ function isVisibility(value: unknown): value is Visibility {
|
|
|
258
264
|
}
|
|
259
265
|
|
|
260
266
|
export function matchesVisibilityFilter(
|
|
261
|
-
item: { visibility?: Visibility },
|
|
267
|
+
item: { visibility?: Visibility; ownerEmail?: string | null },
|
|
262
268
|
filter: SidebarVisibilityFilter,
|
|
269
|
+
currentUserEmail?: string | null,
|
|
263
270
|
): boolean {
|
|
264
|
-
|
|
265
|
-
if (filter === "private") {
|
|
266
|
-
return item.visibility !== "org" && item.visibility !== "public";
|
|
267
|
-
}
|
|
268
|
-
return item.visibility === "org" || item.visibility === "public";
|
|
271
|
+
return matchesDashboardVisibilityFilter(item, filter, currentUserEmail);
|
|
269
272
|
}
|
|
270
273
|
|
|
271
274
|
export function threadMatchesVisibilityFilter(
|
|
@@ -447,7 +450,7 @@ function SidebarSectionSettingsPopover({
|
|
|
447
450
|
|
|
448
451
|
// --- Visibility types and helpers ---
|
|
449
452
|
|
|
450
|
-
type Visibility =
|
|
453
|
+
type Visibility = DashboardVisibility;
|
|
451
454
|
|
|
452
455
|
// --- Shared sortable row (used by both dashboards and analyses) ---
|
|
453
456
|
|
|
@@ -1143,6 +1146,7 @@ type SqlDashboardListItem = {
|
|
|
1143
1146
|
id: string;
|
|
1144
1147
|
name: string;
|
|
1145
1148
|
visibility?: Visibility;
|
|
1149
|
+
ownerEmail?: string | null;
|
|
1146
1150
|
parentId?: string;
|
|
1147
1151
|
};
|
|
1148
1152
|
|
|
@@ -1160,18 +1164,25 @@ async function fetchSqlDashboards(
|
|
|
1160
1164
|
d.visibility === "org" ||
|
|
1161
1165
|
d.visibility === "public"),
|
|
1162
1166
|
)
|
|
1163
|
-
.map((d: any) =>
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1167
|
+
.map((d: any) => {
|
|
1168
|
+
const ownerEmail =
|
|
1169
|
+
typeof d.ownerEmail === "string" && d.ownerEmail.trim().length > 0
|
|
1170
|
+
? d.ownerEmail
|
|
1171
|
+
: undefined;
|
|
1172
|
+
return {
|
|
1173
|
+
id: d.id,
|
|
1174
|
+
name:
|
|
1175
|
+
typeof d.name === "string" && d.name.trim().length > 0
|
|
1176
|
+
? d.name
|
|
1177
|
+
: t("sidebar.untitledDashboard"),
|
|
1178
|
+
visibility: d.visibility as Visibility,
|
|
1179
|
+
...(ownerEmail ? { ownerEmail } : {}),
|
|
1180
|
+
parentId:
|
|
1181
|
+
typeof d.parentId === "string" && d.parentId.trim().length > 0
|
|
1182
|
+
? d.parentId
|
|
1183
|
+
: undefined,
|
|
1184
|
+
};
|
|
1185
|
+
});
|
|
1175
1186
|
}
|
|
1176
1187
|
|
|
1177
1188
|
async function fetchSidebarAnalyses(t: (key: string) => string): Promise<
|
|
@@ -1525,7 +1536,8 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1525
1536
|
activeDashboardId !== null,
|
|
1526
1537
|
);
|
|
1527
1538
|
const [dashShowAll, setDashShowAll] = useState(false);
|
|
1528
|
-
const [dashFilter, setDashFilter] =
|
|
1539
|
+
const [dashFilter, setDashFilter] =
|
|
1540
|
+
useState<SidebarVisibilityFilter>("private");
|
|
1529
1541
|
const [dashboardSortMode, setDashboardSortModeState] =
|
|
1530
1542
|
useState<SidebarSortMode>(() => getStoredSortMode(DASHBOARD_SORT_MODE_KEY));
|
|
1531
1543
|
const { data: popularity, isReady: popularityReady } = usePopularity();
|
|
@@ -1749,6 +1761,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1749
1761
|
name: d.name,
|
|
1750
1762
|
source: "sql",
|
|
1751
1763
|
visibility: d.visibility,
|
|
1764
|
+
ownerEmail: d.ownerEmail,
|
|
1752
1765
|
parentId: d.parentId,
|
|
1753
1766
|
}));
|
|
1754
1767
|
const analysisItems: SidebarDashboard[] = analysesList.map((a) => ({
|
|
@@ -1802,9 +1815,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1802
1815
|
const filteredDashboards = useMemo(
|
|
1803
1816
|
() =>
|
|
1804
1817
|
visibleDashboards.filter((dashboard) =>
|
|
1805
|
-
matchesVisibilityFilter(dashboard, dashFilter),
|
|
1818
|
+
matchesVisibilityFilter(dashboard, dashFilter, auth?.email),
|
|
1806
1819
|
),
|
|
1807
|
-
[visibleDashboards, dashFilter],
|
|
1820
|
+
[auth?.email, visibleDashboards, dashFilter],
|
|
1808
1821
|
);
|
|
1809
1822
|
|
|
1810
1823
|
// Group dashboards that declare a parentId beneath their parent. Nesting is
|
|
@@ -468,6 +468,9 @@ const enUS = {
|
|
|
468
468
|
adminOnlyTitle: "Admin access required",
|
|
469
469
|
adminOnlyDescription:
|
|
470
470
|
"Only organization owners and admins can open Analytics admin tools.",
|
|
471
|
+
roleUnavailableTitle: "Couldn't verify your access",
|
|
472
|
+
roleUnavailableDescription:
|
|
473
|
+
"We couldn't check your organization role: {{message}}",
|
|
471
474
|
notTracked: "Not tracked",
|
|
472
475
|
visibilityprivate: "Private",
|
|
473
476
|
visibilityorg: "Shared with org",
|
|
@@ -13018,6 +13021,8 @@ const translatedDashboardAdminTranslations = {
|
|
|
13018
13021
|
adminOnlyTitle: "需要管理员权限",
|
|
13019
13022
|
adminOnlyDescription:
|
|
13020
13023
|
"只有组织所有者和管理员可以打开 Analytics 管理工具。",
|
|
13024
|
+
roleUnavailableTitle: "无法验证你的访问权限",
|
|
13025
|
+
roleUnavailableDescription: "无法检查你的组织角色:{{message}}",
|
|
13021
13026
|
notTracked: "未跟踪",
|
|
13022
13027
|
visibilityprivate: "私有",
|
|
13023
13028
|
visibilityorg: "与组织共享",
|
|
@@ -13066,6 +13071,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13066
13071
|
adminOnlyTitle: "Se requiere acceso de administrador",
|
|
13067
13072
|
adminOnlyDescription:
|
|
13068
13073
|
"Solo los propietarios y administradores de la organización pueden abrir las herramientas de administración de Analytics.",
|
|
13074
|
+
roleUnavailableTitle: "No se pudo verificar tu acceso",
|
|
13075
|
+
roleUnavailableDescription:
|
|
13076
|
+
"No pudimos comprobar tu rol en la organización: {{message}}",
|
|
13069
13077
|
notTracked: "No registrado",
|
|
13070
13078
|
visibilityprivate: "Privado",
|
|
13071
13079
|
visibilityorg: "Compartido con la organización",
|
|
@@ -13114,6 +13122,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13114
13122
|
adminOnlyTitle: "Accès administrateur requis",
|
|
13115
13123
|
adminOnlyDescription:
|
|
13116
13124
|
"Seuls les propriétaires et administrateurs de l'organisation peuvent ouvrir les outils d'administration Analytics.",
|
|
13125
|
+
roleUnavailableTitle: "Impossible de vérifier votre accès",
|
|
13126
|
+
roleUnavailableDescription:
|
|
13127
|
+
"Nous n'avons pas pu vérifier votre rôle dans l'organisation : {{message}}",
|
|
13117
13128
|
notTracked: "Non suivi",
|
|
13118
13129
|
visibilityprivate: "Privé",
|
|
13119
13130
|
visibilityorg: "Partagé avec l'organisation",
|
|
@@ -13162,6 +13173,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13162
13173
|
adminOnlyTitle: "Adminzugriff erforderlich",
|
|
13163
13174
|
adminOnlyDescription:
|
|
13164
13175
|
"Nur Organisationsinhaber und Administratoren können Analytics-Admin-Tools öffnen.",
|
|
13176
|
+
roleUnavailableTitle: "Zugriff konnte nicht überprüft werden",
|
|
13177
|
+
roleUnavailableDescription:
|
|
13178
|
+
"Deine Organisationsrolle konnte nicht überprüft werden: {{message}}",
|
|
13165
13179
|
notTracked: "Nicht erfasst",
|
|
13166
13180
|
visibilityprivate: "Privat",
|
|
13167
13181
|
visibilityorg: "Mit Organisation geteilt",
|
|
@@ -13210,6 +13224,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13210
13224
|
adminOnlyTitle: "管理者アクセスが必要です",
|
|
13211
13225
|
adminOnlyDescription:
|
|
13212
13226
|
"組織の所有者と管理者のみが Analytics 管理ツールを開けます。",
|
|
13227
|
+
roleUnavailableTitle: "アクセス権を確認できませんでした",
|
|
13228
|
+
roleUnavailableDescription:
|
|
13229
|
+
"組織内のロールを確認できませんでした: {{message}}",
|
|
13213
13230
|
notTracked: "未追跡",
|
|
13214
13231
|
visibilityprivate: "非公開",
|
|
13215
13232
|
visibilityorg: "組織と共有",
|
|
@@ -13257,6 +13274,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13257
13274
|
adminOnlyTitle: "관리자 권한 필요",
|
|
13258
13275
|
adminOnlyDescription:
|
|
13259
13276
|
"조직 소유자와 관리자만 Analytics 관리 도구를 열 수 있습니다.",
|
|
13277
|
+
roleUnavailableTitle: "접근 권한을 확인할 수 없습니다",
|
|
13278
|
+
roleUnavailableDescription:
|
|
13279
|
+
"조직 역할을 확인하지 못했습니다: {{message}}",
|
|
13260
13280
|
notTracked: "추적 안 됨",
|
|
13261
13281
|
visibilityprivate: "비공개",
|
|
13262
13282
|
visibilityorg: "조직과 공유됨",
|
|
@@ -13305,6 +13325,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13305
13325
|
adminOnlyTitle: "Acesso de administrador necessário",
|
|
13306
13326
|
adminOnlyDescription:
|
|
13307
13327
|
"Somente proprietários e administradores da organização podem abrir as ferramentas administrativas do Analytics.",
|
|
13328
|
+
roleUnavailableTitle: "Não foi possível verificar seu acesso",
|
|
13329
|
+
roleUnavailableDescription:
|
|
13330
|
+
"Não conseguimos verificar sua função na organização: {{message}}",
|
|
13308
13331
|
notTracked: "Não rastreado",
|
|
13309
13332
|
visibilityprivate: "Privado",
|
|
13310
13333
|
visibilityorg: "Compartilhado com a organização",
|
|
@@ -13352,6 +13375,9 @@ const translatedDashboardAdminTranslations = {
|
|
|
13352
13375
|
adminOnlyTitle: "एडमिन access आवश्यक है",
|
|
13353
13376
|
adminOnlyDescription:
|
|
13354
13377
|
"केवल organization owners और admins Analytics admin tools खोल सकते हैं।",
|
|
13378
|
+
roleUnavailableTitle: "आपका access सत्यापित नहीं किया जा सका",
|
|
13379
|
+
roleUnavailableDescription:
|
|
13380
|
+
"हम आपकी organization role जांच नहीं सके: {{message}}",
|
|
13355
13381
|
notTracked: "ट्रैक नहीं किया गया",
|
|
13356
13382
|
visibilityprivate: "निजी",
|
|
13357
13383
|
visibilityorg: "संगठन के साथ साझा",
|
|
@@ -13400,6 +13426,8 @@ const translatedDashboardAdminTranslations = {
|
|
|
13400
13426
|
adminOnlyTitle: "مطلوب وصول مسؤول",
|
|
13401
13427
|
adminOnlyDescription:
|
|
13402
13428
|
"يمكن لمالكي المؤسسة والمسؤولين فقط فتح أدوات إدارة Analytics.",
|
|
13429
|
+
roleUnavailableTitle: "تعذر التحقق من وصولك",
|
|
13430
|
+
roleUnavailableDescription: "تعذر التحقق من دورك في المؤسسة: {{message}}",
|
|
13403
13431
|
notTracked: "غير متتبع",
|
|
13404
13432
|
visibilityprivate: "خاص",
|
|
13405
13433
|
visibilityorg: "مشترك مع المؤسسة",
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type DashboardVisibility = "private" | "org" | "public";
|
|
2
|
+
export type DashboardVisibilityFilter = "all" | "private" | "shared";
|
|
3
|
+
|
|
4
|
+
export type DashboardVisibilityItem = {
|
|
5
|
+
visibility?: DashboardVisibility;
|
|
6
|
+
ownerEmail?: string | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function normalizeEmail(email: string | null | undefined): string | null {
|
|
10
|
+
const normalized = email?.trim().toLowerCase();
|
|
11
|
+
return normalized ? normalized : null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function isDashboardMine(
|
|
15
|
+
item: DashboardVisibilityItem,
|
|
16
|
+
currentUserEmail?: string | null,
|
|
17
|
+
): boolean {
|
|
18
|
+
if (item.visibility === "org" || item.visibility === "public") {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if ("ownerEmail" in item) {
|
|
23
|
+
const ownerEmail = normalizeEmail(item.ownerEmail);
|
|
24
|
+
const viewerEmail = normalizeEmail(currentUserEmail);
|
|
25
|
+
return Boolean(ownerEmail && viewerEmail && ownerEmail === viewerEmail);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Older dashboard-shaped items do not always carry ownership metadata.
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function matchesDashboardVisibilityFilter(
|
|
33
|
+
item: DashboardVisibilityItem,
|
|
34
|
+
filter: DashboardVisibilityFilter,
|
|
35
|
+
currentUserEmail?: string | null,
|
|
36
|
+
): boolean {
|
|
37
|
+
if (filter === "all") return true;
|
|
38
|
+
return filter === "private"
|
|
39
|
+
? isDashboardMine(item, currentUserEmail)
|
|
40
|
+
: !isDashboardMine(item, currentUserEmail);
|
|
41
|
+
}
|
|
@@ -428,7 +428,11 @@ function UsageStatCard({
|
|
|
428
428
|
|
|
429
429
|
export default function AgentsPage() {
|
|
430
430
|
const t = useT();
|
|
431
|
-
const {
|
|
431
|
+
const {
|
|
432
|
+
canManageOrg,
|
|
433
|
+
isLoading: orgRoleLoading,
|
|
434
|
+
error: orgRoleError,
|
|
435
|
+
} = useOrgRole();
|
|
432
436
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
433
437
|
const view = parseView(searchParams.get("view"));
|
|
434
438
|
const selectedConnectionId = searchParams.get("db");
|
|
@@ -461,6 +465,26 @@ export default function AgentsPage() {
|
|
|
461
465
|
);
|
|
462
466
|
}
|
|
463
467
|
|
|
468
|
+
if (orgRoleError && isAdminView) {
|
|
469
|
+
return (
|
|
470
|
+
<div className="mx-auto flex h-full w-full max-w-7xl items-center justify-center px-4 py-5 lg:px-6">
|
|
471
|
+
<div className="max-w-sm rounded-lg border bg-background p-6 text-center">
|
|
472
|
+
<div className="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-full bg-muted">
|
|
473
|
+
<IconAlertTriangle className="h-5 w-5 text-muted-foreground" />
|
|
474
|
+
</div>
|
|
475
|
+
<h1 className="text-sm font-semibold">
|
|
476
|
+
{t("agents.roleUnavailableTitle")}
|
|
477
|
+
</h1>
|
|
478
|
+
<p className="mt-1.5 text-sm leading-6 text-muted-foreground">
|
|
479
|
+
{t("agents.roleUnavailableDescription", {
|
|
480
|
+
message: orgRoleError.message,
|
|
481
|
+
})}
|
|
482
|
+
</p>
|
|
483
|
+
</div>
|
|
484
|
+
</div>
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
|
|
464
488
|
if (!canManageOrg && isAdminView) {
|
|
465
489
|
return (
|
|
466
490
|
<div className="mx-auto flex h-full w-full max-w-7xl items-center justify-center px-4 py-5 lg:px-6">
|