@agent-native/core 0.79.17 → 0.79.18
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 +8 -0
- package/corpus/core/docs/content/file-uploads.md +11 -4
- package/corpus/core/docs/content/locales/ar-SA/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/de-DE/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/es-ES/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/fr-FR/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/hi-IN/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/ja-JP/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/ko-KR/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/pt-BR/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/zh-CN/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/locales/zh-TW/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/multi-app-workspace.md +3 -3
- package/corpus/core/docs/content/template-clips.md +14 -5
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/engine/builder-engine.ts +8 -3
- package/corpus/core/src/cli/mcp.ts +11 -6
- package/corpus/core/src/client/AssistantChat.tsx +6 -2
- package/corpus/core/src/client/chat/markdown-renderer.tsx +1 -0
- package/corpus/core/src/client/index.ts +7 -1
- package/corpus/core/src/client/org/OrgSwitcher.tsx +5 -5
- package/corpus/core/src/client/org/TeamPage.tsx +11 -3
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +216 -0
- package/corpus/core/src/client/settings/index.ts +5 -0
- package/corpus/core/src/file-upload/index.ts +1 -0
- package/corpus/core/src/file-upload/registry.ts +22 -6
- package/corpus/core/src/file-upload/types.ts +6 -1
- package/corpus/core/src/integrations/adapters/email.ts +26 -18
- package/corpus/core/src/integrations/adapters/slack.ts +8 -7
- package/corpus/core/src/integrations/adapters/telegram.ts +9 -11
- package/corpus/core/src/integrations/adapters/whatsapp.ts +12 -9
- package/corpus/core/src/integrations/plugin.ts +79 -13
- package/corpus/core/src/onboarding/default-steps.ts +6 -3
- package/corpus/core/src/onboarding/types.ts +1 -1
- package/corpus/core/src/org/handlers.ts +1 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +4 -7
- package/corpus/core/src/server/better-auth-instance.ts +19 -62
- package/corpus/core/src/server/core-routes-plugin.ts +93 -180
- package/corpus/core/src/server/create-server.ts +55 -116
- package/corpus/core/src/server/email-actions.ts +3 -6
- package/corpus/core/src/server/email.ts +52 -17
- package/corpus/core/src/server/index.ts +2 -1
- package/corpus/core/src/server/scoped-key-storage.ts +223 -0
- package/corpus/core/src/shared/agent-env.ts +3 -3
- package/corpus/core/src/sharing/actions/share-resource.ts +1 -1
- package/corpus/core/src/styles/agent-native.css +47 -3
- package/corpus/core/src/templates/workspace-root/AGENTS.md +3 -2
- package/corpus/core/src/templates/workspace-root/README.md +1 -1
- package/corpus/core/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
- package/corpus/core/src/terminal/pty-server.ts +3 -38
- package/corpus/core/src/triggers/dispatcher.ts +1 -2
- package/corpus/templates/.retired/issues/package.json +7 -0
- package/corpus/templates/.retired/meeting-notes/package.json +7 -0
- package/corpus/templates/.retired/recruiting/package.json +7 -0
- package/corpus/templates/.retired/scheduling/package.json +7 -0
- package/corpus/templates/.retired/voice/package.json +7 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +0 -17
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +7 -1
- package/corpus/templates/analytics/app/i18n-data.ts +71 -2
- package/corpus/templates/analytics/app/pages/Settings.tsx +120 -73
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -11
- package/corpus/templates/analytics/app/routes/catalog.tsx +33 -176
- package/corpus/templates/analytics/app/routes/team.tsx +3 -2
- package/corpus/templates/analytics/changelog/2026-06-26-dashboard-templates-are-tucked-into-settings-and-show-simple.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-26-the-sessions-page-shows-a-single-page-title-instead-of-repea.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +37 -28
- package/corpus/templates/assets/app/routes/settings.tsx +65 -43
- package/corpus/templates/assets/app/routes/team.tsx +2 -10
- package/corpus/templates/brain/app/routes/settings.tsx +390 -358
- package/corpus/templates/brain/app/routes/team.tsx +2 -8
- package/corpus/templates/calendar/actions/db-connect.ts +5 -29
- package/corpus/templates/calendar/app/components/CloudUpgrade.tsx +8 -51
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +2 -1
- package/corpus/templates/calendar/app/components/calendar/GoogleSetupWizard.tsx +4 -2
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/calendar/app/pages/Settings.tsx +304 -271
- package/corpus/templates/calendar/app/routes/_app.team.tsx +2 -17
- package/corpus/templates/calendar/server/handlers/google-auth.ts +22 -9
- package/corpus/templates/calendar/server/lib/booking-emails.ts +1 -1
- package/corpus/templates/calendar/server/lib/event-guest-notifications.ts +1 -1
- package/corpus/templates/calendar/server/lib/google-calendar.ts +48 -28
- package/corpus/templates/chat/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +4 -2
- package/corpus/templates/chat/app/routes/settings.tsx +54 -54
- package/corpus/templates/chat/app/routes/team.tsx +2 -10
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +7 -2
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +7 -0
- package/corpus/templates/clips/AGENTS.md +8 -0
- package/corpus/templates/clips/actions/invite-member.ts +1 -1
- package/corpus/templates/clips/actions/request-transcript.ts +1 -1
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +629 -643
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +219 -155
- package/corpus/templates/clips/changelog/2026-06-26-long-desktop-recordings-are-checkpointed-so-macos-finalizati.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-non-mac-desktop-recordings-wait-for-upload-transcription.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-s3-compatible-storage-keys-now-save-securely-from-clips-sett.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-shared-clip-links-guide-agents-through-processing-transcripts.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-26-the-clip-details-sidebar-now-collapses-into-a-slide-out-pane.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +55 -3
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +217 -5
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +176 -5
- package/corpus/templates/clips/server/lib/public-agent-context.ts +31 -0
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +60 -14
- package/corpus/templates/clips/server/lib/video-storage.ts +37 -9
- package/corpus/templates/clips/server/routes/api/agent-transcript.json.get.ts +5 -0
- package/corpus/templates/content/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +1 -0
- package/corpus/templates/content/app/routes/_app.settings.tsx +54 -55
- package/corpus/templates/content/app/routes/_app.team.tsx +2 -28
- package/corpus/templates/content/server/lib/notion.ts +43 -11
- package/corpus/templates/content/server/routes/api/notion/auth-url.get.ts +2 -2
- package/corpus/templates/content/server/routes/api/notion/status.get.ts +3 -3
- package/corpus/templates/design/app/routes/settings.tsx +60 -38
- package/corpus/templates/design/app/routes/team.tsx +2 -10
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +2 -2
- package/corpus/templates/dispatch/app/routes/settings.tsx +70 -55
- package/corpus/templates/dispatch/app/routes/team.tsx +5 -1
- package/corpus/templates/forms/actions/db-connect.ts +7 -36
- package/corpus/templates/forms/actions/navigate.ts +2 -2
- package/corpus/templates/forms/app/components/CloudUpgrade.tsx +8 -47
- package/corpus/templates/forms/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/forms/app/components/layout/Layout.tsx +42 -25
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -76
- package/corpus/templates/forms/app/global.css +9 -25
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +4 -4
- package/corpus/templates/forms/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +1 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/forms/app/lib/route-prewarm.ts +9 -8
- package/corpus/templates/forms/app/pages/AskPage.tsx +70 -0
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +74 -81
- package/corpus/templates/forms/app/root.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.ask.tsx +14 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +54 -54
- package/corpus/templates/forms/app/routes/_app.team.tsx +2 -9
- package/corpus/templates/forms/app/routes/_index.tsx +21 -130
- package/corpus/templates/forms/changelog/2026-06-26-ask-forms-opens-as-a-standard-app-tab-with-a-simpler-sidebar.md +6 -0
- package/corpus/templates/forms/changelog/2026-06-26-forms-are-shown-in-a-tighter-row-list-with-a-denser-sidebar.md +6 -0
- package/corpus/templates/forms/shared/navigation.ts +4 -2
- package/corpus/templates/macros/app/routes/settings.tsx +54 -54
- package/corpus/templates/macros/app/routes/team.tsx +2 -10
- package/corpus/templates/mail/actions/helpers.ts +2 -2
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +2 -1
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +5 -5
- package/corpus/templates/mail/app/routes/team.tsx +3 -2
- package/corpus/templates/mail/server/handlers/emails.ts +3 -2
- package/corpus/templates/mail/server/handlers/google-auth.ts +19 -12
- package/corpus/templates/mail/server/lib/automation-engine.ts +3 -2
- package/corpus/templates/mail/server/lib/email-state.ts +2 -3
- package/corpus/templates/mail/server/lib/google-auth.ts +28 -11
- package/corpus/templates/mail/server/lib/jobs.ts +3 -2
- package/corpus/templates/mail/server/onboarding.ts +9 -6
- package/corpus/templates/mail/server/routes/api/attachments.get.ts +3 -3
- package/corpus/templates/plan/actions/request-plan-access.ts +1 -1
- package/corpus/templates/plan/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +4 -2
- package/corpus/templates/plan/app/lib/route-prewarm.ts +0 -4
- package/corpus/templates/plan/app/routes/settings.tsx +75 -73
- package/corpus/templates/plan/app/routes/team.tsx +2 -8
- package/corpus/templates/plan/server/lib/comment-notifications.ts +1 -1
- package/corpus/templates/slides/actions/check-image-gen.ts +2 -1
- package/corpus/templates/slides/actions/db-connect.ts +7 -45
- package/corpus/templates/slides/actions/edit-image.ts +6 -3
- package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
- package/corpus/templates/slides/actions/generate-image.ts +2 -2
- package/corpus/templates/slides/actions/generate-slides-ai.ts +5 -3
- package/corpus/templates/slides/actions/image-gen-status.ts +4 -3
- package/corpus/templates/slides/actions/image-search.ts +6 -3
- package/corpus/templates/slides/actions/search-images.ts +6 -3
- package/corpus/templates/slides/app/components/CloudUpgrade.tsx +8 -51
- package/corpus/templates/slides/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/slides/app/routes/settings.tsx +54 -54
- package/corpus/templates/slides/app/routes/team.tsx +2 -12
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +9 -9
- package/corpus/templates/slides/server/handlers/image-gen.ts +5 -1
- package/corpus/templates/slides/server/handlers/image-providers/gemini.ts +9 -1
- package/corpus/templates/slides/server/handlers/image-providers/index.ts +18 -8
- package/corpus/templates/slides/server/handlers/image-providers/openai.ts +10 -4
- package/corpus/templates/slides/server/handlers/image-providers/types.ts +1 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +59 -34
- package/corpus/templates/slides/server/register-secrets.ts +60 -0
- package/corpus/templates/videos/actions/db-connect.ts +7 -45
- package/corpus/templates/videos/app/components/CloudUpgrade.tsx +8 -51
- package/corpus/templates/videos/app/components/Sidebar.tsx +1 -9
- package/corpus/templates/videos/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -3
- package/corpus/templates/videos/app/routes/settings.tsx +54 -54
- package/corpus/templates/videos/app/routes/team.tsx +2 -8
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +8 -3
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +3 -4
- package/dist/cli/mcp.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +6 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/client/chat/markdown-renderer.js +1 -0
- package/dist/client/chat/markdown-renderer.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +3 -3
- package/dist/client/org/OrgSwitcher.js +2 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts +6 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +2 -2
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts +27 -0
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -0
- package/dist/client/settings/SettingsTabsPage.js +108 -0
- package/dist/client/settings/SettingsTabsPage.js.map +1 -0
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/file-upload/index.d.ts +1 -1
- package/dist/file-upload/index.d.ts.map +1 -1
- package/dist/file-upload/index.js +1 -1
- package/dist/file-upload/index.js.map +1 -1
- package/dist/file-upload/registry.d.ts +1 -0
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +24 -6
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/file-upload/types.d.ts +6 -1
- package/dist/file-upload/types.d.ts.map +1 -1
- package/dist/file-upload/types.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts.map +1 -1
- package/dist/integrations/adapters/email.js +18 -18
- package/dist/integrations/adapters/email.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +8 -7
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +9 -9
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +10 -9
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +47 -13
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +2 -2
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +6 -5
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/types.d.ts +1 -1
- package/dist/onboarding/types.d.ts.map +1 -1
- package/dist/onboarding/types.js.map +1 -1
- package/dist/org/handlers.js +1 -1
- package/dist/org/handlers.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +4 -6
- 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/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +17 -56
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +67 -153
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +3 -9
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +37 -91
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/email-actions.d.ts +2 -3
- package/dist/server/email-actions.d.ts.map +1 -1
- package/dist/server/email-actions.js +3 -6
- package/dist/server/email-actions.js.map +1 -1
- package/dist/server/email.d.ts +3 -3
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +40 -19
- package/dist/server/email.js.map +1 -1
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/scoped-key-storage.d.ts +22 -0
- package/dist/server/scoped-key-storage.d.ts.map +1 -0
- package/dist/server/scoped-key-storage.js +152 -0
- package/dist/server/scoped-key-storage.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/agent-env.d.ts +3 -3
- package/dist/shared/agent-env.d.ts.map +1 -1
- package/dist/shared/agent-env.js +3 -3
- package/dist/shared/agent-env.js.map +1 -1
- package/dist/sharing/actions/share-resource.js +1 -1
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/styles/agent-native.css +47 -3
- package/dist/templates/workspace-root/AGENTS.md +3 -2
- package/dist/templates/workspace-root/README.md +1 -1
- package/dist/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +3 -36
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/triggers/dispatcher.js +1 -1
- package/dist/triggers/dispatcher.js.map +1 -1
- package/docs/content/file-uploads.md +11 -4
- package/docs/content/locales/ar-SA/multi-app-workspace.md +3 -3
- package/docs/content/locales/de-DE/multi-app-workspace.md +3 -3
- package/docs/content/locales/es-ES/multi-app-workspace.md +3 -3
- package/docs/content/locales/fr-FR/multi-app-workspace.md +3 -3
- package/docs/content/locales/hi-IN/multi-app-workspace.md +3 -3
- package/docs/content/locales/ja-JP/multi-app-workspace.md +3 -3
- package/docs/content/locales/ko-KR/multi-app-workspace.md +3 -3
- package/docs/content/locales/pt-BR/multi-app-workspace.md +3 -3
- package/docs/content/locales/zh-CN/multi-app-workspace.md +3 -3
- package/docs/content/locales/zh-TW/multi-app-workspace.md +3 -3
- package/docs/content/multi-app-workspace.md +3 -3
- package/docs/content/template-clips.md +14 -5
- package/package.json +1 -1
- package/src/templates/workspace-root/AGENTS.md +3 -2
- package/src/templates/workspace-root/README.md +1 -1
- package/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
- package/corpus/core/src/server/env-var-writes.ts +0 -16
- package/corpus/templates/analytics/app/pages/Team.tsx +0 -9
- package/corpus/templates/calendar/app/pages/Team.tsx +0 -12
- package/corpus/templates/mail/app/pages/Team.tsx +0 -17
- package/dist/server/env-var-writes.d.ts +0 -10
- package/dist/server/env-var-writes.d.ts.map +0 -1
- package/dist/server/env-var-writes.js +0 -18
- package/dist/server/env-var-writes.js.map +0 -1
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
IconClipboardCopy,
|
|
25
25
|
IconFileText,
|
|
26
26
|
IconSparkles,
|
|
27
|
+
IconLayoutSidebarRightExpand,
|
|
27
28
|
} from "@tabler/icons-react";
|
|
28
29
|
import { useQuery } from "@tanstack/react-query";
|
|
29
30
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -54,6 +55,12 @@ import {
|
|
|
54
55
|
DropdownMenuSeparator,
|
|
55
56
|
DropdownMenuTrigger,
|
|
56
57
|
} from "@/components/ui/dropdown-menu";
|
|
58
|
+
import {
|
|
59
|
+
Sheet,
|
|
60
|
+
SheetContent,
|
|
61
|
+
SheetDescription,
|
|
62
|
+
SheetTitle,
|
|
63
|
+
} from "@/components/ui/sheet";
|
|
57
64
|
import { Spinner } from "@/components/ui/spinner";
|
|
58
65
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|
59
66
|
import {
|
|
@@ -100,6 +107,20 @@ interface GeneratedWorkflowState {
|
|
|
100
107
|
error?: string;
|
|
101
108
|
}
|
|
102
109
|
|
|
110
|
+
function useIsCompactRecordingLayout() {
|
|
111
|
+
const [isCompact, setIsCompact] = useState(false);
|
|
112
|
+
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const query = window.matchMedia("(max-width: 1279px)");
|
|
115
|
+
const update = () => setIsCompact(query.matches);
|
|
116
|
+
update();
|
|
117
|
+
query.addEventListener("change", update);
|
|
118
|
+
return () => query.removeEventListener("change", update);
|
|
119
|
+
}, []);
|
|
120
|
+
|
|
121
|
+
return isCompact;
|
|
122
|
+
}
|
|
123
|
+
|
|
103
124
|
function isNativeSaveFailureReason(reason: string | null | undefined): boolean {
|
|
104
125
|
return /native recording upload|native fullscreen|screencapture|avconvert/i.test(
|
|
105
126
|
reason ?? "",
|
|
@@ -129,6 +150,7 @@ function nativeSaveFailureMessage(reason: string | null | undefined): string {
|
|
|
129
150
|
|
|
130
151
|
function InsightsUnavailableState() {
|
|
131
152
|
const t = useT();
|
|
153
|
+
|
|
132
154
|
return (
|
|
133
155
|
<div className="flex h-full flex-col items-center justify-center px-8 py-12 text-center">
|
|
134
156
|
<p className="text-sm font-medium text-foreground">
|
|
@@ -179,9 +201,11 @@ export default function RecordingPage() {
|
|
|
179
201
|
const playerRef = useRef<VideoPlayerHandle | null>(null);
|
|
180
202
|
|
|
181
203
|
const [panel, setPanel] = useState<SidePanel>("agent");
|
|
204
|
+
const [sidePanelOpen, setSidePanelOpen] = useState(false);
|
|
182
205
|
const [theaterMode, setTheaterMode] = useState(false);
|
|
183
206
|
const [editing, setEditing] = useState(false);
|
|
184
207
|
const [currentMs, setCurrentMs] = useState(0);
|
|
208
|
+
const isCompactLayout = useIsCompactRecordingLayout();
|
|
185
209
|
const transcriptKickedRef = useRef<string | null>(null);
|
|
186
210
|
// When the recording lands in the processing state but never flips to
|
|
187
211
|
// 'ready', stop spinning forever and surface an error banner so the user
|
|
@@ -413,6 +437,10 @@ export default function RecordingPage() {
|
|
|
413
437
|
if (!canUseNativeEditor && editing) setEditing(false);
|
|
414
438
|
}, [canUseNativeEditor, editing]);
|
|
415
439
|
|
|
440
|
+
useEffect(() => {
|
|
441
|
+
if (editing || !isCompactLayout) setSidePanelOpen(false);
|
|
442
|
+
}, [editing, isCompactLayout]);
|
|
443
|
+
|
|
416
444
|
useEffect(() => {
|
|
417
445
|
if (!recording) return;
|
|
418
446
|
document.title = isDefaultTitle(recording.title)
|
|
@@ -647,6 +675,158 @@ export default function RecordingPage() {
|
|
|
647
675
|
);
|
|
648
676
|
}
|
|
649
677
|
|
|
678
|
+
const renderSidePanel = (compact = false) => (
|
|
679
|
+
<Tabs
|
|
680
|
+
value={panel}
|
|
681
|
+
onValueChange={(v) => setPanel(v as SidePanel)}
|
|
682
|
+
className={cn("flex h-full flex-col", compact && "pt-8")}
|
|
683
|
+
>
|
|
684
|
+
<TabsList
|
|
685
|
+
className={cn(
|
|
686
|
+
"mx-3 mt-3 grid w-auto",
|
|
687
|
+
canEdit ? "grid-cols-5" : "grid-cols-4",
|
|
688
|
+
)}
|
|
689
|
+
>
|
|
690
|
+
<TabsTrigger value="agent" className="min-w-0 px-2 text-xs">
|
|
691
|
+
{t("recordingPage.agent")}
|
|
692
|
+
</TabsTrigger>
|
|
693
|
+
<TabsTrigger value="comments" className="min-w-0 px-2 text-xs">
|
|
694
|
+
{t("recordingPage.activity")}
|
|
695
|
+
</TabsTrigger>
|
|
696
|
+
<TabsTrigger value="transcript" className="min-w-0 px-2 text-xs">
|
|
697
|
+
{t("recordingPage.transcript")}
|
|
698
|
+
</TabsTrigger>
|
|
699
|
+
<TabsTrigger value="insights" className="min-w-0 px-2 text-xs">
|
|
700
|
+
{t("recordingPage.insights")}
|
|
701
|
+
</TabsTrigger>
|
|
702
|
+
{canEdit ? (
|
|
703
|
+
<TabsTrigger value="settings" className="min-w-0 px-2 text-xs">
|
|
704
|
+
{t("recordingPage.settings")}
|
|
705
|
+
</TabsTrigger>
|
|
706
|
+
) : null}
|
|
707
|
+
</TabsList>
|
|
708
|
+
|
|
709
|
+
<TabsContent
|
|
710
|
+
value="agent"
|
|
711
|
+
className="mt-0 flex flex-1 min-h-0 flex-col data-[state=inactive]:hidden"
|
|
712
|
+
>
|
|
713
|
+
<AgentPanel
|
|
714
|
+
browserTabId={getBrowserTabId()}
|
|
715
|
+
emptyStateText={t("recordingPage.askAboutClip")}
|
|
716
|
+
dynamicSuggestions={false}
|
|
717
|
+
chatNotice={
|
|
718
|
+
generatedWorkflow ? (
|
|
719
|
+
<GeneratedWorkflowNotice workflow={generatedWorkflow} />
|
|
720
|
+
) : null
|
|
721
|
+
}
|
|
722
|
+
suggestions={
|
|
723
|
+
canEdit
|
|
724
|
+
? [
|
|
725
|
+
t("recordingPage.summarizeClip"),
|
|
726
|
+
t("recordingPage.generateChapters"),
|
|
727
|
+
t("recordingPage.findActionItems"),
|
|
728
|
+
t("recordingPage.draftRecap"),
|
|
729
|
+
]
|
|
730
|
+
: [
|
|
731
|
+
t("recordingPage.summarizeClip"),
|
|
732
|
+
t("recordingPage.findKeyMoments"),
|
|
733
|
+
t("recordingPage.listFollowUpActions"),
|
|
734
|
+
t("recordingPage.draftQuestions"),
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
/>
|
|
738
|
+
</TabsContent>
|
|
739
|
+
<TabsContent
|
|
740
|
+
value="transcript"
|
|
741
|
+
className="flex-1 min-h-0 mt-3 data-[state=inactive]:hidden"
|
|
742
|
+
>
|
|
743
|
+
<TranscriptPanel
|
|
744
|
+
segments={transcriptSegments}
|
|
745
|
+
fullText={transcriptFullText}
|
|
746
|
+
durationMs={recording.durationMs}
|
|
747
|
+
currentMs={currentMs}
|
|
748
|
+
onSeek={(ms) => playerRef.current?.seek(ms)}
|
|
749
|
+
status={transcriptStatus}
|
|
750
|
+
failureReason={transcriptFailureReason}
|
|
751
|
+
cleanup={transcriptCleanup}
|
|
752
|
+
recordingTitle={recording.title}
|
|
753
|
+
onRetry={() => {
|
|
754
|
+
// Force a fresh transcript job, then let polling swap the panel
|
|
755
|
+
// back to the pending state while it runs.
|
|
756
|
+
fetch(
|
|
757
|
+
agentNativePath("/_agent-native/actions/request-transcript"),
|
|
758
|
+
{
|
|
759
|
+
method: "POST",
|
|
760
|
+
headers: { "Content-Type": "application/json" },
|
|
761
|
+
body: JSON.stringify({
|
|
762
|
+
recordingId: recording.id,
|
|
763
|
+
force: true,
|
|
764
|
+
}),
|
|
765
|
+
},
|
|
766
|
+
)
|
|
767
|
+
.then((res) => {
|
|
768
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
769
|
+
})
|
|
770
|
+
.catch((err) =>
|
|
771
|
+
toast.error(
|
|
772
|
+
t("recordingPage.retryFailed", {
|
|
773
|
+
message: err?.message ?? t("recordingPage.networkError"),
|
|
774
|
+
}),
|
|
775
|
+
),
|
|
776
|
+
)
|
|
777
|
+
.finally(() => playerDataQ.refetch());
|
|
778
|
+
}}
|
|
779
|
+
/>
|
|
780
|
+
</TabsContent>
|
|
781
|
+
<TabsContent
|
|
782
|
+
value="comments"
|
|
783
|
+
className="flex-1 min-h-0 mt-3 data-[state=inactive]:hidden"
|
|
784
|
+
>
|
|
785
|
+
<CommentsPanel
|
|
786
|
+
recordingId={recording.id}
|
|
787
|
+
comments={comments}
|
|
788
|
+
currentMs={currentMs}
|
|
789
|
+
currentUserEmail={session?.email}
|
|
790
|
+
enableComments={recording.enableComments}
|
|
791
|
+
onSeek={(ms) => playerRef.current?.seek(ms)}
|
|
792
|
+
queryKey={[
|
|
793
|
+
"action",
|
|
794
|
+
"get-recording-player-data",
|
|
795
|
+
{ recordingId: recordingId ?? "" },
|
|
796
|
+
]}
|
|
797
|
+
/>
|
|
798
|
+
</TabsContent>
|
|
799
|
+
<TabsContent
|
|
800
|
+
value="insights"
|
|
801
|
+
className="flex-1 min-h-0 mt-3 overflow-y-auto data-[state=inactive]:hidden"
|
|
802
|
+
>
|
|
803
|
+
{canEdit ? (
|
|
804
|
+
<InsightsPanel
|
|
805
|
+
recordingId={recording.id}
|
|
806
|
+
durationMs={recording.durationMs}
|
|
807
|
+
/>
|
|
808
|
+
) : (
|
|
809
|
+
<InsightsUnavailableState />
|
|
810
|
+
)}
|
|
811
|
+
</TabsContent>
|
|
812
|
+
{canEdit ? (
|
|
813
|
+
<TabsContent
|
|
814
|
+
value="settings"
|
|
815
|
+
className="mt-3 flex flex-1 min-h-0 flex-col data-[state=inactive]:hidden"
|
|
816
|
+
>
|
|
817
|
+
<SettingsPanel
|
|
818
|
+
recording={recording}
|
|
819
|
+
visibility={recording.visibility}
|
|
820
|
+
ctas={ctas}
|
|
821
|
+
onClose={() => setPanel("agent")}
|
|
822
|
+
onRefetch={() => playerDataQ.refetch()}
|
|
823
|
+
showHeader={false}
|
|
824
|
+
/>
|
|
825
|
+
</TabsContent>
|
|
826
|
+
) : null}
|
|
827
|
+
</Tabs>
|
|
828
|
+
);
|
|
829
|
+
|
|
650
830
|
return (
|
|
651
831
|
<div className="flex h-screen w-full bg-background overflow-hidden">
|
|
652
832
|
{/* Main video column */}
|
|
@@ -797,6 +977,23 @@ export default function RecordingPage() {
|
|
|
797
977
|
</DropdownMenu>
|
|
798
978
|
) : null}
|
|
799
979
|
|
|
980
|
+
{!editing ? (
|
|
981
|
+
<Tooltip>
|
|
982
|
+
<TooltipTrigger asChild>
|
|
983
|
+
<Button
|
|
984
|
+
variant="outline"
|
|
985
|
+
size="icon"
|
|
986
|
+
className="xl:hidden"
|
|
987
|
+
onClick={() => setSidePanelOpen(true)}
|
|
988
|
+
aria-label={t("recordingPage.details")}
|
|
989
|
+
>
|
|
990
|
+
<IconLayoutSidebarRightExpand className="h-4 w-4" />
|
|
991
|
+
</Button>
|
|
992
|
+
</TooltipTrigger>
|
|
993
|
+
<TooltipContent>{t("recordingPage.details")}</TooltipContent>
|
|
994
|
+
</Tooltip>
|
|
995
|
+
) : null}
|
|
996
|
+
|
|
800
997
|
<ShareRecordingPopover
|
|
801
998
|
recordingId={recording.id}
|
|
802
999
|
recordingTitle={recording.title}
|
|
@@ -935,162 +1132,29 @@ export default function RecordingPage() {
|
|
|
935
1132
|
|
|
936
1133
|
{/* Side panel */}
|
|
937
1134
|
{!editing ? (
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
<TabsList
|
|
945
|
-
className={cn(
|
|
946
|
-
"mx-3 mt-3 grid w-auto",
|
|
947
|
-
canEdit ? "grid-cols-5" : "grid-cols-4",
|
|
948
|
-
)}
|
|
949
|
-
>
|
|
950
|
-
<TabsTrigger value="agent" className="min-w-0 px-2 text-xs">
|
|
951
|
-
{t("recordingPage.agent")}
|
|
952
|
-
</TabsTrigger>
|
|
953
|
-
<TabsTrigger value="comments" className="min-w-0 px-2 text-xs">
|
|
954
|
-
{t("recordingPage.activity")}
|
|
955
|
-
</TabsTrigger>
|
|
956
|
-
<TabsTrigger value="transcript" className="min-w-0 px-2 text-xs">
|
|
957
|
-
{t("recordingPage.transcript")}
|
|
958
|
-
</TabsTrigger>
|
|
959
|
-
<TabsTrigger value="insights" className="min-w-0 px-2 text-xs">
|
|
960
|
-
{t("recordingPage.insights")}
|
|
961
|
-
</TabsTrigger>
|
|
962
|
-
{canEdit ? (
|
|
963
|
-
<TabsTrigger value="settings" className="min-w-0 px-2 text-xs">
|
|
964
|
-
{t("recordingPage.settings")}
|
|
965
|
-
</TabsTrigger>
|
|
966
|
-
) : null}
|
|
967
|
-
</TabsList>
|
|
968
|
-
|
|
969
|
-
<TabsContent
|
|
970
|
-
value="agent"
|
|
971
|
-
className="mt-0 flex flex-1 min-h-0 flex-col data-[state=inactive]:hidden"
|
|
972
|
-
>
|
|
973
|
-
<AgentPanel
|
|
974
|
-
browserTabId={getBrowserTabId()}
|
|
975
|
-
emptyStateText={t("recordingPage.askAboutClip")}
|
|
976
|
-
dynamicSuggestions={false}
|
|
977
|
-
chatNotice={
|
|
978
|
-
generatedWorkflow ? (
|
|
979
|
-
<GeneratedWorkflowNotice workflow={generatedWorkflow} />
|
|
980
|
-
) : null
|
|
981
|
-
}
|
|
982
|
-
suggestions={
|
|
983
|
-
canEdit
|
|
984
|
-
? [
|
|
985
|
-
t("recordingPage.summarizeClip"),
|
|
986
|
-
t("recordingPage.generateChapters"),
|
|
987
|
-
t("recordingPage.findActionItems"),
|
|
988
|
-
t("recordingPage.draftRecap"),
|
|
989
|
-
]
|
|
990
|
-
: [
|
|
991
|
-
t("recordingPage.summarizeClip"),
|
|
992
|
-
t("recordingPage.findKeyMoments"),
|
|
993
|
-
t("recordingPage.listFollowUpActions"),
|
|
994
|
-
t("recordingPage.draftQuestions"),
|
|
995
|
-
]
|
|
996
|
-
}
|
|
997
|
-
/>
|
|
998
|
-
</TabsContent>
|
|
999
|
-
<TabsContent
|
|
1000
|
-
value="transcript"
|
|
1001
|
-
className="flex-1 min-h-0 mt-3 data-[state=inactive]:hidden"
|
|
1002
|
-
>
|
|
1003
|
-
<TranscriptPanel
|
|
1004
|
-
segments={transcriptSegments}
|
|
1005
|
-
fullText={transcriptFullText}
|
|
1006
|
-
durationMs={recording.durationMs}
|
|
1007
|
-
currentMs={currentMs}
|
|
1008
|
-
onSeek={(ms) => playerRef.current?.seek(ms)}
|
|
1009
|
-
status={transcriptStatus}
|
|
1010
|
-
failureReason={transcriptFailureReason}
|
|
1011
|
-
cleanup={transcriptCleanup}
|
|
1012
|
-
recordingTitle={recording.title}
|
|
1013
|
-
onRetry={() => {
|
|
1014
|
-
// Re-run transcription now that the user may have connected
|
|
1015
|
-
// Builder/Gemini or after a one-off network error. The action
|
|
1016
|
-
// flips the row to 'pending' first, so the UI swaps back to
|
|
1017
|
-
// "Transcribing…".
|
|
1018
|
-
fetch(
|
|
1019
|
-
agentNativePath(
|
|
1020
|
-
"/_agent-native/actions/request-transcript",
|
|
1021
|
-
),
|
|
1022
|
-
{
|
|
1023
|
-
method: "POST",
|
|
1024
|
-
headers: { "Content-Type": "application/json" },
|
|
1025
|
-
body: JSON.stringify({
|
|
1026
|
-
recordingId: recording.id,
|
|
1027
|
-
force: true,
|
|
1028
|
-
}),
|
|
1029
|
-
},
|
|
1030
|
-
)
|
|
1031
|
-
.then((res) => {
|
|
1032
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1033
|
-
})
|
|
1034
|
-
.catch((err) =>
|
|
1035
|
-
toast.error(
|
|
1036
|
-
t("recordingPage.retryFailed", {
|
|
1037
|
-
message:
|
|
1038
|
-
err?.message ?? t("recordingPage.networkError"),
|
|
1039
|
-
}),
|
|
1040
|
-
),
|
|
1041
|
-
)
|
|
1042
|
-
.finally(() => playerDataQ.refetch());
|
|
1043
|
-
}}
|
|
1044
|
-
/>
|
|
1045
|
-
</TabsContent>
|
|
1046
|
-
<TabsContent
|
|
1047
|
-
value="comments"
|
|
1048
|
-
className="flex-1 min-h-0 mt-3 data-[state=inactive]:hidden"
|
|
1049
|
-
>
|
|
1050
|
-
<CommentsPanel
|
|
1051
|
-
recordingId={recording.id}
|
|
1052
|
-
comments={comments}
|
|
1053
|
-
currentMs={currentMs}
|
|
1054
|
-
currentUserEmail={session?.email}
|
|
1055
|
-
enableComments={recording.enableComments}
|
|
1056
|
-
onSeek={(ms) => playerRef.current?.seek(ms)}
|
|
1057
|
-
queryKey={[
|
|
1058
|
-
"action",
|
|
1059
|
-
"get-recording-player-data",
|
|
1060
|
-
{ recordingId: recordingId ?? "" },
|
|
1061
|
-
]}
|
|
1062
|
-
/>
|
|
1063
|
-
</TabsContent>
|
|
1064
|
-
<TabsContent
|
|
1065
|
-
value="insights"
|
|
1066
|
-
className="flex-1 min-h-0 mt-3 overflow-y-auto data-[state=inactive]:hidden"
|
|
1067
|
-
>
|
|
1068
|
-
{canEdit ? (
|
|
1069
|
-
<InsightsPanel
|
|
1070
|
-
recordingId={recording.id}
|
|
1071
|
-
durationMs={recording.durationMs}
|
|
1072
|
-
/>
|
|
1073
|
-
) : (
|
|
1074
|
-
<InsightsUnavailableState />
|
|
1075
|
-
)}
|
|
1076
|
-
</TabsContent>
|
|
1077
|
-
{canEdit ? (
|
|
1078
|
-
<TabsContent
|
|
1079
|
-
value="settings"
|
|
1080
|
-
className="mt-3 flex flex-1 min-h-0 flex-col data-[state=inactive]:hidden"
|
|
1135
|
+
<>
|
|
1136
|
+
{isCompactLayout ? (
|
|
1137
|
+
<Sheet open={sidePanelOpen} onOpenChange={setSidePanelOpen}>
|
|
1138
|
+
<SheetContent
|
|
1139
|
+
side="right"
|
|
1140
|
+
className="flex h-full w-[calc(100vw-24px)] max-w-[420px] flex-col gap-0 p-0 sm:max-w-[420px]"
|
|
1081
1141
|
>
|
|
1082
|
-
<
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1142
|
+
<SheetTitle className="sr-only">
|
|
1143
|
+
{t("recordingPage.details")}
|
|
1144
|
+
</SheetTitle>
|
|
1145
|
+
<SheetDescription className="sr-only">
|
|
1146
|
+
{t("recordingPage.askAboutClip")}
|
|
1147
|
+
</SheetDescription>
|
|
1148
|
+
{renderSidePanel(true)}
|
|
1149
|
+
</SheetContent>
|
|
1150
|
+
</Sheet>
|
|
1151
|
+
) : null}
|
|
1152
|
+
{!isCompactLayout ? (
|
|
1153
|
+
<aside className="hidden w-[380px] shrink-0 flex-col border-s border-border bg-background xl:flex">
|
|
1154
|
+
{renderSidePanel()}
|
|
1155
|
+
</aside>
|
|
1156
|
+
) : null}
|
|
1157
|
+
</>
|
|
1094
1158
|
) : null}
|
|
1095
1159
|
</div>
|
|
1096
1160
|
);
|
|
@@ -86,6 +86,7 @@ const NATIVE_FULLSCREEN_RECORDING_FLAG = "clips:native-fullscreen-recording";
|
|
|
86
86
|
const DEV_SYNTHETIC_CAPTURE_FLAG = "clips:dev-synthetic-capture";
|
|
87
87
|
const LEGACY_DEV_REAL_CAPTURE_FLAG = "clips:dev-real-capture";
|
|
88
88
|
const LIVE_UPLOAD_CHUNK_MS = 1_000;
|
|
89
|
+
const NATIVE_FULLSCREEN_SEGMENT_MS = 5 * 60_000;
|
|
89
90
|
const CLOUD_CAPTURE_FRAME_RATE = 24;
|
|
90
91
|
const CLOUD_CAPTURE_MAX_WIDTH = 1920;
|
|
91
92
|
const CLOUD_CAPTURE_MAX_HEIGHT = 1080;
|
|
@@ -122,6 +123,13 @@ export function shouldUseNativeFullscreenRecording(
|
|
|
122
123
|
return isMacPlatform();
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
function shouldSaveLocalTranscriptionStartupFailure(): boolean {
|
|
127
|
+
// Local Whisper/SFSpeech capture is macOS-only today. Non-mac desktop builds
|
|
128
|
+
// should wait for upload transcription instead of publishing a misleading
|
|
129
|
+
// native-transcription failure before `request-transcript` runs.
|
|
130
|
+
return isMacPlatform();
|
|
131
|
+
}
|
|
132
|
+
|
|
125
133
|
function shouldUseDevSyntheticCapture(): boolean {
|
|
126
134
|
if (!import.meta.env.DEV) return false;
|
|
127
135
|
if (typeof localStorage === "undefined") return false;
|
|
@@ -962,7 +970,7 @@ async function saveRecordingTranscript(
|
|
|
962
970
|
recordingId,
|
|
963
971
|
fullText: text,
|
|
964
972
|
segments: transcript.segments,
|
|
965
|
-
source: "whisper",
|
|
973
|
+
source: transcript.source ?? "whisper",
|
|
966
974
|
}),
|
|
967
975
|
});
|
|
968
976
|
if (!res.ok) {
|
|
@@ -1753,6 +1761,8 @@ async function startNativeFullscreenRecording(
|
|
|
1753
1761
|
let cancelPromise: Promise<void> | null = null;
|
|
1754
1762
|
let stateUnlistens: UnlistenFn[] = [];
|
|
1755
1763
|
let tickHandle: ReturnType<typeof setInterval> | null = null;
|
|
1764
|
+
let segmentRotateHandle: ReturnType<typeof setInterval> | null = null;
|
|
1765
|
+
let segmentRotateInFlight = false;
|
|
1756
1766
|
// Pause/resume tracking. The Rust side actually stops the SCStream on
|
|
1757
1767
|
// pause and starts a new segment on resume; on stop it concatenates
|
|
1758
1768
|
// segments via AVFoundation. We keep the JS-side timer in sync so the
|
|
@@ -1760,6 +1770,37 @@ async function startNativeFullscreenRecording(
|
|
|
1760
1770
|
let pausedAt: number | null = null;
|
|
1761
1771
|
let accumulatedPauseMs = 0;
|
|
1762
1772
|
|
|
1773
|
+
function clearSegmentRotator() {
|
|
1774
|
+
if (segmentRotateHandle) {
|
|
1775
|
+
clearInterval(segmentRotateHandle);
|
|
1776
|
+
segmentRotateHandle = null;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
function startSegmentRotator() {
|
|
1781
|
+
clearSegmentRotator();
|
|
1782
|
+
segmentRotateHandle = setInterval(() => {
|
|
1783
|
+
if (stopped || pausedAt != null || segmentRotateInFlight) return;
|
|
1784
|
+
segmentRotateInFlight = true;
|
|
1785
|
+
invoke("native_fullscreen_recording_rotate_segment")
|
|
1786
|
+
.catch((err) => {
|
|
1787
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1788
|
+
console.warn("[clips-recorder] native segment rotation failed:", err);
|
|
1789
|
+
if (
|
|
1790
|
+
!stopped &&
|
|
1791
|
+
pausedAt == null &&
|
|
1792
|
+
message.includes("paused recording")
|
|
1793
|
+
) {
|
|
1794
|
+
pausedAt = Date.now();
|
|
1795
|
+
emitState();
|
|
1796
|
+
}
|
|
1797
|
+
})
|
|
1798
|
+
.finally(() => {
|
|
1799
|
+
segmentRotateInFlight = false;
|
|
1800
|
+
});
|
|
1801
|
+
}, NATIVE_FULLSCREEN_SEGMENT_MS);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1763
1804
|
function emitState() {
|
|
1764
1805
|
const now = Date.now();
|
|
1765
1806
|
const pausedNowMs = pausedAt != null ? now - pausedAt : 0;
|
|
@@ -1781,6 +1822,7 @@ async function startNativeFullscreenRecording(
|
|
|
1781
1822
|
stopped = true;
|
|
1782
1823
|
console.log("[clips-recorder] native full-screen stop requested");
|
|
1783
1824
|
if (!localOnly) showFinalizingFeedback();
|
|
1825
|
+
clearSegmentRotator();
|
|
1784
1826
|
if (tickHandle) {
|
|
1785
1827
|
clearInterval(tickHandle);
|
|
1786
1828
|
tickHandle = null;
|
|
@@ -1940,6 +1982,7 @@ async function startNativeFullscreenRecording(
|
|
|
1940
1982
|
if (stopped) return;
|
|
1941
1983
|
cancelPromise = (async () => {
|
|
1942
1984
|
stopped = true;
|
|
1985
|
+
clearSegmentRotator();
|
|
1943
1986
|
if (tickHandle) {
|
|
1944
1987
|
clearInterval(tickHandle);
|
|
1945
1988
|
tickHandle = null;
|
|
@@ -2020,6 +2063,7 @@ async function startNativeFullscreenRecording(
|
|
|
2020
2063
|
]);
|
|
2021
2064
|
stateUnlistens = toolbarUnlistens;
|
|
2022
2065
|
tickHandle = setInterval(emitState, 500);
|
|
2066
|
+
startSegmentRotator();
|
|
2023
2067
|
emit("clips:toolbar-enabled", true).catch(() => {});
|
|
2024
2068
|
emitState();
|
|
2025
2069
|
|
|
@@ -2041,7 +2085,11 @@ async function startNativeFullscreenRecording(
|
|
|
2041
2085
|
if (stopped && transcriptionCapture) {
|
|
2042
2086
|
void transcriptionCapture.cancel().catch(() => {});
|
|
2043
2087
|
transcriptionCapture = null;
|
|
2044
|
-
} else if (
|
|
2088
|
+
} else if (
|
|
2089
|
+
wantsAudio &&
|
|
2090
|
+
!transcriptionCapture &&
|
|
2091
|
+
shouldSaveLocalTranscriptionStartupFailure()
|
|
2092
|
+
) {
|
|
2045
2093
|
void saveTranscriptFailure(
|
|
2046
2094
|
"macOS Speech recognition could not start for this recording. Check Speech Recognition and Microphone permissions, then retry transcription.",
|
|
2047
2095
|
);
|
|
@@ -2863,7 +2911,11 @@ async function startRecordingInner(
|
|
|
2863
2911
|
if (stopped && transcriptionCapture) {
|
|
2864
2912
|
void transcriptionCapture.cancel().catch(() => {});
|
|
2865
2913
|
transcriptionCapture = null;
|
|
2866
|
-
} else if (
|
|
2914
|
+
} else if (
|
|
2915
|
+
wantsAudio &&
|
|
2916
|
+
!transcriptionCapture &&
|
|
2917
|
+
shouldSaveLocalTranscriptionStartupFailure()
|
|
2918
|
+
) {
|
|
2867
2919
|
void saveTranscriptFailure(
|
|
2868
2920
|
"macOS Speech recognition could not start for this recording. Check Speech Recognition and Microphone permissions, then retry transcription.",
|
|
2869
2921
|
);
|