@agent-native/core 0.90.11 → 0.91.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +22 -0
- package/corpus/core/docs/content/toolkit-settings.mdx +56 -3
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/run-ownership.ts +29 -1
- package/corpus/core/src/changelog/parse.ts +78 -0
- package/corpus/core/src/chat-threads/schema.ts +43 -0
- package/corpus/core/src/chat-threads/store.ts +144 -12
- package/corpus/core/src/cli/workspace-dev.ts +25 -5
- package/corpus/core/src/client/AgentPanel.tsx +79 -14
- package/corpus/core/src/client/AssistantChat.tsx +359 -425
- package/corpus/core/src/client/analytics-session.ts +70 -0
- package/corpus/core/src/client/analytics.ts +175 -49
- package/corpus/core/src/client/chat/message-components.tsx +22 -2
- package/corpus/core/src/client/components/ui/message-scroller.tsx +131 -0
- package/corpus/core/src/client/conversation/AgentConversation.tsx +63 -41
- package/corpus/core/src/client/error-capture.ts +616 -0
- package/corpus/core/src/client/index.ts +12 -0
- package/corpus/core/src/client/session-replay.ts +57 -7
- package/corpus/core/src/client/settings/SettingsPanel.tsx +123 -1
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +292 -45
- package/corpus/core/src/client/settings/index.ts +1 -0
- package/corpus/core/src/client/sharing/ShareButton.tsx +14 -11
- package/corpus/core/src/client/sharing/ShareDialog.tsx +13 -10
- package/corpus/core/src/mcp/builtin-tools.ts +29 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +174 -79
- package/corpus/core/src/server/onboarding-html.ts +28 -16
- package/corpus/core/src/sharing/actions/list-resource-shares.ts +45 -1
- package/corpus/core/src/sharing/actions/share-resource.ts +9 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
- package/corpus/core/src/vite/client.ts +217 -35
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +8 -7
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +14 -10
- package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +15 -15
- package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -22
- package/corpus/templates/analytics/.agents/skills/data-programs/SKILL.md +114 -61
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +7 -7
- package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +1 -0
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +1 -1
- package/corpus/templates/analytics/.builder/skills/bigquery/SKILL.md +17 -17
- package/corpus/templates/analytics/.builder/skills/gcloud/SKILL.md +5 -5
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/gong/SKILL.md +12 -12
- package/corpus/templates/analytics/.builder/skills/grafana/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/sentry/SKILL.md +7 -7
- package/corpus/templates/analytics/.builder/skills/slack/SKILL.md +6 -6
- package/corpus/templates/analytics/.builder/skills/stripe/SKILL.md +7 -7
- package/corpus/templates/analytics/AGENTS.md +47 -2
- package/corpus/templates/analytics/actions/add-status-page-monitor.ts +36 -0
- package/corpus/templates/analytics/actions/capture-test-error.ts +33 -0
- package/corpus/templates/analytics/actions/delete-monitor.ts +24 -0
- package/corpus/templates/analytics/actions/delete-status-page.ts +23 -0
- package/corpus/templates/analytics/actions/get-error-issue.ts +36 -0
- package/corpus/templates/analytics/actions/get-monitor-stats.ts +55 -0
- package/corpus/templates/analytics/actions/get-monitor.ts +27 -0
- package/corpus/templates/analytics/actions/get-public-status-page.ts +41 -0
- package/corpus/templates/analytics/actions/get-status-page.ts +29 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +40 -0
- package/corpus/templates/analytics/actions/list-monitors.ts +21 -0
- package/corpus/templates/analytics/actions/list-status-pages.ts +21 -0
- package/corpus/templates/analytics/actions/match-error-issues.ts +51 -0
- package/corpus/templates/analytics/actions/navigate.ts +58 -4
- package/corpus/templates/analytics/actions/remove-status-page-monitor.ts +22 -0
- package/corpus/templates/analytics/actions/reorder-status-page-monitors.ts +25 -0
- package/corpus/templates/analytics/actions/resolve-error-issue.ts +38 -0
- package/corpus/templates/analytics/actions/run-monitor-check.ts +23 -0
- package/corpus/templates/analytics/actions/save-analysis.ts +1 -0
- package/corpus/templates/analytics/actions/save-monitor.ts +145 -0
- package/corpus/templates/analytics/actions/save-status-page.ts +47 -0
- package/corpus/templates/analytics/actions/view-screen.ts +212 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +10 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +134 -39
- package/corpus/templates/analytics/app/components/monitoring/PublicStatusView.tsx +351 -0
- package/corpus/templates/analytics/app/components/monitoring/ResponseTimeChart.tsx +174 -0
- package/corpus/templates/analytics/app/components/monitoring/UptimeStatCards.tsx +85 -0
- package/corpus/templates/analytics/app/components/monitoring/UptimeTimelineBars.tsx +106 -0
- package/corpus/templates/analytics/app/components/monitoring/chart-utils.ts +101 -0
- package/corpus/templates/analytics/app/components/monitoring/index.ts +28 -0
- package/corpus/templates/analytics/app/components/monitoring/types.ts +42 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +34 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -0
- package/corpus/templates/analytics/app/i18n-data.ts +33 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +28 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +77 -9
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +7 -0
- package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +205 -0
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +100 -0
- package/corpus/templates/analytics/app/pages/monitoring/UptimePanel.tsx +475 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +372 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +360 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/Sparkline.tsx +55 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +106 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +75 -0
- package/corpus/templates/analytics/app/pages/monitoring/errors/utils.ts +132 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorDetail.tsx +535 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +1026 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorList.tsx +311 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +235 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPageEditor.tsx +661 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPagesView.tsx +355 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/i18n.ts +106 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/slug.ts +24 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/types.ts +20 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/status-summary.ts +87 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +161 -0
- package/corpus/templates/analytics/app/pages/monitoring/uptime/utils.ts +210 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +76 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +74 -9
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +197 -20
- package/corpus/templates/analytics/app/root.tsx +33 -1
- package/corpus/templates/analytics/app/routes/monitoring._index.tsx +10 -0
- package/corpus/templates/analytics/app/routes/status.$slug.tsx +118 -0
- package/corpus/templates/analytics/changelog/2026-07-08-add-uptime-monitors-that-ping-your-urls-and-alert-you-when-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-analytics-chats-keep-large-data-dictionaries-compact-so-prov.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-create-public-status-pages-that-share-the-live-health-of-cho.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-extension-panels-use-clearer-open-copy.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-error-capture.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-fixed-single-panel-dashboard-drags-so-they-no-longer-rewrite.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-jump-straight-from-an-error-in-a-session-recording-to-its-fu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitor-detail-and-list-now-show-colorful-uptime-timelines-r.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-pinned-ask-chats-now-show-a-pin-icon-in-the-sidebar.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-publish-a-public-uptime-status-page-with-colorful-uptime-tim.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sessions-now-hide-visitor-emails-in-demo-mode-and-show-clean.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +5 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +5 -0
- package/corpus/templates/analytics/changelog/2026-07-08-the-uptime-monitor-list-now-has-a-current-status-overview-wi.md +6 -0
- package/corpus/templates/analytics/docs/error-capture.md +172 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +150 -0
- package/corpus/templates/analytics/server/db/schema-errors.ts +150 -0
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +177 -0
- package/corpus/templates/analytics/server/db/schema.ts +6 -0
- package/corpus/templates/analytics/server/jobs/uptime-monitors.ts +123 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +41 -0
- package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +55 -12
- package/corpus/templates/analytics/server/lib/error-capture.ts +1331 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +47 -1
- package/corpus/templates/analytics/server/lib/monitor-stats.ts +494 -0
- package/corpus/templates/analytics/server/lib/status-pages.ts +798 -0
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +1665 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -37
- package/corpus/templates/analytics/server/plugins/auth.ts +11 -1
- package/corpus/templates/analytics/server/plugins/db.ts +408 -0
- package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +63 -0
- package/corpus/templates/assets/app/routes/_index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.tsx +22 -1
- package/corpus/templates/assets/changelog/2026-07-08-recent-drafts-keep-comfortable-side-padding.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/brain/app/routes/settings.tsx +43 -5
- package/corpus/templates/brain/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +44 -6
- package/corpus/templates/calendar/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/chat/app/routes/settings.tsx +16 -1
- package/corpus/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +79 -37
- package/corpus/templates/clips/app/components/player/player-controls.tsx +35 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +162 -18
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +63 -6
- package/corpus/templates/clips/app/routes/record.tsx +18 -1
- package/corpus/templates/clips/changelog/2026-07-07-shared-clips-start-playback-reliably-from-the-first-play-click.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-camera-and-microphone-menus-now-show-which-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-copies-new-clip-links-after-saving.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-recordings-now-continue-after-granting-came.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-mobile-shared-clips-now-have-loom-style-tap-and-skip-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-recordings-and-uploads-copy-links-after-saving.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-settings-are-cleaner-searchable-and-collapse-s3-with-builder.md +5 -0
- package/corpus/templates/clips/changelog/2026-07-08-transcripts-are-more-reliable-for-longer-desktop-recordings-.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +162 -13
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +14 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +36 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +99 -25
- package/corpus/templates/clips/chrome-extension/src/permission.ts +63 -14
- package/corpus/templates/clips/chrome-extension/src/popup.ts +123 -23
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +47 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +33 -4
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +214 -29
- package/corpus/templates/content/actions/attach-content-database-source.ts +3 -0
- package/corpus/templates/content/actions/change-content-database-source-role.ts +1 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +42 -32
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +352 -81
- package/corpus/templates/content/app/components/editor/database/settings.tsx +49 -24
- package/corpus/templates/content/app/routes/_app.settings.tsx +19 -1
- package/corpus/templates/content/changelog/2026-07-07-builder-source-tag-fields-now-import-as-multi-select.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/content/shared/api.ts +3 -0
- package/corpus/templates/content/shared/properties.ts +42 -0
- package/corpus/templates/design/actions/generate-design.ts +3 -0
- package/corpus/templates/design/actions/get-design-system.ts +147 -1
- package/corpus/templates/design/app/routes/settings.tsx +16 -1
- package/corpus/templates/design/changelog/2026-07-08-design-generation-now-follows-hydrated-builder-design-system.md +6 -0
- package/corpus/templates/design/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/dispatch/app/routes/settings.tsx +23 -2
- package/corpus/templates/dispatch/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +16 -1
- package/corpus/templates/forms/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/macros/app/routes/settings.tsx +16 -1
- package/corpus/templates/macros/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/mail/app/components/settings/GmailFiltersSection.tsx +1 -1
- package/corpus/templates/mail/app/components/settings/SnippetsSection.tsx +1 -1
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +123 -105
- package/corpus/templates/mail/changelog/2026-07-08-settings-redesigned-with-a-consistent-searchable-layout.md +5 -0
- package/corpus/templates/plan/app/routes/settings.tsx +23 -2
- package/corpus/templates/plan/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/templates/slides/actions/add-slide.ts +1 -0
- package/corpus/templates/slides/actions/get-design-system.ts +147 -1
- package/corpus/templates/slides/app/pages/Index.tsx +46 -1
- package/corpus/templates/slides/app/routes/settings.tsx +16 -1
- package/corpus/templates/slides/changelog/2026-07-08-deck-generation-now-follows-hydrated-builder-design-system-g.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/dist/agent/run-ownership.d.ts +6 -0
- package/dist/agent/run-ownership.d.ts.map +1 -1
- package/dist/agent/run-ownership.js +11 -1
- package/dist/agent/run-ownership.js.map +1 -1
- package/dist/changelog/parse.d.ts +7 -0
- package/dist/changelog/parse.d.ts.map +1 -1
- package/dist/changelog/parse.js +64 -0
- package/dist/changelog/parse.js.map +1 -1
- package/dist/chat-threads/schema.d.ts +445 -0
- package/dist/chat-threads/schema.d.ts.map +1 -0
- package/dist/chat-threads/schema.js +39 -0
- package/dist/chat-threads/schema.js.map +1 -0
- package/dist/chat-threads/store.d.ts +12 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +99 -10
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +20 -5
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +35 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +105 -183
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/analytics-session.d.ts +3 -0
- package/dist/client/analytics-session.d.ts.map +1 -0
- package/dist/client/analytics-session.js +66 -0
- package/dist/client/analytics-session.js.map +1 -0
- package/dist/client/analytics.d.ts +32 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +116 -46
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +2 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +16 -6
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/components/ui/message-scroller.d.ts +16 -0
- package/dist/client/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/client/components/ui/message-scroller.js +25 -0
- package/dist/client/components/ui/message-scroller.js.map +1 -0
- package/dist/client/conversation/AgentConversation.d.ts +1 -1
- package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/client/conversation/AgentConversation.js +3 -8
- package/dist/client/conversation/AgentConversation.js.map +1 -1
- package/dist/client/error-capture.d.ts +99 -0
- package/dist/client/error-capture.d.ts.map +1 -0
- package/dist/client/error-capture.js +437 -0
- package/dist/client/error-capture.js.map +1 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/session-replay.d.ts +22 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +45 -4
- 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 +100 -5
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +49 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +131 -19
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -1
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +13 -8
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +12 -7
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +21 -2
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/org/schema.d.ts +15 -15
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +109 -73
- 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/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +28 -16
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/sharing/actions/list-resource-shares.js +30 -1
- package/dist/sharing/actions/list-resource-shares.js.map +1 -1
- package/dist/sharing/actions/share-resource.js +6 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +192 -30
- package/dist/vite/client.js.map +1 -1
- package/docs/content/toolkit-settings.mdx +56 -3
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CodeSurface } from "@agent-native/core/blocks";
|
|
2
2
|
import {
|
|
3
|
+
agentNativePath,
|
|
3
4
|
useActionQuery,
|
|
4
5
|
useBuilderConnectFlow,
|
|
5
6
|
useBuilderStatus,
|
|
@@ -18,10 +19,10 @@ import {
|
|
|
18
19
|
IconSearch,
|
|
19
20
|
IconServer,
|
|
20
21
|
} from "@tabler/icons-react";
|
|
22
|
+
import { useQuery } from "@tanstack/react-query";
|
|
21
23
|
import { useMemo, useState } from "react";
|
|
22
24
|
import { Link, useNavigate, useSearchParams } from "react-router";
|
|
23
25
|
|
|
24
|
-
import { Badge } from "@/components/ui/badge";
|
|
25
26
|
import { Button } from "@/components/ui/button";
|
|
26
27
|
import { Card, CardContent } from "@/components/ui/card";
|
|
27
28
|
import { Input } from "@/components/ui/input";
|
|
@@ -65,13 +66,27 @@ type SessionRecordingSummary = {
|
|
|
65
66
|
referrer: string | null;
|
|
66
67
|
app: string | null;
|
|
67
68
|
template: string | null;
|
|
69
|
+
metadata?: Record<string, unknown>;
|
|
68
70
|
status: "active" | "completed";
|
|
69
71
|
createdAt: string;
|
|
70
72
|
updatedAt: string;
|
|
71
73
|
lastIngestedAt: string | null;
|
|
72
74
|
};
|
|
73
75
|
|
|
76
|
+
type SessionRecordingIdentity = Pick<
|
|
77
|
+
SessionRecordingSummary,
|
|
78
|
+
"id" | "userId" | "userKey" | "anonymousId" | "sessionId"
|
|
79
|
+
>;
|
|
80
|
+
|
|
81
|
+
type SessionRecordingDevice = Pick<SessionRecordingSummary, "metadata">;
|
|
82
|
+
|
|
83
|
+
type DemoStatus = {
|
|
84
|
+
enabled?: boolean;
|
|
85
|
+
forced?: boolean;
|
|
86
|
+
};
|
|
87
|
+
|
|
74
88
|
const RANGE_OPTIONS: ReplayRange[] = ["24h", "7d", "30d", "90d", "all"];
|
|
89
|
+
const DEMO_STATUS_URL = agentNativePath("/_agent-native/demo/status");
|
|
75
90
|
|
|
76
91
|
export default function SessionsPage() {
|
|
77
92
|
const t = useT();
|
|
@@ -96,6 +111,7 @@ export default function SessionsPage() {
|
|
|
96
111
|
{ staleTime: 30_000 },
|
|
97
112
|
);
|
|
98
113
|
|
|
114
|
+
const demoModeEnabled = useDemoModeEnabled();
|
|
99
115
|
const recordings = data ?? [];
|
|
100
116
|
|
|
101
117
|
function updateFilter(key: string, value: string) {
|
|
@@ -225,6 +241,7 @@ export default function SessionsPage() {
|
|
|
225
241
|
recording.endedAt ??
|
|
226
242
|
recording.lastIngestedAt ??
|
|
227
243
|
recording.startedAt;
|
|
244
|
+
const deviceLabel = sessionDeviceLabel(recording);
|
|
228
245
|
return (
|
|
229
246
|
<button
|
|
230
247
|
key={recording.id}
|
|
@@ -239,7 +256,7 @@ export default function SessionsPage() {
|
|
|
239
256
|
</span>
|
|
240
257
|
<span className="min-w-0">
|
|
241
258
|
<span className="block truncate text-sm font-medium text-foreground">
|
|
242
|
-
{visitorLabel(recording, t)}
|
|
259
|
+
{visitorLabel(recording, t, demoModeEnabled)}
|
|
243
260
|
</span>
|
|
244
261
|
<span className="mt-0.5 block truncate text-xs text-muted-foreground">
|
|
245
262
|
{formatDateTime(lastSeen)} ·{" "}
|
|
@@ -260,35 +277,32 @@ export default function SessionsPage() {
|
|
|
260
277
|
</span>
|
|
261
278
|
</span>
|
|
262
279
|
<span className="analytics-session-app-meta min-w-0 text-left">
|
|
263
|
-
<span className="
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
280
|
+
<span className="analytics-session-badges flex flex-wrap gap-1.5 text-xs text-muted-foreground">
|
|
281
|
+
<span>
|
|
282
|
+
{t("sessions.pageCountCompact", {
|
|
283
|
+
count: formatNumber(recording.pageCount),
|
|
284
|
+
})}
|
|
285
|
+
</span>
|
|
269
286
|
{recording.errorCount > 0 ? (
|
|
270
|
-
<
|
|
287
|
+
<span className="font-medium text-destructive">
|
|
271
288
|
{t("sessions.errorCount", {
|
|
272
289
|
count: String(recording.errorCount),
|
|
273
290
|
})}
|
|
274
|
-
</
|
|
291
|
+
</span>
|
|
275
292
|
) : null}
|
|
276
293
|
{recording.rageClickCount > 0 ? (
|
|
277
|
-
<
|
|
294
|
+
<span>
|
|
278
295
|
{t("sessions.rageClicks", {
|
|
279
296
|
count: String(recording.rageClickCount),
|
|
280
297
|
})}
|
|
281
|
-
</Badge>
|
|
282
|
-
) : null}
|
|
283
|
-
{recording.errorCount === 0 &&
|
|
284
|
-
recording.rageClickCount === 0 ? (
|
|
285
|
-
<span className="text-xs text-muted-foreground">
|
|
286
|
-
{t("sessions.pageCountCompact", {
|
|
287
|
-
count: formatNumber(recording.pageCount),
|
|
288
|
-
})}
|
|
289
298
|
</span>
|
|
290
299
|
) : null}
|
|
291
300
|
</span>
|
|
301
|
+
{deviceLabel ? (
|
|
302
|
+
<span className="mt-1 block truncate text-xs text-muted-foreground">
|
|
303
|
+
{deviceLabel}
|
|
304
|
+
</span>
|
|
305
|
+
) : null}
|
|
292
306
|
</span>
|
|
293
307
|
</button>
|
|
294
308
|
);
|
|
@@ -302,6 +316,22 @@ export default function SessionsPage() {
|
|
|
302
316
|
);
|
|
303
317
|
}
|
|
304
318
|
|
|
319
|
+
function useDemoModeEnabled(): boolean {
|
|
320
|
+
const { data } = useQuery({
|
|
321
|
+
queryKey: ["agent-native", "demo-mode"],
|
|
322
|
+
queryFn: async () => {
|
|
323
|
+
const res = await fetch(DEMO_STATUS_URL, {
|
|
324
|
+
credentials: "same-origin",
|
|
325
|
+
});
|
|
326
|
+
if (!res.ok) return null;
|
|
327
|
+
return (await res.json()) as DemoStatus | null;
|
|
328
|
+
},
|
|
329
|
+
refetchInterval: 4_000,
|
|
330
|
+
staleTime: 2_000,
|
|
331
|
+
});
|
|
332
|
+
return data?.enabled === true || data?.forced === true;
|
|
333
|
+
}
|
|
334
|
+
|
|
305
335
|
function EmptySessionsState() {
|
|
306
336
|
const t = useT();
|
|
307
337
|
const storageStatus = useReplayStorageStatus();
|
|
@@ -472,9 +502,11 @@ function rangeLabel(value: ReplayRange, t: ReturnType<typeof useT>): string {
|
|
|
472
502
|
}
|
|
473
503
|
|
|
474
504
|
function visitorLabel(
|
|
475
|
-
recording:
|
|
505
|
+
recording: SessionRecordingIdentity,
|
|
476
506
|
t: ReturnType<typeof useT>,
|
|
507
|
+
demoModeEnabled: boolean,
|
|
477
508
|
): string {
|
|
509
|
+
if (demoModeEnabled) return demoVisitorLabel(recording);
|
|
478
510
|
const email = emailLike(recording.userId) || emailLike(recording.userKey);
|
|
479
511
|
if (email) return email;
|
|
480
512
|
return (
|
|
@@ -485,6 +517,29 @@ function visitorLabel(
|
|
|
485
517
|
);
|
|
486
518
|
}
|
|
487
519
|
|
|
520
|
+
export function demoVisitorLabel(recording: SessionRecordingIdentity): string {
|
|
521
|
+
const source =
|
|
522
|
+
emailLike(recording.userId) ||
|
|
523
|
+
emailLike(recording.userKey) ||
|
|
524
|
+
recording.userId ||
|
|
525
|
+
recording.userKey ||
|
|
526
|
+
recording.anonymousId ||
|
|
527
|
+
recording.sessionId ||
|
|
528
|
+
recording.id;
|
|
529
|
+
const hash = stableHash(source);
|
|
530
|
+
const first = DEMO_FIRST_NAMES[hash % DEMO_FIRST_NAMES.length];
|
|
531
|
+
const last =
|
|
532
|
+
DEMO_LAST_NAMES[
|
|
533
|
+
Math.floor(hash / DEMO_FIRST_NAMES.length) % DEMO_LAST_NAMES.length
|
|
534
|
+
];
|
|
535
|
+
const domain =
|
|
536
|
+
DEMO_DOMAINS[
|
|
537
|
+
Math.floor(hash / (DEMO_FIRST_NAMES.length * DEMO_LAST_NAMES.length)) %
|
|
538
|
+
DEMO_DOMAINS.length
|
|
539
|
+
];
|
|
540
|
+
return `${first}.${last}@${domain}`.toLowerCase();
|
|
541
|
+
}
|
|
542
|
+
|
|
488
543
|
function emailLike(value: string | null): string | null {
|
|
489
544
|
if (!value?.includes("@")) return null;
|
|
490
545
|
return value;
|
|
@@ -512,6 +567,81 @@ function safePathFromUrl(value: string): string {
|
|
|
512
567
|
}
|
|
513
568
|
}
|
|
514
569
|
|
|
570
|
+
export function sessionDeviceLabel(
|
|
571
|
+
recording: SessionRecordingDevice,
|
|
572
|
+
): string | null {
|
|
573
|
+
const metadata = recordValue(recording.metadata);
|
|
574
|
+
const device = recordValue(metadata.device);
|
|
575
|
+
const browser = recordValue(metadata.browser);
|
|
576
|
+
const client = recordValue(metadata.client);
|
|
577
|
+
const os = osLabelFromValue(
|
|
578
|
+
metadata.os ??
|
|
579
|
+
metadata.operatingSystem ??
|
|
580
|
+
metadata.operating_system ??
|
|
581
|
+
metadata.deviceOs ??
|
|
582
|
+
metadata.device_os ??
|
|
583
|
+
device.os ??
|
|
584
|
+
device.operatingSystem ??
|
|
585
|
+
browser.os ??
|
|
586
|
+
client.os,
|
|
587
|
+
);
|
|
588
|
+
if (os) return os;
|
|
589
|
+
const platform = stringValue(
|
|
590
|
+
metadata.platform ?? device.platform ?? client.platform,
|
|
591
|
+
);
|
|
592
|
+
const platformLabel = inferOsLabel(platform);
|
|
593
|
+
if (platformLabel) return platformLabel;
|
|
594
|
+
const userAgent = stringValue(
|
|
595
|
+
metadata.userAgent ??
|
|
596
|
+
metadata.user_agent ??
|
|
597
|
+
device.userAgent ??
|
|
598
|
+
device.user_agent ??
|
|
599
|
+
client.userAgent ??
|
|
600
|
+
client.user_agent,
|
|
601
|
+
);
|
|
602
|
+
return inferOsLabel(userAgent);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function osLabelFromValue(value: unknown): string | null {
|
|
606
|
+
const record = recordValue(value);
|
|
607
|
+
if (record) {
|
|
608
|
+
const name = stringValue(record.name ?? record.family ?? record.os);
|
|
609
|
+
const version = stringValue(record.version ?? record.release);
|
|
610
|
+
if (name && version) return `${normalizeOsName(name)} ${version}`;
|
|
611
|
+
if (name) return normalizeOsName(name);
|
|
612
|
+
}
|
|
613
|
+
const label = stringValue(value);
|
|
614
|
+
if (!label) return null;
|
|
615
|
+
return inferOsLabel(label) ?? label;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function inferOsLabel(value: string | null): string | null {
|
|
619
|
+
if (!value) return null;
|
|
620
|
+
if (/cros|chrome os/i.test(value)) return "ChromeOS";
|
|
621
|
+
if (/iphone|ipad|ipod|ios/i.test(value)) return "iOS";
|
|
622
|
+
if (/mac os x|macintosh|macintel|darwin|macos/i.test(value)) return "macOS";
|
|
623
|
+
if (/windows|win32|win64/i.test(value)) return "Windows";
|
|
624
|
+
if (/android/i.test(value)) return "Android";
|
|
625
|
+
if (/linux/i.test(value)) return "Linux";
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function normalizeOsName(value: string): string {
|
|
630
|
+
return inferOsLabel(value) ?? value;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function recordValue(value: unknown): Record<string, unknown> {
|
|
634
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
635
|
+
? (value as Record<string, unknown>)
|
|
636
|
+
: {};
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function stringValue(value: unknown): string | null {
|
|
640
|
+
if (typeof value !== "string") return null;
|
|
641
|
+
const trimmed = value.trim();
|
|
642
|
+
return trimmed || null;
|
|
643
|
+
}
|
|
644
|
+
|
|
515
645
|
function formatDateTime(value: string): string {
|
|
516
646
|
const date = new Date(value);
|
|
517
647
|
if (!Number.isFinite(date.getTime())) return value;
|
|
@@ -537,6 +667,53 @@ function formatNumber(value: number): string {
|
|
|
537
667
|
return new Intl.NumberFormat().format(value);
|
|
538
668
|
}
|
|
539
669
|
|
|
670
|
+
function stableHash(value: string): number {
|
|
671
|
+
let hash = 2166136261;
|
|
672
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
673
|
+
hash ^= value.charCodeAt(i);
|
|
674
|
+
hash = Math.imul(hash, 16777619);
|
|
675
|
+
}
|
|
676
|
+
return hash >>> 0;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
const DEMO_FIRST_NAMES = [
|
|
680
|
+
"Avery",
|
|
681
|
+
"Blake",
|
|
682
|
+
"Cameron",
|
|
683
|
+
"Devon",
|
|
684
|
+
"Emerson",
|
|
685
|
+
"Finley",
|
|
686
|
+
"Harper",
|
|
687
|
+
"Jordan",
|
|
688
|
+
"Morgan",
|
|
689
|
+
"Quinn",
|
|
690
|
+
"Riley",
|
|
691
|
+
"Taylor",
|
|
692
|
+
];
|
|
693
|
+
|
|
694
|
+
const DEMO_LAST_NAMES = [
|
|
695
|
+
"Bennett",
|
|
696
|
+
"Carter",
|
|
697
|
+
"Ellis",
|
|
698
|
+
"Hayes",
|
|
699
|
+
"Keller",
|
|
700
|
+
"Monroe",
|
|
701
|
+
"Parker",
|
|
702
|
+
"Reed",
|
|
703
|
+
"Sullivan",
|
|
704
|
+
"Walker",
|
|
705
|
+
"Young",
|
|
706
|
+
"Zimmer",
|
|
707
|
+
];
|
|
708
|
+
|
|
709
|
+
const DEMO_DOMAINS = [
|
|
710
|
+
"acme.test",
|
|
711
|
+
"northstar.test",
|
|
712
|
+
"orbit.test",
|
|
713
|
+
"riverbank.test",
|
|
714
|
+
"summit.test",
|
|
715
|
+
];
|
|
716
|
+
|
|
540
717
|
const SESSION_REPLAY_SNIPPET = `// Agent Native templates already call configureTracking().
|
|
541
718
|
import { configureTracking } from "@agent-native/core/client";
|
|
542
719
|
|
|
@@ -9,7 +9,14 @@ import {
|
|
|
9
9
|
import { configureTracking } from "@agent-native/core/client";
|
|
10
10
|
import { useQueryClient } from "@tanstack/react-query";
|
|
11
11
|
import { useCallback, useState } from "react";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
Links,
|
|
14
|
+
Meta,
|
|
15
|
+
Outlet,
|
|
16
|
+
Scripts,
|
|
17
|
+
ScrollRestoration,
|
|
18
|
+
useLocation,
|
|
19
|
+
} from "react-router";
|
|
13
20
|
import type { LinksFunction } from "react-router";
|
|
14
21
|
|
|
15
22
|
import { AuthProvider } from "@/components/auth/AuthProvider";
|
|
@@ -100,6 +107,31 @@ function DbSyncBridge() {
|
|
|
100
107
|
|
|
101
108
|
export default function Root() {
|
|
102
109
|
const [queryClient] = useState(() => createAgentNativeQueryClient());
|
|
110
|
+
const location = useLocation();
|
|
111
|
+
|
|
112
|
+
// Public, unauthenticated uptime status pages (`/status/<slug>`) render
|
|
113
|
+
// SSR-first without the authenticated app chrome (sidebar/chat/command
|
|
114
|
+
// palette). See app/routes/status.$slug.tsx and the `/status` public path in
|
|
115
|
+
// server/plugins/auth.ts.
|
|
116
|
+
const isPublicStatusPath =
|
|
117
|
+
location.pathname === "/status" || location.pathname.startsWith("/status/");
|
|
118
|
+
|
|
119
|
+
if (isPublicStatusPath) {
|
|
120
|
+
return (
|
|
121
|
+
<AppToolkitProvider>
|
|
122
|
+
<AppProviders
|
|
123
|
+
queryClient={queryClient}
|
|
124
|
+
isPublicPath
|
|
125
|
+
defaultTheme="dark"
|
|
126
|
+
toaster={null}
|
|
127
|
+
i18n={{ catalog: i18nCatalog }}
|
|
128
|
+
>
|
|
129
|
+
<Outlet />
|
|
130
|
+
</AppProviders>
|
|
131
|
+
</AppToolkitProvider>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
103
135
|
return (
|
|
104
136
|
// defaultTheme="dark": analytics defaults to dark mode if no stored preference.
|
|
105
137
|
// toaster={null}: suppress AppProviders' built-in sonner; analytics renders
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { messagesByLocale } from "@/i18n-data";
|
|
2
|
+
import MonitoringPage from "@/pages/monitoring/MonitoringPage";
|
|
3
|
+
|
|
4
|
+
export function meta() {
|
|
5
|
+
return [{ title: messagesByLocale["en-US"].routeTitles.monitoring }];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function MonitoringRoute() {
|
|
9
|
+
return <MonitoringPage />;
|
|
10
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public, unauthenticated uptime status page: `/status/<slug>`.
|
|
3
|
+
*
|
|
4
|
+
* SSR-first: the loader resolves the sanitized, PUBLISHED-only status view on
|
|
5
|
+
* the server so crawlers and first-time visitors get real markup (framework
|
|
6
|
+
* rule: public/SEO pages SSR real content). The client then lightly
|
|
7
|
+
* auto-refreshes via the same `get-public-status-page` action (whitelisted in
|
|
8
|
+
* server/plugins/auth.ts). Unknown or unpublished slugs render a branded 404.
|
|
9
|
+
*
|
|
10
|
+
* This route is rendered without the authenticated app chrome — see the
|
|
11
|
+
* `/status/` public branch in app/root.tsx.
|
|
12
|
+
*/
|
|
13
|
+
import { useActionQuery } from "@agent-native/core/client";
|
|
14
|
+
import { IconActivity } from "@tabler/icons-react";
|
|
15
|
+
import { useMemo } from "react";
|
|
16
|
+
import { data, useLoaderData, useParams } from "react-router";
|
|
17
|
+
import type {
|
|
18
|
+
HeadersArgs,
|
|
19
|
+
LoaderFunctionArgs,
|
|
20
|
+
MetaFunction,
|
|
21
|
+
} from "react-router";
|
|
22
|
+
|
|
23
|
+
import { getPublicStatusPage } from "../../server/lib/status-pages";
|
|
24
|
+
import type { PublicStatusPage } from "../../server/lib/status-pages";
|
|
25
|
+
import { PublicStatusView } from "../components/monitoring/PublicStatusView";
|
|
26
|
+
|
|
27
|
+
interface StatusLoaderData {
|
|
28
|
+
slug: string;
|
|
29
|
+
page: PublicStatusPage | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const FOUND_CACHE = {
|
|
33
|
+
"Cache-Control": "public, max-age=30, s-maxage=30, stale-while-revalidate=60",
|
|
34
|
+
};
|
|
35
|
+
const MISSING_CACHE = { "Cache-Control": "public, max-age=15, s-maxage=15" };
|
|
36
|
+
|
|
37
|
+
export function headers({ loaderHeaders }: HeadersArgs) {
|
|
38
|
+
return loaderHeaders;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function loader({ params }: LoaderFunctionArgs) {
|
|
42
|
+
const slug = params.slug ?? "";
|
|
43
|
+
const page = await getPublicStatusPage(slug);
|
|
44
|
+
return data<StatusLoaderData>(
|
|
45
|
+
{ slug, page },
|
|
46
|
+
{ status: page ? 200 : 404, headers: page ? FOUND_CACHE : MISSING_CACHE },
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const meta: MetaFunction<typeof loader> = ({ loaderData }) => {
|
|
51
|
+
const page = loaderData?.page;
|
|
52
|
+
if (!page) {
|
|
53
|
+
return [
|
|
54
|
+
{ title: "Status page not found" }, // i18n-ignore public status page meta copy
|
|
55
|
+
{ name: "robots", content: "noindex" },
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
const description =
|
|
59
|
+
page.description ||
|
|
60
|
+
(page.overall === "operational"
|
|
61
|
+
? "All systems operational."
|
|
62
|
+
: "Current service status.");
|
|
63
|
+
return [
|
|
64
|
+
{ title: `${page.title} · Status` },
|
|
65
|
+
{ name: "description", content: description },
|
|
66
|
+
{ property: "og:title", content: `${page.title} · Status` },
|
|
67
|
+
{ property: "og:description", content: description },
|
|
68
|
+
{ property: "og:type", content: "website" },
|
|
69
|
+
];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function StatusNotFound() {
|
|
73
|
+
return (
|
|
74
|
+
<main className="flex min-h-screen items-center justify-center bg-background p-6 text-foreground">
|
|
75
|
+
<div className="flex max-w-md flex-col items-center text-center">
|
|
76
|
+
<span className="mb-4 inline-flex size-12 items-center justify-center rounded-xl border border-border bg-muted text-muted-foreground">
|
|
77
|
+
<IconActivity className="size-6" />
|
|
78
|
+
</span>
|
|
79
|
+
<h1 className="text-2xl font-semibold tracking-tight">
|
|
80
|
+
Status page not found{/* i18n-ignore public status page fixed copy */}
|
|
81
|
+
</h1>
|
|
82
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
83
|
+
This status page doesn’t exist or hasn’t been published
|
|
84
|
+
yet.
|
|
85
|
+
</p>
|
|
86
|
+
</div>
|
|
87
|
+
</main>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default function PublicStatusRoute() {
|
|
92
|
+
const loaderData = useLoaderData<typeof loader>();
|
|
93
|
+
const params = useParams();
|
|
94
|
+
const slug = loaderData.slug || params.slug || "";
|
|
95
|
+
|
|
96
|
+
// SSR gives us the initial page; the client lightly polls the same public
|
|
97
|
+
// action to keep the banner/uptime fresh without a manual reload.
|
|
98
|
+
const query = useActionQuery<PublicStatusPage>(
|
|
99
|
+
"get-public-status-page",
|
|
100
|
+
{ slug },
|
|
101
|
+
{
|
|
102
|
+
initialData: loaderData.page ?? undefined,
|
|
103
|
+
enabled: Boolean(loaderData.page),
|
|
104
|
+
refetchInterval: 60_000,
|
|
105
|
+
staleTime: 30_000,
|
|
106
|
+
retry: false,
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const page = useMemo(
|
|
111
|
+
() => query.data ?? loaderData.page,
|
|
112
|
+
[query.data, loaderData.page],
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (!page) return <StatusNotFound />;
|
|
116
|
+
|
|
117
|
+
return <PublicStatusView page={page} refreshing={query.isFetching} />;
|
|
118
|
+
}
|