@agent-native/core 0.91.2 → 0.92.1
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +31 -0
- package/corpus/core/docs/content/faq.mdx +17 -0
- package/corpus/core/docs/content/notifications.mdx +12 -6
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +140 -46
- package/corpus/core/src/agent/tool-search.ts +71 -4
- package/corpus/core/src/application-state/store.ts +12 -1
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/upgrade.ts +798 -0
- package/corpus/core/src/client/AssistantChat.tsx +28 -15
- package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
- package/corpus/core/src/client/PoweredByBadge.tsx +1 -8
- package/corpus/core/src/client/agent-chat-adapter.ts +68 -16
- package/corpus/core/src/client/chat/message-components.tsx +85 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
- package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +52 -1
- package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
- package/corpus/core/src/client/db-admin/TableEditor.tsx +49 -0
- package/corpus/core/src/client/db-admin/export-utils.ts +13 -4
- package/corpus/core/src/client/db-admin/useAgentSync.ts +72 -0
- package/corpus/core/src/client/error-capture.ts +69 -7
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +5 -1
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +53 -8
- package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +5 -1
- package/corpus/core/src/client/extensions/portable-extension.ts +1 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +12 -9
- package/corpus/core/src/client/org/TeamPage.tsx +77 -71
- package/corpus/core/src/client/session-replay.ts +3 -97
- package/corpus/core/src/client/settings/SettingsPanel.tsx +738 -441
- package/corpus/core/src/client/settings/SettingsSection.tsx +161 -17
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +25 -9
- package/corpus/core/src/client/sse-event-processor.ts +29 -2
- package/corpus/core/src/db-admin/agent-tools.ts +8 -2
- package/corpus/core/src/db-admin/operations.ts +116 -4
- package/corpus/core/src/db-admin/routes.ts +1 -0
- package/corpus/core/src/db-admin/types.ts +4 -0
- package/corpus/core/src/extensions/actions.ts +113 -5
- package/corpus/core/src/extensions/html-shell.ts +5 -4
- package/corpus/core/src/extensions/routes.ts +10 -0
- package/corpus/core/src/navigation/index.ts +1 -1
- package/corpus/core/src/notifications/channels.ts +88 -25
- package/corpus/core/src/notifications/registry.ts +17 -3
- package/corpus/core/src/notifications/types.ts +4 -1
- package/corpus/core/src/resources/handlers.ts +10 -8
- package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
- package/corpus/core/src/server/poll.ts +293 -8
- package/corpus/core/src/server/request-context.ts +7 -0
- package/corpus/core/src/styles/agent-conversation.css +1 -1
- package/corpus/core/src/styles/agent-native.css +27 -0
- package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +7 -0
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/default/AGENTS.md +14 -5
- package/corpus/core/src/templates/default/package.json +2 -1
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/headless/AGENTS.md +13 -3
- package/corpus/core/src/templates/headless/package.json +1 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/workspace-core/AGENTS.md +7 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +17 -5
- package/corpus/core/src/templates/workspace-root/package.json +1 -0
- package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/analytics/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +5 -6
- package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/analytics/AGENTS.md +39 -18
- package/corpus/templates/analytics/actions/capture-test-error.ts +4 -0
- package/corpus/templates/analytics/actions/get-analytics-alert-rule-defaults.ts +23 -0
- package/corpus/templates/analytics/actions/get-error-issue.ts +1 -1
- package/corpus/templates/analytics/actions/list-analysis-revisions.ts +40 -0
- package/corpus/templates/analytics/actions/list-dashboard-revisions.ts +40 -0
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +299 -0
- package/corpus/templates/analytics/actions/navigate.ts +4 -2
- package/corpus/templates/analytics/actions/restore-analysis-revision.ts +43 -0
- package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +68 -0
- package/corpus/templates/analytics/actions/save-analytics-alert-rule.ts +14 -0
- package/corpus/templates/analytics/actions/save-monitor.ts +15 -1
- package/corpus/templates/analytics/actions/view-screen.ts +24 -0
- package/corpus/templates/analytics/app/components/analysis/AnalysisHistoryPanel.tsx +181 -0
- package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +184 -0
- package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +22 -16
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +27 -21
- package/corpus/templates/analytics/app/hooks/use-analysis-revisions.ts +43 -0
- package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +110 -0
- package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +43 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +8 -3
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +64 -2
- package/corpus/templates/analytics/app/i18n-data.ts +783 -3
- package/corpus/templates/analytics/app/pages/Agents.tsx +359 -19
- package/corpus/templates/analytics/app/pages/Settings.tsx +3 -2
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +34 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +28 -0
- package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +18 -1
- package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +7 -10
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +479 -23
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +0 -9
- package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +11 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +9 -1
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +157 -35
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +80 -220
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -99
- package/corpus/templates/analytics/app/pages/settings/AlertRulesSettingsCard.tsx +262 -104
- package/corpus/templates/analytics/app/routes/team.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-07-08-admins-can-audit-dashboard-usage-ownership-and-cleanup-signa.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-agent-monitoring-stays-available-to-non-admins.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-alert-rules-are-easier-to-scan-expand-and-edit-from-settings.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-forms-remember-last-email-recipients.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-rules-can-now-use-per-rule-slack-and-webhook.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +5 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-usage-now-counts-explorer-dashboard-traffic.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-demo-mode-session-emails-are-filtered-and-anonymized.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-adds-stack-traces-and-frequency-bars.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-now-shows-the-latest-occurrence-message-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitoring-errors-only-show-test-action-when-empty.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-production-session-replay-now-requires-private-blob-storage-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-shared-extension-links-now-show-a-clear-message-when-you-do-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-team-settings-show-access-controls-next-to-member-lists.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-uptime-monitors-now-use-a-10-second-request-timeout-by-defau.md +6 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +5 -1
- package/corpus/templates/analytics/server/db/schema.ts +56 -0
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +92 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +334 -5
- package/corpus/templates/analytics/server/lib/error-capture.ts +231 -36
- package/corpus/templates/analytics/server/lib/session-replay.ts +114 -8
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +65 -16
- package/corpus/templates/analytics/server/plugins/db.ts +122 -2
- package/corpus/templates/analytics/server/routes/api/dashboard-agent-context.json.get.ts +1 -0
- package/corpus/templates/assets/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/assets/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/assets/AGENTS.md +4 -0
- package/corpus/templates/assets/app/routes/settings.tsx +1 -1
- package/corpus/templates/assets/app/routes/team.tsx +1 -1
- package/corpus/templates/brain/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/brain/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/brain/AGENTS.md +4 -0
- package/corpus/templates/brain/app/routes/team.tsx +1 -1
- package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/calendar/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/calendar/AGENTS.md +4 -0
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +11 -2
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +21 -8
- package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +7 -1
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -2
- package/corpus/templates/calendar/app/lib/popover-click-guard.ts +48 -4
- package/corpus/templates/calendar/app/pages/Settings.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-07-08-clicking-empty-calendar-space-closes-an-open-event-popover-b.md +6 -0
- package/corpus/templates/chat/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/chat/AGENTS.md +4 -0
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/chat/app/routes/settings.tsx +2 -2
- package/corpus/templates/chat/app/routes/team.tsx +1 -1
- package/corpus/templates/clips/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/finalize-recording.ts +9 -3
- package/corpus/templates/clips/actions/set-thumbnail.ts +11 -2
- package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +1 -7
- package/corpus/templates/clips/app/components/player/player-controls.tsx +21 -13
- package/corpus/templates/clips/app/components/player/video-player.tsx +30 -75
- package/corpus/templates/clips/app/i18n/ar-SA.ts +6 -5
- package/corpus/templates/clips/app/i18n/de-DE.ts +6 -6
- package/corpus/templates/clips/app/i18n/en-US.ts +6 -5
- package/corpus/templates/clips/app/i18n/es-ES.ts +6 -5
- package/corpus/templates/clips/app/i18n/fr-FR.ts +6 -6
- package/corpus/templates/clips/app/i18n/hi-IN.ts +6 -5
- package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -5
- package/corpus/templates/clips/app/i18n/ko-KR.ts +6 -5
- package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -5
- package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -5
- package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -5
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +51 -118
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-hosted-clip-uploads-now-clear-failed-buffered-chunks.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-hosted-recording-uploads-now-avoid-sql-chunk-storage.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-recaps-now-keep-summaries-action-items-and-transcrip.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-video-playback-controls-now-match-loom-style-5-second-skips-.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +123 -3
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +15 -1
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -0
- package/corpus/templates/clips/desktop/src/styles.css +23 -1
- package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +1 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +40 -6
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -2
- package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +3 -5
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +23 -19
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +0 -1
- package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +63 -0
- package/corpus/templates/clips/server/lib/video-storage.ts +4 -0
- package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +19 -13
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +40 -1
- package/corpus/templates/content/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/content/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/content/AGENTS.md +4 -0
- package/corpus/templates/content/actions/_batch-utils.ts +8 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
- package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
- package/corpus/templates/content/actions/_database-utils.ts +6 -1
- package/corpus/templates/content/actions/_property-utils.ts +168 -0
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
- package/corpus/templates/content/actions/delete-document.ts +9 -13
- package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
- package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +47 -5
- package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
- package/corpus/templates/content/app/routes/_app.settings.tsx +2 -2
- package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
- package/corpus/templates/content/server/plugins/db.ts +19 -0
- package/corpus/templates/design/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/design/AGENTS.md +4 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +12 -9
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +57 -13
- package/corpus/templates/design/app/routes/team.tsx +1 -1
- package/corpus/templates/design/changelog/2026-07-08-local-images-added-to-designs-now-upload-to-file-storage-ins.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/dispatch/AGENTS.md +4 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/dispatch/app/routes/settings.tsx +2 -2
- package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
- package/corpus/templates/forms/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/forms/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/forms/AGENTS.md +4 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +2 -2
- package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/forms/shared/navigation.ts +1 -1
- package/corpus/templates/macros/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/macros/AGENTS.md +4 -0
- package/corpus/templates/macros/app/routes/settings.tsx +2 -2
- package/corpus/templates/macros/app/routes/team.tsx +1 -1
- package/corpus/templates/mail/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +5 -1
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/mail/AGENTS.md +4 -0
- package/corpus/templates/mail/changelog/2026-07-08-mail-attachments-in-hosted-environments-now-require-file-sto.md +6 -0
- package/corpus/templates/mail/server/handlers/media.ts +26 -1
- package/corpus/templates/mail/server/lib/outgoing-email.ts +24 -1
- package/corpus/templates/mail/server/lib/upload-store.ts +2 -1
- package/corpus/templates/plan/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/plan/AGENTS.md +4 -0
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/plan/app/routes/settings.tsx +2 -2
- package/corpus/templates/plan/app/routes/team.tsx +1 -1
- package/corpus/templates/plan/changelog/2026-07-08-hosted-plan-images-now-require-connected-storage.md +6 -0
- package/corpus/templates/plan/server/lib/plan-assets.ts +33 -4
- package/corpus/templates/slides/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/security/SKILL.md +7 -0
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/actions/generate-image-api.ts +15 -3
- package/corpus/templates/slides/app/routes/settings.tsx +2 -2
- package/corpus/templates/slides/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-08-generated-slide-images-now-return-hosted-file-storage-urls-i.md +6 -0
- package/corpus/templates/slides/shared/api.ts +1 -1
- package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/agent/production-agent.d.ts +5 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +112 -42
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/tool-search.d.ts +2 -0
- package/dist/agent/tool-search.d.ts.map +1 -1
- package/dist/agent/tool-search.js +60 -4
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +8 -2
- package/dist/application-state/store.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/upgrade.d.ts +100 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +678 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +25 -14
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/HighlightedCodeBlock.d.ts +2 -0
- package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
- package/dist/client/HighlightedCodeBlock.js +10 -1
- package/dist/client/HighlightedCodeBlock.js.map +1 -1
- package/dist/client/PoweredByBadge.d.ts +1 -1
- package/dist/client/PoweredByBadge.d.ts.map +1 -1
- package/dist/client/PoweredByBadge.js +3 -9
- package/dist/client/PoweredByBadge.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +60 -13
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +61 -8
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +12 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +136 -42
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.js +19 -2
- package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +2 -9
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
- package/dist/client/db-admin/TableEditor.js +19 -2
- package/dist/client/db-admin/TableEditor.js.map +1 -1
- package/dist/client/db-admin/export-utils.d.ts +2 -0
- package/dist/client/db-admin/export-utils.d.ts.map +1 -1
- package/dist/client/db-admin/export-utils.js +11 -3
- package/dist/client/db-admin/export-utils.js.map +1 -1
- package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
- package/dist/client/db-admin/useAgentSync.js +63 -0
- package/dist/client/db-admin/useAgentSync.js.map +1 -1
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +41 -7
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +3 -1
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +32 -5
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
- package/dist/client/extensions/InlineExtensionFrame.js +3 -1
- package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
- package/dist/client/extensions/portable-extension.d.ts.map +1 -1
- package/dist/client/extensions/portable-extension.js +1 -0
- package/dist/client/extensions/portable-extension.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +11 -6
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +5 -5
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/session-replay.d.ts +0 -8
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +3 -80
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +89 -33
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.d.ts +19 -4
- package/dist/client/settings/SettingsSection.d.ts.map +1 -1
- package/dist/client/settings/SettingsSection.js +33 -4
- package/dist/client/settings/SettingsSection.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +21 -10
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +9 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +20 -2
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/db-admin/agent-tools.d.ts.map +1 -1
- package/dist/db-admin/agent-tools.js +7 -2
- package/dist/db-admin/agent-tools.js.map +1 -1
- package/dist/db-admin/operations.d.ts.map +1 -1
- package/dist/db-admin/operations.js +90 -4
- package/dist/db-admin/operations.js.map +1 -1
- package/dist/db-admin/routes.d.ts.map +1 -1
- package/dist/db-admin/routes.js +1 -0
- package/dist/db-admin/routes.js.map +1 -1
- package/dist/db-admin/types.d.ts +4 -0
- package/dist/db-admin/types.d.ts.map +1 -1
- package/dist/db-admin/types.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +85 -5
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/html-shell.d.ts +5 -4
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +8 -0
- package/dist/extensions/routes.js.map +1 -1
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +1 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/notifications/channels.d.ts +8 -3
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +61 -22
- package/dist/notifications/channels.js.map +1 -1
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +14 -3
- package/dist/notifications/registry.js.map +1 -1
- package/dist/notifications/types.d.ts +4 -1
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/notifications/types.js.map +1 -1
- package/dist/resources/handlers.d.ts +5 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +9 -8
- package/dist/resources/handlers.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +5 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/poll.d.ts +12 -4
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +236 -9
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/styles/agent-conversation.css +1 -1
- package/dist/styles/agent-native.css +27 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/default/.agents/skills/security/SKILL.md +7 -0
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/default/AGENTS.md +14 -5
- package/dist/templates/default/package.json +2 -1
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/headless/AGENTS.md +13 -3
- package/dist/templates/headless/package.json +1 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/workspace-core/AGENTS.md +7 -1
- package/dist/templates/workspace-root/AGENTS.md +17 -5
- package/dist/templates/workspace-root/package.json +1 -0
- package/docs/content/faq.mdx +17 -0
- package/docs/content/notifications.mdx +12 -6
- package/package.json +2 -2
- package/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/default/.agents/skills/security/SKILL.md +7 -0
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/default/AGENTS.md +14 -5
- package/src/templates/default/package.json +2 -1
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/headless/AGENTS.md +13 -3
- package/src/templates/headless/package.json +1 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/workspace-core/AGENTS.md +7 -1
- package/src/templates/workspace-root/AGENTS.md +17 -5
- package/src/templates/workspace-root/package.json +1 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-clamps-ultra-wide-viewports-while-keeping-the.md +0 -6
|
@@ -98,12 +98,11 @@ agent answers about browser recordings in the Analytics template.
|
|
|
98
98
|
- Wait for all replay chunks (`isComplete`) before constructing the rrweb
|
|
99
99
|
`Replayer`. Progressive chunk publishes should only update the loading bar;
|
|
100
100
|
rebuilding the player mid-load desyncs the scrubber and playhead.
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Meta widths.
|
|
101
|
+
- Pass events to `Replayer` untouched (aside from stylesheet/script sanitization
|
|
102
|
+
that prevents blank frames from live CSS loads). Let rrweb own iframe sizing
|
|
103
|
+
via Meta / ViewportResize; use those dimensions only for CSS fit-to-stage of
|
|
104
|
+
the outer wrapper. Never rewrite Meta widths or force iframe dimensions —
|
|
105
|
+
that desyncs the FullSnapshot DOM and blanks the stage.
|
|
107
106
|
- The event timeline soft-highlights the active marker, auto-scrolls it into
|
|
108
107
|
view (pausing briefly after manual scroll), and supports search. It appears
|
|
109
108
|
beside the player from ~880px content width upward.
|
|
@@ -13,7 +13,9 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
## Rule
|
|
15
15
|
|
|
16
|
-
All application data lives in **SQL** (SQLite locally, persistent database in production). The agent and UI share the same database. Do not store durable app data in the filesystem unless the app is explicitly running a Local File Mode artifact flow described below.
|
|
16
|
+
All application data lives in **SQL** (SQLite locally, persistent database in production). The agent and UI share the same database. SQL stores structured records, metadata, references, and searchable text — not large raw file payloads. Do not store durable app data in the filesystem unless the app is explicitly running a Local File Mode artifact flow described below.
|
|
17
|
+
|
|
18
|
+
Large binary or file-like payloads (images, video/audio, PDFs, ZIPs, screenshots, session replay chunks, thumbnails, generated assets, `data:` URLs, and base64 file bodies) must go through configured file/blob storage such as `uploadFile()` or `putPrivateBlob()`. Persist only the returned URL, asset id, or opaque blob handle in SQL. If storage is unavailable in hosted or persistent-database mode, fail closed with setup guidance instead of falling back to base64 in `application_state`, `settings`, `resources`, or app tables. Local SQLite-only dev fallbacks may exist for tiny assets, but they must be capped, documented as dev-only, and kept off hot list/read paths.
|
|
17
19
|
|
|
18
20
|
**Local File Mode exception:** some artifact apps (Content, Plans, Slides, Dashboards, Designs, etc.) can intentionally use repo files as the source of truth for the artifact itself. This must be explicit via `agent-native.json`, `AGENT_NATIVE_MODE=local-files`, or an app-owned local-file action helper. In that mode, the UI and agent still go through app actions, but those actions read/write scoped files through `@agent-native/core/local-artifacts` instead of SQL rows. App state, auth, settings, credentials, collaboration metadata, and hosted database mode remain SQL. File-to-database or file-to-provider synchronization is an explicit sync step, not an implicit side effect of editing.
|
|
19
21
|
|
|
@@ -136,6 +138,7 @@ Polling streams database changes to the UI. When the agent writes to the databas
|
|
|
136
138
|
- Use the `settings` store for app configuration and user preferences
|
|
137
139
|
- Use `application-state` for ephemeral UI state that the agent and UI share
|
|
138
140
|
- Use `oauth-tokens` for OAuth credentials
|
|
141
|
+
- Use `uploadFile()` or `putPrivateBlob()` for large files/blob data and store only URLs, ids, or handles in SQL
|
|
139
142
|
- Use core DB scripts (`db-schema`, `db-query`, `db-exec`, `db-patch`) for ad-hoc database operations
|
|
140
143
|
- Use `db-exec --statements` instead of several separate `db-exec` calls for related writes; it is faster and rolls back the whole batch if one statement fails
|
|
141
144
|
- Reach for `db-patch` instead of `db-exec UPDATE` whenever you're making a small change to a large text/JSON column — it's much cheaper on tokens
|
|
@@ -146,6 +149,7 @@ Polling streams database changes to the UI. When the agent writes to the databas
|
|
|
146
149
|
- Don't store app state in localStorage, sessionStorage, or cookies (except for UI-only preferences like sidebar width)
|
|
147
150
|
- Don't keep state only in memory (server variables, global stores)
|
|
148
151
|
- Don't use Redis or any external state store for app data
|
|
152
|
+
- Don't store large files, base64 blobs, `data:` URLs, screenshots, videos, audio, PDFs, ZIPs, or session replay chunks directly in SQL rows, `application_state`, `settings`, or `resources`
|
|
149
153
|
- Don't implement product features with raw SQL or `getDbExec()` when Drizzle can express the query
|
|
150
154
|
- Don't write SQLite-only or Postgres-only SQL in app code
|
|
151
155
|
- Don't interpolate user input directly into SQL queries — use Drizzle ORM's query builder
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upgrade-agent-native
|
|
3
|
+
description: >-
|
|
4
|
+
Bring an older Agent Native app or workspace current. Use when updating
|
|
5
|
+
@agent-native/core, fixing a broken upgrade, or when tempted to patch or
|
|
6
|
+
override core/dispatch packages to make an old branch run.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Upgrade Agent Native
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
When an older Agent Native app/branch needs to run on current packages, use
|
|
17
|
+
`agent-native upgrade`. Never "fix" upgrade breakage with
|
|
18
|
+
`pnpm.overrides`, `patchedDependencies`, `resolutions`, local patches, or
|
|
19
|
+
edits under `node_modules/@agent-native/*` — especially not against
|
|
20
|
+
`@agent-native/core` or `@agent-native/dispatch`.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Agents often respond to a failed core bump by inventing framework patches and
|
|
25
|
+
dispatch behavior overrides. That hides the real app-level break, drifts from
|
|
26
|
+
upstream, and makes the next upgrade worse. The supported path is bump →
|
|
27
|
+
install → refresh scaffold skills → verify, then fix **app** code only.
|
|
28
|
+
|
|
29
|
+
## How
|
|
30
|
+
|
|
31
|
+
1. **Doctor first (optional but recommended)**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx @agent-native/core@latest upgrade check
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This reports framework overrides/patches and pending `@agent-native/*`
|
|
38
|
+
bumps. If overrides/patches are present, remove them before continuing.
|
|
39
|
+
|
|
40
|
+
2. **Run the upgrade**
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx @agent-native/core@latest upgrade
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or from an already-installed CLI: `pnpm exec agent-native upgrade` /
|
|
47
|
+
`agent-native upgrade`.
|
|
48
|
+
|
|
49
|
+
What it does:
|
|
50
|
+
|
|
51
|
+
- Blocks (unless `--force`) when `@agent-native/*` overrides/patches exist
|
|
52
|
+
- Rewrites non-local `@agent-native/*` dependency pins to `latest`
|
|
53
|
+
- Runs the package manager install
|
|
54
|
+
- Runs `skills update scaffold --project`
|
|
55
|
+
- Runs `typecheck` when the project has that script
|
|
56
|
+
|
|
57
|
+
3. **If upgrade or typecheck fails**
|
|
58
|
+
|
|
59
|
+
- Read the concrete error
|
|
60
|
+
- Fix **app** source, actions, config, or env — not framework packages
|
|
61
|
+
- Re-run `agent-native upgrade` or `pnpm typecheck`
|
|
62
|
+
- Stop and ask the user if you cannot fix the app-level error
|
|
63
|
+
|
|
64
|
+
4. **Dry-run / partial runs**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
agent-native upgrade --dry-run
|
|
68
|
+
agent-native upgrade --skip-verify
|
|
69
|
+
agent-native upgrade --skip-install # package.json bumps only
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Don't
|
|
73
|
+
|
|
74
|
+
- Don't add `pnpm.overrides`, `overrides`, `resolutions`, or
|
|
75
|
+
`patchedDependencies` for any `@agent-native/*` package
|
|
76
|
+
- Don't edit `node_modules/@agent-native/core` or
|
|
77
|
+
`node_modules/@agent-native/dispatch`
|
|
78
|
+
- Don't invent local "dispatch behavior" shims to paper over version skew
|
|
79
|
+
- Don't keep iterating with more framework patches after a failed install
|
|
80
|
+
- Don't skip `skills update scaffold --project` after a core bump (the
|
|
81
|
+
upgrade command does this for you)
|
|
82
|
+
|
|
83
|
+
## Related Skills
|
|
84
|
+
|
|
85
|
+
- **self-modifying-code** — Tier 4: framework packages are off limits
|
|
86
|
+
- **agent-native-docs** — version-matched docs after the bump
|
|
87
|
+
- **portability** — keep app code provider-agnostic across upgrades
|
|
@@ -9,6 +9,10 @@ details live in `.agents/skills/`.
|
|
|
9
9
|
|
|
10
10
|
## Core Rules
|
|
11
11
|
|
|
12
|
+
- Store large file/blob payloads in configured file/blob storage, not SQL: no
|
|
13
|
+
base64, `data:` URLs, images, video/audio, PDFs, ZIPs, screenshots,
|
|
14
|
+
thumbnails, or replay chunks in app tables, `application_state`, `settings`,
|
|
15
|
+
or `resources`; persist URLs, ids, or handles instead.
|
|
12
16
|
- Never hardcode API keys, tokens, webhook URLs, signing secrets, private Builder/internal data, customer data, or credential-looking literals. Use secrets/OAuth/runtime configuration and obvious placeholders in examples.
|
|
13
17
|
- Data integrity comes first. Do not invent numbers, dimensions, filters, or
|
|
14
18
|
source semantics. State uncertainty and inspect the source when needed.
|
|
@@ -84,15 +88,18 @@ details live in `.agents/skills/`.
|
|
|
84
88
|
/ `$ai_latency`, `status`, `tool_calls`, `successful_tools`, `failed_tools`,
|
|
85
89
|
and `$ai_error` / `error_message`. Do not expect prompts, tool args, or model
|
|
86
90
|
responses in these tracked events by default.
|
|
87
|
-
- `/agents` is the Analytics home for
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
agent-
|
|
95
|
-
|
|
91
|
+
- `/agents` is the Analytics home for admin surfaces. The default Monitoring
|
|
92
|
+
view embeds the shared observability dashboard for traces, conversations,
|
|
93
|
+
evals, experiments, and feedback. `/agents?view=dashboards` shows the
|
|
94
|
+
admin-only dashboard usage audit; call `list-dashboard-usage-stats` when
|
|
95
|
+
admins ask about dashboard created/modified dates, owners, last tracked
|
|
96
|
+
modifier, views, engagements, saved views, or cleanup candidates. The
|
|
97
|
+
Advanced menu opens `/agents?view=database`, where organization owners/admins
|
|
98
|
+
can connect other agent-native app databases and use the shared database admin
|
|
99
|
+
tool for table browsing, row editing, and SQL inspection. This database
|
|
100
|
+
surface is for connected target app databases, not broad access to all
|
|
101
|
+
Analytics data. Keep future admin additions inside this route instead of
|
|
102
|
+
adding many top-level sidebar tabs.
|
|
96
103
|
- For dashboard edits, default to `mutate-dashboard` with its typed
|
|
97
104
|
`dashboard.*` script API. It supports id-based panel moves, title/SQL/config
|
|
98
105
|
edits, inserts, duplication, removal, and dashboard field patches in one
|
|
@@ -100,6 +107,13 @@ details live in `.agents/skills/`.
|
|
|
100
107
|
serialization traps. The script is constrained: only documented dashboard
|
|
101
108
|
method calls with JSON-compatible arguments are parsed; variables, imports,
|
|
102
109
|
loops, functions, network, filesystem, and DB access are not available.
|
|
110
|
+
- Dashboard saves keep bounded history in SQL. Use
|
|
111
|
+
`list-dashboard-revisions` to inspect undo points and
|
|
112
|
+
`restore-dashboard-revision` to restore one instead of hand-editing history
|
|
113
|
+
rows.
|
|
114
|
+
- Saved analyses also keep bounded history. Use `list-analysis-revisions` and
|
|
115
|
+
`restore-analysis-revision` for rollback after a re-run updates the saved
|
|
116
|
+
findings.
|
|
103
117
|
- Do not count shifting `/panels/<index>` values for ordinary dashboard edit
|
|
104
118
|
requests. Use low-level JSON-pointer edits only when explicitly requested.
|
|
105
119
|
- `get-sql-dashboard` is compact by default for agents. Use its `panels`
|
|
@@ -140,11 +154,15 @@ details live in `.agents/skills/`.
|
|
|
140
154
|
`thresholdMode: "distinct_count"` counts unique values from `distinctBy`.
|
|
141
155
|
Alert notifications use the shared notification channel registry, so
|
|
142
156
|
`channels` can include `inbox`, `email`, `slack`, `webhook`, or any custom
|
|
143
|
-
registered channel.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
`
|
|
147
|
-
|
|
157
|
+
registered channel. Slack/webhook prefer delivery-only
|
|
158
|
+
`metadata.delivery.slackWebhookUrl` / `metadata.delivery.webhookUrl` (uptime
|
|
159
|
+
monitors store these on the monitor row), then fall back to
|
|
160
|
+
`NOTIFICATIONS_SLACK_WEBHOOK_URL` / `NOTIFICATIONS_WEBHOOK_URL`. Configure
|
|
161
|
+
optional `NOTIFICATIONS_SLACK_WEBHOOK_AUTH`; configure email with existing
|
|
162
|
+
`RESEND_API_KEY` or `SENDGRID_API_KEY` plus `EMAIL_FROM`, and pass per-rule
|
|
163
|
+
`emailRecipients` or the fallback `NOTIFICATIONS_EMAIL_RECIPIENTS`. Saving
|
|
164
|
+
explicit `emailRecipients` also remembers them as the current user's defaults
|
|
165
|
+
for the next alert rule created in Settings.
|
|
148
166
|
Netlify builds emit an alert cron trigger plus background worker from
|
|
149
167
|
`scripts/emit-netlify-dashboard-report-cron.ts` every five minutes; long-lived
|
|
150
168
|
runtimes use the in-process scheduler unless `ANALYTICS_ALERT_JOBS=0` is set.
|
|
@@ -161,9 +179,9 @@ details live in `.agents/skills/`.
|
|
|
161
179
|
`view="catalog"` for the template catalog, `view="sessions"` for session
|
|
162
180
|
replay, `view="monitoring"` with `monitoringView="uptime|errors"` (plus the
|
|
163
181
|
`monitorId`, `statusPageId`, or `errorIssueId` deep links) for uptime checks,
|
|
164
|
-
public status pages, or error triage, and `view="agents"`
|
|
165
|
-
`agentsView="database"`
|
|
166
|
-
|
|
182
|
+
public status pages, or error triage, and `view="agents"` with
|
|
183
|
+
`agentsView="dashboards|database"` plus optional `dbAdminConnectionId` for
|
|
184
|
+
dashboard usage or connected app database admin.
|
|
167
185
|
- Use `view-screen` when the active dashboard/chart context is unclear.
|
|
168
186
|
|
|
169
187
|
## Session Replay
|
|
@@ -240,7 +258,10 @@ details live in `.agents/skills/`.
|
|
|
240
258
|
`@agent-native/core/client` (`captureException` / `captureMessage` /
|
|
241
259
|
`addErrorBreadcrumb`), auto-enabled by `configureTracking` and transported
|
|
242
260
|
through the first-party analytics ingest as a `$exception` event. Deep link:
|
|
243
|
-
`?view=errors&issue=<id>`.
|
|
261
|
+
`?view=errors&issue=<id>`. Issue detail includes recent frequency,
|
|
262
|
+
parsed/raw stack traces, source code snippets when available, breadcrumbs,
|
|
263
|
+
tags, occurrence history, and session replay links. See
|
|
264
|
+
`docs/error-capture.md`.
|
|
244
265
|
- Session replay ↔ Errors: a recording's devtools Console error lines link to
|
|
245
266
|
the grouped issue at `/monitoring?view=errors&issue=<id>`, resolved by
|
|
246
267
|
`match-error-issues` (exact fingerprint match, no heuristics); issues link
|
|
@@ -19,10 +19,14 @@ export default defineAction({
|
|
|
19
19
|
schema: z.object({
|
|
20
20
|
message: z
|
|
21
21
|
.string()
|
|
22
|
+
.trim()
|
|
23
|
+
.max(500)
|
|
22
24
|
.optional()
|
|
23
25
|
.describe("Optional custom error message for the sample error."),
|
|
24
26
|
type: z
|
|
25
27
|
.string()
|
|
28
|
+
.trim()
|
|
29
|
+
.regex(/^[A-Za-z_$][\w$.]{0,79}$/)
|
|
26
30
|
.optional()
|
|
27
31
|
.describe("Optional error type/name, e.g. TypeError. Defaults to Error."),
|
|
28
32
|
}),
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
getRequestOrgId,
|
|
4
|
+
getRequestUserEmail,
|
|
5
|
+
} from "@agent-native/core/server";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import { getAnalyticsAlertRuleDefaults } from "../server/lib/analytics-alerts";
|
|
9
|
+
|
|
10
|
+
export default defineAction({
|
|
11
|
+
description:
|
|
12
|
+
"Read the current user's remembered defaults for creating analytics alert rules.",
|
|
13
|
+
schema: z.object({}),
|
|
14
|
+
http: { method: "GET" },
|
|
15
|
+
readOnly: true,
|
|
16
|
+
agentTool: false,
|
|
17
|
+
run: async () => {
|
|
18
|
+
const email = getRequestUserEmail();
|
|
19
|
+
if (!email) throw new Error("no authenticated user");
|
|
20
|
+
const orgId = getRequestOrgId() || null;
|
|
21
|
+
return getAnalyticsAlertRuleDefaults({ email, orgId });
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -15,7 +15,7 @@ function resolveScope() {
|
|
|
15
15
|
|
|
16
16
|
export default defineAction({
|
|
17
17
|
description:
|
|
18
|
-
"Get one captured error issue with its recent
|
|
18
|
+
"Get one captured error issue with its recent occurrence frequency, parsed/raw stack traces, source code snippets when available, breadcrumbs, tags/extra, and links to the session replays where the error happened. Use this to triage a specific issue and jump to the replay.",
|
|
19
19
|
schema: z.object({
|
|
20
20
|
id: z.string().describe("Error issue id (erriss_...)."),
|
|
21
21
|
eventsLimit: z.coerce
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
getRequestOrgId,
|
|
4
|
+
getRequestUserEmail,
|
|
5
|
+
} from "@agent-native/core/server";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import { listAnalysisRevisions } from "../server/lib/dashboards-store";
|
|
9
|
+
|
|
10
|
+
function resolveScope() {
|
|
11
|
+
const orgId = getRequestOrgId() || null;
|
|
12
|
+
const email = getRequestUserEmail();
|
|
13
|
+
if (!email) throw new Error("no authenticated user");
|
|
14
|
+
return { orgId, email };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default defineAction({
|
|
18
|
+
description: "List saved history revisions for an ad-hoc analysis.",
|
|
19
|
+
schema: z.object({
|
|
20
|
+
analysisId: z.string().describe("Analysis id to inspect"),
|
|
21
|
+
}),
|
|
22
|
+
http: { method: "GET" },
|
|
23
|
+
readOnly: true,
|
|
24
|
+
run: async (args) => {
|
|
25
|
+
const revisions = await listAnalysisRevisions(
|
|
26
|
+
args.analysisId,
|
|
27
|
+
resolveScope(),
|
|
28
|
+
);
|
|
29
|
+
return {
|
|
30
|
+
revisions: revisions.map((revision) => ({
|
|
31
|
+
id: revision.id,
|
|
32
|
+
analysisId: revision.analysisId,
|
|
33
|
+
name: revision.name,
|
|
34
|
+
description: revision.description,
|
|
35
|
+
createdAt: revision.createdAt,
|
|
36
|
+
createdBy: revision.createdBy,
|
|
37
|
+
})),
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
getRequestOrgId,
|
|
4
|
+
getRequestUserEmail,
|
|
5
|
+
} from "@agent-native/core/server";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
8
|
+
import { listDashboardRevisions } from "../server/lib/dashboards-store";
|
|
9
|
+
|
|
10
|
+
function resolveScope() {
|
|
11
|
+
const orgId = getRequestOrgId() || null;
|
|
12
|
+
const email = getRequestUserEmail();
|
|
13
|
+
if (!email) throw new Error("no authenticated user");
|
|
14
|
+
return { orgId, email };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default defineAction({
|
|
18
|
+
description: "List saved dashboard history revisions for undo/restore.",
|
|
19
|
+
schema: z.object({
|
|
20
|
+
dashboardId: z.string().describe("Dashboard id to inspect"),
|
|
21
|
+
}),
|
|
22
|
+
http: { method: "GET" },
|
|
23
|
+
readOnly: true,
|
|
24
|
+
run: async (args) => {
|
|
25
|
+
const revisions = await listDashboardRevisions(
|
|
26
|
+
args.dashboardId,
|
|
27
|
+
resolveScope(),
|
|
28
|
+
);
|
|
29
|
+
return {
|
|
30
|
+
revisions: revisions.map((revision) => ({
|
|
31
|
+
id: revision.id,
|
|
32
|
+
dashboardId: revision.dashboardId,
|
|
33
|
+
kind: revision.kind,
|
|
34
|
+
title: revision.title,
|
|
35
|
+
createdAt: revision.createdAt,
|
|
36
|
+
createdBy: revision.createdBy,
|
|
37
|
+
})),
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core/action";
|
|
2
|
+
import { buildDeepLink } from "@agent-native/core/server";
|
|
3
|
+
import { and, eq, like, or, sql } from "drizzle-orm";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
7
|
+
import { requireDbAdminContextFromRequest } from "../server/lib/db-admin-connections";
|
|
8
|
+
|
|
9
|
+
type DashboardUsageStats = {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
kind: "explorer" | "sql";
|
|
13
|
+
ownerEmail: string | null;
|
|
14
|
+
visibility: "private" | "org" | "public";
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
updatedBy: string | null;
|
|
18
|
+
archivedAt: string | null;
|
|
19
|
+
hiddenAt: string | null;
|
|
20
|
+
hiddenBy: string | null;
|
|
21
|
+
viewCount: number;
|
|
22
|
+
engagementCount: number;
|
|
23
|
+
eventEngagementCount: number;
|
|
24
|
+
savedViewCount: number;
|
|
25
|
+
uniqueUserCount: number;
|
|
26
|
+
lastViewedAt: string | null;
|
|
27
|
+
lastSavedViewAt: string | null;
|
|
28
|
+
panelCount: number | null;
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function toNumber(value: unknown): number {
|
|
33
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
34
|
+
if (typeof value === "bigint") return Number(value);
|
|
35
|
+
if (typeof value === "string" && value.trim()) {
|
|
36
|
+
const parsed = Number(value);
|
|
37
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function parseConfig(value: unknown): Record<string, unknown> {
|
|
43
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
44
|
+
return value as Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value !== "string") return {};
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(value);
|
|
49
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
50
|
+
? parsed
|
|
51
|
+
: {};
|
|
52
|
+
} catch {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function dashboardName(row: { title: string; config: unknown }): string {
|
|
58
|
+
const config = parseConfig(row.config);
|
|
59
|
+
const configName = config.name;
|
|
60
|
+
if (typeof configName === "string" && configName.trim()) {
|
|
61
|
+
return configName.trim();
|
|
62
|
+
}
|
|
63
|
+
return row.title || "Untitled";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function dashboardPanelCount(row: {
|
|
67
|
+
kind: string;
|
|
68
|
+
config: unknown;
|
|
69
|
+
}): number | null {
|
|
70
|
+
if (row.kind !== "sql") return null;
|
|
71
|
+
const panels = parseConfig(row.config).panels;
|
|
72
|
+
return Array.isArray(panels) ? panels.length : 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function dashboardIdFromPath(path: string | null): string | null {
|
|
76
|
+
const pathname = path ?? "";
|
|
77
|
+
const match = pathname.match(/(?:^|\/)(?:dashboards|adhoc)\/([^/?#]+)/);
|
|
78
|
+
if (!match) return null;
|
|
79
|
+
if (match[1] === "explorer-dashboard") {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
return decodeURIComponent(match[1]);
|
|
84
|
+
} catch {
|
|
85
|
+
return match[1];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function dashboardIdFromEventLocation(
|
|
90
|
+
path: string | null,
|
|
91
|
+
url: string | null,
|
|
92
|
+
): string | null {
|
|
93
|
+
const direct = dashboardIdFromPath(path);
|
|
94
|
+
if (direct) return direct;
|
|
95
|
+
const raw = url || path;
|
|
96
|
+
if (!raw) return null;
|
|
97
|
+
try {
|
|
98
|
+
const parsed = new URL(raw, "https://analytics.local");
|
|
99
|
+
if (
|
|
100
|
+
/(?:^|\/)(?:dashboards|adhoc)\/explorer-dashboard$/.test(parsed.pathname)
|
|
101
|
+
) {
|
|
102
|
+
const id = parsed.searchParams.get("id");
|
|
103
|
+
return id && id.trim() ? id : null;
|
|
104
|
+
}
|
|
105
|
+
} catch {
|
|
106
|
+
// Fall through to regex below for malformed relative strings.
|
|
107
|
+
}
|
|
108
|
+
const match = raw.match(
|
|
109
|
+
/(?:^|\/)(?:dashboards|adhoc)\/explorer-dashboard(?:\?[^#]*)?[?&]id=([^&#]+)/,
|
|
110
|
+
);
|
|
111
|
+
if (!match) return null;
|
|
112
|
+
try {
|
|
113
|
+
return decodeURIComponent(match[1].replace(/\+/g, " "));
|
|
114
|
+
} catch {
|
|
115
|
+
return match[1];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function dashboardUrl(row: { id: string; kind: string }): string {
|
|
120
|
+
return row.kind === "explorer"
|
|
121
|
+
? `/dashboards/explorer-dashboard?id=${encodeURIComponent(row.id)}`
|
|
122
|
+
: `/dashboards/${encodeURIComponent(row.id)}`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default defineAction({
|
|
126
|
+
description:
|
|
127
|
+
"List admin-only dashboard usage and cleanup stats for every dashboard in the active organization. Includes lifecycle metadata, owner, last tracked modifier, pageviews, engagement events, unique viewers, saved view counts, archive/hidden state, and dashboard links. Requires active organization owner/admin role.",
|
|
128
|
+
schema: z.object({}),
|
|
129
|
+
http: { method: "GET" },
|
|
130
|
+
readOnly: true,
|
|
131
|
+
link: () => ({
|
|
132
|
+
url: buildDeepLink({
|
|
133
|
+
app: "analytics",
|
|
134
|
+
view: "agents",
|
|
135
|
+
params: { agentsView: "dashboards" },
|
|
136
|
+
}),
|
|
137
|
+
label: "Open dashboard usage admin",
|
|
138
|
+
view: "agents",
|
|
139
|
+
}),
|
|
140
|
+
run: async (_args, ctx) => {
|
|
141
|
+
const admin = await requireDbAdminContextFromRequest(ctx);
|
|
142
|
+
const db = getDb() as any;
|
|
143
|
+
|
|
144
|
+
// guard:allow-unscoped — org owner/admin audit intentionally spans all
|
|
145
|
+
// dashboard rows in the active org after requireDbAdminContextFromRequest.
|
|
146
|
+
const dashboardRows = await db
|
|
147
|
+
.select()
|
|
148
|
+
.from(schema.dashboards)
|
|
149
|
+
.where(eq(schema.dashboards.orgId, admin.orgId));
|
|
150
|
+
|
|
151
|
+
const dashboardIds = new Set<string>(
|
|
152
|
+
dashboardRows.map((row: { id: string }) => row.id),
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const savedViewRows = await db
|
|
156
|
+
.select({
|
|
157
|
+
dashboardId: schema.dashboardViews.dashboardId,
|
|
158
|
+
count: sql<number>`count(*)`,
|
|
159
|
+
lastSavedViewAt: sql<
|
|
160
|
+
string | null
|
|
161
|
+
>`max(${schema.dashboardViews.createdAt})`,
|
|
162
|
+
})
|
|
163
|
+
.from(schema.dashboardViews)
|
|
164
|
+
.groupBy(schema.dashboardViews.dashboardId);
|
|
165
|
+
|
|
166
|
+
const savedViewsByDashboard = new Map<
|
|
167
|
+
string,
|
|
168
|
+
{ count: number; lastSavedViewAt: string | null }
|
|
169
|
+
>();
|
|
170
|
+
for (const row of savedViewRows as Array<{
|
|
171
|
+
dashboardId: string;
|
|
172
|
+
count: unknown;
|
|
173
|
+
lastSavedViewAt: string | null;
|
|
174
|
+
}>) {
|
|
175
|
+
if (!dashboardIds.has(row.dashboardId)) continue;
|
|
176
|
+
savedViewsByDashboard.set(row.dashboardId, {
|
|
177
|
+
count: toNumber(row.count),
|
|
178
|
+
lastSavedViewAt: row.lastSavedViewAt ?? null,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const analyticsUserIdentity = sql<
|
|
183
|
+
string | null
|
|
184
|
+
>`coalesce(nullif(${schema.analyticsEvents.userKey}, ''), nullif(${schema.analyticsEvents.userId}, ''), nullif(${schema.analyticsEvents.anonymousId}, ''), nullif(${schema.analyticsEvents.sessionId}, ''))`;
|
|
185
|
+
const eventRows = await db
|
|
186
|
+
.select({
|
|
187
|
+
path: schema.analyticsEvents.path,
|
|
188
|
+
url: schema.analyticsEvents.url,
|
|
189
|
+
eventName: schema.analyticsEvents.eventName,
|
|
190
|
+
count: sql<number>`count(*)`,
|
|
191
|
+
userIdentity: analyticsUserIdentity,
|
|
192
|
+
lastSeenAt: sql<
|
|
193
|
+
string | null
|
|
194
|
+
>`max(${schema.analyticsEvents.receivedAt})`,
|
|
195
|
+
})
|
|
196
|
+
.from(schema.analyticsEvents)
|
|
197
|
+
.where(
|
|
198
|
+
and(
|
|
199
|
+
eq(schema.analyticsEvents.orgId, admin.orgId),
|
|
200
|
+
or(
|
|
201
|
+
like(schema.analyticsEvents.path, "%/dashboards/%"),
|
|
202
|
+
like(schema.analyticsEvents.path, "%/adhoc/%"),
|
|
203
|
+
like(schema.analyticsEvents.url, "%/dashboards/%"),
|
|
204
|
+
like(schema.analyticsEvents.url, "%/adhoc/%"),
|
|
205
|
+
),
|
|
206
|
+
),
|
|
207
|
+
)
|
|
208
|
+
.groupBy(
|
|
209
|
+
schema.analyticsEvents.path,
|
|
210
|
+
schema.analyticsEvents.url,
|
|
211
|
+
schema.analyticsEvents.eventName,
|
|
212
|
+
analyticsUserIdentity,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const eventsByDashboard = new Map<
|
|
216
|
+
string,
|
|
217
|
+
{
|
|
218
|
+
viewCount: number;
|
|
219
|
+
eventEngagementCount: number;
|
|
220
|
+
uniqueUsers: Set<string>;
|
|
221
|
+
lastViewedAt: string | null;
|
|
222
|
+
}
|
|
223
|
+
>();
|
|
224
|
+
for (const row of eventRows as Array<{
|
|
225
|
+
path: string | null;
|
|
226
|
+
url: string | null;
|
|
227
|
+
eventName: string;
|
|
228
|
+
count: unknown;
|
|
229
|
+
userIdentity: string | null;
|
|
230
|
+
lastSeenAt: string | null;
|
|
231
|
+
}>) {
|
|
232
|
+
const dashboardId = dashboardIdFromEventLocation(row.path, row.url);
|
|
233
|
+
if (!dashboardId || !dashboardIds.has(dashboardId)) continue;
|
|
234
|
+
const current = eventsByDashboard.get(dashboardId) ?? {
|
|
235
|
+
viewCount: 0,
|
|
236
|
+
eventEngagementCount: 0,
|
|
237
|
+
uniqueUsers: new Set<string>(),
|
|
238
|
+
lastViewedAt: null,
|
|
239
|
+
};
|
|
240
|
+
const count = toNumber(row.count);
|
|
241
|
+
if (row.eventName === "pageview") {
|
|
242
|
+
current.viewCount += count;
|
|
243
|
+
current.lastViewedAt =
|
|
244
|
+
!current.lastViewedAt ||
|
|
245
|
+
(row.lastSeenAt && row.lastSeenAt > current.lastViewedAt)
|
|
246
|
+
? (row.lastSeenAt ?? current.lastViewedAt)
|
|
247
|
+
: current.lastViewedAt;
|
|
248
|
+
} else {
|
|
249
|
+
current.eventEngagementCount += count;
|
|
250
|
+
}
|
|
251
|
+
if (row.userIdentity) current.uniqueUsers.add(row.userIdentity);
|
|
252
|
+
eventsByDashboard.set(dashboardId, current);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return (dashboardRows as Array<any>)
|
|
256
|
+
.map((row): DashboardUsageStats => {
|
|
257
|
+
const savedViews = savedViewsByDashboard.get(row.id) ?? {
|
|
258
|
+
count: 0,
|
|
259
|
+
lastSavedViewAt: null,
|
|
260
|
+
};
|
|
261
|
+
const events = eventsByDashboard.get(row.id) ?? {
|
|
262
|
+
viewCount: 0,
|
|
263
|
+
eventEngagementCount: 0,
|
|
264
|
+
uniqueUsers: new Set<string>(),
|
|
265
|
+
lastViewedAt: null,
|
|
266
|
+
};
|
|
267
|
+
return {
|
|
268
|
+
id: row.id,
|
|
269
|
+
name: dashboardName(row),
|
|
270
|
+
kind: row.kind === "explorer" ? "explorer" : "sql",
|
|
271
|
+
ownerEmail: row.ownerEmail ?? null,
|
|
272
|
+
visibility:
|
|
273
|
+
row.visibility === "org" || row.visibility === "public"
|
|
274
|
+
? row.visibility
|
|
275
|
+
: "private",
|
|
276
|
+
createdAt: row.createdAt,
|
|
277
|
+
updatedAt: row.updatedAt,
|
|
278
|
+
updatedBy: row.updatedBy ?? null,
|
|
279
|
+
archivedAt: row.archivedAt ?? null,
|
|
280
|
+
hiddenAt: row.hiddenAt ?? null,
|
|
281
|
+
hiddenBy: row.hiddenBy ?? null,
|
|
282
|
+
viewCount: events.viewCount,
|
|
283
|
+
eventEngagementCount: events.eventEngagementCount,
|
|
284
|
+
savedViewCount: savedViews.count,
|
|
285
|
+
engagementCount: events.eventEngagementCount + savedViews.count,
|
|
286
|
+
uniqueUserCount: events.uniqueUsers.size,
|
|
287
|
+
lastViewedAt: events.lastViewedAt,
|
|
288
|
+
lastSavedViewAt: savedViews.lastSavedViewAt,
|
|
289
|
+
panelCount: dashboardPanelCount(row),
|
|
290
|
+
url: dashboardUrl(row),
|
|
291
|
+
};
|
|
292
|
+
})
|
|
293
|
+
.sort((a, b) => {
|
|
294
|
+
const views = b.viewCount - a.viewCount;
|
|
295
|
+
if (views !== 0) return views;
|
|
296
|
+
return b.updatedAt.localeCompare(a.updatedAt);
|
|
297
|
+
});
|
|
298
|
+
},
|
|
299
|
+
});
|