@agent-native/core 0.121.1 → 0.122.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 +145 -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/getting-started.mdx +477 -115
- 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/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/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/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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +5 -0
- 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/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/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/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/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -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/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/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.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +46 -15
- package/corpus/templates/clips/app/routes/record.tsx +77 -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/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 +25 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- 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/db.ts +23 -0
- 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/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/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- 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/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/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/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/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 +3 -3
- 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/resources/handlers.d.ts +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/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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +2 -0
- 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/getting-started.mdx +477 -115
- 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/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/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- 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/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -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 +5 -0
|
@@ -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
|
+
}
|
|
@@ -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,5 +1,6 @@
|
|
|
1
1
|
import { AgentPanel } from "@agent-native/core/client/agent-chat";
|
|
2
2
|
import { appPath, agentNativePath } from "@agent-native/core/client/api-path";
|
|
3
|
+
import { writeClipboardText } from "@agent-native/core/client/clipboard";
|
|
3
4
|
import {
|
|
4
5
|
useActionMutation,
|
|
5
6
|
useActionQuery,
|
|
@@ -19,7 +20,12 @@ import {
|
|
|
19
20
|
isLoomEmbedBackedRecording,
|
|
20
21
|
isLoomRecordingSource,
|
|
21
22
|
} from "@shared/loom";
|
|
22
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
CLIP_SHARE_REF,
|
|
25
|
+
DASHBOARD_REDIRECT_PARAM,
|
|
26
|
+
DASHBOARD_REDIRECT_VALUE,
|
|
27
|
+
REF_PARAM,
|
|
28
|
+
} from "@shared/share-attribution";
|
|
23
29
|
import {
|
|
24
30
|
IconShare3,
|
|
25
31
|
IconArrowLeft,
|
|
@@ -50,6 +56,7 @@ import { CommentsPanel } from "@/components/player/comments-panel";
|
|
|
50
56
|
import { RecordingOptionsMenu } from "@/components/player/delete-recording-menu";
|
|
51
57
|
import { InsightsPanel } from "@/components/player/insights-panel";
|
|
52
58
|
import { ReactionsTray } from "@/components/player/reactions-tray";
|
|
59
|
+
import { RecordingViewsBadge } from "@/components/player/recording-views-badge";
|
|
53
60
|
import { SettingsPanel } from "@/components/player/settings-panel";
|
|
54
61
|
import { ShareRecordingPopover } from "@/components/player/share-dialog";
|
|
55
62
|
import {
|
|
@@ -85,6 +92,7 @@ import { usePlayerShortcuts } from "@/hooks/use-player-shortcuts";
|
|
|
85
92
|
import { useViewTracking } from "@/hooks/use-view-tracking";
|
|
86
93
|
import enMessages from "@/i18n/en-US";
|
|
87
94
|
import { parsePlaybackSpeed } from "@/lib/playback-speed";
|
|
95
|
+
import { recordingShareUrl } from "@/lib/recording-link";
|
|
88
96
|
import { isStorageSetupFailureReason } from "@/lib/storage-failures";
|
|
89
97
|
import { cn } from "@/lib/utils";
|
|
90
98
|
|
|
@@ -253,6 +261,18 @@ export default function RecordingPage() {
|
|
|
253
261
|
}
|
|
254
262
|
return currentMs;
|
|
255
263
|
}, [currentMs]);
|
|
264
|
+
// The compact layout stacks the panel below the video, so switching tabs
|
|
265
|
+
// alone leaves the user looking at the player. Desktop always renders the
|
|
266
|
+
// side aside, so nothing to scroll there.
|
|
267
|
+
const openInsightsPanel = useCallback(() => {
|
|
268
|
+
setPanel("insights");
|
|
269
|
+
if (!isCompactLayout) return;
|
|
270
|
+
requestAnimationFrame(() => {
|
|
271
|
+
document
|
|
272
|
+
.getElementById("clip-activity-panel")
|
|
273
|
+
?.scrollIntoView({ block: "start" });
|
|
274
|
+
});
|
|
275
|
+
}, [isCompactLayout]);
|
|
256
276
|
const transcriptKickedRef = useRef<string | null>(null);
|
|
257
277
|
// When the recording lands in the processing state but never flips to
|
|
258
278
|
// 'ready', stop spinning forever and surface an error banner so the user
|
|
@@ -366,8 +386,11 @@ export default function RecordingPage() {
|
|
|
366
386
|
// password.
|
|
367
387
|
useEffect(() => {
|
|
368
388
|
if (!recordingId || !playerDataForbidden) return;
|
|
389
|
+
const shareParams = new URLSearchParams();
|
|
390
|
+
shareParams.set(REF_PARAM, CLIP_SHARE_REF);
|
|
391
|
+
shareParams.set(DASHBOARD_REDIRECT_PARAM, DASHBOARD_REDIRECT_VALUE);
|
|
369
392
|
navigate(
|
|
370
|
-
`/share/${encodeURIComponent(recordingId)}?${
|
|
393
|
+
`/share/${encodeURIComponent(recordingId)}?${shareParams.toString()}`,
|
|
371
394
|
{
|
|
372
395
|
replace: true,
|
|
373
396
|
},
|
|
@@ -408,23 +431,21 @@ export default function RecordingPage() {
|
|
|
408
431
|
const visibleTitle = recording
|
|
409
432
|
? displayRecordingTitle(recording.title)
|
|
410
433
|
: "Untitled Clip";
|
|
434
|
+
// Attribution `via` must never point at someone who isn't the owner, so it
|
|
435
|
+
// is only tagged when the viewer is the owner (same rule as the share dialog).
|
|
436
|
+
const shareViaId =
|
|
437
|
+
role === "owner" ? (session?.userId ?? undefined) : undefined;
|
|
411
438
|
const pendingShareUrl = useMemo(() => {
|
|
412
439
|
if (!recordingId || typeof window === "undefined") return "";
|
|
413
|
-
return
|
|
414
|
-
|
|
415
|
-
window.location.origin,
|
|
416
|
-
).toString();
|
|
417
|
-
}, [recordingId]);
|
|
440
|
+
return recordingShareUrl(recordingId, shareViaId);
|
|
441
|
+
}, [recordingId, shareViaId]);
|
|
418
442
|
const copyPendingShareLink = useCallback(async () => {
|
|
419
443
|
if (!pendingShareUrl) return;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
// The full Share popover remains available when clipboard permission is
|
|
426
|
-
// unavailable, so a denied clipboard write does not block the page.
|
|
427
|
-
}
|
|
444
|
+
// The full Share popover remains available when clipboard permission is
|
|
445
|
+
// unavailable, so a denied clipboard write does not block the page.
|
|
446
|
+
if (!(await writeClipboardText(pendingShareUrl))) return;
|
|
447
|
+
setPendingLinkCopied(true);
|
|
448
|
+
window.setTimeout(() => setPendingLinkCopied(false), 1400);
|
|
428
449
|
}, [pendingShareUrl]);
|
|
429
450
|
useEffect(() => {
|
|
430
451
|
if (!recording?.id) return;
|
|
@@ -1336,6 +1357,16 @@ export default function RecordingPage() {
|
|
|
1336
1357
|
) : null}
|
|
1337
1358
|
</div>
|
|
1338
1359
|
|
|
1360
|
+
{!editing ? (
|
|
1361
|
+
<RecordingViewsBadge
|
|
1362
|
+
recordingId={recording.id}
|
|
1363
|
+
viewCount={playerDataQ.data?.viewCount ?? 0}
|
|
1364
|
+
canViewDetails={canEdit}
|
|
1365
|
+
onOpenInsights={openInsightsPanel}
|
|
1366
|
+
className="shrink-0"
|
|
1367
|
+
/>
|
|
1368
|
+
) : null}
|
|
1369
|
+
|
|
1339
1370
|
{canUseNativeEditor ? (
|
|
1340
1371
|
<Button
|
|
1341
1372
|
variant={editing ? "secondary" : "outline"}
|
|
@@ -46,6 +46,10 @@ import {
|
|
|
46
46
|
createBrowserDiagnosticsCapture,
|
|
47
47
|
type BrowserDiagnosticsCapture,
|
|
48
48
|
} from "@/lib/browser-diagnostics-capture";
|
|
49
|
+
import {
|
|
50
|
+
getCaptureHostApp,
|
|
51
|
+
macPermissionGuidanceFor,
|
|
52
|
+
} from "@/lib/capture-permissions";
|
|
49
53
|
import {
|
|
50
54
|
COMPRESS_THRESHOLD_BYTES,
|
|
51
55
|
COMPRESSION_ENABLED,
|
|
@@ -61,6 +65,7 @@ import {
|
|
|
61
65
|
loadRecorderPreferences,
|
|
62
66
|
saveRecorderPreferences,
|
|
63
67
|
} from "@/lib/recorder-preferences";
|
|
68
|
+
import { copyRecordingShareLink } from "@/lib/recording-link";
|
|
64
69
|
import {
|
|
65
70
|
buildCaptureTitle,
|
|
66
71
|
defaultRecordingTitle,
|
|
@@ -87,19 +92,6 @@ async function writeAppState(key: string, value: unknown): Promise<void> {
|
|
|
87
92
|
);
|
|
88
93
|
}
|
|
89
94
|
|
|
90
|
-
function recordingLink(recordingId: string): string {
|
|
91
|
-
const path = `${appBasePath()}/r/${encodeURIComponent(recordingId)}`;
|
|
92
|
-
if (typeof window === "undefined") return path;
|
|
93
|
-
return new URL(path, window.location.origin).toString();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async function copyRecordingLink(recordingId: string): Promise<void> {
|
|
97
|
-
if (typeof navigator === "undefined") return;
|
|
98
|
-
if (!navigator.clipboard?.writeText) return;
|
|
99
|
-
await navigator.clipboard
|
|
100
|
-
.writeText(recordingLink(recordingId))
|
|
101
|
-
.catch(() => undefined);
|
|
102
|
-
}
|
|
103
95
|
import {
|
|
104
96
|
bugReportTitle,
|
|
105
97
|
parseBugReportContext,
|
|
@@ -368,27 +360,30 @@ function permissionGuidance(
|
|
|
368
360
|
return "Browser site permissions are not the blocker here. Open Clips directly in a browser tab, or use an app frame that delegates the selected capture sources.";
|
|
369
361
|
}
|
|
370
362
|
if (isScreenPermissionError(message)) {
|
|
371
|
-
|
|
363
|
+
// The desktop shell hosts the recorder in its own webview, so "open it in a
|
|
364
|
+
// real tab" is not advice a desktop user can act on.
|
|
365
|
+
if (isEmbeddedWindow() && getCaptureHostApp().kind !== "desktop") {
|
|
372
366
|
return "The web client is running Clips inside a frame. Open the recorder in its own tab, then start recording; Chrome can block screen sharing in embedded pages even when macOS access is enabled.";
|
|
373
367
|
}
|
|
374
368
|
if (isMacPlatform()) {
|
|
375
|
-
return
|
|
369
|
+
return `Camera and Microphone can be allowed while macOS still blocks screen capture. ${macPermissionGuidanceFor("screen")}`;
|
|
376
370
|
}
|
|
377
371
|
return "Choose a source in the browser screen picker. If it still fails, check this site's browser permissions and reload Clips.";
|
|
378
372
|
}
|
|
379
373
|
if (isCameraPermissionError(message)) {
|
|
380
374
|
if (isMacPlatform()) {
|
|
381
|
-
return
|
|
375
|
+
return `Allow Camera for this site first. ${macPermissionGuidanceFor("camera")}`;
|
|
382
376
|
}
|
|
383
377
|
return "Open this site's browser settings, allow Camera, then reload Clips.";
|
|
384
378
|
}
|
|
385
379
|
if (isMicrophonePermissionError(message)) {
|
|
386
380
|
if (isMacPlatform()) {
|
|
387
|
-
return
|
|
381
|
+
return `Allow Microphone for this site first. ${macPermissionGuidanceFor("microphone")}`;
|
|
388
382
|
}
|
|
389
383
|
return "Open this site's browser settings, allow Microphone, then reload Clips.";
|
|
390
384
|
}
|
|
391
385
|
if (isMacPlatform()) {
|
|
386
|
+
const host = getCaptureHostApp();
|
|
392
387
|
const labels = getModePermissionLabels(opts?.mode, opts?.micDeviceId);
|
|
393
388
|
if (labels.length > 0) {
|
|
394
389
|
const readable = labels
|
|
@@ -400,9 +395,9 @@ function permissionGuidance(
|
|
|
400
395
|
: "Microphone",
|
|
401
396
|
)
|
|
402
397
|
.join(", ");
|
|
403
|
-
return `Check this site's
|
|
398
|
+
return `Check this site's permissions first. If it still fails, turn on ${host.name} under ${readable} in macOS System Settings > Privacy & Security, then quit and reopen it. Clips is never listed there — macOS grants access to ${host.name}.`;
|
|
404
399
|
}
|
|
405
|
-
return
|
|
400
|
+
return `Check this site's permissions first. If it still fails, turn on ${host.name} in macOS System Settings > Privacy & Security, then quit and reopen it.`;
|
|
406
401
|
}
|
|
407
402
|
return "Open this site's browser settings and allow the selected capture sources, then reload this page.";
|
|
408
403
|
}
|
|
@@ -511,7 +506,7 @@ function friendlyRecordingErrorMessage(error: string): string {
|
|
|
511
506
|
}
|
|
512
507
|
if (isScreenPermissionError(error)) {
|
|
513
508
|
if (isMacPlatform()) {
|
|
514
|
-
return
|
|
509
|
+
return `Clips could not start screen capture. macOS is blocking screen recording for ${getCaptureHostApp().name}.`;
|
|
515
510
|
}
|
|
516
511
|
return "Clips could not start screen capture. Allow screen sharing for this site, then try again.";
|
|
517
512
|
}
|
|
@@ -629,7 +624,10 @@ function RecordingErrorCard({
|
|
|
629
624
|
const permissionError = !uploadFailure && isPermissionError(error);
|
|
630
625
|
const policyError = !uploadFailure && isPolicyPermissionError(error);
|
|
631
626
|
const embeddedScreenError =
|
|
632
|
-
!uploadFailure &&
|
|
627
|
+
!uploadFailure &&
|
|
628
|
+
isEmbeddedWindow() &&
|
|
629
|
+
getCaptureHostApp().kind !== "desktop" &&
|
|
630
|
+
isScreenPermissionError(error);
|
|
633
631
|
const settings = permissionError
|
|
634
632
|
? getModePermissionLabels(mode, micDeviceId)
|
|
635
633
|
: [];
|
|
@@ -766,6 +764,27 @@ export default function RecordRoute() {
|
|
|
766
764
|
const t = useT();
|
|
767
765
|
const navigate = useNavigate();
|
|
768
766
|
const location = useLocation();
|
|
767
|
+
// A clipboard write can be refused (insecure origin, unfocused document, no
|
|
768
|
+
// transient activation). Never let the success toast imply the link was
|
|
769
|
+
// copied when it wasn't — offer a click instead, which restores the user
|
|
770
|
+
// gesture the browser is asking for.
|
|
771
|
+
const showSavedToast = useCallback(
|
|
772
|
+
(message: string, copied: boolean, recordingId: string) => {
|
|
773
|
+
if (copied) {
|
|
774
|
+
toast.success(message, { description: t("recordRoute.linkCopied") });
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
toast.success(message, {
|
|
778
|
+
action: {
|
|
779
|
+
label: t("recordRoute.copyLinkAction"),
|
|
780
|
+
onClick: () => {
|
|
781
|
+
void copyRecordingShareLink(recordingId);
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
});
|
|
785
|
+
},
|
|
786
|
+
[t],
|
|
787
|
+
);
|
|
769
788
|
const [uiState, setUiState] = useState<UiState>("idle");
|
|
770
789
|
const [error, setError] = useState<string | null>(null);
|
|
771
790
|
const [isPaused, setIsPaused] = useState(false);
|
|
@@ -1723,8 +1742,13 @@ export default function RecordRoute() {
|
|
|
1723
1742
|
description: t("recordRoute.connectStorageToFinish"),
|
|
1724
1743
|
duration: 12_000,
|
|
1725
1744
|
});
|
|
1745
|
+
} else if (createdId && !reportContext) {
|
|
1746
|
+
showSavedToast(
|
|
1747
|
+
t("recordRoute.videoUploaded"),
|
|
1748
|
+
await copyRecordingShareLink(createdId),
|
|
1749
|
+
createdId,
|
|
1750
|
+
);
|
|
1726
1751
|
} else {
|
|
1727
|
-
if (createdId && !reportContext) await copyRecordingLink(createdId);
|
|
1728
1752
|
toast.success(t("recordRoute.videoUploaded"));
|
|
1729
1753
|
}
|
|
1730
1754
|
if (reportContext && createdId) {
|
|
@@ -1789,7 +1813,7 @@ export default function RecordRoute() {
|
|
|
1789
1813
|
setUploadProgress(null);
|
|
1790
1814
|
}
|
|
1791
1815
|
},
|
|
1792
|
-
[markStorageConfigured, navigate, probeVideoMetadata],
|
|
1816
|
+
[markStorageConfigured, navigate, probeVideoMetadata, showSavedToast],
|
|
1793
1817
|
);
|
|
1794
1818
|
|
|
1795
1819
|
const importLoom = useCallback(
|
|
@@ -1827,8 +1851,11 @@ export default function RecordRoute() {
|
|
|
1827
1851
|
duration: 12_000,
|
|
1828
1852
|
});
|
|
1829
1853
|
} else {
|
|
1830
|
-
|
|
1831
|
-
|
|
1854
|
+
showSavedToast(
|
|
1855
|
+
t("recordRoute.loomImported"),
|
|
1856
|
+
await copyRecordingShareLink(recordingId),
|
|
1857
|
+
recordingId,
|
|
1858
|
+
);
|
|
1832
1859
|
}
|
|
1833
1860
|
await writeAppState("navigate", {
|
|
1834
1861
|
view: "recording",
|
|
@@ -1845,7 +1872,7 @@ export default function RecordRoute() {
|
|
|
1845
1872
|
setLoomImporting(false);
|
|
1846
1873
|
}
|
|
1847
1874
|
},
|
|
1848
|
-
[folderIdFromUrl, navigate, spaceIdFromUrl],
|
|
1875
|
+
[folderIdFromUrl, navigate, spaceIdFromUrl, showSavedToast],
|
|
1849
1876
|
);
|
|
1850
1877
|
|
|
1851
1878
|
const saveBrowserDiagnostics = useCallback(
|
|
@@ -1944,7 +1971,14 @@ export default function RecordRoute() {
|
|
|
1944
1971
|
// Stop / upload / navigate.
|
|
1945
1972
|
// -------------------------------------------------------------------------
|
|
1946
1973
|
const finishSavedRecording = useCallback(
|
|
1947
|
-
async (
|
|
1974
|
+
async (
|
|
1975
|
+
recordingId: string,
|
|
1976
|
+
result: RecorderFinalizeResult,
|
|
1977
|
+
// Started by the caller the moment the recording became durable, so the
|
|
1978
|
+
// clipboard write happens closer to the user's stop gesture than to the
|
|
1979
|
+
// end of the post-save bookkeeping.
|
|
1980
|
+
pendingCopy?: Promise<boolean>,
|
|
1981
|
+
) => {
|
|
1948
1982
|
// Recording is fully saved — clear refs so that if anything below throws
|
|
1949
1983
|
// and the user clicks "Try again", doCancel() won't trash a good recording.
|
|
1950
1984
|
pendingRef.current = null;
|
|
@@ -1960,9 +1994,14 @@ export default function RecordRoute() {
|
|
|
1960
1994
|
description: t("recordRoute.connectStorageToFinish"),
|
|
1961
1995
|
duration: 12_000,
|
|
1962
1996
|
});
|
|
1963
|
-
} else {
|
|
1964
|
-
if (!reportContext) await copyRecordingLink(recordingId);
|
|
1997
|
+
} else if (reportContext) {
|
|
1965
1998
|
toast.success(t("recordRoute.recordingSaved"));
|
|
1999
|
+
} else {
|
|
2000
|
+
showSavedToast(
|
|
2001
|
+
t("recordRoute.recordingSaved"),
|
|
2002
|
+
await (pendingCopy ?? copyRecordingShareLink(recordingId)),
|
|
2003
|
+
recordingId,
|
|
2004
|
+
);
|
|
1966
2005
|
}
|
|
1967
2006
|
|
|
1968
2007
|
if (reportContext) {
|
|
@@ -1986,7 +2025,7 @@ export default function RecordRoute() {
|
|
|
1986
2025
|
navigate(`/r/${recordingId}`);
|
|
1987
2026
|
}, 50);
|
|
1988
2027
|
},
|
|
1989
|
-
[navigate],
|
|
2028
|
+
[navigate, showSavedToast],
|
|
1990
2029
|
);
|
|
1991
2030
|
|
|
1992
2031
|
const doStop = useCallback(async () => {
|
|
@@ -2056,8 +2095,15 @@ export default function RecordRoute() {
|
|
|
2056
2095
|
}
|
|
2057
2096
|
|
|
2058
2097
|
const stopResult = await engine.stop();
|
|
2098
|
+
// The recording is durable here; saveBrowserDiagnostics is one more
|
|
2099
|
+
// round trip. Start the clipboard write first so it isn't pushed even
|
|
2100
|
+
// further from the stop gesture that authorized it.
|
|
2101
|
+
const pendingCopy =
|
|
2102
|
+
stopResult.waitingForStorage || bugReportContextRef.current
|
|
2103
|
+
? undefined
|
|
2104
|
+
: copyRecordingShareLink(pending.id).catch(() => false);
|
|
2059
2105
|
await saveBrowserDiagnostics(pending.id);
|
|
2060
|
-
await finishSavedRecording(pending.id, stopResult);
|
|
2106
|
+
await finishSavedRecording(pending.id, stopResult, pendingCopy);
|
|
2061
2107
|
} catch (err) {
|
|
2062
2108
|
const message =
|
|
2063
2109
|
err instanceof Error ? err.message : t("recordRoute.uploadFailed");
|