@agent-native/core 0.121.2 → 0.122.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -12
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +148 -0
- package/corpus/core/docs/content/actions.mdx +2 -2
- package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +2 -0
- package/corpus/core/docs/content/deployment.mdx +36 -0
- package/corpus/core/docs/content/http-api.mdx +266 -0
- package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/a2a/activity.ts +38 -27
- package/corpus/core/src/a2a/client.ts +57 -4
- package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
- package/corpus/core/src/agent/run-manager.ts +20 -1
- package/corpus/core/src/agent/run-store.ts +4 -1
- package/corpus/core/src/agent/types.ts +28 -8
- package/corpus/core/src/chat-threads/store.ts +45 -0
- package/corpus/core/src/checkpoints/index.ts +2 -0
- package/corpus/core/src/checkpoints/route-match.ts +13 -0
- package/corpus/core/src/cli/create.ts +105 -17
- package/corpus/core/src/cli/index.ts +20 -0
- package/corpus/core/src/cli/template-baseline.ts +410 -0
- package/corpus/core/src/cli/template-sync.ts +1004 -0
- package/corpus/core/src/cli/templates-meta.ts +1 -0
- package/corpus/core/src/client/AssistantChat.tsx +38 -12
- package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/corpus/core/src/client/chat/message-components.tsx +127 -66
- package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
- package/corpus/core/src/client/error-format.ts +18 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
- package/corpus/core/src/client/org/TeamPage.tsx +7 -6
- package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
- package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/corpus/core/src/client/sse-event-processor.ts +3 -0
- package/corpus/core/src/data-widgets/index.ts +41 -0
- package/corpus/core/src/deploy/build.ts +11 -9
- package/corpus/core/src/extensions/url-safety.ts +67 -4
- package/corpus/core/src/integrations/webhook-handler.ts +63 -9
- package/corpus/core/src/org/auto-join-domain.ts +4 -3
- package/corpus/core/src/org/context.ts +108 -39
- package/corpus/core/src/org/index.ts +5 -0
- package/corpus/core/src/org/service-identity.ts +60 -0
- package/corpus/core/src/provider-api/index.ts +22 -1
- package/corpus/core/src/scripts/docs/search.ts +12 -1
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
- package/corpus/core/src/server/agents-bundle.ts +84 -5
- package/corpus/core/src/server/auth.ts +4 -3
- package/corpus/core/src/server/builder-browser.ts +47 -19
- package/corpus/core/src/server/core-routes-plugin.ts +2 -2
- package/corpus/core/src/server/credential-provider.ts +209 -68
- package/corpus/core/src/server/index.ts +3 -0
- package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
- package/corpus/core/src/server/prompts/framework-core.ts +9 -21
- package/corpus/core/src/server/prompts/index.ts +0 -1
- package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
- package/corpus/core/src/server/ssr-handler.ts +13 -2
- package/corpus/core/src/settings/user-settings.ts +13 -1
- package/corpus/core/src/shared/cache-control.ts +141 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/chat/_gitignore +1 -0
- package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/default/app/root.tsx +1 -1
- package/corpus/core/src/templates/default/public/manifest.json +2 -2
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
- package/corpus/core/src/vite/client.ts +69 -3
- package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
- package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/analytics/AGENTS.md +91 -563
- package/corpus/templates/analytics/_gitignore +1 -0
- package/corpus/templates/analytics/actions/bigquery.ts +12 -4
- package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
- package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/analytics/package.json +1 -1
- package/corpus/templates/analytics/public/manifest.json +1 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
- package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
- package/corpus/templates/analytics/server/lib/notion.ts +15 -4
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
- package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/assets/app/routes/_index.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/assets/server/plugins/auth.ts +1 -1
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/brain/_gitignore +1 -0
- package/corpus/templates/brain/app/lib/brain.ts +0 -7
- package/corpus/templates/brain/app/routes/_index.tsx +1 -2
- package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/brain/package.json +1 -1
- package/corpus/templates/brain/public/manifest.json +1 -1
- package/corpus/templates/brain/server/plugins/auth.ts +1 -1
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/calendar/_gitignore +1 -0
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
- package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/calendar/package.json +1 -1
- package/corpus/templates/calendar/public/manifest.json +1 -1
- package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/chat/_gitignore +1 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
- package/corpus/templates/clips/AGENTS.md +5 -4
- package/corpus/templates/clips/_gitignore +1 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
- package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
- package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
- package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
- package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
- package/corpus/templates/clips/actions/list-recordings.ts +69 -19
- package/corpus/templates/clips/actions/list-viewers.ts +5 -2
- package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
- package/corpus/templates/clips/actions/request-transcript.ts +28 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
- package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
- package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
- package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
- package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
- package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
- package/corpus/templates/clips/app/routes/_index.tsx +1 -1
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
- package/corpus/templates/clips/app/routes/record.tsx +82 -31
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
- package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
- package/corpus/templates/clips/desktop/package.json +2 -0
- package/corpus/templates/clips/desktop/src/app.tsx +89 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
- package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
- package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
- package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
- package/corpus/templates/clips/desktop/src/styles.css +127 -78
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
- package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
- package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
- package/corpus/templates/clips/server/db/schema.ts +27 -0
- package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
- package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
- package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
- package/corpus/templates/clips/server/lib/recordings.ts +51 -3
- package/corpus/templates/clips/server/plugins/auth.ts +1 -1
- package/corpus/templates/clips/server/plugins/db.ts +31 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
- package/corpus/templates/clips/shared/recording-link.ts +43 -0
- package/corpus/templates/clips/shared/share-attribution.ts +4 -0
- package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
- package/corpus/templates/clips/shared/view-analytics.ts +26 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/content/AGENTS.md +62 -583
- package/corpus/templates/content/_gitignore +1 -0
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
- package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
- package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/content/package.json +1 -1
- package/corpus/templates/content/public/manifest.json +1 -1
- package/corpus/templates/content/server/plugins/auth.ts +1 -1
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
- package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
- package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
- package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
- package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
- package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
- package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
- package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
- package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
- package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
- package/corpus/templates/design/AGENTS.md +88 -503
- package/corpus/templates/design/_gitignore +1 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/design/app/routes/_index.tsx +1 -1
- package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/design/server/plugins/auth.ts +1 -1
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/dispatch/_gitignore +1 -0
- package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
- package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/dispatch/package.json +1 -1
- package/corpus/templates/dispatch/public/manifest.json +1 -1
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/forms/_gitignore +1 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
- package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/forms/package.json +1 -1
- package/corpus/templates/forms/public/manifest.json +1 -1
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
- package/corpus/templates/forms/server/plugins/auth.ts +1 -1
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/macros/_gitignore +1 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
- package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/macros/package.json +1 -1
- package/corpus/templates/macros/server/plugins/auth.ts +2 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/mail/_gitignore +1 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
- package/corpus/templates/mail/app/routes/$view.tsx +1 -1
- package/corpus/templates/mail/app/routes/_index.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/mail/package.json +1 -1
- package/corpus/templates/mail/public/manifest.json +1 -1
- package/corpus/templates/mail/server/plugins/auth.ts +1 -1
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/plan/_gitignore +1 -0
- package/corpus/templates/plan/agent-native.app-skill.json +1 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
- package/corpus/templates/plan/app/lib/app-config.ts +1 -1
- package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/plan/package.json +1 -1
- package/corpus/templates/plan/public/manifest.json +1 -1
- package/corpus/templates/plan/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
- package/corpus/templates/slides/app/routes/_index.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/corpus/templates/slides/package.json +1 -1
- package/corpus/templates/slides/public/manifest.json +1 -1
- package/corpus/templates/slides/server/plugins/auth.ts +1 -1
- package/corpus/templates/slides/server/plugins/db.ts +4 -0
- package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/corpus/templates/tasks/AGENTS.md +1 -1
- package/corpus/templates/tasks/_gitignore +1 -0
- package/dist/a2a/activity.d.ts +4 -1
- package/dist/a2a/activity.d.ts.map +1 -1
- package/dist/a2a/activity.js +27 -16
- package/dist/a2a/activity.js.map +1 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +58 -4
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +31 -4
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +18 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +1 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +2 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +12 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +21 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +41 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/index.d.ts +1 -0
- package/dist/checkpoints/index.d.ts.map +1 -1
- package/dist/checkpoints/index.js +1 -0
- package/dist/checkpoints/index.js.map +1 -1
- package/dist/checkpoints/route-match.d.ts +8 -0
- package/dist/checkpoints/route-match.d.ts.map +1 -0
- package/dist/checkpoints/route-match.js +13 -0
- package/dist/checkpoints/route-match.js.map +1 -0
- package/dist/cli/create.d.ts +35 -4
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +69 -19
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/template-baseline.d.ts +54 -0
- package/dist/cli/template-baseline.d.ts.map +1 -0
- package/dist/cli/template-baseline.js +334 -0
- package/dist/cli/template-baseline.js.map +1 -0
- package/dist/cli/template-sync.d.ts +57 -0
- package/dist/cli/template-sync.d.ts.map +1 -0
- package/dist/cli/template-sync.js +787 -0
- package/dist/cli/template-sync.js.map +1 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +1 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +32 -2
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +20 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +81 -46
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -6
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +13 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js +9 -9
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/client/settings/SettingsTabsPage.js +7 -4
- package/dist/client/settings/SettingsTabsPage.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +3 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/data-widgets/index.d.ts +3 -0
- package/dist/data-widgets/index.d.ts.map +1 -1
- package/dist/data-widgets/index.js +33 -0
- package/dist/data-widgets/index.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +11 -7
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +1 -0
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/extensions/url-safety.d.ts +9 -16
- package/dist/extensions/url-safety.d.ts.map +1 -1
- package/dist/extensions/url-safety.js +48 -4
- package/dist/extensions/url-safety.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +46 -9
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/auto-join-domain.d.ts +3 -2
- package/dist/org/auto-join-domain.d.ts.map +1 -1
- package/dist/org/auto-join-domain.js +1 -1
- package/dist/org/auto-join-domain.js.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +84 -28
- package/dist/org/context.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/service-identity.d.ts +43 -0
- package/dist/org/service-identity.d.ts.map +1 -0
- package/dist/org/service-identity.js +34 -0
- package/dist/org/service-identity.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +13 -11
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/index.d.ts +4 -0
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +17 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/scripts/docs/search.d.ts.map +1 -1
- package/dist/scripts/docs/search.js +12 -1
- package/dist/scripts/docs/search.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +3 -3
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +33 -62
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agents-bundle.d.ts +18 -0
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +70 -4
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +43 -19
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.js +2 -2
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +38 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +142 -64
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +7 -13
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +10 -21
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/prompts/shared-rules.d.ts +16 -10
- package/dist/server/prompts/shared-rules.d.ts.map +1 -1
- package/dist/server/prompts/shared-rules.js +19 -10
- package/dist/server/prompts/shared-rules.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +10 -3
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/settings/user-settings.d.ts.map +1 -1
- package/dist/settings/user-settings.js +13 -1
- package/dist/settings/user-settings.js.map +1 -1
- package/dist/shared/cache-control.d.ts +52 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +107 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/chat/_gitignore +1 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/default/app/root.tsx +1 -1
- package/dist/templates/default/public/manifest.json +2 -2
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +8 -7
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +66 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/actions.mdx +2 -2
- package/docs/content/agent-surfaces.mdx +1 -1
- package/docs/content/authentication.mdx +2 -0
- package/docs/content/deployment.mdx +36 -0
- package/docs/content/http-api.mdx +266 -0
- package/docs/content/syncing-template-changes.mdx +159 -0
- package/package.json +4 -3
- package/src/a2a/activity.ts +38 -27
- package/src/a2a/client.ts +57 -4
- package/src/agent/engine/builder-engine.ts +35 -4
- package/src/agent/run-manager.ts +20 -1
- package/src/agent/run-store.ts +4 -1
- package/src/agent/types.ts +28 -8
- package/src/chat-threads/store.ts +45 -0
- package/src/checkpoints/index.ts +2 -0
- package/src/checkpoints/route-match.ts +13 -0
- package/src/cli/create.ts +105 -17
- package/src/cli/index.ts +20 -0
- package/src/cli/template-baseline.ts +410 -0
- package/src/cli/template-sync.ts +1004 -0
- package/src/cli/templates-meta.ts +1 -0
- package/src/client/AssistantChat.tsx +38 -12
- package/src/client/NewWorkspaceAppFlow.tsx +75 -10
- package/src/client/chat/message-components.tsx +127 -66
- package/src/client/chat/tool-call-display.tsx +29 -5
- package/src/client/error-format.ts +18 -0
- package/src/client/org/OrgSwitcher.tsx +30 -8
- package/src/client/org/TeamPage.tsx +7 -6
- package/src/client/settings/SettingsPanel.tsx +9 -9
- package/src/client/settings/SettingsTabsPage.tsx +12 -2
- package/src/client/sse-event-processor.ts +3 -0
- package/src/data-widgets/index.ts +41 -0
- package/src/deploy/build.ts +11 -9
- package/src/extensions/url-safety.ts +67 -4
- package/src/integrations/webhook-handler.ts +63 -9
- package/src/org/auto-join-domain.ts +4 -3
- package/src/org/context.ts +108 -39
- package/src/org/index.ts +5 -0
- package/src/org/service-identity.ts +60 -0
- package/src/provider-api/index.ts +22 -1
- package/src/scripts/docs/search.ts +12 -1
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
- package/src/server/agent-chat/context-tools.ts +9 -4
- package/src/server/agent-chat/framework-prompts.ts +38 -66
- package/src/server/agent-chat-plugin.ts +17 -10
- package/src/server/agents-bundle.ts +84 -5
- package/src/server/auth.ts +4 -3
- package/src/server/builder-browser.ts +47 -19
- package/src/server/core-routes-plugin.ts +2 -2
- package/src/server/credential-provider.ts +209 -68
- package/src/server/index.ts +3 -0
- package/src/server/prompts/framework-core-compact.ts +6 -13
- package/src/server/prompts/framework-core.ts +9 -21
- package/src/server/prompts/index.ts +0 -1
- package/src/server/prompts/shared-rules.ts +19 -11
- package/src/server/ssr-handler.ts +13 -2
- package/src/settings/user-settings.ts +13 -1
- package/src/shared/cache-control.ts +141 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/chat/_gitignore +1 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
- package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/default/app/root.tsx +1 -1
- package/src/templates/default/public/manifest.json +2 -2
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
- package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
- package/src/vite/agents-bundle-plugin.ts +7 -6
- package/src/vite/client.ts +69 -3
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { buildRecordingShareUrl } from "@shared/recording-link";
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
restartUploadModeFromResponse,
|
|
3
5
|
restartUploadResetBody,
|
|
@@ -1080,12 +1082,26 @@ function sendOffscreenMessage<T>(message: Record<string, unknown>): Promise<T> {
|
|
|
1080
1082
|
});
|
|
1081
1083
|
}
|
|
1082
1084
|
|
|
1085
|
+
// The author's own dashboard. Fine to OPEN for the person who just recorded;
|
|
1086
|
+
// never the thing to hand someone else — see recordingShareUrl below.
|
|
1083
1087
|
function recordingUrl(
|
|
1084
1088
|
recording: Pick<NativeRecording, "clipsBaseUrl" | "recordingId">,
|
|
1085
1089
|
): string {
|
|
1086
1090
|
return `${recording.clipsBaseUrl}/r/${encodeURIComponent(recording.recordingId)}`;
|
|
1087
1091
|
}
|
|
1088
1092
|
|
|
1093
|
+
// The extension only stores the signed-in user's token and email; email is PII
|
|
1094
|
+
// and must never become the `via` attribution param, so share URLs go out
|
|
1095
|
+
// without an owner id.
|
|
1096
|
+
function recordingShareUrl(
|
|
1097
|
+
recording: Pick<NativeRecording, "clipsBaseUrl" | "recordingId">,
|
|
1098
|
+
): string {
|
|
1099
|
+
return buildRecordingShareUrl({
|
|
1100
|
+
recordingId: recording.recordingId,
|
|
1101
|
+
origin: recording.clipsBaseUrl,
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1089
1105
|
async function copyRecordingUrlToClipboard(
|
|
1090
1106
|
recording: NativeRecording,
|
|
1091
1107
|
): Promise<void> {
|
|
@@ -1093,7 +1109,7 @@ async function copyRecordingUrlToClipboard(
|
|
|
1093
1109
|
await ensureOffscreenDocument();
|
|
1094
1110
|
await sendOffscreenMessage({
|
|
1095
1111
|
type: "CLIPS_OFFSCREEN_COPY_TEXT",
|
|
1096
|
-
text: recording
|
|
1112
|
+
text: recordingShareUrl(recording),
|
|
1097
1113
|
});
|
|
1098
1114
|
} catch (err) {
|
|
1099
1115
|
console.warn("[clips-bg] could not copy recording URL", err);
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"@sentry/browser": "10.62.0",
|
|
24
24
|
"@tabler/icons-react": "catalog:",
|
|
25
25
|
"@tauri-apps/api": "^2.11.0",
|
|
26
|
+
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
|
|
26
27
|
"@tauri-apps/plugin-fs": "2.5.1",
|
|
28
|
+
"@tauri-apps/plugin-notification": "^2.3.3",
|
|
27
29
|
"@tauri-apps/plugin-process": "^2.3.1",
|
|
28
30
|
"@tauri-apps/plugin-shell": "^2.3.5",
|
|
29
31
|
"@tauri-apps/plugin-updater": "^2.10.1",
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
getCameraStreamWithFallback,
|
|
64
64
|
isMediaConstraintFailure,
|
|
65
65
|
} from "./lib/media-capture-constraints";
|
|
66
|
+
import { sendNativeNotification } from "./lib/native-notification";
|
|
66
67
|
import { openMeetingJoinUrl } from "./lib/open-meeting-join-url";
|
|
67
68
|
import {
|
|
68
69
|
DESKTOP_CAPTURE_PERMISSION_MESSAGE,
|
|
@@ -88,6 +89,10 @@ import {
|
|
|
88
89
|
type RecorderHandle,
|
|
89
90
|
type RecorderStopResult,
|
|
90
91
|
} from "./lib/recorder";
|
|
92
|
+
import {
|
|
93
|
+
copyRecordingShareLink,
|
|
94
|
+
recordingShareUrl,
|
|
95
|
+
} from "./lib/recording-link";
|
|
91
96
|
import { REWIND_AGENT_PROMPT } from "./lib/rewind-agent-prompt";
|
|
92
97
|
import { getRewindStatusPresentation } from "./lib/rewind-status";
|
|
93
98
|
import {
|
|
@@ -208,6 +213,13 @@ interface LocalRecordingNotice {
|
|
|
208
213
|
files: LocalExportedFile[];
|
|
209
214
|
}
|
|
210
215
|
|
|
216
|
+
interface ShareLinkNotice {
|
|
217
|
+
recordingId: string;
|
|
218
|
+
origin: string;
|
|
219
|
+
url: string;
|
|
220
|
+
copied: boolean;
|
|
221
|
+
}
|
|
222
|
+
|
|
211
223
|
interface ScreenMemoryExportResult {
|
|
212
224
|
folderPath: string;
|
|
213
225
|
files: Array<{
|
|
@@ -907,6 +919,8 @@ export function App() {
|
|
|
907
919
|
);
|
|
908
920
|
const [localRecordingNotice, setLocalRecordingNotice] =
|
|
909
921
|
useState<LocalRecordingNotice | null>(null);
|
|
922
|
+
const [shareLinkNotice, setShareLinkNotice] =
|
|
923
|
+
useState<ShareLinkNotice | null>(null);
|
|
910
924
|
const [popoverView, setPopoverView] = useState<PopoverView>("recorder");
|
|
911
925
|
const [rewindSettingsReturnView, setRewindSettingsReturnView] = useState<
|
|
912
926
|
"recorder" | "settings"
|
|
@@ -2565,6 +2579,32 @@ export function App() {
|
|
|
2565
2579
|
});
|
|
2566
2580
|
}
|
|
2567
2581
|
|
|
2582
|
+
// Never rejects: a clipboard failure must not be mistaken for a failed
|
|
2583
|
+
// recording by the stop/retry callers that await this inside their try block.
|
|
2584
|
+
async function copyShareLink(
|
|
2585
|
+
recordingId: string,
|
|
2586
|
+
origin = serverUrl,
|
|
2587
|
+
{ notify = true }: { notify?: boolean } = {},
|
|
2588
|
+
) {
|
|
2589
|
+
try {
|
|
2590
|
+
const url = recordingShareUrl(recordingId, origin);
|
|
2591
|
+
const copied = await copyRecordingShareLink(recordingId, origin);
|
|
2592
|
+
setShareLinkNotice({ recordingId, origin, url, copied });
|
|
2593
|
+
// The popover hides right after an automatic copy, so the banner below is
|
|
2594
|
+
// only seen on the next open — the OS notification is the live signal.
|
|
2595
|
+
if (copied && notify) {
|
|
2596
|
+
await sendNativeNotification({
|
|
2597
|
+
title: "Link copied",
|
|
2598
|
+
body: "Your clip link is ready to paste.",
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
return copied;
|
|
2602
|
+
} catch (err) {
|
|
2603
|
+
console.error("[clips-tray] copy share link failed:", err);
|
|
2604
|
+
return false;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2568
2608
|
async function retryPendingUpload(upload: PendingDesktopUpload) {
|
|
2569
2609
|
if (retryingUploadId || exportingUploadId || dismissingUploadId) return;
|
|
2570
2610
|
const targetServerUrl = serverUrlForPendingUpload(upload, serverUrl);
|
|
@@ -2598,6 +2638,7 @@ export function App() {
|
|
|
2598
2638
|
});
|
|
2599
2639
|
}
|
|
2600
2640
|
await loadPendingUploads();
|
|
2641
|
+
await copyShareLink(upload.recordingId, targetServerUrl);
|
|
2601
2642
|
await openExternal(`${targetServerUrl}/r/${upload.recordingId}`);
|
|
2602
2643
|
getCurrentWindow()
|
|
2603
2644
|
.hide()
|
|
@@ -2737,6 +2778,7 @@ export function App() {
|
|
|
2737
2778
|
}
|
|
2738
2779
|
setRecError(null);
|
|
2739
2780
|
setLocalRecordingNotice(null);
|
|
2781
|
+
setShareLinkNotice(null);
|
|
2740
2782
|
console.log("[clips-popover] handleStartRecording clicked", {
|
|
2741
2783
|
serverUrl,
|
|
2742
2784
|
mode,
|
|
@@ -3101,6 +3143,10 @@ export function App() {
|
|
|
3101
3143
|
});
|
|
3102
3144
|
} else {
|
|
3103
3145
|
setLastRecordingId(stopResult.recordingId);
|
|
3146
|
+
// The browser opens `/r/<id>` (the author's dashboard); what lands
|
|
3147
|
+
// on the clipboard must be the public `/share/<id>` link, which is
|
|
3148
|
+
// the one a recipient can actually open.
|
|
3149
|
+
await copyShareLink(stopResult.recordingId);
|
|
3104
3150
|
}
|
|
3105
3151
|
} catch (err) {
|
|
3106
3152
|
stopFailed = true;
|
|
@@ -3639,6 +3685,20 @@ export function App() {
|
|
|
3639
3685
|
/>
|
|
3640
3686
|
) : null}
|
|
3641
3687
|
|
|
3688
|
+
{shareLinkNotice ? (
|
|
3689
|
+
<ShareLinkBanner
|
|
3690
|
+
notice={shareLinkNotice}
|
|
3691
|
+
onCopy={() => {
|
|
3692
|
+
void copyShareLink(
|
|
3693
|
+
shareLinkNotice.recordingId,
|
|
3694
|
+
shareLinkNotice.origin,
|
|
3695
|
+
{ notify: false },
|
|
3696
|
+
);
|
|
3697
|
+
}}
|
|
3698
|
+
onDismiss={() => setShareLinkNotice(null)}
|
|
3699
|
+
/>
|
|
3700
|
+
) : null}
|
|
3701
|
+
|
|
3642
3702
|
<div className="panel">
|
|
3643
3703
|
{showSourceRow ? (
|
|
3644
3704
|
<SourceRow
|
|
@@ -4233,6 +4293,35 @@ function LocalRecordingSavedBanner({
|
|
|
4233
4293
|
);
|
|
4234
4294
|
}
|
|
4235
4295
|
|
|
4296
|
+
function ShareLinkBanner({
|
|
4297
|
+
notice,
|
|
4298
|
+
onCopy,
|
|
4299
|
+
onDismiss,
|
|
4300
|
+
}: {
|
|
4301
|
+
notice: ShareLinkNotice;
|
|
4302
|
+
onCopy: () => void;
|
|
4303
|
+
onDismiss: () => void;
|
|
4304
|
+
}) {
|
|
4305
|
+
return (
|
|
4306
|
+
<div className="share-link-banner">
|
|
4307
|
+
<div className="local-save-copy">
|
|
4308
|
+
<div className="local-save-title">
|
|
4309
|
+
{notice.copied ? "Share link copied" : "Share link ready"}
|
|
4310
|
+
</div>
|
|
4311
|
+
<div className="local-save-sub">{notice.url}</div>
|
|
4312
|
+
</div>
|
|
4313
|
+
{notice.copied ? null : (
|
|
4314
|
+
<button type="button" onClick={onCopy}>
|
|
4315
|
+
Copy
|
|
4316
|
+
</button>
|
|
4317
|
+
)}
|
|
4318
|
+
<button type="button" className="local-save-dismiss" onClick={onDismiss}>
|
|
4319
|
+
Dismiss
|
|
4320
|
+
</button>
|
|
4321
|
+
</div>
|
|
4322
|
+
);
|
|
4323
|
+
}
|
|
4324
|
+
|
|
4236
4325
|
function Header({
|
|
4237
4326
|
mode,
|
|
4238
4327
|
onModeChange,
|
|
@@ -830,13 +830,19 @@ export function useMeetingTranscription({
|
|
|
830
830
|
);
|
|
831
831
|
|
|
832
832
|
unlistens.push(
|
|
833
|
-
listen<{ meetingId: string; openChat?: boolean }>(
|
|
833
|
+
listen<{ meetingId: string; openChat?: boolean; prompt?: string }>(
|
|
834
834
|
"clips:open-meeting",
|
|
835
835
|
(ev) => {
|
|
836
836
|
if (!ev.payload?.meetingId) return;
|
|
837
|
-
const
|
|
837
|
+
const params = new URLSearchParams();
|
|
838
|
+
if (ev.payload.openChat) params.set("chat", "1");
|
|
839
|
+
const prompt = ev.payload.prompt?.trim();
|
|
840
|
+
if (prompt) params.set("ask", prompt);
|
|
841
|
+
const query = params.toString();
|
|
838
842
|
openExternal(
|
|
839
|
-
`${normalizedServerUrl}/meetings/${ev.payload.meetingId}${
|
|
843
|
+
`${normalizedServerUrl}/meetings/${ev.payload.meetingId}${
|
|
844
|
+
query ? `?${query}` : ""
|
|
845
|
+
}`,
|
|
840
846
|
).catch((err) =>
|
|
841
847
|
console.warn("[clips-popover] open meeting in web failed:", err),
|
|
842
848
|
);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Level math for the Granola-style waveform meter on the recording pill.
|
|
3
|
+
*
|
|
4
|
+
* Kept separate from the React overlay so the "bars must track how loud people
|
|
5
|
+
* are talking" behaviour is unit-testable without a DOM.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Per-bar scale. The middle bar swings widest, like Granola's meter. */
|
|
9
|
+
export const METER_BAR_GAINS = [0.72, 1, 0.84];
|
|
10
|
+
export const METER_BAR_COUNT = METER_BAR_GAINS.length;
|
|
11
|
+
/** Height (0-1) each bar keeps at silence, so the meter idles as three dots. */
|
|
12
|
+
export const METER_IDLE_HEIGHT = 0.14;
|
|
13
|
+
/** Multiplier applied on every sample tick when no louder audio arrives. */
|
|
14
|
+
export const METER_LEVEL_DECAY = 0.82;
|
|
15
|
+
/** Floor a new sample must clear, so the meter falls smoothly instead of snapping. */
|
|
16
|
+
export const METER_ATTACK_DECAY = 0.55;
|
|
17
|
+
export const METER_SAMPLE_MS = 50;
|
|
18
|
+
|
|
19
|
+
/** Fold an incoming 0-1 audio level into the current level. */
|
|
20
|
+
export function nextMeterLevel(current: number, incoming: number): number {
|
|
21
|
+
if (!Number.isFinite(incoming)) return current;
|
|
22
|
+
const clamped = Math.max(0, Math.min(1, incoming));
|
|
23
|
+
return Math.max(current * METER_ATTACK_DECAY, clamped);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** One decay tick. Snaps to silence below a threshold so bars settle at rest. */
|
|
27
|
+
export function decayMeterLevel(current: number): number {
|
|
28
|
+
const decayed = current * METER_LEVEL_DECAY;
|
|
29
|
+
return decayed < 0.01 ? 0 : decayed;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Push the newest sample onto the front of the meter's history. Bar 0 shows
|
|
34
|
+
* the newest level and older levels travel outward, so the bars ripple against
|
|
35
|
+
* each other instead of moving as one block.
|
|
36
|
+
*/
|
|
37
|
+
export function advanceMeterLevels(levels: number[], sample: number): number[] {
|
|
38
|
+
return [sample, ...levels.slice(0, METER_BAR_COUNT - 1)];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Bar height as a percentage of the meter's box. Peak levels from speech taps
|
|
43
|
+
* are often quiet even when speech is clear, so a gentle curve keeps the meter
|
|
44
|
+
* responsive without turning background noise into a full-height signal.
|
|
45
|
+
*/
|
|
46
|
+
export function meterBarHeight(level: number, barIndex: number): number {
|
|
47
|
+
const gain = METER_BAR_GAINS[barIndex] ?? 1;
|
|
48
|
+
const safe = Number.isFinite(level) ? Math.max(0, Math.min(1, level)) : 0;
|
|
49
|
+
const shaped = safe > 0 ? Math.min(1, Math.pow(safe, 0.52) * 1.08) : 0;
|
|
50
|
+
return (METER_IDLE_HEIGHT + shaped * gain * (1 - METER_IDLE_HEIGHT)) * 100;
|
|
51
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPermissionGranted,
|
|
3
|
+
requestPermission,
|
|
4
|
+
sendNotification,
|
|
5
|
+
} from "@tauri-apps/plugin-notification";
|
|
6
|
+
|
|
7
|
+
export interface NativeNotification {
|
|
8
|
+
title: string;
|
|
9
|
+
body?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface NativeNotificationDeps {
|
|
13
|
+
isPermissionGranted: () => Promise<boolean>;
|
|
14
|
+
requestPermission: () => Promise<NotificationPermission>;
|
|
15
|
+
sendNotification: (notification: NativeNotification) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const tauriNotificationDeps: NativeNotificationDeps = {
|
|
19
|
+
isPermissionGranted,
|
|
20
|
+
requestPermission,
|
|
21
|
+
sendNotification,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Post an OS notification, requesting permission first when the user has not
|
|
26
|
+
* answered yet. Never rejects: callers await this inside recording stop/retry
|
|
27
|
+
* try blocks, where a throw would be reported as a failed recording.
|
|
28
|
+
*/
|
|
29
|
+
export async function sendNativeNotification(
|
|
30
|
+
notification: NativeNotification,
|
|
31
|
+
deps: NativeNotificationDeps = tauriNotificationDeps,
|
|
32
|
+
): Promise<boolean> {
|
|
33
|
+
try {
|
|
34
|
+
const granted =
|
|
35
|
+
(await deps.isPermissionGranted()) ||
|
|
36
|
+
(await deps.requestPermission()) === "granted";
|
|
37
|
+
if (!granted) return false;
|
|
38
|
+
deps.sendNotification(notification);
|
|
39
|
+
return true;
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.warn("[clips-tray] native notification failed:", err);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
|
2
|
+
|
|
3
|
+
import { buildRecordingShareUrl } from "../../../shared/recording-link";
|
|
4
|
+
import { normalizeServerUrl } from "./url";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Absolute, paste-ready `/share/<id>` URL. Never `/r/<id>` — that is the owner
|
|
8
|
+
* dashboard and renders a sign-in prompt for anyone the link is sent to.
|
|
9
|
+
*/
|
|
10
|
+
export function recordingShareUrl(
|
|
11
|
+
recordingId: string,
|
|
12
|
+
serverUrl: string,
|
|
13
|
+
): string {
|
|
14
|
+
return buildRecordingShareUrl({
|
|
15
|
+
recordingId,
|
|
16
|
+
origin: normalizeServerUrl(serverUrl),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function writeClipboardText(text: string): Promise<boolean> {
|
|
21
|
+
// Rust-side write first: at recording-stop time the popover webview is
|
|
22
|
+
// usually not focused, and `navigator.clipboard.writeText` rejects with
|
|
23
|
+
// `NotAllowedError: Document is not focused` in exactly that case.
|
|
24
|
+
try {
|
|
25
|
+
await writeText(text);
|
|
26
|
+
return true;
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.warn("[clips-tray] native clipboard write failed:", err);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await navigator.clipboard.writeText(text);
|
|
33
|
+
return true;
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.warn("[clips-tray] navigator clipboard write failed:", err);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const textarea = document.createElement("textarea");
|
|
40
|
+
textarea.value = text;
|
|
41
|
+
textarea.setAttribute("readonly", "");
|
|
42
|
+
textarea.style.position = "fixed";
|
|
43
|
+
textarea.style.opacity = "0";
|
|
44
|
+
textarea.style.pointerEvents = "none";
|
|
45
|
+
document.body.appendChild(textarea);
|
|
46
|
+
textarea.select();
|
|
47
|
+
textarea.setSelectionRange(0, text.length);
|
|
48
|
+
const copied = document.execCommand("copy");
|
|
49
|
+
document.body.removeChild(textarea);
|
|
50
|
+
return copied;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.warn("[clips-tray] execCommand clipboard write failed:", err);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Copy a recording's public share URL. Resolves to whether the clipboard
|
|
59
|
+
* actually took the text so callers never claim a copy that did not happen.
|
|
60
|
+
*/
|
|
61
|
+
export async function copyRecordingShareLink(
|
|
62
|
+
recordingId: string,
|
|
63
|
+
serverUrl: string,
|
|
64
|
+
): Promise<boolean> {
|
|
65
|
+
if (!recordingId.trim() || !normalizeServerUrl(serverUrl)) return false;
|
|
66
|
+
return writeClipboardText(recordingShareUrl(recordingId, serverUrl));
|
|
67
|
+
}
|
|
@@ -1,42 +1,50 @@
|
|
|
1
1
|
import { listen } from "@tauri-apps/api/event";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
advanceMeterLevels,
|
|
6
|
+
decayMeterLevel,
|
|
7
|
+
METER_BAR_COUNT,
|
|
8
|
+
METER_BAR_GAINS,
|
|
9
|
+
METER_SAMPLE_MS,
|
|
10
|
+
meterBarHeight,
|
|
11
|
+
nextMeterLevel,
|
|
12
|
+
} from "../lib/audio-meter";
|
|
7
13
|
|
|
8
14
|
interface LiveAudioBarsProps {
|
|
9
15
|
className?: string;
|
|
10
16
|
compact?: boolean;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Small Granola-style meter shared by the compact and expanded overlays. The
|
|
21
|
+
* bars track how loud the meeting actually is — mic and system audio both feed
|
|
22
|
+
* `voice:audio-level`, and the meter rides whichever is louder.
|
|
23
|
+
*/
|
|
14
24
|
export function LiveAudioBars({
|
|
15
25
|
className,
|
|
16
26
|
compact = false,
|
|
17
27
|
}: LiveAudioBarsProps) {
|
|
18
|
-
const [
|
|
28
|
+
const [levels, setLevels] = useState<number[]>(() =>
|
|
29
|
+
new Array(METER_BAR_COUNT).fill(0),
|
|
30
|
+
);
|
|
19
31
|
const levelRef = useRef(0);
|
|
20
32
|
|
|
21
33
|
useEffect(() => {
|
|
22
34
|
let stopped = false;
|
|
23
35
|
let unlisten: (() => void) | null = null;
|
|
24
36
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
levelRef.current =
|
|
28
|
-
|
|
29
|
-
},
|
|
37
|
+
const sampleTimer = window.setInterval(() => {
|
|
38
|
+
const current = levelRef.current;
|
|
39
|
+
levelRef.current = decayMeterLevel(current);
|
|
40
|
+
setLevels((prev) => advanceMeterLevels(prev, current));
|
|
41
|
+
}, METER_SAMPLE_MS);
|
|
30
42
|
|
|
31
43
|
listen<{ level?: number }>("voice:audio-level", (event) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
levelRef.current * EVENT_ATTACK_DECAY,
|
|
36
|
-
Math.max(0, Math.min(1, incoming)),
|
|
44
|
+
levelRef.current = nextMeterLevel(
|
|
45
|
+
levelRef.current,
|
|
46
|
+
Number(event.payload?.level),
|
|
37
47
|
);
|
|
38
|
-
levelRef.current = next;
|
|
39
|
-
setLevel(next);
|
|
40
48
|
})
|
|
41
49
|
.then((cleanup) => {
|
|
42
50
|
if (stopped) {
|
|
@@ -49,15 +57,11 @@ export function LiveAudioBars({
|
|
|
49
57
|
|
|
50
58
|
return () => {
|
|
51
59
|
stopped = true;
|
|
52
|
-
window.clearInterval(
|
|
60
|
+
window.clearInterval(sampleTimer);
|
|
53
61
|
unlisten?.();
|
|
54
62
|
};
|
|
55
63
|
}, []);
|
|
56
64
|
|
|
57
|
-
// Peak levels from speech taps are often quiet even when speech is clear.
|
|
58
|
-
// A gentle curve keeps the meter responsive without turning background noise
|
|
59
|
-
// into a full-height signal.
|
|
60
|
-
const visualLevel = level > 0 ? Math.min(1, Math.pow(level, 0.52) * 1.08) : 0;
|
|
61
65
|
const rootClassName = [
|
|
62
66
|
"live-audio-bars",
|
|
63
67
|
compact ? "live-audio-bars-compact" : null,
|
|
@@ -68,19 +72,15 @@ export function LiveAudioBars({
|
|
|
68
72
|
|
|
69
73
|
return (
|
|
70
74
|
<span className={rootClassName} aria-hidden="true">
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
style={{ height: `${Math.max(12, height)}%` }}
|
|
81
|
-
/>
|
|
82
|
-
);
|
|
83
|
-
})}
|
|
75
|
+
{METER_BAR_GAINS.map((_gain, index) => (
|
|
76
|
+
<span
|
|
77
|
+
className="live-audio-bar"
|
|
78
|
+
key={index}
|
|
79
|
+
style={{
|
|
80
|
+
height: `${Math.round(meterBarHeight(levels[index] ?? 0, index))}%`,
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
))}
|
|
84
84
|
</span>
|
|
85
85
|
);
|
|
86
86
|
}
|
|
@@ -151,8 +151,9 @@ export function LiveTranscript({
|
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
153
|
* A single chat-style transcript bubble. The mic stream ("You") is aligned to
|
|
154
|
-
* the right
|
|
155
|
-
*
|
|
154
|
+
* the right; the system-audio stream ("Them") sits on the left. Both use
|
|
155
|
+
* neutral greys — side, not hue, is what distinguishes the speakers. In-flight
|
|
156
|
+
* partials render dimmed.
|
|
156
157
|
*/
|
|
157
158
|
function ChatBubble({
|
|
158
159
|
source,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
IconArrowUp,
|
|
2
3
|
IconCheck,
|
|
3
4
|
IconChevronDown,
|
|
4
5
|
IconChevronUp,
|
|
5
6
|
IconCopy,
|
|
6
7
|
IconExternalLink,
|
|
7
8
|
IconLoader2,
|
|
8
|
-
IconMessageCircle,
|
|
9
9
|
IconPlayerPauseFilled,
|
|
10
10
|
IconPlayerPlayFilled,
|
|
11
11
|
IconPlayerStopFilled,
|
|
@@ -32,8 +32,8 @@ interface PillContext {
|
|
|
32
32
|
* Granola-style recording indicator. A floating pill anchored by Rust:
|
|
33
33
|
* center-right for meetings, bottom-center for ordinary recordings.
|
|
34
34
|
*
|
|
35
|
-
* - Collapsed (default):
|
|
36
|
-
* - Expanded:
|
|
35
|
+
* - Collapsed (default): logo + live waveform capsule, click to expand.
|
|
36
|
+
* - Expanded: header + scrolling live transcript + Pause / Stop + Ask bar.
|
|
37
37
|
*
|
|
38
38
|
* The hosting Tauri window is always-on-top, transparent, no decorations,
|
|
39
39
|
* and capture-excluded — see `recording_indicator.rs`. We only deal with
|
|
@@ -51,6 +51,7 @@ export function RecordingPill() {
|
|
|
51
51
|
const [hasTranscriptLines, setHasTranscriptLines] = useState(false);
|
|
52
52
|
const [transcriptCopied, setTranscriptCopied] = useState(false);
|
|
53
53
|
const [preloadedLines, setPreloadedLines] = useState<FinalLine[]>([]);
|
|
54
|
+
const [ask, setAsk] = useState("");
|
|
54
55
|
const activeMeetingIdRef = useRef<string | null>(null);
|
|
55
56
|
// Detached / "floating" mode — Wispr-style pill that auto-moves to the
|
|
56
57
|
// top-right when the main app loses focus, with a drag handle. Driven by
|
|
@@ -196,17 +197,6 @@ export function RecordingPill() {
|
|
|
196
197
|
};
|
|
197
198
|
}, [ctx.mode, paused]);
|
|
198
199
|
|
|
199
|
-
// Let the compact chip land first, then reveal the live transcript once per
|
|
200
|
-
// meeting. The delay keeps the indicator from feeling like a sudden panel.
|
|
201
|
-
useEffect(() => {
|
|
202
|
-
if (ctx.mode !== "meeting" || detached) return;
|
|
203
|
-
const timer = setTimeout(() => {
|
|
204
|
-
setExpanded(true);
|
|
205
|
-
invoke("recording_pill_expand", { expanded: true }).catch(() => {});
|
|
206
|
-
}, 280);
|
|
207
|
-
return () => clearTimeout(timer);
|
|
208
|
-
}, [ctx.mode, detached]);
|
|
209
|
-
|
|
210
200
|
async function toggleExpanded() {
|
|
211
201
|
const next = !expanded;
|
|
212
202
|
setExpanded(next);
|
|
@@ -258,6 +248,19 @@ export function RecordingPill() {
|
|
|
258
248
|
}
|
|
259
249
|
};
|
|
260
250
|
|
|
251
|
+
const handleAskSubmit = (e: React.FormEvent) => {
|
|
252
|
+
e.preventDefault();
|
|
253
|
+
const question = ask.trim();
|
|
254
|
+
const mid = activeMeetingIdRef.current;
|
|
255
|
+
if (!question || !mid) return;
|
|
256
|
+
setAsk("");
|
|
257
|
+
emit("clips:open-meeting", {
|
|
258
|
+
meetingId: mid,
|
|
259
|
+
openChat: true,
|
|
260
|
+
prompt: question,
|
|
261
|
+
}).catch(() => {});
|
|
262
|
+
};
|
|
263
|
+
|
|
261
264
|
const handlePillMouseDown = (e: React.MouseEvent) => {
|
|
262
265
|
if (e.button !== 0) return;
|
|
263
266
|
const target = e.target as HTMLElement;
|
|
@@ -307,11 +310,9 @@ export function RecordingPill() {
|
|
|
307
310
|
? " pill-vertical"
|
|
308
311
|
: ""
|
|
309
312
|
}`}
|
|
313
|
+
onClick={!expanded && !detached ? handlePillMediaClick : undefined}
|
|
310
314
|
>
|
|
311
|
-
<div
|
|
312
|
-
className="pill-media"
|
|
313
|
-
onClick={!expanded && !detached ? handlePillMediaClick : undefined}
|
|
314
|
-
>
|
|
315
|
+
<div className="pill-media">
|
|
315
316
|
<PillLogo className="pill-logo" />
|
|
316
317
|
<LiveAudioBars
|
|
317
318
|
compact={!expanded && !detached}
|
|
@@ -413,43 +414,43 @@ export function RecordingPill() {
|
|
|
413
414
|
/>
|
|
414
415
|
</div>
|
|
415
416
|
{ctx.mode === "meeting" ? (
|
|
416
|
-
<
|
|
417
|
+
<form className="pill-ask-bar" onSubmit={handleAskSubmit}>
|
|
418
|
+
<input
|
|
419
|
+
data-no-drag
|
|
420
|
+
className="pill-ask-input"
|
|
421
|
+
value={ask}
|
|
422
|
+
onChange={(e) => setAsk(e.target.value)}
|
|
423
|
+
placeholder="Ask anything"
|
|
424
|
+
aria-label="Ask anything about this meeting"
|
|
425
|
+
disabled={!ctx.meetingId}
|
|
426
|
+
/>
|
|
427
|
+
<button
|
|
428
|
+
type="submit"
|
|
429
|
+
data-no-drag
|
|
430
|
+
className="pill-ask-send"
|
|
431
|
+
disabled={!ask.trim() || !ctx.meetingId}
|
|
432
|
+
aria-label="Ask"
|
|
433
|
+
title="Ask"
|
|
434
|
+
>
|
|
435
|
+
<IconArrowUp size={13} />
|
|
436
|
+
</button>
|
|
417
437
|
<button
|
|
418
438
|
type="button"
|
|
419
439
|
data-no-drag
|
|
420
|
-
className="pill-open
|
|
440
|
+
className="pill-ask-open"
|
|
421
441
|
onClick={() => {
|
|
422
442
|
const mid = activeMeetingIdRef.current;
|
|
423
443
|
if (mid)
|
|
424
|
-
emit("clips:open-meeting", {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}).catch(() => {});
|
|
444
|
+
emit("clips:open-meeting", { meetingId: mid }).catch(
|
|
445
|
+
() => {},
|
|
446
|
+
);
|
|
428
447
|
}}
|
|
429
|
-
|
|
448
|
+
aria-label="Open in browser"
|
|
449
|
+
title="Open this meeting in the browser"
|
|
430
450
|
>
|
|
431
|
-
<
|
|
432
|
-
Chat with transcript
|
|
451
|
+
<IconExternalLink size={13} />
|
|
433
452
|
</button>
|
|
434
|
-
|
|
435
|
-
<button
|
|
436
|
-
type="button"
|
|
437
|
-
data-no-drag
|
|
438
|
-
className="pill-open-web-btn"
|
|
439
|
-
onClick={() => {
|
|
440
|
-
const mid = activeMeetingIdRef.current;
|
|
441
|
-
if (mid)
|
|
442
|
-
emit("clips:open-meeting", { meetingId: mid }).catch(
|
|
443
|
-
() => {},
|
|
444
|
-
);
|
|
445
|
-
}}
|
|
446
|
-
title="Open this meeting in the browser"
|
|
447
|
-
>
|
|
448
|
-
<IconExternalLink size={12} />
|
|
449
|
-
Open in browser
|
|
450
|
-
</button>
|
|
451
|
-
</span>
|
|
452
|
-
</div>
|
|
453
|
+
</form>
|
|
453
454
|
) : null}
|
|
454
455
|
</div>
|
|
455
456
|
</div>
|