@agent-native/core 0.91.1 → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blueprints/action/crud.md +1 -1
- package/blueprints/channel/discord.md +1 -1
- package/blueprints/provider/stripe.md +1 -1
- package/blueprints/sandbox/docker.md +1 -1
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +31 -0
- package/corpus/core/blueprints/action/crud.md +1 -1
- package/corpus/core/blueprints/channel/discord.md +1 -1
- package/corpus/core/blueprints/provider/stripe.md +1 -1
- package/corpus/core/blueprints/sandbox/docker.md +1 -1
- package/corpus/core/docs/content/faq.mdx +17 -0
- package/corpus/core/docs/content/notifications.mdx +12 -6
- package/corpus/core/package.json +6 -5
- package/corpus/core/src/agent/production-agent.ts +140 -46
- package/corpus/core/src/agent/run-manager.ts +23 -2
- package/corpus/core/src/agent/run-store.ts +2 -2
- package/corpus/core/src/agent/tool-search.ts +71 -4
- package/corpus/core/src/cli/add.ts +1 -1
- package/corpus/core/src/cli/create.ts +8 -3
- package/corpus/core/src/cli/index.ts +25 -4
- package/corpus/core/src/cli/upgrade.ts +798 -0
- package/corpus/core/src/client/AssistantChat.tsx +1 -1
- package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
- package/corpus/core/src/client/agent-chat-adapter.ts +31 -6
- package/corpus/core/src/client/chat/message-components.tsx +85 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
- package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +7 -0
- package/corpus/core/src/client/settings/SettingsPanel.tsx +533 -389
- package/corpus/core/src/client/settings/SettingsSection.tsx +154 -17
- package/corpus/core/src/client/sse-event-processor.ts +29 -2
- package/corpus/core/src/extensions/actions.ts +113 -5
- package/corpus/core/src/jobs/scheduler.ts +30 -1
- package/corpus/core/src/localization/default-messages.ts +21 -0
- package/corpus/core/src/notifications/channels.ts +88 -25
- package/corpus/core/src/notifications/registry.ts +17 -3
- package/corpus/core/src/notifications/types.ts +4 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
- package/corpus/core/src/server/request-context.ts +7 -0
- package/corpus/core/src/styles/agent-conversation.css +1 -1
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/default/AGENTS.md +10 -3
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/default/package.json +4 -3
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/headless/AGENTS.md +9 -3
- package/corpus/core/src/templates/headless/package.json +4 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/workspace-core/package.json +6 -6
- package/corpus/core/src/templates/workspace-root/AGENTS.md +10 -4
- package/corpus/core/src/templates/workspace-root/package.json +3 -2
- package/corpus/core/src/triggers/dispatcher.ts +30 -2
- package/corpus/core/src/vite/client.ts +96 -1
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/analytics/AGENTS.md +7 -5
- package/corpus/templates/analytics/actions/save-monitor.ts +14 -0
- package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
- package/corpus/templates/analytics/app/global.css +26 -10
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +25 -0
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +151 -32
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +461 -286
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +285 -294
- package/corpus/templates/analytics/changelog/2026-07-08-console-details-expand-inline-under-each-row-and-the-event-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-keeps-a-usable-stage-when-dev-tools-is-open-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-resumes-after-scrubbing-and-expands-console-r.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replays-wait-for-full-load-keep-a-normal-viewport-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
- package/corpus/templates/analytics/package.json +2 -2
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +4 -0
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +60 -12
- package/corpus/templates/analytics/server/plugins/db.ts +10 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/assets/package.json +2 -2
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/brain/package.json +2 -2
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/calendar/AGENTS.md +10 -0
- package/corpus/templates/calendar/actions/create-event.ts +5 -1
- package/corpus/templates/calendar/actions/event-action-helpers.ts +41 -0
- package/corpus/templates/calendar/actions/get-attendee-timezones.ts +28 -0
- package/corpus/templates/calendar/actions/set-attendee-timezone.ts +68 -0
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +150 -11
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +36 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +32 -0
- package/corpus/templates/calendar/app/hooks/use-attendee-timezones.ts +24 -0
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/app/lib/attendee-local-time.ts +122 -0
- package/corpus/templates/calendar/changelog/2026-07-08-event-details-now-support-extension-widgets-and-you-can-see-.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-08-when-you-invite-guests-to-a-new-event-you-now-appear-in.md +6 -0
- package/corpus/templates/calendar/package.json +2 -2
- package/corpus/templates/calendar/server/handlers/events.ts +5 -1
- package/corpus/templates/calendar/shared/api.ts +6 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/chat/package.json +2 -2
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +6 -2
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/clips/actions/create-meeting.ts +8 -3
- package/corpus/templates/clips/actions/list-meetings.ts +31 -3
- package/corpus/templates/clips/changelog/2026-07-08-after-finishing-a-desktop-recording-reopening-clips-restor.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-clips-now-pops-up-to-take-notes-when-you-join-an-adhoc-zoom-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-clip-recordings-are-louder-after-capture-mic-only.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminders-now-appear-1-minute-before-start-stay-unti.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-the-desktop-meetings-panel-has-room-for-its-drop-shadow-and-.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +2 -2
- package/corpus/templates/clips/desktop/package.json +2 -2
- package/corpus/templates/clips/desktop/src/app.tsx +214 -37
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +30 -6
- package/corpus/templates/clips/desktop/src/lib/meeting-notification-timing.ts +83 -0
- package/corpus/templates/clips/desktop/src/lib/native-recording-warm.ts +21 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +98 -20
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +197 -50
- package/corpus/templates/clips/desktop/src/styles.css +150 -53
- package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +362 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +41 -7
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +9 -2
- package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +89 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +71 -17
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +36 -1
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +62 -10
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +1 -25
- package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +36 -1
- package/corpus/templates/clips/package.json +2 -2
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/content/actions/_batch-utils.ts +8 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
- package/corpus/templates/content/actions/_content-database-personal-view.ts +80 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
- package/corpus/templates/content/actions/_database-utils.ts +6 -1
- package/corpus/templates/content/actions/_property-utils.ts +168 -0
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
- package/corpus/templates/content/actions/delete-document.ts +9 -13
- package/corpus/templates/content/actions/get-content-database-personal-view.ts +27 -0
- package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
- package/corpus/templates/content/actions/update-content-database-personal-view.ts +31 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +3 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +1 -1
- package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2631 -551
- package/corpus/templates/content/app/components/editor/database/filter-sort.ts +220 -18
- package/corpus/templates/content/app/hooks/use-content-database.ts +32 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
- package/corpus/templates/content/app/i18n/zh-TW.ts +16 -0
- package/corpus/templates/content/app/i18n-data.ts +154 -0
- package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-database-filters-now-support-notion-style-reset-save-for-eve.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-date-filters-can-now-target-a-between-range.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
- package/corpus/templates/content/package.json +2 -2
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +2 -0
- package/corpus/templates/content/server/plugins/db.ts +19 -0
- package/corpus/templates/content/shared/api.ts +24 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/design/package.json +2 -2
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/dispatch/app/i18n/zh-TW.ts +34 -1
- package/corpus/templates/dispatch/app/i18n-data.ts +387 -10
- package/corpus/templates/dispatch/app/routes/automations.tsx +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-08-added-an-automations-page-to-review-pause-and-create.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-08-destinations-now-shows-outbound-delivery-queue-health.md +6 -0
- package/corpus/templates/dispatch/package.json +2 -2
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/forms/package.json +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/macros/package.json +2 -2
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/mail/app/hooks/use-emails.ts +56 -44
- package/corpus/templates/mail/app/lib/gmail-mutation-queue.ts +325 -0
- package/corpus/templates/mail/changelog/2026-07-08-rapid-archive-and-mark-read-now-batch-gmail-updates-so-the-i.md +6 -0
- package/corpus/templates/mail/package.json +2 -2
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/plan/package.json +2 -2
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +46 -29
- package/corpus/templates/slides/app/context/DeckContext.tsx +45 -18
- package/corpus/templates/slides/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +115 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +22 -13
- package/corpus/templates/slides/changelog/2026-07-08-dropping-an-image-onto-a-slide-and-sending-it-to-the-agent-w.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-08-undo-works-after-the-agent-edits-a-slide-so-you-can-reverse.md +6 -0
- package/corpus/templates/slides/package.json +2 -2
- package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/agent/production-agent.d.ts +5 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +112 -42
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +23 -2
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.js +2 -2
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/tool-search.d.ts +2 -0
- package/dist/agent/tool-search.d.ts.map +1 -1
- package/dist/agent/tool-search.js +60 -4
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/catalog.json +2 -2
- package/dist/cli/add.js +1 -1
- package/dist/cli/add.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -3
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +24 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/upgrade.d.ts +100 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +678 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/client/AssistantChat.js +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/HighlightedCodeBlock.d.ts +2 -0
- package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
- package/dist/client/HighlightedCodeBlock.js +10 -1
- package/dist/client/HighlightedCodeBlock.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +32 -4
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +61 -8
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +12 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +136 -42
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +2 -9
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +6 -0
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +52 -19
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.d.ts +19 -4
- package/dist/client/settings/SettingsSection.d.ts.map +1 -1
- package/dist/client/settings/SettingsSection.js +33 -4
- package/dist/client/settings/SettingsSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +9 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +20 -2
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +85 -5
- package/dist/extensions/actions.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/scheduler.js +26 -1
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +19 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +19 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/channels.d.ts +8 -3
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +61 -22
- package/dist/notifications/channels.js.map +1 -1
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +14 -3
- package/dist/notifications/registry.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/types.d.ts +4 -1
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/notifications/types.js.map +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-chat-plugin.d.ts +5 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- 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/request-context.d.ts +7 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/styles/agent-conversation.css +1 -1
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/default/AGENTS.md +10 -3
- package/dist/templates/default/app/i18n/ar-SA.ts +21 -0
- package/dist/templates/default/app/i18n/de-DE.ts +21 -0
- package/dist/templates/default/app/i18n/en-US.ts +21 -0
- package/dist/templates/default/app/i18n/es-ES.ts +21 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +20 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +21 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +20 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +21 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +20 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/default/package.json +4 -3
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/headless/AGENTS.md +9 -3
- package/dist/templates/headless/package.json +4 -3
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/workspace-core/package.json +6 -6
- package/dist/templates/workspace-root/AGENTS.md +10 -4
- package/dist/templates/workspace-root/package.json +3 -2
- package/dist/triggers/dispatcher.js +27 -2
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +70 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/faq.mdx +17 -0
- package/docs/content/notifications.mdx +12 -6
- package/package.json +7 -6
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/default/AGENTS.md +10 -3
- package/src/templates/default/app/i18n/ar-SA.ts +21 -0
- package/src/templates/default/app/i18n/de-DE.ts +21 -0
- package/src/templates/default/app/i18n/en-US.ts +21 -0
- package/src/templates/default/app/i18n/es-ES.ts +21 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +20 -0
- package/src/templates/default/app/i18n/ja-JP.ts +21 -0
- package/src/templates/default/app/i18n/ko-KR.ts +20 -0
- package/src/templates/default/app/i18n/pt-BR.ts +21 -0
- package/src/templates/default/app/i18n/zh-CN.ts +20 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/default/package.json +4 -3
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/headless/AGENTS.md +9 -3
- package/src/templates/headless/package.json +4 -3
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/workspace-core/package.json +6 -6
- package/src/templates/workspace-root/AGENTS.md +10 -4
- package/src/templates/workspace-root/package.json +3 -2
|
@@ -73,6 +73,15 @@ export default defineAction({
|
|
|
73
73
|
.describe(
|
|
74
74
|
"If set, only return upcoming meetings starting within this many minutes. Used by the desktop reminder watcher.",
|
|
75
75
|
),
|
|
76
|
+
includeStartedWithinMin: z.coerce
|
|
77
|
+
.number()
|
|
78
|
+
.int()
|
|
79
|
+
.min(0)
|
|
80
|
+
.max(60)
|
|
81
|
+
.optional()
|
|
82
|
+
.describe(
|
|
83
|
+
"Also include meetings that started within this many minutes (desktop reminder hold window). Default 0.",
|
|
84
|
+
),
|
|
76
85
|
}),
|
|
77
86
|
http: { method: "GET" },
|
|
78
87
|
run: async (args) => {
|
|
@@ -92,6 +101,11 @@ export default defineAction({
|
|
|
92
101
|
now.getTime() + args.upcomingWithinMin * 60 * 1000,
|
|
93
102
|
).toISOString()
|
|
94
103
|
: null;
|
|
104
|
+
const startedWithinMin = args.includeStartedWithinMin ?? 0;
|
|
105
|
+
const upcomingWindowMinIso =
|
|
106
|
+
startedWithinMin > 0
|
|
107
|
+
? new Date(now.getTime() - startedWithinMin * 60 * 1000).toISOString()
|
|
108
|
+
: nowIso;
|
|
95
109
|
|
|
96
110
|
const whereClauses = [accessFilter(schema.meetings, schema.meetingShares)];
|
|
97
111
|
|
|
@@ -102,11 +116,12 @@ export default defineAction({
|
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
if (args.view === "upcoming") {
|
|
105
|
-
// Scheduled in the future
|
|
119
|
+
// Scheduled in the future (or recently started, for desktop hold window)
|
|
120
|
+
// and not yet finished.
|
|
106
121
|
whereClauses.push(
|
|
107
122
|
and(
|
|
108
123
|
isNotNull(schema.meetings.scheduledStart),
|
|
109
|
-
gte(schema.meetings.scheduledStart,
|
|
124
|
+
gte(schema.meetings.scheduledStart, upcomingWindowMinIso),
|
|
110
125
|
isNull(schema.meetings.actualStart),
|
|
111
126
|
isNull(schema.meetings.actualEnd),
|
|
112
127
|
upcomingWindowMaxIso
|
|
@@ -209,7 +224,10 @@ export default defineAction({
|
|
|
209
224
|
? new Date(now.getTime() - THIRTY_DAYS_MS).toISOString()
|
|
210
225
|
: args.view === "all"
|
|
211
226
|
? new Date(now.getTime() - THIRTY_DAYS_MS).toISOString()
|
|
212
|
-
:
|
|
227
|
+
: startedWithinMin > 0
|
|
228
|
+
? upcomingWindowMinIso
|
|
229
|
+
: // Small cushion for clock skew when listing pure upcoming.
|
|
230
|
+
new Date(now.getTime() - 60 * 1000).toISOString();
|
|
213
231
|
const timeMax =
|
|
214
232
|
args.view === "past"
|
|
215
233
|
? nowIso
|
|
@@ -253,6 +271,16 @@ export default defineAction({
|
|
|
253
271
|
const endMs = Date.parse(endIso);
|
|
254
272
|
if (Number.isNaN(startMs) || Number.isNaN(endMs)) continue;
|
|
255
273
|
if (args.view === "upcoming" && endMs < now.getTime()) continue;
|
|
274
|
+
// Only clamp already-started events when the desktop hold window
|
|
275
|
+
// is active — the normal Meetings list still shows in-progress
|
|
276
|
+
// calendar events until they end.
|
|
277
|
+
if (
|
|
278
|
+
args.view === "upcoming" &&
|
|
279
|
+
startedWithinMin > 0 &&
|
|
280
|
+
startMs < Date.parse(upcomingWindowMinIso)
|
|
281
|
+
) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
256
284
|
if (args.view === "past" && endMs >= now.getTime()) continue;
|
|
257
285
|
if (
|
|
258
286
|
upcomingWindowMaxIso &&
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: fixed
|
|
3
|
+
date: 2026-07-08
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Desktop clip recordings are louder after capture — mic-only clips skip the half-volume downmix and get a stronger pre-gain before loudness normalization; mic+system clips get makeup gain so the centered mix is not systematically quieter.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"dev": "vite build --watch",
|
|
8
8
|
"dev:hot": "tsx scripts/dev.ts",
|
|
9
9
|
"build": "vite build",
|
|
10
|
-
"typecheck": "
|
|
10
|
+
"typecheck": "tsc --noEmit",
|
|
11
11
|
"package": "pnpm build && tsx scripts/package.ts"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@types/chrome": "^0.2.0",
|
|
18
|
-
"@typescript/native-preview": "catalog:",
|
|
19
18
|
"tsx": "catalog:",
|
|
20
19
|
"typescript": "catalog:",
|
|
20
|
+
"typescript-7": "catalog:",
|
|
21
21
|
"vite": "catalog:"
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"@tauri-apps/cli": "^2.11.2",
|
|
32
32
|
"@types/react": "^19.2.14",
|
|
33
33
|
"@types/react-dom": "^19.2.3",
|
|
34
|
-
"@typescript/native-preview": "catalog:",
|
|
35
34
|
"@vitejs/plugin-react": "catalog:",
|
|
36
|
-
"typescript": "
|
|
35
|
+
"typescript": "catalog:",
|
|
36
|
+
"typescript-7": "catalog:",
|
|
37
37
|
"vite": "catalog:"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -713,6 +713,7 @@ export function App() {
|
|
|
713
713
|
const [meetingStartMessage, setMeetingStartMessage] = useState<string | null>(
|
|
714
714
|
null,
|
|
715
715
|
);
|
|
716
|
+
const [activeMeetingId, setActiveMeetingId] = useState<string | null>(null);
|
|
716
717
|
const [readinessOpen, setReadinessOpen] = useState<boolean>(
|
|
717
718
|
() => !loadBool(READINESS_REVIEWED_KEY, false),
|
|
718
719
|
);
|
|
@@ -1140,6 +1141,7 @@ export function App() {
|
|
|
1140
1141
|
}, [authStatus, callClipsAction]);
|
|
1141
1142
|
|
|
1142
1143
|
const startMeetingNotes = useCallback((meeting: PopoverMeeting) => {
|
|
1144
|
+
setActiveMeetingId(meeting.id);
|
|
1143
1145
|
setMeetingStartMessage(`Starting notes for ${meeting.title}…`);
|
|
1144
1146
|
emit("meetings:start-transcription", {
|
|
1145
1147
|
meetingId: meeting.id,
|
|
@@ -1147,10 +1149,98 @@ export function App() {
|
|
|
1147
1149
|
reason: "user",
|
|
1148
1150
|
}).catch((err) => {
|
|
1149
1151
|
console.error("[clips-popover] start meeting notes failed:", err);
|
|
1152
|
+
setActiveMeetingId(null);
|
|
1150
1153
|
setMeetingStartMessage("Could not start notes. Try again from Meetings.");
|
|
1151
1154
|
});
|
|
1152
1155
|
}, []);
|
|
1153
1156
|
|
|
1157
|
+
const startMeetingNotesAndJoin = useCallback(
|
|
1158
|
+
(meeting: PopoverMeeting) => {
|
|
1159
|
+
if (meeting.joinUrl) {
|
|
1160
|
+
openExternal(meeting.joinUrl).catch((err) => {
|
|
1161
|
+
console.error("[clips-popover] open meeting join url failed:", err);
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
startMeetingNotes(meeting);
|
|
1165
|
+
},
|
|
1166
|
+
[startMeetingNotes],
|
|
1167
|
+
);
|
|
1168
|
+
|
|
1169
|
+
const showActiveMeetingPill = useCallback((meetingId: string) => {
|
|
1170
|
+
invoke("recording_pill_show", { meetingId, mode: "meeting" }).catch(
|
|
1171
|
+
(err) => {
|
|
1172
|
+
console.error("[clips-popover] show meeting pill failed:", err);
|
|
1173
|
+
},
|
|
1174
|
+
);
|
|
1175
|
+
emit("clips:pill-context", { meetingId, mode: "meeting" }).catch(() => {});
|
|
1176
|
+
}, []);
|
|
1177
|
+
|
|
1178
|
+
useEffect(() => {
|
|
1179
|
+
invoke<string | null>("get_active_meeting_id")
|
|
1180
|
+
.then((meetingId) => {
|
|
1181
|
+
if (meetingId) setActiveMeetingId(meetingId);
|
|
1182
|
+
})
|
|
1183
|
+
.catch(() => {});
|
|
1184
|
+
|
|
1185
|
+
let stopped = false;
|
|
1186
|
+
const unlistens: Array<() => void> = [];
|
|
1187
|
+
const track = (promise: Promise<() => void>) => {
|
|
1188
|
+
promise
|
|
1189
|
+
.then((unlisten) => {
|
|
1190
|
+
if (stopped) {
|
|
1191
|
+
unlisten();
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
unlistens.push(unlisten);
|
|
1195
|
+
})
|
|
1196
|
+
.catch(() => {});
|
|
1197
|
+
};
|
|
1198
|
+
track(
|
|
1199
|
+
listen<{ meetingId?: string | null }>(
|
|
1200
|
+
"meetings:transcription-started",
|
|
1201
|
+
(event) => {
|
|
1202
|
+
if (event.payload?.meetingId) {
|
|
1203
|
+
setActiveMeetingId(event.payload.meetingId);
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
),
|
|
1207
|
+
);
|
|
1208
|
+
track(
|
|
1209
|
+
listen<{ meetingId?: string | null }>(
|
|
1210
|
+
"meetings:transcription-stopped",
|
|
1211
|
+
(event) => {
|
|
1212
|
+
setActiveMeetingId((current) =>
|
|
1213
|
+
!event.payload?.meetingId || event.payload.meetingId === current
|
|
1214
|
+
? null
|
|
1215
|
+
: current,
|
|
1216
|
+
);
|
|
1217
|
+
},
|
|
1218
|
+
),
|
|
1219
|
+
);
|
|
1220
|
+
track(
|
|
1221
|
+
listen<{ meetingId?: string | null }>(
|
|
1222
|
+
"meetings:transcription-error",
|
|
1223
|
+
(event) => {
|
|
1224
|
+
setActiveMeetingId((current) =>
|
|
1225
|
+
!event.payload?.meetingId || event.payload.meetingId === current
|
|
1226
|
+
? null
|
|
1227
|
+
: current,
|
|
1228
|
+
);
|
|
1229
|
+
},
|
|
1230
|
+
),
|
|
1231
|
+
);
|
|
1232
|
+
return () => {
|
|
1233
|
+
stopped = true;
|
|
1234
|
+
unlistens.forEach((unlisten) => unlisten());
|
|
1235
|
+
unlistens.length = 0;
|
|
1236
|
+
};
|
|
1237
|
+
}, []);
|
|
1238
|
+
|
|
1239
|
+
useEffect(() => {
|
|
1240
|
+
if (!popoverVisible || !activeMeetingId) return;
|
|
1241
|
+
showActiveMeetingPill(activeMeetingId);
|
|
1242
|
+
}, [activeMeetingId, popoverVisible, showActiveMeetingPill]);
|
|
1243
|
+
|
|
1154
1244
|
useMeetingTranscription({
|
|
1155
1245
|
callClipsAction,
|
|
1156
1246
|
serverUrl,
|
|
@@ -1286,6 +1376,9 @@ export function App() {
|
|
|
1286
1376
|
if (e.key === "Escape") {
|
|
1287
1377
|
// Don't close mid-recording — user would lose the recorder handle.
|
|
1288
1378
|
if (isRecording) return;
|
|
1379
|
+
// Reset nested views before hide so the next tray open lands on the
|
|
1380
|
+
// main recorder UI instead of resuming scrolled settings/meetings.
|
|
1381
|
+
setPopoverView("recorder");
|
|
1289
1382
|
hidePopover();
|
|
1290
1383
|
}
|
|
1291
1384
|
}
|
|
@@ -1328,7 +1421,11 @@ export function App() {
|
|
|
1328
1421
|
track(
|
|
1329
1422
|
listen<boolean>("clips:popover-visible", (ev) => {
|
|
1330
1423
|
console.log("[clips-popover] popover-visible =", ev.payload);
|
|
1331
|
-
|
|
1424
|
+
const visible = !!ev.payload;
|
|
1425
|
+
setPopoverVisible(visible);
|
|
1426
|
+
// Leaving settings/meetings/dictation mid-scroll should not resume on
|
|
1427
|
+
// the next open — always return to the main recorder surface.
|
|
1428
|
+
if (!visible) setPopoverView("recorder");
|
|
1332
1429
|
}),
|
|
1333
1430
|
);
|
|
1334
1431
|
// The bubble window emits `clips:bubble-closed` when the user clicks
|
|
@@ -1415,6 +1512,10 @@ export function App() {
|
|
|
1415
1512
|
// tracks (which causes the laggy / black / silently-failing recording
|
|
1416
1513
|
// symptoms). Reset to false once the recording is fully torn down.
|
|
1417
1514
|
const bubbleStreamTransferredToRecorder = useRef(false);
|
|
1515
|
+
// Bumped when the native stop path releases the camera mid-session so the
|
|
1516
|
+
// bubble effect re-acquires even if bubbleActive/cameraId are unchanged
|
|
1517
|
+
// (post-stop reopen with a blank "Default Camera" preview).
|
|
1518
|
+
const [bubbleSessionEpoch, setBubbleSessionEpoch] = useState(0);
|
|
1418
1519
|
const wantsCamera = mode !== "screen" && cameraOn;
|
|
1419
1520
|
const nativeFullscreenRecordingActive =
|
|
1420
1521
|
mode !== "camera" && shouldUseNativeFullscreenRecording(source);
|
|
@@ -1623,14 +1724,21 @@ export function App() {
|
|
|
1623
1724
|
invoke("hide_overlays").catch(() => {});
|
|
1624
1725
|
}
|
|
1625
1726
|
};
|
|
1626
|
-
}, [bubbleActive, cameraId]);
|
|
1727
|
+
}, [bubbleActive, cameraId, bubbleSessionEpoch]);
|
|
1627
1728
|
|
|
1628
1729
|
useEffect(() => {
|
|
1629
1730
|
let unlisten: (() => void) | null = null;
|
|
1630
1731
|
let cancelled = false;
|
|
1631
1732
|
listen("clips:release-camera", () => {
|
|
1632
1733
|
console.log(`[popover] releasing camera`);
|
|
1734
|
+
// Native stop closes the bubble and kills tracks while React may still
|
|
1735
|
+
// hold a live RecorderHandle during finalize/upload. Clear ownership so
|
|
1736
|
+
// the bubble session can re-acquire a fresh preview, and so Start is not
|
|
1737
|
+
// stuck on an ended stream.
|
|
1738
|
+
bubbleStreamTransferredToRecorder.current = false;
|
|
1633
1739
|
bubbleStreamRef.current?.getTracks().forEach((t) => t.stop());
|
|
1740
|
+
bubbleStreamRef.current = null;
|
|
1741
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
1634
1742
|
})
|
|
1635
1743
|
.then((u) => {
|
|
1636
1744
|
if (cancelled) u();
|
|
@@ -1643,6 +1751,24 @@ export function App() {
|
|
|
1643
1751
|
};
|
|
1644
1752
|
}, []);
|
|
1645
1753
|
|
|
1754
|
+
// If the popover reopens while camera is still wanted, and the previous
|
|
1755
|
+
// bubble stream is gone or all tracks have ended (common after native stop
|
|
1756
|
+
// + mid-upload reopen), bump the session epoch so the bubble effect
|
|
1757
|
+
// re-acquires getUserMedia + WebRTC instead of showing a blank "Default
|
|
1758
|
+
// Camera" label with a silent Start.
|
|
1759
|
+
useEffect(() => {
|
|
1760
|
+
if (!popoverVisible || !wantsCamera) return;
|
|
1761
|
+
if (recordingFlowGateRef.current || recordingFlowActive) return;
|
|
1762
|
+
const tracks = bubbleStreamRef.current?.getTracks() ?? [];
|
|
1763
|
+
const needsFreshBubble =
|
|
1764
|
+
tracks.length === 0 ||
|
|
1765
|
+
tracks.every((track) => track.readyState === "ended");
|
|
1766
|
+
if (!needsFreshBubble) return;
|
|
1767
|
+
bubbleStreamTransferredToRecorder.current = false;
|
|
1768
|
+
bubbleStreamRef.current = null;
|
|
1769
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
1770
|
+
}, [popoverVisible, wantsCamera, recordingFlowActive]);
|
|
1771
|
+
|
|
1646
1772
|
// ---- auto-size popover to content --------------------------------------
|
|
1647
1773
|
// The Tauri window is fixed-size via tauri.conf.json, but our content
|
|
1648
1774
|
// height varies (more rows when a camera is on, Recent list toggle, etc.).
|
|
@@ -1859,7 +1985,25 @@ export function App() {
|
|
|
1859
1985
|
async function handleStartRecording(options?: {
|
|
1860
1986
|
ignoreActiveRecorder?: boolean;
|
|
1861
1987
|
}) {
|
|
1862
|
-
if (recorder && !options?.ignoreActiveRecorder)
|
|
1988
|
+
if (recorder && !options?.ignoreActiveRecorder) {
|
|
1989
|
+
console.warn(
|
|
1990
|
+
"[clips-popover] handleStartRecording ignored — recorder already active",
|
|
1991
|
+
);
|
|
1992
|
+
setRecError(
|
|
1993
|
+
"Still finishing the last recording. Wait a moment, then try again.",
|
|
1994
|
+
);
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1997
|
+
const bubbleTracks = bubbleStreamRef.current?.getTracks() ?? [];
|
|
1998
|
+
const bubbleStreamDead =
|
|
1999
|
+
bubbleTracks.length > 0 &&
|
|
2000
|
+
bubbleTracks.every((track) => track.readyState === "ended");
|
|
2001
|
+
if (bubbleStreamDead) {
|
|
2002
|
+
console.warn("[clips-popover] clearing ended bubble stream before start");
|
|
2003
|
+
bubbleStreamTransferredToRecorder.current = false;
|
|
2004
|
+
bubbleStreamRef.current = null;
|
|
2005
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
2006
|
+
}
|
|
1863
2007
|
if (localRecordingMode === "off") {
|
|
1864
2008
|
if (videoStorageStatus === "checking") {
|
|
1865
2009
|
setRecError("Checking video storage. Try again in a moment.");
|
|
@@ -2202,11 +2346,28 @@ export function App() {
|
|
|
2202
2346
|
};
|
|
2203
2347
|
track(
|
|
2204
2348
|
listen("clips:recorder-stop", async () => {
|
|
2349
|
+
// Detach the React Start/bubble gate immediately. Native stop already
|
|
2350
|
+
// released the camera and cleared Rust `is_recording_active` mid-
|
|
2351
|
+
// finalize; keeping `recorder` set through the whole upload made
|
|
2352
|
+
// reopen show a blank preview and made Start a silent no-op.
|
|
2353
|
+
const handle = recorder;
|
|
2354
|
+
bubbleStreamTransferredToRecorder.current = false;
|
|
2355
|
+
bubbleStreamRef.current = null;
|
|
2356
|
+
recordingFlowGateRef.current = false;
|
|
2357
|
+
(window as unknown as { clipsForceAlive?: boolean }).clipsForceAlive =
|
|
2358
|
+
false;
|
|
2359
|
+
setRecordingFlowActive(false);
|
|
2360
|
+
setRecorder(null);
|
|
2361
|
+
// Force a fresh bubble session even when bubbleActive stays true
|
|
2362
|
+
// (popover still open / camera still on). Without this epoch bump the
|
|
2363
|
+
// effect does not re-run and reopen shows ended tracks until Start
|
|
2364
|
+
// discovers them.
|
|
2365
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
2366
|
+
|
|
2205
2367
|
let stopFailed = false;
|
|
2206
2368
|
let stopResult: RecorderStopResult | null = null;
|
|
2207
2369
|
try {
|
|
2208
|
-
stopResult = await
|
|
2209
|
-
if (cancelled) return;
|
|
2370
|
+
stopResult = await handle.stop();
|
|
2210
2371
|
if (stopResult.localOnly) {
|
|
2211
2372
|
setLocalRecordingNotice({
|
|
2212
2373
|
folderPath: stopResult.localFolder,
|
|
@@ -2217,36 +2378,20 @@ export function App() {
|
|
|
2217
2378
|
}
|
|
2218
2379
|
} catch (err) {
|
|
2219
2380
|
stopFailed = true;
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
await loadPendingUploads();
|
|
2223
|
-
}
|
|
2381
|
+
setRecError(err instanceof Error ? err.message : String(err));
|
|
2382
|
+
await loadPendingUploads();
|
|
2224
2383
|
} finally {
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
//
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
setRecorder(null);
|
|
2237
|
-
setRecordingFlowActive(false);
|
|
2238
|
-
invoke("set_recording_state", { active: false }).catch(() => {});
|
|
2239
|
-
if (stopFailed || stopResult?.localOnly) {
|
|
2240
|
-
invoke("show_popover").catch(() => {});
|
|
2241
|
-
} else {
|
|
2242
|
-
// Close the popover — recorder.stop() already opened the
|
|
2243
|
-
// recording's page in the default browser. The popover doesn't
|
|
2244
|
-
// need to hang around.
|
|
2245
|
-
getCurrentWindow()
|
|
2246
|
-
.hide()
|
|
2247
|
-
.catch(() => {});
|
|
2248
|
-
emit("clips:popover-visible", false).catch(() => {});
|
|
2249
|
-
}
|
|
2384
|
+
invoke("set_recording_state", { active: false }).catch(() => {});
|
|
2385
|
+
if (stopFailed || stopResult?.localOnly) {
|
|
2386
|
+
invoke("show_popover").catch(() => {});
|
|
2387
|
+
} else {
|
|
2388
|
+
// Close the popover — recorder.stop() already opened the
|
|
2389
|
+
// recording's page in the default browser. The popover doesn't
|
|
2390
|
+
// need to hang around.
|
|
2391
|
+
getCurrentWindow()
|
|
2392
|
+
.hide()
|
|
2393
|
+
.catch(() => {});
|
|
2394
|
+
emit("clips:popover-visible", false).catch(() => {});
|
|
2250
2395
|
}
|
|
2251
2396
|
}
|
|
2252
2397
|
}),
|
|
@@ -2265,6 +2410,7 @@ export function App() {
|
|
|
2265
2410
|
recordingFlowGateRef.current = false;
|
|
2266
2411
|
setRecorder(null);
|
|
2267
2412
|
setRecordingFlowActive(false);
|
|
2413
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
2268
2414
|
invoke("set_recording_state", { active: false }).catch(() => {});
|
|
2269
2415
|
invoke("show_popover").catch(() => {});
|
|
2270
2416
|
}
|
|
@@ -2285,6 +2431,7 @@ export function App() {
|
|
|
2285
2431
|
recordingFlowGateRef.current = false;
|
|
2286
2432
|
setRecorder(null);
|
|
2287
2433
|
setRecordingFlowActive(false);
|
|
2434
|
+
setBubbleSessionEpoch((epoch) => epoch + 1);
|
|
2288
2435
|
invoke("set_recording_state", { active: false }).catch(() => {});
|
|
2289
2436
|
// Starting a new browser capture must come from a fresh click in
|
|
2290
2437
|
// this webview. The toolbar click arrives here through async Tauri
|
|
@@ -2362,6 +2509,7 @@ export function App() {
|
|
|
2362
2509
|
loading={meetingsLoading}
|
|
2363
2510
|
error={meetingsError}
|
|
2364
2511
|
startMessage={meetingStartMessage}
|
|
2512
|
+
activeMeetingId={activeMeetingId}
|
|
2365
2513
|
meetingsEnabled={featureConfig?.meetingsEnabled !== false}
|
|
2366
2514
|
onBack={() => setPopoverView("recorder")}
|
|
2367
2515
|
onRefresh={fetchUpcomingMeetings}
|
|
@@ -2371,6 +2519,8 @@ export function App() {
|
|
|
2371
2519
|
}
|
|
2372
2520
|
onOpenSettings={() => setPopoverView("settings")}
|
|
2373
2521
|
onStartNotes={startMeetingNotes}
|
|
2522
|
+
onStartNotesAndJoin={startMeetingNotesAndJoin}
|
|
2523
|
+
onShowActiveMeeting={showActiveMeetingPill}
|
|
2374
2524
|
/>
|
|
2375
2525
|
</div>
|
|
2376
2526
|
);
|
|
@@ -3269,6 +3419,7 @@ function MeetingsPopoverView({
|
|
|
3269
3419
|
loading,
|
|
3270
3420
|
error,
|
|
3271
3421
|
startMessage,
|
|
3422
|
+
activeMeetingId,
|
|
3272
3423
|
meetingsEnabled,
|
|
3273
3424
|
onBack,
|
|
3274
3425
|
onRefresh,
|
|
@@ -3276,11 +3427,14 @@ function MeetingsPopoverView({
|
|
|
3276
3427
|
onOpenMeeting,
|
|
3277
3428
|
onOpenSettings,
|
|
3278
3429
|
onStartNotes,
|
|
3430
|
+
onStartNotesAndJoin,
|
|
3431
|
+
onShowActiveMeeting,
|
|
3279
3432
|
}: {
|
|
3280
3433
|
meetings: PopoverMeeting[];
|
|
3281
3434
|
loading: boolean;
|
|
3282
3435
|
error: string | null;
|
|
3283
3436
|
startMessage: string | null;
|
|
3437
|
+
activeMeetingId: string | null;
|
|
3284
3438
|
meetingsEnabled: boolean;
|
|
3285
3439
|
onBack: () => void;
|
|
3286
3440
|
onRefresh: () => void;
|
|
@@ -3288,6 +3442,8 @@ function MeetingsPopoverView({
|
|
|
3288
3442
|
onOpenMeeting: (meetingId: string) => void;
|
|
3289
3443
|
onOpenSettings: () => void;
|
|
3290
3444
|
onStartNotes: (meeting: PopoverMeeting) => void;
|
|
3445
|
+
onStartNotesAndJoin: (meeting: PopoverMeeting) => void;
|
|
3446
|
+
onShowActiveMeeting: (meetingId: string) => void;
|
|
3291
3447
|
}) {
|
|
3292
3448
|
return (
|
|
3293
3449
|
<div className="setup popover-view">
|
|
@@ -3345,6 +3501,8 @@ function MeetingsPopoverView({
|
|
|
3345
3501
|
<div className="popover-list">
|
|
3346
3502
|
{meetings.map((meeting) => {
|
|
3347
3503
|
const canStart = meetingCanStartNotes(meeting);
|
|
3504
|
+
const hasJoin = Boolean(meeting.joinUrl);
|
|
3505
|
+
const isActive = activeMeetingId === meeting.id;
|
|
3348
3506
|
return (
|
|
3349
3507
|
<div className="popover-list-item" key={meeting.id}>
|
|
3350
3508
|
<div className="popover-list-icon">
|
|
@@ -3357,13 +3515,32 @@ function MeetingsPopoverView({
|
|
|
3357
3515
|
{meeting.platform ? ` · ${meeting.platform}` : ""}
|
|
3358
3516
|
</div>
|
|
3359
3517
|
</div>
|
|
3360
|
-
{
|
|
3518
|
+
{isActive ? (
|
|
3519
|
+
<button
|
|
3520
|
+
type="button"
|
|
3521
|
+
className="popover-list-action popover-list-action-active"
|
|
3522
|
+
onClick={() => onShowActiveMeeting(meeting.id)}
|
|
3523
|
+
title="Meeting notes are recording"
|
|
3524
|
+
>
|
|
3525
|
+
<span className="popover-list-action-dot" aria-hidden />
|
|
3526
|
+
Recording
|
|
3527
|
+
</button>
|
|
3528
|
+
) : canStart ? (
|
|
3361
3529
|
<button
|
|
3362
3530
|
type="button"
|
|
3363
3531
|
className="popover-list-action popover-list-action-primary"
|
|
3364
|
-
onClick={() =>
|
|
3532
|
+
onClick={() =>
|
|
3533
|
+
hasJoin
|
|
3534
|
+
? onStartNotesAndJoin(meeting)
|
|
3535
|
+
: onStartNotes(meeting)
|
|
3536
|
+
}
|
|
3537
|
+
title={
|
|
3538
|
+
hasJoin
|
|
3539
|
+
? "Start notes and join the meeting"
|
|
3540
|
+
: "Start meeting notes"
|
|
3541
|
+
}
|
|
3365
3542
|
>
|
|
3366
|
-
Start notes
|
|
3543
|
+
{hasJoin ? "Start + join" : "Start notes"}
|
|
3367
3544
|
</button>
|
|
3368
3545
|
) : (
|
|
3369
3546
|
<button
|
|
@@ -245,6 +245,14 @@ export function useMeetingTranscription({
|
|
|
245
245
|
const existing = sessionRef.current;
|
|
246
246
|
if (existing) {
|
|
247
247
|
if (!existing.stopping && existing.meetingId === meetingId) {
|
|
248
|
+
await invoke("recording_pill_show", {
|
|
249
|
+
meetingId: existing.meetingId,
|
|
250
|
+
mode: "meeting",
|
|
251
|
+
}).catch(() => {});
|
|
252
|
+
emit("clips:pill-context", {
|
|
253
|
+
meetingId: existing.meetingId,
|
|
254
|
+
mode: "meeting",
|
|
255
|
+
}).catch(() => {});
|
|
248
256
|
emit("meetings:hide-notification", { meetingId }).catch(() => {});
|
|
249
257
|
return;
|
|
250
258
|
}
|
|
@@ -282,7 +290,13 @@ export function useMeetingTranscription({
|
|
|
282
290
|
};
|
|
283
291
|
sessionRef.current = session;
|
|
284
292
|
await invoke("set_recording_state", { active: true }).catch(() => {});
|
|
285
|
-
await invoke("set_meeting_active", {
|
|
293
|
+
await invoke("set_meeting_active", {
|
|
294
|
+
active: true,
|
|
295
|
+
meetingId: resolvedMeetingId,
|
|
296
|
+
}).catch(() => {});
|
|
297
|
+
emit("meetings:transcription-started", {
|
|
298
|
+
meetingId: resolvedMeetingId,
|
|
299
|
+
}).catch(() => {});
|
|
286
300
|
|
|
287
301
|
const scheduleFlush = () => {
|
|
288
302
|
if (session.flushTimer) window.clearTimeout(session.flushTimer);
|
|
@@ -363,12 +377,19 @@ export function useMeetingTranscription({
|
|
|
363
377
|
};
|
|
364
378
|
|
|
365
379
|
// Resume the engine that initial start settled on (no fallback here —
|
|
366
|
-
// the engine choice was already made below).
|
|
380
|
+
// the engine choice was already made below). Keep voice processing
|
|
381
|
+
// off: AEC/ducking on the shared mic can make Zoom/Meet callers hear
|
|
382
|
+
// the local user at a whisper while Clips is transcribed.
|
|
367
383
|
const startAudio = async () => {
|
|
368
|
-
await restartTranscriptionEngine(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
384
|
+
await restartTranscriptionEngine(
|
|
385
|
+
session.engine,
|
|
386
|
+
{
|
|
387
|
+
deviceId: selectedMicId,
|
|
388
|
+
label: selectedMicLabel,
|
|
389
|
+
},
|
|
390
|
+
true,
|
|
391
|
+
false,
|
|
392
|
+
);
|
|
372
393
|
};
|
|
373
394
|
|
|
374
395
|
// Pause/resume state machine — see app.tsx for full explanation.
|
|
@@ -538,6 +559,9 @@ export function useMeetingTranscription({
|
|
|
538
559
|
|
|
539
560
|
session.engine = await startTranscriptionEngine({
|
|
540
561
|
mic: { deviceId: selectedMicId, label: selectedMicLabel },
|
|
562
|
+
// Match clip recordings: VoiceProcessingIO AEC/ducking on the shared
|
|
563
|
+
// mic can tank live meeting volume for remote participants.
|
|
564
|
+
voiceProcessing: false,
|
|
541
565
|
});
|
|
542
566
|
|
|
543
567
|
await invoke("silence_detector_start", {
|