@agent-native/core 0.92.0 → 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 +1 -1
- package/corpus/core/CHANGELOG.md +14 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/application-state/store.ts +12 -1
- package/corpus/core/src/client/AssistantChat.tsx +27 -14
- package/corpus/core/src/client/PoweredByBadge.tsx +1 -8
- package/corpus/core/src/client/agent-chat-adapter.ts +37 -10
- package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +52 -1
- 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/settings/SettingsPanel.tsx +205 -52
- package/corpus/core/src/client/settings/SettingsSection.tsx +8 -1
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +25 -9
- 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/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/resources/handlers.ts +10 -8
- package/corpus/core/src/server/poll.ts +293 -8
- 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/storing-data/SKILL.md +5 -1
- package/corpus/core/src/templates/default/AGENTS.md +4 -2
- package/corpus/core/src/templates/headless/AGENTS.md +4 -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/storing-data/SKILL.md +5 -1
- package/corpus/core/src/templates/workspace-core/AGENTS.md +7 -1
- package/corpus/core/src/templates/workspace-root/AGENTS.md +7 -1
- 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/storing-data/SKILL.md +5 -1
- package/corpus/templates/analytics/AGENTS.md +33 -14
- 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 +1 -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/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/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 +6 -3
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +26 -30
- 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-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-production-session-replay-now-requires-private-blob-storage-.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-team-settings-show-access-controls-next-to-member-lists.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/server/db/schema-monitoring.ts +1 -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 +5 -4
- package/corpus/templates/analytics/server/plugins/db.ts +112 -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/storing-data/SKILL.md +5 -1
- 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.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/storing-data/SKILL.md +5 -1
- 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.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.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-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-recaps-now-keep-summaries-action-items-and-transcrip.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/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/storing-data/SKILL.md +5 -1
- package/corpus/templates/content/AGENTS.md +4 -0
- 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/design/.agents/skills/actions/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/security/SKILL.md +7 -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.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/storing-data/SKILL.md +5 -1
- 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.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/storing-data/SKILL.md +5 -1
- 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.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.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/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/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +24 -13
- package/dist/client/AssistantChat.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 +28 -9
- package/dist/client/agent-chat-adapter.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/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/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +37 -14
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.js +1 -1
- 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/collab/routes.d.ts +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/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/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +6 -1
- 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/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/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/storing-data/SKILL.md +5 -1
- package/dist/templates/default/AGENTS.md +4 -2
- package/dist/templates/headless/AGENTS.md +4 -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/storing-data/SKILL.md +5 -1
- package/dist/templates/workspace-core/AGENTS.md +7 -1
- package/dist/templates/workspace-root/AGENTS.md +7 -1
- package/package.json +1 -1
- 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/storing-data/SKILL.md +5 -1
- package/src/templates/default/AGENTS.md +4 -2
- package/src/templates/headless/AGENTS.md +4 -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/storing-data/SKILL.md +5 -1
- package/src/templates/workspace-core/AGENTS.md +7 -1
- package/src/templates/workspace-root/AGENTS.md +7 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.92.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1d13434: Allow extension iframes to trigger user-initiated downloads and add CSV export to standard data table widgets.
|
|
8
|
+
- 1d13434: Remove the GitHub icon from the free and open source badge on public booking pages.
|
|
9
|
+
- 1d13434: Make framework polling cheaper with durable sync events, remove Dispatch's short app-list polling intervals, preview large DB admin cells by default to avoid accidental blob transfers, and require configured file storage for binary resource uploads instead of storing base64 blobs in SQL.
|
|
10
|
+
- 1d13434: Stage database-admin table selections as agent chat context chips and selected-object application state so users can ask the agent about the active table.
|
|
11
|
+
- 1d13434: Show a clear unavailable state for shared extension links that the viewer cannot access, instead of leaving the standalone extension page looking blank.
|
|
12
|
+
- 1d13434: Filter known browser and extension noise from first-party error auto-capture while preserving real app fetch failures.
|
|
13
|
+
- 1d13434: Recover stale background chat runs instead of surfacing them as terminal failures, and keep chat handoffs from restoring stale server snapshots over fresher completed replies.
|
|
14
|
+
- 1d13434: Fix durable polling cursors, DB admin large-cell safeguards, extension unavailable states, and stale chat snapshot handling.
|
|
15
|
+
- 1d13434: Show organization access controls alongside long team member lists when the Team settings surface has enough width.
|
|
16
|
+
|
|
3
17
|
## 0.92.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.92.
|
|
3
|
+
"version": "0.92.1",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getDbExec,
|
|
3
|
+
isLocalDatabase,
|
|
3
4
|
isConnectionError,
|
|
4
5
|
isPostgres,
|
|
5
6
|
intType,
|
|
@@ -10,6 +11,7 @@ import type { StoreWriteOptions } from "../settings/store.js";
|
|
|
10
11
|
import { emitAppStateChange, emitAppStateDelete } from "./emitter.js";
|
|
11
12
|
|
|
12
13
|
let _initPromise: Promise<void> | undefined;
|
|
14
|
+
const MAX_HOSTED_APP_STATE_VALUE_BYTES = 1024 * 1024;
|
|
13
15
|
|
|
14
16
|
// Escapes LIKE wildcards (`%`, `_`) and the escape char itself so a caller's
|
|
15
17
|
// literal prefix is matched verbatim. Used with `ESCAPE '!'` in prefix queries
|
|
@@ -123,11 +125,20 @@ export async function appStatePut(
|
|
|
123
125
|
): Promise<void> {
|
|
124
126
|
await ensureTable();
|
|
125
127
|
const client = getDbExec();
|
|
128
|
+
const serialized = JSON.stringify(value);
|
|
129
|
+
if (
|
|
130
|
+
!isLocalDatabase() &&
|
|
131
|
+
Buffer.byteLength(serialized, "utf8") > MAX_HOSTED_APP_STATE_VALUE_BYTES
|
|
132
|
+
) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`application_state value "${key}" is too large for hosted SQL storage. Store large files, base64, or blobs in file storage and write only a URL or handle.`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
126
137
|
await client.execute({
|
|
127
138
|
sql: isPostgres()
|
|
128
139
|
? `INSERT INTO application_state (session_id, key, value, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT (session_id, key) DO UPDATE SET value=EXCLUDED.value, updated_at=EXCLUDED.updated_at`
|
|
129
140
|
: `INSERT OR REPLACE INTO application_state (session_id, key, value, updated_at) VALUES (?, ?, ?, ?)`,
|
|
130
|
-
args: [sessionId, key,
|
|
141
|
+
args: [sessionId, key, serialized, Date.now()],
|
|
131
142
|
});
|
|
132
143
|
emitAppStateChange(key, options?.requestSource, sessionId);
|
|
133
144
|
}
|
|
@@ -1894,7 +1894,9 @@ const AssistantChatInner = forwardRef<
|
|
|
1894
1894
|
repo,
|
|
1895
1895
|
);
|
|
1896
1896
|
} catch {
|
|
1897
|
-
|
|
1897
|
+
// If the runtime/export comparison itself fails, do not fail open by
|
|
1898
|
+
// importing a server snapshot that may be stale relative to local UI.
|
|
1899
|
+
shouldImport = false;
|
|
1898
1900
|
}
|
|
1899
1901
|
if (shouldImport) {
|
|
1900
1902
|
if (options?.markTitleGenerated) {
|
|
@@ -1907,7 +1909,7 @@ const AssistantChatInner = forwardRef<
|
|
|
1907
1909
|
settled = false;
|
|
1908
1910
|
}
|
|
1909
1911
|
}
|
|
1910
|
-
if (Array.isArray(repo?.queuedMessages)) {
|
|
1912
|
+
if (settled && Array.isArray(repo?.queuedMessages)) {
|
|
1911
1913
|
const incomingQueue = repo.queuedMessages as QueuedMessage[];
|
|
1912
1914
|
const incomingSerialized = JSON.stringify(incomingQueue);
|
|
1913
1915
|
const currentSerialized = JSON.stringify(queuedMessagesRef.current);
|
|
@@ -2521,18 +2523,29 @@ const AssistantChatInner = forwardRef<
|
|
|
2521
2523
|
markTitleGenerated: true,
|
|
2522
2524
|
});
|
|
2523
2525
|
if (repo) {
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2526
|
+
let shouldCacheServerSnapshot = true;
|
|
2527
|
+
try {
|
|
2528
|
+
shouldCacheServerSnapshot = shouldImportServerThreadData(
|
|
2529
|
+
normalizeThreadRepository(threadRuntime.export()),
|
|
2530
|
+
repo,
|
|
2531
|
+
);
|
|
2532
|
+
} catch {
|
|
2533
|
+
shouldCacheServerSnapshot = false;
|
|
2534
|
+
}
|
|
2535
|
+
if (shouldCacheServerSnapshot) {
|
|
2536
|
+
const { title, preview } = extractThreadMeta(repo);
|
|
2537
|
+
writeCachedThreadSnapshot(apiUrl, threadId, {
|
|
2538
|
+
threadData:
|
|
2539
|
+
typeof data.threadData === "string"
|
|
2540
|
+
? data.threadData
|
|
2541
|
+
: JSON.stringify(data.threadData),
|
|
2542
|
+
title: data.title || title,
|
|
2543
|
+
preview,
|
|
2544
|
+
messageCount: Array.isArray(repo.messages)
|
|
2545
|
+
? repo.messages.length
|
|
2546
|
+
: 0,
|
|
2547
|
+
});
|
|
2548
|
+
}
|
|
2536
2549
|
}
|
|
2537
2550
|
}
|
|
2538
2551
|
// Also skip title generation if thread already has a title
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { IconBrandGithub } from "@tabler/icons-react";
|
|
2
1
|
import type { CSSProperties } from "react";
|
|
3
2
|
|
|
4
3
|
import { appPath } from "./api-path.js";
|
|
@@ -192,7 +191,7 @@ export function PoweredByBadge({
|
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
/**
|
|
195
|
-
* Small
|
|
194
|
+
* Small badge: "Free and open source"
|
|
196
195
|
*
|
|
197
196
|
* Intended to pair with PoweredByBadge on public pages.
|
|
198
197
|
*/
|
|
@@ -209,11 +208,6 @@ export function OpenSourceBadge({
|
|
|
209
208
|
return (
|
|
210
209
|
<>
|
|
211
210
|
<style>{`
|
|
212
|
-
.an-open-source-badge svg {
|
|
213
|
-
width: 15px;
|
|
214
|
-
height: 15px;
|
|
215
|
-
flex: none;
|
|
216
|
-
}
|
|
217
211
|
.an-open-source-badge {
|
|
218
212
|
background: transparent !important;
|
|
219
213
|
border-color: transparent !important;
|
|
@@ -283,7 +277,6 @@ export function OpenSourceBadge({
|
|
|
283
277
|
: containerStyle(position)
|
|
284
278
|
}
|
|
285
279
|
>
|
|
286
|
-
<IconBrandGithub aria-hidden="true" stroke={1.8} />
|
|
287
280
|
<span>Free and open source</span>
|
|
288
281
|
</a>
|
|
289
282
|
</>
|
|
@@ -2276,7 +2276,11 @@ export function createAgentChatAdapter(
|
|
|
2276
2276
|
// ends the turn from the client side.
|
|
2277
2277
|
const followBackgroundTurn = async function* (
|
|
2278
2278
|
initialSignal: AgentAutoContinueSignal,
|
|
2279
|
-
): AsyncGenerator<
|
|
2279
|
+
): AsyncGenerator<
|
|
2280
|
+
ChatModelRunResult,
|
|
2281
|
+
"completed" | "client_continue",
|
|
2282
|
+
unknown
|
|
2283
|
+
> {
|
|
2280
2284
|
lastAutoContinueReason = initialSignal.reason;
|
|
2281
2285
|
if (initialSignal.activityTrail.length > 0) {
|
|
2282
2286
|
lastActivityTrail = [...initialSignal.activityTrail];
|
|
@@ -2310,7 +2314,7 @@ export function createAgentChatAdapter(
|
|
|
2310
2314
|
while (true) {
|
|
2311
2315
|
if (abortSignal.aborted) {
|
|
2312
2316
|
clearActiveRun();
|
|
2313
|
-
return;
|
|
2317
|
+
return "completed";
|
|
2314
2318
|
}
|
|
2315
2319
|
let active: Record<string, unknown> | null = null;
|
|
2316
2320
|
try {
|
|
@@ -2324,7 +2328,7 @@ export function createAgentChatAdapter(
|
|
|
2324
2328
|
} catch (pollErr: unknown) {
|
|
2325
2329
|
if (pollErr instanceof Error && pollErr.name === "AbortError") {
|
|
2326
2330
|
clearActiveRun();
|
|
2327
|
-
return;
|
|
2331
|
+
return "completed";
|
|
2328
2332
|
}
|
|
2329
2333
|
// Transient poll failure — counts as "no active run" this tick.
|
|
2330
2334
|
}
|
|
@@ -2351,8 +2355,25 @@ export function createAgentChatAdapter(
|
|
|
2351
2355
|
const isTerminal =
|
|
2352
2356
|
activeStatus === "completed" || activeStatus === "errored";
|
|
2353
2357
|
if (isTerminal && replayedTerminalRunIds.has(activeRunId)) {
|
|
2358
|
+
if (
|
|
2359
|
+
lastAutoContinueReason === "stale_run" &&
|
|
2360
|
+
lastRecoverableRunError?.errorCode === "stale_run"
|
|
2361
|
+
) {
|
|
2362
|
+
const continuation = prepareAutoContinuation(
|
|
2363
|
+
new AgentAutoContinueSignal({
|
|
2364
|
+
reason: "stale_run",
|
|
2365
|
+
errorInfo: lastRecoverableRunError,
|
|
2366
|
+
activityTrail: lastActivityTrail,
|
|
2367
|
+
}),
|
|
2368
|
+
);
|
|
2369
|
+
if (continuation.ok) {
|
|
2370
|
+
dispatchResumingUiEvent();
|
|
2371
|
+
await delay(250, abortSignal);
|
|
2372
|
+
return "client_continue";
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2354
2375
|
yield* emitBackgroundTerminalOutcome(active);
|
|
2355
|
-
return;
|
|
2376
|
+
return "completed";
|
|
2356
2377
|
}
|
|
2357
2378
|
const previousRunId = runId;
|
|
2358
2379
|
runId = activeRunId;
|
|
@@ -2365,7 +2386,7 @@ export function createAgentChatAdapter(
|
|
|
2365
2386
|
}
|
|
2366
2387
|
const attach = yield* followAttachOnce();
|
|
2367
2388
|
if (attach === "completed" || attach === "aborted") {
|
|
2368
|
-
return;
|
|
2389
|
+
return "completed";
|
|
2369
2390
|
}
|
|
2370
2391
|
if (isTerminal) {
|
|
2371
2392
|
replayedTerminalRunIds.add(activeRunId);
|
|
@@ -2387,7 +2408,7 @@ export function createAgentChatAdapter(
|
|
|
2387
2408
|
BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS
|
|
2388
2409
|
) {
|
|
2389
2410
|
yield* emitBackgroundTerminalOutcome(lastSeenActive);
|
|
2390
|
-
return;
|
|
2411
|
+
return "completed";
|
|
2391
2412
|
}
|
|
2392
2413
|
}
|
|
2393
2414
|
dispatchResumingUiEvent();
|
|
@@ -2407,13 +2428,13 @@ export function createAgentChatAdapter(
|
|
|
2407
2428
|
},
|
|
2408
2429
|
);
|
|
2409
2430
|
yield* emitBackgroundTerminalOutcome(lastSeenActive);
|
|
2410
|
-
return;
|
|
2431
|
+
return "completed";
|
|
2411
2432
|
}
|
|
2412
2433
|
}
|
|
2413
2434
|
await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
|
|
2414
2435
|
if (abortSignal.aborted) {
|
|
2415
2436
|
clearActiveRun();
|
|
2416
|
-
return;
|
|
2437
|
+
return "completed";
|
|
2417
2438
|
}
|
|
2418
2439
|
}
|
|
2419
2440
|
};
|
|
@@ -3003,7 +3024,10 @@ export function createAgentChatAdapter(
|
|
|
3003
3024
|
// client/server recovery race: client watchdog signals here are
|
|
3004
3025
|
// just "reattach", not "recover".
|
|
3005
3026
|
if (shouldFollowServerContinuation(err) && threadId) {
|
|
3006
|
-
yield* followBackgroundTurn(err);
|
|
3027
|
+
const followOutcome = yield* followBackgroundTurn(err);
|
|
3028
|
+
if (followOutcome === "client_continue") {
|
|
3029
|
+
continue;
|
|
3030
|
+
}
|
|
3007
3031
|
return;
|
|
3008
3032
|
}
|
|
3009
3033
|
if (err.reason === "no_progress") {
|
|
@@ -3182,9 +3206,12 @@ export function createAgentChatAdapter(
|
|
|
3182
3206
|
// before any response headers arrived has no dispatch mode yet
|
|
3183
3207
|
// and keeps the foreground startup-retry path.)
|
|
3184
3208
|
if (shouldFollowServerContinuation() && threadId) {
|
|
3185
|
-
yield* followBackgroundTurn(
|
|
3209
|
+
const followOutcome = yield* followBackgroundTurn(
|
|
3186
3210
|
new AgentAutoContinueSignal({ reason: "stream_ended" }),
|
|
3187
3211
|
);
|
|
3212
|
+
if (followOutcome === "client_continue") {
|
|
3213
|
+
continue;
|
|
3214
|
+
}
|
|
3188
3215
|
return;
|
|
3189
3216
|
}
|
|
3190
3217
|
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IconDots,
|
|
3
|
+
IconDownload,
|
|
4
|
+
IconExternalLink,
|
|
5
|
+
IconTable,
|
|
6
|
+
} from "@tabler/icons-react";
|
|
2
7
|
|
|
3
8
|
import { requestAgentSidebarOpen } from "../../agent-sidebar-state.js";
|
|
4
9
|
import { appPath } from "../../api-path.js";
|
|
5
10
|
import { startAgentChatViewTransition } from "../../chat-view-transition.js";
|
|
11
|
+
import {
|
|
12
|
+
DropdownMenu,
|
|
13
|
+
DropdownMenuContent,
|
|
14
|
+
DropdownMenuItem,
|
|
15
|
+
DropdownMenuTrigger,
|
|
16
|
+
} from "../../components/ui/dropdown-menu.js";
|
|
17
|
+
import { downloadFile, toCSVTable } from "../../db-admin/export-utils.js";
|
|
6
18
|
import { cn } from "../../utils.js";
|
|
7
19
|
import type { DataTableWidget as DataTableWidgetData } from "./data-widget-types.js";
|
|
8
20
|
|
|
@@ -82,6 +94,15 @@ function navigateSameAppHref(href: string): void {
|
|
|
82
94
|
});
|
|
83
95
|
}
|
|
84
96
|
|
|
97
|
+
function slugifyFilenamePart(value: string | undefined): string {
|
|
98
|
+
const slug = (value ?? "data-table")
|
|
99
|
+
.trim()
|
|
100
|
+
.toLowerCase()
|
|
101
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
102
|
+
.replace(/^-+|-+$/g, "");
|
|
103
|
+
return slug || "data-table";
|
|
104
|
+
}
|
|
105
|
+
|
|
85
106
|
export function DataTableWidget({
|
|
86
107
|
table,
|
|
87
108
|
action,
|
|
@@ -91,6 +112,19 @@ export function DataTableWidget({
|
|
|
91
112
|
}) {
|
|
92
113
|
const rows = table.rows ?? [];
|
|
93
114
|
const actionHref = action ? normalizeActionHref(action.href) : null;
|
|
115
|
+
const canExportCsv = table.columns.length > 0;
|
|
116
|
+
const exportCsv = () => {
|
|
117
|
+
if (!canExportCsv) return;
|
|
118
|
+
const stamp = new Date().toISOString().slice(0, 10);
|
|
119
|
+
downloadFile(
|
|
120
|
+
`${slugifyFilenamePart(table.title)}-${stamp}.csv`,
|
|
121
|
+
"text/csv;charset=utf-8",
|
|
122
|
+
toCSVTable(
|
|
123
|
+
table.columns.map((column) => column.label),
|
|
124
|
+
rows.map((row) => table.columns.map((column) => row[column.key])),
|
|
125
|
+
),
|
|
126
|
+
);
|
|
127
|
+
};
|
|
94
128
|
|
|
95
129
|
return (
|
|
96
130
|
<div className="my-1.5 overflow-hidden rounded-lg border border-border bg-background text-foreground shadow-sm">
|
|
@@ -131,6 +165,23 @@ export function DataTableWidget({
|
|
|
131
165
|
<IconExternalLink className="h-3 w-3" />
|
|
132
166
|
</a>
|
|
133
167
|
) : null}
|
|
168
|
+
<DropdownMenu>
|
|
169
|
+
<DropdownMenuTrigger asChild>
|
|
170
|
+
<button
|
|
171
|
+
type="button"
|
|
172
|
+
aria-label="Data table options"
|
|
173
|
+
className="inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
|
|
174
|
+
>
|
|
175
|
+
<IconDots className="h-3.5 w-3.5" />
|
|
176
|
+
</button>
|
|
177
|
+
</DropdownMenuTrigger>
|
|
178
|
+
<DropdownMenuContent align="end" className="w-44">
|
|
179
|
+
<DropdownMenuItem onSelect={exportCsv} disabled={!canExportCsv}>
|
|
180
|
+
<IconDownload className="mr-2 h-3.5 w-3.5" />
|
|
181
|
+
Download CSV
|
|
182
|
+
</DropdownMenuItem>
|
|
183
|
+
</DropdownMenuContent>
|
|
184
|
+
</DropdownMenu>
|
|
134
185
|
</div>
|
|
135
186
|
<div className="max-h-[360px] overflow-auto">
|
|
136
187
|
<table className="w-full min-w-[420px] border-collapse text-xs">
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
IconCode,
|
|
8
8
|
IconArrowBackUp,
|
|
9
9
|
IconDeviceFloppy,
|
|
10
|
+
IconDots,
|
|
11
|
+
IconDownload,
|
|
10
12
|
IconChevronLeft,
|
|
11
13
|
IconChevronRight,
|
|
12
14
|
IconChevronsLeft,
|
|
@@ -25,6 +27,12 @@ import type {
|
|
|
25
27
|
DbAdminSort,
|
|
26
28
|
DbAdminMutationResult,
|
|
27
29
|
} from "../../db-admin/types.js";
|
|
30
|
+
import {
|
|
31
|
+
DropdownMenu,
|
|
32
|
+
DropdownMenuContent,
|
|
33
|
+
DropdownMenuItem,
|
|
34
|
+
DropdownMenuTrigger,
|
|
35
|
+
} from "../components/ui/dropdown-menu.js";
|
|
28
36
|
import {
|
|
29
37
|
Popover,
|
|
30
38
|
PopoverContent,
|
|
@@ -33,6 +41,7 @@ import {
|
|
|
33
41
|
import { cn } from "../utils.js";
|
|
34
42
|
import { useChangeset, pkStringFor } from "./changeset.js";
|
|
35
43
|
import { DataGrid, type GridRow, type ActiveCell } from "./DataGrid.js";
|
|
44
|
+
import { downloadFile, toCSVTable } from "./export-utils.js";
|
|
36
45
|
import { FilterBar } from "./FilterBar.js";
|
|
37
46
|
import { RowSidePanel, type RowSidePanelMode } from "./RowSidePanel.js";
|
|
38
47
|
import { loadGridState, saveGridState } from "./storage.js";
|
|
@@ -54,6 +63,15 @@ export interface TableEditorProps {
|
|
|
54
63
|
const DEFAULT_PAGE_SIZE = 100;
|
|
55
64
|
const PAGE_SIZES = [25, 50, 100, 250, 500];
|
|
56
65
|
|
|
66
|
+
function slugifyFilenamePart(value: string): string {
|
|
67
|
+
const slug = value
|
|
68
|
+
.trim()
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
71
|
+
.replace(/^-+|-+$/g, "");
|
|
72
|
+
return slug || "table";
|
|
73
|
+
}
|
|
74
|
+
|
|
57
75
|
export function TableEditor({
|
|
58
76
|
table,
|
|
59
77
|
dialect: _dialect,
|
|
@@ -300,6 +318,20 @@ export function TableEditor({
|
|
|
300
318
|
}
|
|
301
319
|
|
|
302
320
|
const noPk = schema.primaryKey.length === 0;
|
|
321
|
+
const exportCurrentPageCsv = () => {
|
|
322
|
+
const columns = schema.columns.map((column) => column.name);
|
|
323
|
+
const stamp = new Date().toISOString().slice(0, 10);
|
|
324
|
+
downloadFile(
|
|
325
|
+
`${slugifyFilenamePart(table)}-${stamp}.csv`,
|
|
326
|
+
"text/csv;charset=utf-8",
|
|
327
|
+
toCSVTable(
|
|
328
|
+
columns,
|
|
329
|
+
gridRows
|
|
330
|
+
.filter((row) => !row.isDeleted)
|
|
331
|
+
.map((row) => columns.map((column) => row.values[column])),
|
|
332
|
+
),
|
|
333
|
+
);
|
|
334
|
+
};
|
|
303
335
|
|
|
304
336
|
return (
|
|
305
337
|
<div className="flex h-full min-h-0 flex-col">
|
|
@@ -337,6 +369,23 @@ export function TableEditor({
|
|
|
337
369
|
primary
|
|
338
370
|
/>
|
|
339
371
|
)}
|
|
372
|
+
<DropdownMenu>
|
|
373
|
+
<DropdownMenuTrigger asChild>
|
|
374
|
+
<button
|
|
375
|
+
type="button"
|
|
376
|
+
aria-label="Table options"
|
|
377
|
+
className="inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
378
|
+
>
|
|
379
|
+
<IconDots className="h-3.5 w-3.5" />
|
|
380
|
+
</button>
|
|
381
|
+
</DropdownMenuTrigger>
|
|
382
|
+
<DropdownMenuContent align="end" className="w-44">
|
|
383
|
+
<DropdownMenuItem onSelect={exportCurrentPageCsv}>
|
|
384
|
+
<IconDownload className="mr-2 h-3.5 w-3.5" />
|
|
385
|
+
Download CSV
|
|
386
|
+
</DropdownMenuItem>
|
|
387
|
+
</DropdownMenuContent>
|
|
388
|
+
</DropdownMenu>
|
|
340
389
|
</div>
|
|
341
390
|
</div>
|
|
342
391
|
|
|
@@ -16,6 +16,9 @@ function cellToCSV(value: unknown): string {
|
|
|
16
16
|
} else {
|
|
17
17
|
str = String(value);
|
|
18
18
|
}
|
|
19
|
+
// Spreadsheet apps treat leading =, +, -, and @ as formulas. Prefix with an
|
|
20
|
+
// apostrophe so exported CSV opens as literal text instead of executing.
|
|
21
|
+
if (/^[=+\-@]/.test(str)) str = `'${str}`;
|
|
19
22
|
// Quote when the value contains a comma, quote, CR, or LF. Escape embedded
|
|
20
23
|
// double-quotes by doubling them (RFC 4180).
|
|
21
24
|
if (/[",\r\n]/.test(str)) {
|
|
@@ -24,16 +27,22 @@ function cellToCSV(value: unknown): string {
|
|
|
24
27
|
return str;
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
/** Render a matrix as RFC-4180-style CSV with a header row. */
|
|
31
|
+
export function toCSVTable(headers: string[], rows: unknown[][]): string {
|
|
32
|
+
const header = headers.map(cellToCSV).join(",");
|
|
33
|
+
const body = rows.map((row) => row.map(cellToCSV).join(","));
|
|
34
|
+
return [header, ...body].join("\r\n");
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
/** Render rows as RFC-4180-style CSV with a header row of the given columns. */
|
|
28
38
|
export function toCSV(
|
|
29
39
|
columns: string[],
|
|
30
40
|
rows: Record<string, unknown>[],
|
|
31
41
|
): string {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
columns.map((col) =>
|
|
42
|
+
return toCSVTable(
|
|
43
|
+
columns,
|
|
44
|
+
rows.map((row) => columns.map((col) => row[col])),
|
|
35
45
|
);
|
|
36
|
-
return [header, ...body].join("\r\n");
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/** Render rows as a pretty-printed JSON array. */
|
|
@@ -14,7 +14,16 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { useEffect, useRef } from "react";
|
|
16
16
|
|
|
17
|
+
import {
|
|
18
|
+
removeAgentChatContextItem,
|
|
19
|
+
setAgentChatContextItem,
|
|
20
|
+
} from "../agent-chat.js";
|
|
17
21
|
import { agentNativePath } from "../api-path.js";
|
|
22
|
+
import {
|
|
23
|
+
deleteClientAppState,
|
|
24
|
+
readClientAppState,
|
|
25
|
+
setClientAppState,
|
|
26
|
+
} from "../application-state.js";
|
|
18
27
|
|
|
19
28
|
const NAVIGATION_PATH = agentNativePath(
|
|
20
29
|
"/_agent-native/application-state/navigation",
|
|
@@ -24,6 +33,9 @@ const NAVIGATE_PATH = agentNativePath(
|
|
|
24
33
|
);
|
|
25
34
|
|
|
26
35
|
const POLL_INTERVAL_MS = 1500;
|
|
36
|
+
const TABLE_CONTEXT_KEY = "database-selected-table";
|
|
37
|
+
const SELECTED_OBJECT_STATE_KEY = "selected-object";
|
|
38
|
+
const SELECTED_OBJECT_SOURCE_FIELD = "__agentNativeSelectedObjectSource";
|
|
27
39
|
|
|
28
40
|
let cachedSource: string | null = null;
|
|
29
41
|
|
|
@@ -55,6 +67,23 @@ function headers(extra?: Record<string, string>): Record<string, string> {
|
|
|
55
67
|
return h;
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
async function deleteSelectedObjectIfOwned(source: string | undefined) {
|
|
71
|
+
if (!source) return;
|
|
72
|
+
try {
|
|
73
|
+
const current = await readClientAppState<Record<string, unknown>>(
|
|
74
|
+
SELECTED_OBJECT_STATE_KEY,
|
|
75
|
+
);
|
|
76
|
+
if (current?.[SELECTED_OBJECT_SOURCE_FIELD] !== source) return;
|
|
77
|
+
await deleteClientAppState(SELECTED_OBJECT_STATE_KEY, {
|
|
78
|
+
keepalive: true,
|
|
79
|
+
requestSource: source,
|
|
80
|
+
});
|
|
81
|
+
} catch {
|
|
82
|
+
// Best effort only; stale selected-object context is less harmful than
|
|
83
|
+
// clearing a selection owned by another tab.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
58
87
|
export interface DbAdminNavigationState {
|
|
59
88
|
view: "database";
|
|
60
89
|
table: string | null;
|
|
@@ -88,6 +117,49 @@ export function useDbAdminAgentSync({
|
|
|
88
117
|
body: JSON.stringify(state),
|
|
89
118
|
}).catch(() => {});
|
|
90
119
|
}, [enabled, table, mode]);
|
|
120
|
+
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (!enabled) return;
|
|
123
|
+
const source = requestSource();
|
|
124
|
+
if (!table) {
|
|
125
|
+
removeAgentChatContextItem({
|
|
126
|
+
key: TABLE_CONTEXT_KEY,
|
|
127
|
+
openSidebar: false,
|
|
128
|
+
});
|
|
129
|
+
deleteSelectedObjectIfOwned(source);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const selection = {
|
|
134
|
+
type: "database-table",
|
|
135
|
+
table,
|
|
136
|
+
mode,
|
|
137
|
+
[SELECTED_OBJECT_SOURCE_FIELD]: source,
|
|
138
|
+
};
|
|
139
|
+
setAgentChatContextItem({
|
|
140
|
+
key: TABLE_CONTEXT_KEY,
|
|
141
|
+
title: `Table: ${table}`,
|
|
142
|
+
context: [
|
|
143
|
+
`The user currently has this database table selected: ${table}.`,
|
|
144
|
+
`Database admin mode: ${mode}`,
|
|
145
|
+
"Use the database admin actions and current-screen context to inspect rows, schema, or run SQL against this table.",
|
|
146
|
+
].join("\n"),
|
|
147
|
+
openSidebar: false,
|
|
148
|
+
focus: false,
|
|
149
|
+
});
|
|
150
|
+
setClientAppState(SELECTED_OBJECT_STATE_KEY, selection, {
|
|
151
|
+
keepalive: true,
|
|
152
|
+
requestSource: source,
|
|
153
|
+
}).catch(() => {});
|
|
154
|
+
|
|
155
|
+
return () => {
|
|
156
|
+
removeAgentChatContextItem({
|
|
157
|
+
key: TABLE_CONTEXT_KEY,
|
|
158
|
+
openSidebar: false,
|
|
159
|
+
});
|
|
160
|
+
deleteSelectedObjectIfOwned(source);
|
|
161
|
+
};
|
|
162
|
+
}, [enabled, table, mode]);
|
|
91
163
|
}
|
|
92
164
|
|
|
93
165
|
interface NavigateCommand {
|