@agent-native/core 0.121.2 → 0.122.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/README.md +4 -12
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +148 -0
- package/corpus/core/docs/content/actions.mdx +2 -2
- package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +2 -0
- package/corpus/core/docs/content/deployment.mdx +36 -0
- package/corpus/core/docs/content/http-api.mdx +266 -0
- package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/activity.ts +38 -27
- package/corpus/core/src/a2a/client.ts +57 -4
- package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
- package/corpus/core/src/agent/run-manager.ts +20 -1
- package/corpus/core/src/agent/run-store.ts +4 -1
- package/corpus/core/src/agent/types.ts +28 -8
- package/corpus/core/src/chat-threads/store.ts +45 -0
- package/corpus/core/src/checkpoints/index.ts +2 -0
- package/corpus/core/src/checkpoints/route-match.ts +13 -0
- package/corpus/core/src/cli/create.ts +105 -17
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/template-baseline.ts +410 -0
- package/corpus/core/src/cli/template-sync.ts +1004 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +38 -12
- package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/corpus/core/src/client/chat/message-components.tsx +127 -66
- package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
- package/corpus/core/src/client/error-format.ts +18 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
- package/corpus/core/src/client/org/TeamPage.tsx +7 -6
- package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/corpus/core/src/client/sse-event-processor.ts +3 -0
- package/corpus/core/src/data-widgets/index.ts +41 -0
- package/corpus/core/src/deploy/build.ts +11 -9
- package/corpus/core/src/extensions/url-safety.ts +67 -4
- package/corpus/core/src/integrations/webhook-handler.ts +63 -9
- package/corpus/core/src/org/auto-join-domain.ts +4 -3
- package/corpus/core/src/org/context.ts +108 -39
- package/corpus/core/src/org/index.ts +5 -0
- package/corpus/core/src/org/service-identity.ts +60 -0
- package/corpus/core/src/provider-api/index.ts +22 -1
- package/corpus/core/src/scripts/docs/search.ts +12 -1
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
- package/corpus/core/src/server/agents-bundle.ts +84 -5
- package/corpus/core/src/server/auth.ts +4 -3
- package/corpus/core/src/server/builder-browser.ts +47 -19
- package/corpus/core/src/server/core-routes-plugin.ts +2 -2
- package/corpus/core/src/server/credential-provider.ts +209 -68
- package/corpus/core/src/server/index.ts +3 -0
- package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
- package/corpus/core/src/server/prompts/framework-core.ts +9 -21
- package/corpus/core/src/server/prompts/index.ts +0 -1
- package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
- package/corpus/core/src/server/ssr-handler.ts +13 -2
- package/corpus/core/src/settings/user-settings.ts +13 -1
- package/corpus/core/src/shared/cache-control.ts +141 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/chat/_gitignore +1 -0
- package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/default/app/root.tsx +1 -1
- package/corpus/core/src/templates/default/public/manifest.json +2 -2
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
- package/corpus/core/src/vite/client.ts +69 -3
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
- package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/analytics/AGENTS.md +91 -563
- package/corpus/templates/analytics/_gitignore +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +12 -4
- package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
- package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/analytics/package.json +1 -1
- package/corpus/templates/analytics/public/manifest.json +1 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
- package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
- package/corpus/templates/analytics/server/lib/notion.ts +15 -4
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/assets/app/routes/_index.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/assets/server/plugins/auth.ts +1 -1
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/brain/app/lib/brain.ts +0 -7
- package/corpus/templates/brain/app/routes/_index.tsx +1 -2
- package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/brain/package.json +1 -1
- package/corpus/templates/brain/public/manifest.json +1 -1
- package/corpus/templates/brain/server/plugins/auth.ts +1 -1
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
- package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/calendar/package.json +1 -1
- package/corpus/templates/calendar/public/manifest.json +1 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
- package/corpus/templates/clips/AGENTS.md +5 -4
- package/corpus/templates/clips/_gitignore +1 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
- package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
- package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
- package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
- package/corpus/templates/clips/actions/list-recordings.ts +69 -19
- package/corpus/templates/clips/actions/list-viewers.ts +5 -2
- package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
- package/corpus/templates/clips/actions/request-transcript.ts +28 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
- package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
- package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
- package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
- package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/_index.tsx +1 -1
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
- package/corpus/templates/clips/app/routes/record.tsx +82 -31
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
- package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +2 -0
- package/corpus/templates/clips/desktop/src/app.tsx +89 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
- package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
- package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
- package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
- package/corpus/templates/clips/desktop/src/styles.css +127 -78
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
- package/corpus/templates/clips/server/db/schema.ts +27 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
- package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
- package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
- package/corpus/templates/clips/server/lib/recordings.ts +51 -3
- package/corpus/templates/clips/server/plugins/auth.ts +1 -1
- package/corpus/templates/clips/server/plugins/db.ts +31 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
- package/corpus/templates/clips/shared/recording-link.ts +43 -0
- package/corpus/templates/clips/shared/share-attribution.ts +4 -0
- package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
- package/corpus/templates/clips/shared/view-analytics.ts +26 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/content/AGENTS.md +62 -583
- package/corpus/templates/content/_gitignore +1 -0
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
- package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
- package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/content/package.json +1 -1
- package/corpus/templates/content/public/manifest.json +1 -1
- package/corpus/templates/content/server/plugins/auth.ts +1 -1
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
- package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
- package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
- package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
- package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
- package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
- package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
- package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
- package/corpus/templates/design/AGENTS.md +88 -503
- package/corpus/templates/design/_gitignore +1 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/design/app/routes/_index.tsx +1 -1
- package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/design/server/plugins/auth.ts +1 -1
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
- package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/dispatch/package.json +1 -1
- package/corpus/templates/dispatch/public/manifest.json +1 -1
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
- package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/forms/package.json +1 -1
- package/corpus/templates/forms/public/manifest.json +1 -1
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/forms/server/plugins/auth.ts +1 -1
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
- package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/macros/package.json +1 -1
- package/corpus/templates/macros/server/plugins/auth.ts +2 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
- package/corpus/templates/mail/app/routes/$view.tsx +1 -1
- package/corpus/templates/mail/app/routes/_index.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/mail/package.json +1 -1
- package/corpus/templates/mail/public/manifest.json +1 -1
- package/corpus/templates/mail/server/plugins/auth.ts +1 -1
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/plan/agent-native.app-skill.json +1 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
- package/corpus/templates/plan/app/lib/app-config.ts +1 -1
- package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/plan/package.json +1 -1
- package/corpus/templates/plan/public/manifest.json +1 -1
- package/corpus/templates/plan/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/slides/app/routes/_index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/slides/package.json +1 -1
- package/corpus/templates/slides/public/manifest.json +1 -1
- package/corpus/templates/slides/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/server/plugins/db.ts +4 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/tasks/AGENTS.md +1 -1
- package/corpus/templates/tasks/_gitignore +1 -0
- package/dist/a2a/activity.d.ts +4 -1
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +27 -16
- package/dist/a2a/activity.js.map +1 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +58 -4
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +31 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +12 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +21 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +41 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/index.d.ts +1 -0
- package/dist/checkpoints/index.d.ts.map +1 -1
- package/dist/checkpoints/index.js +1 -0
- package/dist/checkpoints/index.js.map +1 -1
- package/dist/checkpoints/route-match.d.ts +8 -0
- package/dist/checkpoints/route-match.d.ts.map +1 -0
- package/dist/checkpoints/route-match.js +13 -0
- package/dist/checkpoints/route-match.js.map +1 -0
- package/dist/cli/create.d.ts +35 -4
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +69 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/template-baseline.d.ts +54 -0
- package/dist/cli/template-baseline.d.ts.map +1 -0
- package/dist/cli/template-baseline.js +334 -0
- package/dist/cli/template-baseline.js.map +1 -0
- package/dist/cli/template-sync.d.ts +57 -0
- package/dist/cli/template-sync.d.ts.map +1 -0
- package/dist/cli/template-sync.js +787 -0
- package/dist/cli/template-sync.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +32 -2
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +20 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +81 -46
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -6
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +13 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- 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 +1 -1
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +9 -9
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +7 -4
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/data-widgets/index.d.ts +3 -0
- package/dist/data-widgets/index.d.ts.map +1 -1
- package/dist/data-widgets/index.js +33 -0
- package/dist/data-widgets/index.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +11 -7
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +1 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/extensions/url-safety.d.ts +9 -16
- package/dist/extensions/url-safety.d.ts.map +1 -1
- package/dist/extensions/url-safety.js +48 -4
- package/dist/extensions/url-safety.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +46 -9
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/auto-join-domain.d.ts +3 -2
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +1 -1
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +84 -28
- package/dist/org/context.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/service-identity.d.ts +43 -0
- package/dist/org/service-identity.d.ts.map +1 -0
- package/dist/org/service-identity.js +34 -0
- package/dist/org/service-identity.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +13 -11
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/index.d.ts +4 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +17 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +12 -1
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +3 -3
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +33 -62
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -10
- 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/agents-bundle.d.ts +18 -0
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +70 -4
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +43 -19
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.js +2 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +38 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +142 -64
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +7 -13
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +10 -21
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/shared-rules.d.ts +16 -10
- package/dist/server/prompts/shared-rules.d.ts.map +1 -1
- package/dist/server/prompts/shared-rules.js +19 -10
- package/dist/server/prompts/shared-rules.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +10 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/user-settings.d.ts.map +1 -1
- package/dist/settings/user-settings.js +13 -1
- package/dist/settings/user-settings.js.map +1 -1
- package/dist/shared/cache-control.d.ts +52 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +107 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/chat/_gitignore +1 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/default/app/root.tsx +1 -1
- package/dist/templates/default/public/manifest.json +2 -2
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +8 -7
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +66 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.mdx +2 -2
- package/docs/content/agent-surfaces.mdx +1 -1
- package/docs/content/authentication.mdx +2 -0
- package/docs/content/deployment.mdx +36 -0
- package/docs/content/http-api.mdx +266 -0
- package/docs/content/syncing-template-changes.mdx +159 -0
- package/package.json +4 -3
- package/src/a2a/activity.ts +38 -27
- package/src/a2a/client.ts +57 -4
- package/src/agent/engine/builder-engine.ts +35 -4
- package/src/agent/run-manager.ts +20 -1
- package/src/agent/run-store.ts +4 -1
- package/src/agent/types.ts +28 -8
- package/src/chat-threads/store.ts +45 -0
- package/src/checkpoints/index.ts +2 -0
- package/src/checkpoints/route-match.ts +13 -0
- package/src/cli/create.ts +105 -17
- package/src/cli/index.ts +20 -0
- package/src/cli/template-baseline.ts +410 -0
- package/src/cli/template-sync.ts +1004 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/client/AssistantChat.tsx +38 -12
- package/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/src/client/chat/message-components.tsx +127 -66
- package/src/client/chat/tool-call-display.tsx +29 -5
- package/src/client/error-format.ts +18 -0
- package/src/client/org/OrgSwitcher.tsx +30 -8
- package/src/client/org/TeamPage.tsx +7 -6
- package/src/client/settings/SettingsPanel.tsx +9 -9
- package/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/src/client/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- package/src/extensions/url-safety.ts +67 -4
- package/src/integrations/webhook-handler.ts +63 -9
- package/src/org/auto-join-domain.ts +4 -3
- package/src/org/context.ts +108 -39
- package/src/org/index.ts +5 -0
- package/src/org/service-identity.ts +60 -0
- package/src/provider-api/index.ts +22 -1
- package/src/scripts/docs/search.ts +12 -1
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
- package/src/server/agent-chat/context-tools.ts +9 -4
- package/src/server/agent-chat/framework-prompts.ts +38 -66
- package/src/server/agent-chat-plugin.ts +17 -10
- package/src/server/agents-bundle.ts +84 -5
- package/src/server/auth.ts +4 -3
- package/src/server/builder-browser.ts +47 -19
- package/src/server/core-routes-plugin.ts +2 -2
- package/src/server/credential-provider.ts +209 -68
- package/src/server/index.ts +3 -0
- package/src/server/prompts/framework-core-compact.ts +6 -13
- package/src/server/prompts/framework-core.ts +9 -21
- package/src/server/prompts/index.ts +0 -1
- package/src/server/prompts/shared-rules.ts +19 -11
- package/src/server/ssr-handler.ts +13 -2
- package/src/settings/user-settings.ts +13 -1
- package/src/shared/cache-control.ts +141 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/chat/_gitignore +1 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/default/app/root.tsx +1 -1
- package/src/templates/default/public/manifest.json +2 -2
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/src/vite/agents-bundle-plugin.ts +7 -6
- package/src/vite/client.ts +69 -3
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
2
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
import { IconTerminal2, IconUser } from "@tabler/icons-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
|
|
6
|
+
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
|
7
|
+
import { Button } from "@/components/ui/button";
|
|
8
|
+
import {
|
|
9
|
+
Popover,
|
|
10
|
+
PopoverContent,
|
|
11
|
+
PopoverTrigger,
|
|
12
|
+
} from "@/components/ui/popover";
|
|
13
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
14
|
+
import { cn } from "@/lib/utils";
|
|
15
|
+
|
|
16
|
+
interface ViewerRow {
|
|
17
|
+
id: string;
|
|
18
|
+
viewerEmail: string | null;
|
|
19
|
+
viewerName: string | null;
|
|
20
|
+
totalWatchMs: number;
|
|
21
|
+
completedPct: number;
|
|
22
|
+
countedView: boolean;
|
|
23
|
+
ctaClicked: boolean;
|
|
24
|
+
firstViewedAt: string | null;
|
|
25
|
+
lastViewedAt: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface AgentViewerRow {
|
|
29
|
+
agentLabel: string;
|
|
30
|
+
views: number;
|
|
31
|
+
lastSeenAt: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface Insights {
|
|
35
|
+
views: number;
|
|
36
|
+
agentViews: number;
|
|
37
|
+
agentViewers: AgentViewerRow[];
|
|
38
|
+
uniqueViewers: number;
|
|
39
|
+
completionRate: number;
|
|
40
|
+
ctaConversionRate: number;
|
|
41
|
+
dropOff: { bucket: number; watching: number }[];
|
|
42
|
+
topViewers: {
|
|
43
|
+
viewerEmail: string | null;
|
|
44
|
+
viewerName: string | null;
|
|
45
|
+
totalWatchMs: number;
|
|
46
|
+
completedPct: number;
|
|
47
|
+
}[];
|
|
48
|
+
durationMs: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RecordingViewsBadgeProps {
|
|
52
|
+
recordingId: string;
|
|
53
|
+
/** Public counted-view total. Rendered as-is when details are unavailable. */
|
|
54
|
+
viewCount: number;
|
|
55
|
+
/** True only for owner/editor — gates avatars, the popover, and all viewer identities. */
|
|
56
|
+
canViewDetails: boolean;
|
|
57
|
+
/** Optional: called by the popover's "More insights" button. Omit to hide that button. */
|
|
58
|
+
onOpenInsights?: () => void;
|
|
59
|
+
className?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Header-sized view counter. Viewer identities are owner/editor-only, so a
|
|
64
|
+
* visitor gets plain text and fires no viewer queries at all — `canViewDetails`
|
|
65
|
+
* is the client half of the server-side access check on `list-viewers`.
|
|
66
|
+
*/
|
|
67
|
+
export function RecordingViewsBadge({
|
|
68
|
+
recordingId,
|
|
69
|
+
viewCount,
|
|
70
|
+
canViewDetails,
|
|
71
|
+
onOpenInsights,
|
|
72
|
+
className,
|
|
73
|
+
}: RecordingViewsBadgeProps): React.ReactElement | null {
|
|
74
|
+
const t = useT();
|
|
75
|
+
const [open, setOpen] = useState(false);
|
|
76
|
+
|
|
77
|
+
const viewersQuery = useActionQuery<{ viewers: ViewerRow[] }>(
|
|
78
|
+
"list-viewers",
|
|
79
|
+
{ recordingId, limit: 12 },
|
|
80
|
+
{ enabled: canViewDetails },
|
|
81
|
+
);
|
|
82
|
+
const insightsQuery = useActionQuery<Insights>(
|
|
83
|
+
"get-recording-insights",
|
|
84
|
+
{ recordingId },
|
|
85
|
+
{ enabled: canViewDetails && open },
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const countLabel = t("recordingInsights.viewsCount", { count: viewCount });
|
|
89
|
+
|
|
90
|
+
if (viewCount <= 0 && !canViewDetails) return null;
|
|
91
|
+
|
|
92
|
+
if (!canViewDetails) {
|
|
93
|
+
return (
|
|
94
|
+
<span
|
|
95
|
+
className={cn("text-sm text-muted-foreground tabular-nums", className)}
|
|
96
|
+
>
|
|
97
|
+
{countLabel}
|
|
98
|
+
</span>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const viewers = viewersQuery.data?.viewers ?? [];
|
|
103
|
+
const insights = insightsQuery.data;
|
|
104
|
+
const agentViewers = insights?.agentViewers ?? [];
|
|
105
|
+
const summary = insights
|
|
106
|
+
? t("recordingInsights.totalViewsSummary", {
|
|
107
|
+
total: insights.views,
|
|
108
|
+
unique: insights.uniqueViewers,
|
|
109
|
+
})
|
|
110
|
+
: countLabel;
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<Popover open={open} onOpenChange={setOpen}>
|
|
114
|
+
<PopoverTrigger asChild onClick={(e) => e.stopPropagation()}>
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
className={cn(
|
|
118
|
+
"inline-flex cursor-pointer items-center gap-2 rounded-full border border-border bg-card px-2 py-1 text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
119
|
+
className,
|
|
120
|
+
)}
|
|
121
|
+
>
|
|
122
|
+
{viewers.length > 0 ? (
|
|
123
|
+
<span className="hidden -space-x-1.5 sm:flex">
|
|
124
|
+
{viewers.slice(0, 3).map((v) => (
|
|
125
|
+
<ViewerAvatar
|
|
126
|
+
key={v.id}
|
|
127
|
+
viewer={v}
|
|
128
|
+
className="h-6 w-6 ring-2 ring-card"
|
|
129
|
+
/>
|
|
130
|
+
))}
|
|
131
|
+
</span>
|
|
132
|
+
) : null}
|
|
133
|
+
<span className="tabular-nums">{countLabel}</span>
|
|
134
|
+
</button>
|
|
135
|
+
</PopoverTrigger>
|
|
136
|
+
<PopoverContent
|
|
137
|
+
align="end"
|
|
138
|
+
className="w-80 p-0"
|
|
139
|
+
onClick={(e) => e.stopPropagation()}
|
|
140
|
+
>
|
|
141
|
+
<Tabs defaultValue="views">
|
|
142
|
+
<div className="p-2 pb-0">
|
|
143
|
+
<TabsList className="grid h-8 w-full grid-cols-2">
|
|
144
|
+
<TabsTrigger value="views" className="text-xs">
|
|
145
|
+
{t("recordingInsights.viewsTab")}
|
|
146
|
+
</TabsTrigger>
|
|
147
|
+
<TabsTrigger value="insights" className="text-xs">
|
|
148
|
+
{t("recordingInsights.insightsTab")}
|
|
149
|
+
</TabsTrigger>
|
|
150
|
+
</TabsList>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<TabsContent value="views" className="mt-2">
|
|
154
|
+
<div className="border-y border-border px-3 py-2 text-xs text-muted-foreground">
|
|
155
|
+
{summary}
|
|
156
|
+
</div>
|
|
157
|
+
<div className="max-h-80 overflow-y-auto p-1.5">
|
|
158
|
+
<p className="px-2 pt-1 pb-1.5 text-xs font-medium text-muted-foreground">
|
|
159
|
+
{t("recordingInsights.humanViews")}
|
|
160
|
+
</p>
|
|
161
|
+
{viewersQuery.isLoading ? (
|
|
162
|
+
<p className="px-2 py-3 text-sm text-muted-foreground">
|
|
163
|
+
{t("recordingInsights.loading")}
|
|
164
|
+
</p>
|
|
165
|
+
) : viewers.length === 0 ? (
|
|
166
|
+
<p className="px-2 py-3 text-sm text-muted-foreground">
|
|
167
|
+
{t("recordingInsights.noViewsYet")}
|
|
168
|
+
</p>
|
|
169
|
+
) : (
|
|
170
|
+
<ul className="space-y-0.5">
|
|
171
|
+
{viewers.map((v) => (
|
|
172
|
+
<li
|
|
173
|
+
key={v.id}
|
|
174
|
+
className="flex items-center gap-2 rounded-md px-2 py-1.5"
|
|
175
|
+
>
|
|
176
|
+
<ViewerAvatar viewer={v} />
|
|
177
|
+
<span className="min-w-0 flex-1 truncate text-sm text-foreground">
|
|
178
|
+
{viewerLabel(v, t("recordingInsights.anonymous"))}
|
|
179
|
+
</span>
|
|
180
|
+
<span className="shrink-0 text-xs text-muted-foreground tabular-nums">
|
|
181
|
+
{Math.round(v.completedPct)}%
|
|
182
|
+
</span>
|
|
183
|
+
</li>
|
|
184
|
+
))}
|
|
185
|
+
</ul>
|
|
186
|
+
)}
|
|
187
|
+
|
|
188
|
+
<p className="mt-2 border-t border-border px-2 pt-2.5 pb-1.5 text-xs font-medium text-muted-foreground">
|
|
189
|
+
{t("recordingInsights.agentViews")}
|
|
190
|
+
</p>
|
|
191
|
+
{agentViewers.length === 0 ? (
|
|
192
|
+
<p className="px-2 py-1.5 text-sm text-muted-foreground">
|
|
193
|
+
{t("recordingInsights.noAgentViewsYet")}
|
|
194
|
+
</p>
|
|
195
|
+
) : (
|
|
196
|
+
<ul className="space-y-0.5">
|
|
197
|
+
{agentViewers.map((a) => (
|
|
198
|
+
<li
|
|
199
|
+
key={a.agentLabel}
|
|
200
|
+
className="flex items-center gap-2 rounded-md px-2 py-1.5"
|
|
201
|
+
>
|
|
202
|
+
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground">
|
|
203
|
+
<IconTerminal2 className="h-3.5 w-3.5" />
|
|
204
|
+
</span>
|
|
205
|
+
<span className="min-w-0 flex-1 truncate text-sm text-foreground">
|
|
206
|
+
{a.agentLabel}
|
|
207
|
+
</span>
|
|
208
|
+
<span className="shrink-0 text-xs text-muted-foreground tabular-nums">
|
|
209
|
+
{t("recordingInsights.viewsCount", { count: a.views })}
|
|
210
|
+
</span>
|
|
211
|
+
</li>
|
|
212
|
+
))}
|
|
213
|
+
</ul>
|
|
214
|
+
)}
|
|
215
|
+
</div>
|
|
216
|
+
</TabsContent>
|
|
217
|
+
|
|
218
|
+
<TabsContent value="insights" className="mt-2 space-y-3 p-3 pt-1">
|
|
219
|
+
{insightsQuery.isLoading ? (
|
|
220
|
+
<p className="py-3 text-sm text-muted-foreground">
|
|
221
|
+
{t("recordingInsights.loading")}
|
|
222
|
+
</p>
|
|
223
|
+
) : (
|
|
224
|
+
<>
|
|
225
|
+
<div className="grid grid-cols-2 gap-2">
|
|
226
|
+
<StatCard
|
|
227
|
+
label={t("recordingInsights.humanViews")}
|
|
228
|
+
value={insights?.views ?? viewCount}
|
|
229
|
+
/>
|
|
230
|
+
<StatCard
|
|
231
|
+
label={t("recordingInsights.agentViews")}
|
|
232
|
+
value={insights?.agentViews ?? 0}
|
|
233
|
+
/>
|
|
234
|
+
</div>
|
|
235
|
+
<div className="grid grid-cols-3 gap-2 text-xs text-muted-foreground">
|
|
236
|
+
<MiniStat
|
|
237
|
+
label={t("recordingInsights.uniqueViewers")}
|
|
238
|
+
value={insights?.uniqueViewers ?? 0}
|
|
239
|
+
/>
|
|
240
|
+
<MiniStat
|
|
241
|
+
label={t("recordingInsights.completion")}
|
|
242
|
+
value={`${Math.round(insights?.completionRate ?? 0)}%`}
|
|
243
|
+
/>
|
|
244
|
+
<MiniStat
|
|
245
|
+
label={t("recordingInsights.ctaConversion")}
|
|
246
|
+
value={`${Math.round(insights?.ctaConversionRate ?? 0)}%`}
|
|
247
|
+
/>
|
|
248
|
+
</div>
|
|
249
|
+
</>
|
|
250
|
+
)}
|
|
251
|
+
{onOpenInsights ? (
|
|
252
|
+
<Button
|
|
253
|
+
type="button"
|
|
254
|
+
variant="outline"
|
|
255
|
+
size="sm"
|
|
256
|
+
className="w-full cursor-pointer"
|
|
257
|
+
onClick={() => {
|
|
258
|
+
setOpen(false);
|
|
259
|
+
onOpenInsights();
|
|
260
|
+
}}
|
|
261
|
+
>
|
|
262
|
+
{t("recordingInsights.moreInsights")}
|
|
263
|
+
</Button>
|
|
264
|
+
) : null}
|
|
265
|
+
</TabsContent>
|
|
266
|
+
</Tabs>
|
|
267
|
+
</PopoverContent>
|
|
268
|
+
</Popover>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Identity fields every viewer surface shares — `list-viewers` rows and the
|
|
273
|
+
* leaner `topViewers` rows from `get-recording-insights` alike. */
|
|
274
|
+
export interface ViewerIdentity {
|
|
275
|
+
viewerEmail: string | null;
|
|
276
|
+
viewerName: string | null;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function ViewerAvatar({
|
|
280
|
+
viewer,
|
|
281
|
+
className,
|
|
282
|
+
}: {
|
|
283
|
+
viewer: ViewerIdentity;
|
|
284
|
+
className?: string;
|
|
285
|
+
}) {
|
|
286
|
+
const anonymous = !viewer.viewerName && !viewer.viewerEmail;
|
|
287
|
+
return (
|
|
288
|
+
<Avatar className={cn("h-6 w-6 shrink-0", className)}>
|
|
289
|
+
<AvatarFallback className="bg-primary text-[10px] text-primary-foreground">
|
|
290
|
+
{anonymous ? (
|
|
291
|
+
<IconUser className="h-3 w-3" />
|
|
292
|
+
) : (
|
|
293
|
+
initials(viewer.viewerName || viewer.viewerEmail || "?")
|
|
294
|
+
)}
|
|
295
|
+
</AvatarFallback>
|
|
296
|
+
</Avatar>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function MiniStat({ label, value }: { label: string; value: string | number }) {
|
|
301
|
+
return (
|
|
302
|
+
<div className="min-w-0">
|
|
303
|
+
<div className="truncate">{label}</div>
|
|
304
|
+
<div className="mt-0.5 text-foreground tabular-nums">{value}</div>
|
|
305
|
+
</div>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function StatCard({ label, value }: { label: string; value: string | number }) {
|
|
310
|
+
return (
|
|
311
|
+
<div className="rounded-lg border border-border bg-card p-2.5">
|
|
312
|
+
<div className="text-xs text-muted-foreground">{label}</div>
|
|
313
|
+
<div className="mt-0.5 text-xl font-semibold text-foreground tabular-nums">
|
|
314
|
+
{value}
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export function viewerLabel(
|
|
321
|
+
viewer: ViewerIdentity,
|
|
322
|
+
anonymousLabel: string,
|
|
323
|
+
): string {
|
|
324
|
+
if (viewer.viewerName) return viewer.viewerName;
|
|
325
|
+
if (viewer.viewerEmail) return viewer.viewerEmail.split("@")[0];
|
|
326
|
+
return anonymousLabel;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function initials(s: string): string {
|
|
330
|
+
return s
|
|
331
|
+
.split(/\s+|@/)
|
|
332
|
+
.slice(0, 2)
|
|
333
|
+
.map((p) => p[0]?.toUpperCase() ?? "")
|
|
334
|
+
.join("");
|
|
335
|
+
}
|
|
@@ -1400,7 +1400,10 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
|
|
|
1400
1400
|
v,
|
|
1401
1401
|
resolvedDurationMs,
|
|
1402
1402
|
);
|
|
1403
|
-
|
|
1403
|
+
// Only ever correct forward (skipping a trimmed range). Seeking
|
|
1404
|
+
// backwards here flushes the decode pipeline and replays from the
|
|
1405
|
+
// previous keyframe, which reads as a stutter with a buffering flash.
|
|
1406
|
+
if (visibleMs > ms) {
|
|
1404
1407
|
v.currentTime = visibleMs / 1000;
|
|
1405
1408
|
setCurrentMs(visibleMs);
|
|
1406
1409
|
if (visibleMs > 0) {
|
|
@@ -1815,21 +1818,23 @@ function CenterPlaybackOverlay({
|
|
|
1815
1818
|
* trustworthy finite number we have — preferring the resolved duration from
|
|
1816
1819
|
* the player, then falling back to `video.duration`, then the seekable range.
|
|
1817
1820
|
*/
|
|
1818
|
-
function clampSeek(
|
|
1821
|
+
export function clampSeek(
|
|
1819
1822
|
ms: number,
|
|
1820
1823
|
v: HTMLVideoElement,
|
|
1821
1824
|
resolvedDurationMs: number,
|
|
1822
1825
|
): number {
|
|
1823
|
-
|
|
1826
|
+
// Clamp in integer milliseconds. Routing through seconds and back loses 1ms
|
|
1827
|
+
// for ~1% of integer inputs (1001 -> 1000), which the timeupdate handler
|
|
1828
|
+
// would then "correct" by seeking the player backwards.
|
|
1829
|
+
let maxMs = Number.POSITIVE_INFINITY;
|
|
1824
1830
|
if (resolvedDurationMs > 0) {
|
|
1825
|
-
|
|
1831
|
+
maxMs = resolvedDurationMs;
|
|
1826
1832
|
} else if (Number.isFinite(v.duration) && v.duration > 0) {
|
|
1827
|
-
|
|
1833
|
+
maxMs = v.duration * 1000;
|
|
1828
1834
|
} else if (v.seekable && v.seekable.length > 0) {
|
|
1829
|
-
|
|
1835
|
+
maxMs = v.seekable.end(v.seekable.length - 1) * 1000;
|
|
1830
1836
|
}
|
|
1831
|
-
|
|
1832
|
-
return Math.floor(sec * 1000);
|
|
1837
|
+
return Math.floor(Math.max(0, Math.min(maxMs, ms)));
|
|
1833
1838
|
}
|
|
1834
1839
|
|
|
1835
1840
|
function skipExcludedRange(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { writeClipboardText } from "@agent-native/core/client/clipboard";
|
|
1
2
|
import {
|
|
2
3
|
useActionMutation,
|
|
3
4
|
useActionQuery,
|
|
@@ -70,7 +71,7 @@ export const ROLE_OPTIONS: Array<{ value: Role; label: string }> = [
|
|
|
70
71
|
];
|
|
71
72
|
|
|
72
73
|
export function copyToClipboard(value: string): void {
|
|
73
|
-
|
|
74
|
+
void writeClipboardText(value);
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
// ---------------------------------------------------------------------------
|
|
@@ -288,7 +288,6 @@ const messages = {
|
|
|
288
288
|
storageConnectedChecking: "Storage connected. Checking this clip...",
|
|
289
289
|
signInToFinish: "Sign in to finish",
|
|
290
290
|
signInIfYours: "Sign in if this is yours",
|
|
291
|
-
openDashboard: "Open dashboard",
|
|
292
291
|
checkAgain: "Check again",
|
|
293
292
|
backToHome: "Back to home",
|
|
294
293
|
generatingTitle: "Generating title",
|
|
@@ -807,11 +806,21 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
807
806
|
recentViewers: "Recent viewers",
|
|
808
807
|
noViewers: "No viewers yet.",
|
|
809
808
|
anonymous: "Anonymous",
|
|
810
|
-
anon: "Anon",
|
|
811
809
|
moreViewers: "+{{count}} more",
|
|
812
810
|
viewedBy: "Viewed by",
|
|
813
811
|
someone: "Someone",
|
|
814
812
|
noViewsYet: "No views yet.",
|
|
813
|
+
viewsCount_one: "{{count}} view",
|
|
814
|
+
viewsCount_other: "{{count}} views",
|
|
815
|
+
totalViewsSummary: "{{total}} total views, {{unique}} unique viewers",
|
|
816
|
+
viewsTab: "Views",
|
|
817
|
+
insightsTab: "Insights",
|
|
818
|
+
humanViews: "Human views",
|
|
819
|
+
agentViews: "Agent views",
|
|
820
|
+
noAgentViewsYet: "No agent views yet.",
|
|
821
|
+
totalVideoViews: "Total video views",
|
|
822
|
+
averageCompletionRate: "Average completion rate",
|
|
823
|
+
moreInsights: "More insights",
|
|
815
824
|
},
|
|
816
825
|
libraryGrid: {
|
|
817
826
|
spaceRoot: "Space root",
|
|
@@ -1291,6 +1300,8 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
1291
1300
|
couldNotImportLoom: "Could not import that Loom.",
|
|
1292
1301
|
recordingReadyToUpload: "Recording is ready to upload",
|
|
1293
1302
|
recordingSaved: "Recording saved",
|
|
1303
|
+
linkCopied: "Link copied",
|
|
1304
|
+
copyLinkAction: "Copy link",
|
|
1294
1305
|
noLocalRecordingData: "No local recording data is available to download.",
|
|
1295
1306
|
recordingDownloadStarted: "Recording download started",
|
|
1296
1307
|
backToLibrary: "Back to library",
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export type CaptureHostApp = {
|
|
2
|
+
/** The name macOS lists this app under in Privacy & Security. */
|
|
3
|
+
name: string;
|
|
4
|
+
kind: "desktop" | "browser";
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type CapturePermissionPane = "screen" | "camera" | "microphone";
|
|
8
|
+
|
|
9
|
+
export type CaptureHostEnv = {
|
|
10
|
+
userAgent: string;
|
|
11
|
+
isTauri: boolean;
|
|
12
|
+
isBrave: boolean;
|
|
13
|
+
isArc: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const UNKNOWN_BROWSER = "your browser";
|
|
17
|
+
|
|
18
|
+
// Arc does not identify itself in the user agent, but it injects its palette
|
|
19
|
+
// variables onto the document element, so a browser reporting plain Chrome
|
|
20
|
+
// while exposing --arc-palette-title is Arc.
|
|
21
|
+
function detectArc(): boolean {
|
|
22
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return Boolean(
|
|
27
|
+
window
|
|
28
|
+
.getComputedStyle(document.documentElement)
|
|
29
|
+
.getPropertyValue("--arc-palette-title")
|
|
30
|
+
.trim(),
|
|
31
|
+
);
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function readCaptureHostEnv(): CaptureHostEnv {
|
|
38
|
+
const tauri =
|
|
39
|
+
typeof window === "undefined"
|
|
40
|
+
? undefined
|
|
41
|
+
: (window as unknown as {
|
|
42
|
+
__TAURI_INTERNALS__?: unknown;
|
|
43
|
+
__TAURI__?: unknown;
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
userAgent: typeof navigator === "undefined" ? "" : navigator.userAgent,
|
|
47
|
+
isTauri: Boolean(tauri?.__TAURI_INTERNALS__ || tauri?.__TAURI__),
|
|
48
|
+
isBrave:
|
|
49
|
+
typeof navigator !== "undefined" &&
|
|
50
|
+
Boolean((navigator as { brave?: unknown }).brave),
|
|
51
|
+
isArc: detectArc(),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function detectCaptureHostApp(env: CaptureHostEnv): CaptureHostApp {
|
|
56
|
+
if (env.isTauri) return { name: "Clips", kind: "desktop" };
|
|
57
|
+
if (/Electron/i.test(env.userAgent)) {
|
|
58
|
+
return { name: "Agent Native", kind: "desktop" };
|
|
59
|
+
}
|
|
60
|
+
const ua = env.userAgent;
|
|
61
|
+
const name = /Vivaldi/i.test(ua)
|
|
62
|
+
? "Vivaldi"
|
|
63
|
+
: /OPR\//i.test(ua)
|
|
64
|
+
? "Opera"
|
|
65
|
+
: /Edg\//i.test(ua)
|
|
66
|
+
? "Microsoft Edge"
|
|
67
|
+
: env.isBrave
|
|
68
|
+
? "Brave Browser"
|
|
69
|
+
: env.isArc
|
|
70
|
+
? "Arc"
|
|
71
|
+
: /Firefox\//i.test(ua)
|
|
72
|
+
? "Firefox"
|
|
73
|
+
: /Chrome\//i.test(ua)
|
|
74
|
+
? "Google Chrome"
|
|
75
|
+
: /Safari\//i.test(ua)
|
|
76
|
+
? "Safari"
|
|
77
|
+
: UNKNOWN_BROWSER;
|
|
78
|
+
return { name, kind: "browser" };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* macOS grants screen, camera, and microphone access per application, so
|
|
83
|
+
* permission guidance has to name the app hosting the recorder — Clips itself
|
|
84
|
+
* never appears in System Settings when it runs in a browser tab.
|
|
85
|
+
*/
|
|
86
|
+
export function getCaptureHostApp(): CaptureHostApp {
|
|
87
|
+
return detectCaptureHostApp(readCaptureHostEnv());
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function macSettingsPath(pane: CapturePermissionPane): string {
|
|
91
|
+
const label =
|
|
92
|
+
pane === "screen"
|
|
93
|
+
? "Screen & System Audio Recording"
|
|
94
|
+
: pane === "camera"
|
|
95
|
+
? "Camera"
|
|
96
|
+
: "Microphone";
|
|
97
|
+
return `System Settings > Privacy & Security > ${label}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function macPermissionGuidanceFor(
|
|
101
|
+
pane: CapturePermissionPane,
|
|
102
|
+
host: CaptureHostApp = getCaptureHostApp(),
|
|
103
|
+
): string {
|
|
104
|
+
const where = macSettingsPath(pane);
|
|
105
|
+
if (host.kind === "desktop") {
|
|
106
|
+
return `macOS grants this per app. Turn on ${host.name} in ${where}, then quit and reopen ${host.name} and start the recording again.`;
|
|
107
|
+
}
|
|
108
|
+
const subject = host.name === UNKNOWN_BROWSER ? "it" : host.name;
|
|
109
|
+
return `macOS grants this per app, not per site, so Clips is never listed by name — look for ${host.name} instead. Turn ${subject} on in ${where}, then quit and reopen it. If it is not listed yet, add it with the + button.`;
|
|
110
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { appBasePath } from "@agent-native/core/client/api-path";
|
|
2
|
+
import { writeClipboardText } from "@agent-native/core/client/clipboard";
|
|
3
|
+
import {
|
|
4
|
+
buildRecordingShareUrl,
|
|
5
|
+
recordingSharePath,
|
|
6
|
+
} from "@shared/recording-link";
|
|
7
|
+
|
|
8
|
+
/** Absolute, ready-to-paste public share URL for a recording. */
|
|
9
|
+
export function recordingShareUrl(
|
|
10
|
+
recordingId: string,
|
|
11
|
+
ownerId?: string | null,
|
|
12
|
+
): string {
|
|
13
|
+
if (typeof window === "undefined") return recordingSharePath(recordingId);
|
|
14
|
+
return buildRecordingShareUrl({
|
|
15
|
+
recordingId,
|
|
16
|
+
origin: window.location.origin,
|
|
17
|
+
basePath: appBasePath(),
|
|
18
|
+
ownerId,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Copy a recording's public share link. Returns whether the write actually
|
|
24
|
+
* landed so callers can tell the user the truth instead of assuming a silent
|
|
25
|
+
* `navigator.clipboard` rejection was a success.
|
|
26
|
+
*/
|
|
27
|
+
export async function copyRecordingShareLink(
|
|
28
|
+
recordingId: string,
|
|
29
|
+
ownerId?: string | null,
|
|
30
|
+
): Promise<boolean> {
|
|
31
|
+
return writeClipboardText(recordingShareUrl(recordingId, ownerId));
|
|
32
|
+
}
|
|
@@ -6,7 +6,7 @@ import { LibraryGrid } from "@/components/library/library-grid";
|
|
|
6
6
|
import { usePageHeaderLayout } from "@/components/library/page-header";
|
|
7
7
|
import { Button } from "@/components/ui/button";
|
|
8
8
|
|
|
9
|
-
const SEO_TITLE = "
|
|
9
|
+
const SEO_TITLE = "Clips - Open Source screen recorder";
|
|
10
10
|
const SEO_DESCRIPTION =
|
|
11
11
|
"Open Source screen recorder and meeting-notes app with AI transcripts, summaries, search, dictation, and agent-readable share links.";
|
|
12
12
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { appPath } from "@agent-native/core/client/api-path";
|
|
2
|
+
import { writeClipboardText } from "@agent-native/core/client/clipboard";
|
|
1
3
|
import {
|
|
2
4
|
useActionMutation,
|
|
3
5
|
useActionQuery,
|
|
@@ -99,6 +101,7 @@ interface Meeting {
|
|
|
99
101
|
recordingId?: string | null;
|
|
100
102
|
recordingDurationMs?: number | null;
|
|
101
103
|
transcriptStatus?: "pending" | "ready" | "failed" | "in_progress" | string;
|
|
104
|
+
visibility?: "private" | "org" | "public" | null;
|
|
102
105
|
shareTranscript?: boolean | null;
|
|
103
106
|
summaryMd?: string | null;
|
|
104
107
|
userNotesMd?: string | null;
|
|
@@ -542,6 +545,30 @@ export default function MeetingDetailRoute() {
|
|
|
542
545
|
|
|
543
546
|
const handleEndMeeting = () => {
|
|
544
547
|
if (!meeting) return;
|
|
548
|
+
// The meeting share link is valid independently of the stop call, so copy
|
|
549
|
+
// it while the user's click still counts as activation instead of waiting
|
|
550
|
+
// on the mutation. The public meeting page resolves `visibility = public`
|
|
551
|
+
// rows only — anything else would hand the user a link that 404s for the
|
|
552
|
+
// people they send it to.
|
|
553
|
+
if (meeting.visibility === "public" && typeof window !== "undefined") {
|
|
554
|
+
const shareUrl = `${window.location.origin}${appPath(
|
|
555
|
+
`/share/meeting/${meeting.id}`,
|
|
556
|
+
)}`;
|
|
557
|
+
void writeClipboardText(shareUrl).then((copied) => {
|
|
558
|
+
if (copied) {
|
|
559
|
+
toast.success(t("recordRoute.linkCopied"));
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
toast(t("meetingDetail.share"), {
|
|
563
|
+
action: {
|
|
564
|
+
label: t("recordRoute.copyLinkAction"),
|
|
565
|
+
onClick: () => {
|
|
566
|
+
void writeClipboardText(shareUrl);
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
}
|
|
545
572
|
// Optimistic: flip the live badge off immediately rather than waiting
|
|
546
573
|
// for the next 2s poll — stop-meeting-recording stamps actualEnd and
|
|
547
574
|
// flips transcriptStatus server-side.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DefaultSpinner } from "@agent-native/core/client/ui";
|
|
2
2
|
import { redirect, type LoaderFunctionArgs } from "react-router";
|
|
3
3
|
|
|
4
|
-
const SEO_TITLE = "
|
|
4
|
+
const SEO_TITLE = "Clips - Open Source screen recorder";
|
|
5
5
|
const SEO_DESCRIPTION =
|
|
6
6
|
"Open Source screen recorder and meeting-notes app with AI transcripts, summaries, search, dictation, and agent-readable share links.";
|
|
7
7
|
|