@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
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
* - `o:<orgId>:sql-dashboard-{id}` → kind='sql', owner=caller, visibility='org'
|
|
28
28
|
* - `adhoc-analysis-{id}` → owner=caller, legacy visibility from its source key
|
|
29
29
|
*/
|
|
30
|
-
import { and, eq, isNotNull, isNull } from "drizzle-orm";
|
|
30
|
+
import { and, desc, eq, isNotNull, isNull } from "drizzle-orm";
|
|
31
31
|
|
|
32
32
|
import { getDb, schema } from "../db/index.js";
|
|
33
33
|
|
|
@@ -44,6 +44,7 @@ export interface DashboardRecord {
|
|
|
44
44
|
visibility: "private" | "org" | "public";
|
|
45
45
|
createdAt: string;
|
|
46
46
|
updatedAt: string;
|
|
47
|
+
updatedBy: string | null;
|
|
47
48
|
/** ISO timestamp set when the dashboard is archived. Null = active. */
|
|
48
49
|
archivedAt: string | null;
|
|
49
50
|
/** ISO timestamp set when the dashboard is hidden from default navigation. */
|
|
@@ -55,6 +56,16 @@ export interface DashboardRecord {
|
|
|
55
56
|
canManage?: boolean;
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
export interface DashboardRevisionRecord {
|
|
60
|
+
id: string;
|
|
61
|
+
dashboardId: string;
|
|
62
|
+
kind: DashboardKind;
|
|
63
|
+
title: string;
|
|
64
|
+
config: Record<string, unknown>;
|
|
65
|
+
createdAt: string;
|
|
66
|
+
createdBy: string | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
58
69
|
export type DashboardArchiveFilter = "active" | "archived" | "all";
|
|
59
70
|
export type DashboardHiddenFilter = "visible" | "hidden" | "all";
|
|
60
71
|
|
|
@@ -82,6 +93,20 @@ export interface AnalysisRecord {
|
|
|
82
93
|
canManage?: boolean;
|
|
83
94
|
}
|
|
84
95
|
|
|
96
|
+
export interface AnalysisRevisionRecord {
|
|
97
|
+
id: string;
|
|
98
|
+
analysisId: string;
|
|
99
|
+
name: string;
|
|
100
|
+
description: string;
|
|
101
|
+
question: string;
|
|
102
|
+
instructions: string;
|
|
103
|
+
dataSources: string[];
|
|
104
|
+
resultMarkdown: string;
|
|
105
|
+
resultData: Record<string, unknown> | null;
|
|
106
|
+
createdAt: string;
|
|
107
|
+
createdBy: string | null;
|
|
108
|
+
}
|
|
109
|
+
|
|
85
110
|
interface AccessCtx {
|
|
86
111
|
email: string;
|
|
87
112
|
orgId: string | null;
|
|
@@ -90,6 +115,8 @@ interface AccessCtx {
|
|
|
90
115
|
const SQL_PREFIX = "sql-dashboard-";
|
|
91
116
|
const EXPLORER_PREFIX = "dashboard-";
|
|
92
117
|
const ANALYSIS_PREFIX = "adhoc-analysis-";
|
|
118
|
+
const DASHBOARD_REVISION_LIMIT = 50;
|
|
119
|
+
const ANALYSIS_REVISION_LIMIT = 30;
|
|
93
120
|
|
|
94
121
|
function nowIso(): string {
|
|
95
122
|
return new Date().toISOString();
|
|
@@ -157,6 +184,7 @@ function rowToDashboard(row: any, role?: AccessRole): DashboardRecord {
|
|
|
157
184
|
visibility: row.visibility,
|
|
158
185
|
createdAt: row.createdAt,
|
|
159
186
|
updatedAt: row.updatedAt,
|
|
187
|
+
updatedBy: row.updatedBy ?? null,
|
|
160
188
|
archivedAt: row.archivedAt ?? null,
|
|
161
189
|
hiddenAt: row.hiddenAt ?? null,
|
|
162
190
|
hiddenBy: row.hiddenBy ?? null,
|
|
@@ -164,6 +192,19 @@ function rowToDashboard(row: any, role?: AccessRole): DashboardRecord {
|
|
|
164
192
|
};
|
|
165
193
|
}
|
|
166
194
|
|
|
195
|
+
function rowToDashboardRevision(row: any): DashboardRevisionRecord {
|
|
196
|
+
return {
|
|
197
|
+
id: row.id,
|
|
198
|
+
dashboardId: row.dashboardId,
|
|
199
|
+
kind: row.kind,
|
|
200
|
+
title: row.title,
|
|
201
|
+
config:
|
|
202
|
+
typeof row.config === "string" ? JSON.parse(row.config) : row.config,
|
|
203
|
+
createdAt: row.createdAt,
|
|
204
|
+
createdBy: row.createdBy ?? null,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
167
208
|
function configFromSettings(data: Record<string, unknown>): {
|
|
168
209
|
title: string;
|
|
169
210
|
config: Record<string, unknown>;
|
|
@@ -208,6 +249,7 @@ async function migrateDashboardFromSettings(
|
|
|
208
249
|
visibility,
|
|
209
250
|
createdAt,
|
|
210
251
|
updatedAt,
|
|
252
|
+
updatedBy: ownerEmail,
|
|
211
253
|
})
|
|
212
254
|
.onConflictDoNothing();
|
|
213
255
|
// guard:allow-unscoped — read-after-write of the row just inserted above
|
|
@@ -384,6 +426,42 @@ export async function listDashboards(
|
|
|
384
426
|
return out;
|
|
385
427
|
}
|
|
386
428
|
|
|
429
|
+
async function pruneDashboardRevisions(
|
|
430
|
+
db: any,
|
|
431
|
+
dashboardId: string,
|
|
432
|
+
): Promise<void> {
|
|
433
|
+
const rows = await db
|
|
434
|
+
.select({ id: schema.dashboardRevisions.id })
|
|
435
|
+
.from(schema.dashboardRevisions)
|
|
436
|
+
.where(eq(schema.dashboardRevisions.dashboardId, dashboardId))
|
|
437
|
+
.orderBy(desc(schema.dashboardRevisions.createdAt));
|
|
438
|
+
const stale = rows.slice(DASHBOARD_REVISION_LIMIT);
|
|
439
|
+
for (const row of stale) {
|
|
440
|
+
await db
|
|
441
|
+
.delete(schema.dashboardRevisions)
|
|
442
|
+
.where(eq(schema.dashboardRevisions.id, row.id));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async function snapshotDashboardRevision(
|
|
447
|
+
db: any,
|
|
448
|
+
dashboard: DashboardRecord,
|
|
449
|
+
ctx: AccessCtx,
|
|
450
|
+
): Promise<void> {
|
|
451
|
+
await db.insert(schema.dashboardRevisions).values({
|
|
452
|
+
id: `dashrev-${Date.now()}-${nanoidFallback()}`,
|
|
453
|
+
dashboardId: dashboard.id,
|
|
454
|
+
kind: dashboard.kind,
|
|
455
|
+
title: dashboard.title,
|
|
456
|
+
config: JSON.stringify(dashboard.config),
|
|
457
|
+
createdAt: nowIso(),
|
|
458
|
+
createdBy: ctx.email,
|
|
459
|
+
ownerEmail: dashboard.ownerEmail,
|
|
460
|
+
orgId: dashboard.orgId,
|
|
461
|
+
});
|
|
462
|
+
await pruneDashboardRevisions(db, dashboard.id);
|
|
463
|
+
}
|
|
464
|
+
|
|
387
465
|
/**
|
|
388
466
|
* Upsert a dashboard. On create, caller becomes owner and visibility defaults
|
|
389
467
|
* to `private`; users explicitly promote useful dashboards to org/public via
|
|
@@ -399,18 +477,25 @@ export async function upsertDashboard(
|
|
|
399
477
|
const existing = await getDashboard(id, ctx);
|
|
400
478
|
const db = getDb() as any;
|
|
401
479
|
const { title, config } = configFromSettings(body);
|
|
480
|
+
const configJson = JSON.stringify(config);
|
|
402
481
|
if (existing) {
|
|
403
482
|
await assertAccess("dashboard", id, "editor", {
|
|
404
483
|
userEmail: ctx.email,
|
|
405
484
|
orgId: ctx.orgId ?? undefined,
|
|
406
485
|
});
|
|
486
|
+
const changed =
|
|
487
|
+
existing.kind !== kind ||
|
|
488
|
+
existing.title !== title ||
|
|
489
|
+
JSON.stringify(existing.config) !== configJson;
|
|
490
|
+
if (changed) await snapshotDashboardRevision(db, existing, ctx);
|
|
407
491
|
await db
|
|
408
492
|
.update(schema.dashboards)
|
|
409
493
|
.set({
|
|
410
494
|
kind,
|
|
411
495
|
title,
|
|
412
|
-
config:
|
|
496
|
+
config: configJson,
|
|
413
497
|
updatedAt: nowIso(),
|
|
498
|
+
updatedBy: ctx.email,
|
|
414
499
|
})
|
|
415
500
|
.where(eq(schema.dashboards.id, id));
|
|
416
501
|
} else {
|
|
@@ -422,6 +507,7 @@ export async function upsertDashboard(
|
|
|
422
507
|
ownerEmail: ctx.email,
|
|
423
508
|
orgId: ctx.orgId,
|
|
424
509
|
visibility: "private",
|
|
510
|
+
updatedBy: ctx.email,
|
|
425
511
|
});
|
|
426
512
|
}
|
|
427
513
|
const [row] = await db
|
|
@@ -442,6 +528,77 @@ export async function upsertDashboard(
|
|
|
442
528
|
return dashboard;
|
|
443
529
|
}
|
|
444
530
|
|
|
531
|
+
export async function listDashboardRevisions(
|
|
532
|
+
dashboardId: string,
|
|
533
|
+
ctx: AccessCtx,
|
|
534
|
+
): Promise<DashboardRevisionRecord[]> {
|
|
535
|
+
const existing = await getDashboard(dashboardId, ctx);
|
|
536
|
+
if (!existing) return [];
|
|
537
|
+
await assertAccess("dashboard", dashboardId, "viewer", {
|
|
538
|
+
userEmail: ctx.email,
|
|
539
|
+
orgId: ctx.orgId ?? undefined,
|
|
540
|
+
});
|
|
541
|
+
const db = getDb() as any;
|
|
542
|
+
const rows = await db
|
|
543
|
+
.select()
|
|
544
|
+
.from(schema.dashboardRevisions)
|
|
545
|
+
.where(eq(schema.dashboardRevisions.dashboardId, dashboardId))
|
|
546
|
+
.orderBy(desc(schema.dashboardRevisions.createdAt))
|
|
547
|
+
.limit(DASHBOARD_REVISION_LIMIT);
|
|
548
|
+
return rows.map(rowToDashboardRevision);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export async function restoreDashboardRevision(
|
|
552
|
+
dashboardId: string,
|
|
553
|
+
revisionId: string,
|
|
554
|
+
ctx: AccessCtx,
|
|
555
|
+
): Promise<DashboardRecord | null> {
|
|
556
|
+
const existing = await getDashboard(dashboardId, ctx);
|
|
557
|
+
if (!existing) return null;
|
|
558
|
+
await assertAccess("dashboard", dashboardId, "editor", {
|
|
559
|
+
userEmail: ctx.email,
|
|
560
|
+
orgId: ctx.orgId ?? undefined,
|
|
561
|
+
});
|
|
562
|
+
const db = getDb() as any;
|
|
563
|
+
const [revisionRow] = await db
|
|
564
|
+
.select()
|
|
565
|
+
.from(schema.dashboardRevisions)
|
|
566
|
+
.where(
|
|
567
|
+
and(
|
|
568
|
+
eq(schema.dashboardRevisions.id, revisionId),
|
|
569
|
+
eq(schema.dashboardRevisions.dashboardId, dashboardId),
|
|
570
|
+
),
|
|
571
|
+
)
|
|
572
|
+
.limit(1);
|
|
573
|
+
if (!revisionRow) return null;
|
|
574
|
+
const revision = rowToDashboardRevision(revisionRow);
|
|
575
|
+
await snapshotDashboardRevision(db, existing, ctx);
|
|
576
|
+
await db
|
|
577
|
+
.update(schema.dashboards)
|
|
578
|
+
.set({
|
|
579
|
+
kind: revision.kind,
|
|
580
|
+
title: revision.title,
|
|
581
|
+
config: JSON.stringify(revision.config),
|
|
582
|
+
updatedAt: nowIso(),
|
|
583
|
+
updatedBy: ctx.email,
|
|
584
|
+
})
|
|
585
|
+
.where(eq(schema.dashboards.id, dashboardId));
|
|
586
|
+
const [row] = await db
|
|
587
|
+
.select()
|
|
588
|
+
.from(schema.dashboards)
|
|
589
|
+
.where(eq(schema.dashboards.id, dashboardId));
|
|
590
|
+
const dashboard = rowToDashboard(row);
|
|
591
|
+
recordScopedChange(
|
|
592
|
+
"dashboards",
|
|
593
|
+
"change",
|
|
594
|
+
dashboard.id,
|
|
595
|
+
dashboard.ownerEmail,
|
|
596
|
+
dashboard.orgId,
|
|
597
|
+
dashboard.visibility,
|
|
598
|
+
);
|
|
599
|
+
return dashboard;
|
|
600
|
+
}
|
|
601
|
+
|
|
445
602
|
/**
|
|
446
603
|
* Archive a dashboard (soft-delete). Requires editor. The row stays in the
|
|
447
604
|
* dashboards table with `archived_at` set, so it disappears from the default
|
|
@@ -462,7 +619,7 @@ export async function archiveDashboard(
|
|
|
462
619
|
const now = nowIso();
|
|
463
620
|
await db
|
|
464
621
|
.update(schema.dashboards)
|
|
465
|
-
.set({ archivedAt: now, updatedAt: now })
|
|
622
|
+
.set({ archivedAt: now, updatedAt: now, updatedBy: ctx.email })
|
|
466
623
|
.where(eq(schema.dashboards.id, id));
|
|
467
624
|
const [row] = await db
|
|
468
625
|
.select()
|
|
@@ -495,7 +652,7 @@ export async function unarchiveDashboard(
|
|
|
495
652
|
const db = getDb() as any;
|
|
496
653
|
await db
|
|
497
654
|
.update(schema.dashboards)
|
|
498
|
-
.set({ archivedAt: null, updatedAt: nowIso() })
|
|
655
|
+
.set({ archivedAt: null, updatedAt: nowIso(), updatedBy: ctx.email })
|
|
499
656
|
.where(eq(schema.dashboards.id, id));
|
|
500
657
|
const [row] = await db
|
|
501
658
|
.select()
|
|
@@ -533,7 +690,12 @@ export async function hideDashboard(
|
|
|
533
690
|
const now = nowIso();
|
|
534
691
|
await db
|
|
535
692
|
.update(schema.dashboards)
|
|
536
|
-
.set({
|
|
693
|
+
.set({
|
|
694
|
+
hiddenAt: now,
|
|
695
|
+
hiddenBy: ctx.email,
|
|
696
|
+
updatedAt: now,
|
|
697
|
+
updatedBy: ctx.email,
|
|
698
|
+
})
|
|
537
699
|
.where(eq(schema.dashboards.id, id));
|
|
538
700
|
const [row] = await db
|
|
539
701
|
.select()
|
|
@@ -572,6 +734,7 @@ export async function unhideDashboard(
|
|
|
572
734
|
hiddenAt: null,
|
|
573
735
|
hiddenBy: null,
|
|
574
736
|
updatedAt: now,
|
|
737
|
+
updatedBy: ctx.email,
|
|
575
738
|
};
|
|
576
739
|
if (!existing.ownerEmail) {
|
|
577
740
|
patch.ownerEmail = ctx.email;
|
|
@@ -609,6 +772,9 @@ export async function removeDashboard(
|
|
|
609
772
|
});
|
|
610
773
|
const db = getDb() as any;
|
|
611
774
|
await db.delete(schema.dashboards).where(eq(schema.dashboards.id, id));
|
|
775
|
+
await db
|
|
776
|
+
.delete(schema.dashboardRevisions)
|
|
777
|
+
.where(eq(schema.dashboardRevisions.dashboardId, id));
|
|
612
778
|
await db
|
|
613
779
|
.delete(schema.dashboardShares)
|
|
614
780
|
.where(eq(schema.dashboardShares.resourceId, id));
|
|
@@ -658,6 +824,22 @@ function rowToAnalysis(row: any, role?: AccessRole): AnalysisRecord {
|
|
|
658
824
|
};
|
|
659
825
|
}
|
|
660
826
|
|
|
827
|
+
function rowToAnalysisRevision(row: any): AnalysisRevisionRecord {
|
|
828
|
+
return {
|
|
829
|
+
id: row.id,
|
|
830
|
+
analysisId: row.analysisId,
|
|
831
|
+
name: row.name,
|
|
832
|
+
description: row.description,
|
|
833
|
+
question: row.question,
|
|
834
|
+
instructions: row.instructions,
|
|
835
|
+
dataSources: safeJsonParse(row.dataSources, []),
|
|
836
|
+
resultMarkdown: row.resultMarkdown,
|
|
837
|
+
resultData: row.resultData ? safeJsonParse(row.resultData, null) : null,
|
|
838
|
+
createdAt: row.createdAt,
|
|
839
|
+
createdBy: row.createdBy ?? null,
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
|
|
661
843
|
function safeJsonParse<T>(s: unknown, fallback: T): T {
|
|
662
844
|
if (typeof s !== "string") return fallback;
|
|
663
845
|
try {
|
|
@@ -880,6 +1062,48 @@ export async function listAnalyses(
|
|
|
880
1062
|
return out;
|
|
881
1063
|
}
|
|
882
1064
|
|
|
1065
|
+
async function pruneAnalysisRevisions(
|
|
1066
|
+
db: any,
|
|
1067
|
+
analysisId: string,
|
|
1068
|
+
): Promise<void> {
|
|
1069
|
+
const rows = await db
|
|
1070
|
+
.select({ id: schema.analysisRevisions.id })
|
|
1071
|
+
.from(schema.analysisRevisions)
|
|
1072
|
+
.where(eq(schema.analysisRevisions.analysisId, analysisId))
|
|
1073
|
+
.orderBy(desc(schema.analysisRevisions.createdAt));
|
|
1074
|
+
const stale = rows.slice(ANALYSIS_REVISION_LIMIT);
|
|
1075
|
+
for (const row of stale) {
|
|
1076
|
+
await db
|
|
1077
|
+
.delete(schema.analysisRevisions)
|
|
1078
|
+
.where(eq(schema.analysisRevisions.id, row.id));
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
async function snapshotAnalysisRevision(
|
|
1083
|
+
db: any,
|
|
1084
|
+
analysis: AnalysisRecord,
|
|
1085
|
+
ctx: AccessCtx,
|
|
1086
|
+
): Promise<void> {
|
|
1087
|
+
await db.insert(schema.analysisRevisions).values({
|
|
1088
|
+
id: `analysisrev-${Date.now()}-${nanoidFallback()}`,
|
|
1089
|
+
analysisId: analysis.id,
|
|
1090
|
+
name: analysis.name,
|
|
1091
|
+
description: analysis.description,
|
|
1092
|
+
question: analysis.question,
|
|
1093
|
+
instructions: analysis.instructions,
|
|
1094
|
+
dataSources: JSON.stringify(analysis.dataSources),
|
|
1095
|
+
resultMarkdown: analysis.resultMarkdown,
|
|
1096
|
+
resultData: analysis.resultData
|
|
1097
|
+
? JSON.stringify(analysis.resultData)
|
|
1098
|
+
: null,
|
|
1099
|
+
createdAt: nowIso(),
|
|
1100
|
+
createdBy: ctx.email,
|
|
1101
|
+
ownerEmail: analysis.ownerEmail,
|
|
1102
|
+
orgId: analysis.orgId,
|
|
1103
|
+
});
|
|
1104
|
+
await pruneAnalysisRevisions(db, analysis.id);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
883
1107
|
export async function upsertAnalysis(
|
|
884
1108
|
id: string,
|
|
885
1109
|
body: {
|
|
@@ -913,6 +1137,32 @@ export async function upsertAnalysis(
|
|
|
913
1137
|
patch.resultData = body.resultData
|
|
914
1138
|
? JSON.stringify(body.resultData)
|
|
915
1139
|
: null;
|
|
1140
|
+
const next = {
|
|
1141
|
+
name: (patch.name as string | undefined) ?? existing.name,
|
|
1142
|
+
description:
|
|
1143
|
+
(patch.description as string | undefined) ?? existing.description,
|
|
1144
|
+
question: (patch.question as string | undefined) ?? existing.question,
|
|
1145
|
+
instructions:
|
|
1146
|
+
(patch.instructions as string | undefined) ?? existing.instructions,
|
|
1147
|
+
dataSources:
|
|
1148
|
+
body.dataSources !== undefined
|
|
1149
|
+
? body.dataSources
|
|
1150
|
+
: existing.dataSources,
|
|
1151
|
+
resultMarkdown:
|
|
1152
|
+
(patch.resultMarkdown as string | undefined) ?? existing.resultMarkdown,
|
|
1153
|
+
resultData:
|
|
1154
|
+
body.resultData !== undefined ? body.resultData : existing.resultData,
|
|
1155
|
+
};
|
|
1156
|
+
const changed =
|
|
1157
|
+
next.name !== existing.name ||
|
|
1158
|
+
next.description !== existing.description ||
|
|
1159
|
+
next.question !== existing.question ||
|
|
1160
|
+
next.instructions !== existing.instructions ||
|
|
1161
|
+
JSON.stringify(next.dataSources) !==
|
|
1162
|
+
JSON.stringify(existing.dataSources) ||
|
|
1163
|
+
next.resultMarkdown !== existing.resultMarkdown ||
|
|
1164
|
+
JSON.stringify(next.resultData) !== JSON.stringify(existing.resultData);
|
|
1165
|
+
if (changed) await snapshotAnalysisRevision(db, existing, ctx);
|
|
916
1166
|
await db
|
|
917
1167
|
.update(schema.analyses)
|
|
918
1168
|
.set(patch)
|
|
@@ -944,6 +1194,82 @@ export async function upsertAnalysis(
|
|
|
944
1194
|
return rowToAnalysis(row);
|
|
945
1195
|
}
|
|
946
1196
|
|
|
1197
|
+
export async function listAnalysisRevisions(
|
|
1198
|
+
analysisId: string,
|
|
1199
|
+
ctx: AccessCtx,
|
|
1200
|
+
): Promise<AnalysisRevisionRecord[]> {
|
|
1201
|
+
const existing = await getAnalysis(analysisId, ctx);
|
|
1202
|
+
if (!existing) return [];
|
|
1203
|
+
await assertAccess("analysis", analysisId, "viewer", {
|
|
1204
|
+
userEmail: ctx.email,
|
|
1205
|
+
orgId: ctx.orgId ?? undefined,
|
|
1206
|
+
});
|
|
1207
|
+
const db = getDb() as any;
|
|
1208
|
+
const rows = await db
|
|
1209
|
+
.select()
|
|
1210
|
+
.from(schema.analysisRevisions)
|
|
1211
|
+
.where(eq(schema.analysisRevisions.analysisId, analysisId))
|
|
1212
|
+
.orderBy(desc(schema.analysisRevisions.createdAt))
|
|
1213
|
+
.limit(ANALYSIS_REVISION_LIMIT);
|
|
1214
|
+
return rows.map(rowToAnalysisRevision);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
export async function restoreAnalysisRevision(
|
|
1218
|
+
analysisId: string,
|
|
1219
|
+
revisionId: string,
|
|
1220
|
+
ctx: AccessCtx,
|
|
1221
|
+
): Promise<AnalysisRecord | null> {
|
|
1222
|
+
const existing = await getAnalysis(analysisId, ctx);
|
|
1223
|
+
if (!existing) return null;
|
|
1224
|
+
await assertAccess("analysis", analysisId, "editor", {
|
|
1225
|
+
userEmail: ctx.email,
|
|
1226
|
+
orgId: ctx.orgId ?? undefined,
|
|
1227
|
+
});
|
|
1228
|
+
const db = getDb() as any;
|
|
1229
|
+
const [revisionRow] = await db
|
|
1230
|
+
.select()
|
|
1231
|
+
.from(schema.analysisRevisions)
|
|
1232
|
+
.where(
|
|
1233
|
+
and(
|
|
1234
|
+
eq(schema.analysisRevisions.id, revisionId),
|
|
1235
|
+
eq(schema.analysisRevisions.analysisId, analysisId),
|
|
1236
|
+
),
|
|
1237
|
+
)
|
|
1238
|
+
.limit(1);
|
|
1239
|
+
if (!revisionRow) return null;
|
|
1240
|
+
const revision = rowToAnalysisRevision(revisionRow);
|
|
1241
|
+
await snapshotAnalysisRevision(db, existing, ctx);
|
|
1242
|
+
await db
|
|
1243
|
+
.update(schema.analyses)
|
|
1244
|
+
.set({
|
|
1245
|
+
name: revision.name,
|
|
1246
|
+
description: revision.description,
|
|
1247
|
+
question: revision.question,
|
|
1248
|
+
instructions: revision.instructions,
|
|
1249
|
+
dataSources: JSON.stringify(revision.dataSources),
|
|
1250
|
+
resultMarkdown: revision.resultMarkdown,
|
|
1251
|
+
resultData: revision.resultData
|
|
1252
|
+
? JSON.stringify(revision.resultData)
|
|
1253
|
+
: null,
|
|
1254
|
+
updatedAt: nowIso(),
|
|
1255
|
+
})
|
|
1256
|
+
.where(eq(schema.analyses.id, analysisId));
|
|
1257
|
+
const [row] = await db
|
|
1258
|
+
.select()
|
|
1259
|
+
.from(schema.analyses)
|
|
1260
|
+
.where(eq(schema.analyses.id, analysisId));
|
|
1261
|
+
const analysis = rowToAnalysis(row);
|
|
1262
|
+
recordScopedChange(
|
|
1263
|
+
"analyses",
|
|
1264
|
+
"change",
|
|
1265
|
+
analysis.id,
|
|
1266
|
+
analysis.ownerEmail,
|
|
1267
|
+
analysis.orgId,
|
|
1268
|
+
analysis.visibility,
|
|
1269
|
+
);
|
|
1270
|
+
return analysis;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
947
1273
|
export async function removeAnalysis(
|
|
948
1274
|
id: string,
|
|
949
1275
|
ctx: AccessCtx,
|
|
@@ -956,6 +1282,9 @@ export async function removeAnalysis(
|
|
|
956
1282
|
});
|
|
957
1283
|
const db = getDb() as any;
|
|
958
1284
|
await db.delete(schema.analyses).where(eq(schema.analyses.id, id));
|
|
1285
|
+
await db
|
|
1286
|
+
.delete(schema.analysisRevisions)
|
|
1287
|
+
.where(eq(schema.analysisRevisions.analysisId, id));
|
|
959
1288
|
await db
|
|
960
1289
|
.delete(schema.analysisShares)
|
|
961
1290
|
.where(eq(schema.analysisShares.resourceId, id));
|