@agent-native/core 0.98.17 → 0.99.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +25 -0
- package/corpus/core/docs/content/actions.mdx +1 -1
- package/corpus/core/docs/content/authentication.mdx +1 -1
- package/corpus/core/docs/content/dispatch.mdx +3 -3
- package/corpus/core/docs/content/external-agents.mdx +30 -19
- package/corpus/core/docs/content/locales/ar-SA/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
- package/corpus/core/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
- package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/ar-SA/server.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
- package/corpus/core/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
- package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/server.mdx +2 -2
- package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +32 -19
- package/corpus/core/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
- package/corpus/core/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
- package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/es-ES/server.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
- package/corpus/core/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
- package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/fr-FR/server.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +31 -19
- package/corpus/core/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
- package/corpus/core/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
- package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/hi-IN/server.mdx +2 -2
- package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/ja-JP/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
- package/corpus/core/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
- package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/ja-JP/server.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/ko-KR/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +30 -19
- package/corpus/core/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
- package/corpus/core/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
- package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/ko-KR/server.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +32 -19
- package/corpus/core/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
- package/corpus/core/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
- package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/pt-BR/server.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-CN/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
- package/corpus/core/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
- package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-CN/server.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-TW/actions.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/dispatch.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +23 -19
- package/corpus/core/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
- package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
- package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/locales/zh-TW/server.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/template-assets.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +3 -3
- package/corpus/core/docs/content/mcp-clients.mdx +31 -4
- package/corpus/core/docs/content/mcp-protocol.mdx +35 -15
- package/corpus/core/docs/content/plan-plugin.mdx +3 -3
- package/corpus/core/docs/content/server.mdx +2 -2
- package/corpus/core/docs/content/skills-guide.mdx +1 -1
- package/corpus/core/docs/content/template-assets.mdx +1 -1
- package/corpus/core/docs/content/template-dispatch.mdx +2 -2
- package/corpus/core/docs/content/template-plan.mdx +3 -3
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +3 -0
- package/corpus/core/src/a2a/handlers.ts +95 -7
- package/corpus/core/src/agent/production-agent.ts +21 -0
- package/corpus/core/src/cli/connect.ts +50 -24
- package/corpus/core/src/cli/mcp-config-writers.ts +10 -0
- package/corpus/core/src/cli/mcp.ts +5 -5
- package/corpus/core/src/cli/pr-visual-recap-workflow.ts +1 -1
- package/corpus/core/src/cli/skills-content/assets-skill.ts +1 -1
- package/corpus/core/src/cli/skills-content/design-exploration-skill.ts +1 -1
- package/corpus/core/src/cli/skills-content/help.ts +1 -1
- package/corpus/core/src/cli/skills-content/plan-setup-auth.ts +1 -1
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +1 -1
- package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +2 -2
- package/corpus/core/src/cli/skills.ts +23 -12
- package/corpus/core/src/client/analytics.ts +13 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +5 -0
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +17 -0
- package/corpus/core/src/embedding/agent.ts +8 -6
- package/corpus/core/src/localization/default-messages.ts +7 -0
- package/corpus/core/src/mcp/ask-app-inline-tasks.ts +125 -0
- package/corpus/core/src/mcp/build-server.ts +65 -3
- package/corpus/core/src/mcp/builtin-tools.ts +186 -22
- package/corpus/core/src/mcp/connect-route.ts +17 -14
- package/corpus/core/src/mcp/oauth-route.ts +38 -13
- package/corpus/core/src/mcp/route-paths.ts +34 -0
- package/corpus/core/src/mcp/server.ts +21 -10
- package/corpus/core/src/mcp/stdio.ts +34 -16
- package/corpus/core/src/mcp/workspace-resolve.ts +2 -1
- package/corpus/core/src/mcp-client/manager.ts +5 -3
- package/corpus/core/src/mcp-client/remote-store.ts +10 -10
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +13 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +42 -9
- package/corpus/core/src/server/agent-teams.ts +17 -0
- package/corpus/core/src/server/auth.ts +22 -6
- package/corpus/core/src/server/core-routes-plugin.ts +30 -24
- package/corpus/core/src/server/csrf.ts +17 -0
- package/corpus/core/src/server/framework-request-handler.ts +8 -2
- package/corpus/core/src/server/google-oauth.ts +12 -2
- package/corpus/core/src/server/http-response-telemetry.ts +6 -1
- package/corpus/core/src/server/recap-image-route.ts +3 -3
- package/corpus/core/src/server/security-headers.ts +7 -1
- package/corpus/core/src/server/ssr-handler.ts +2 -0
- package/corpus/core/src/shared/cache-control.ts +6 -4
- package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +10 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/analytics/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/analytics/app/assets/replay-cursor.svg +17 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -3
- package/corpus/templates/analytics/app/global.css +71 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +32 -4
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +1 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +49 -11
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
- package/corpus/templates/analytics/changelog/2026-07-13-all-time-dashboard-filters-no-longer-send-invalid-dates-to-b.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-daily-dashboard-emails-recover-more-reliably-from-serverless.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-error-issue-titles-wrap-instead-of-overflowing.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-saving-a-new-dashboard-view-no-longer-fails-with-a-server-er.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-session-replay-cursors-stay-hidden-until-their-first-recorde.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-session-replay-links-now-support-cmd-click-and-middle-click-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-13-session-replays-keep-a-visible-mac-style-cursor-over-the-vis.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -2
- package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +57 -1
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +266 -28
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +43 -4
- package/corpus/templates/analytics/server/lib/error-capture.ts +24 -5
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/analytics/server/routes/[...page].get.ts +0 -2
- package/corpus/templates/assets/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/assets/agent-native.app-skill.json +1 -1
- package/corpus/templates/brain/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/calendar/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/calendar/AGENTS.md +2 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -19
- package/corpus/templates/calendar/app/lib/attendee-local-time.ts +14 -5
- package/corpus/templates/calendar/changelog/2026-07-13-your-local-time-now-follows-your-browser-timezone-and-event-.md +6 -0
- package/corpus/templates/chat/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -2
- package/corpus/templates/clips/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/clips/AGENTS.md +7 -0
- package/corpus/templates/clips/actions/list-meetings.ts +19 -4
- package/corpus/templates/clips/actions/start-meeting-recording.ts +7 -1
- package/corpus/templates/clips/app/components/library/recording-card.tsx +27 -26
- package/corpus/templates/clips/app/components/library/space-card.tsx +4 -6
- package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +75 -78
- package/corpus/templates/clips/app/components/recorder/confetti-canvas.tsx +18 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +6 -12
- package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +19 -2
- package/corpus/templates/clips/app/lib/camera-composite.ts +70 -10
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -1
- package/corpus/templates/clips/app/routes/record.tsx +5 -25
- package/corpus/templates/clips/changelog/2026-07-13-clips-desktop-now-requires-macos-13-for-native-capture.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-clips-hide-solo-meeting-reminders.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-clips-now-removes-duplicate-mic-and-system-transcript-turns-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-desktop-recordings-run-cooler-and-quieter-live-transcription.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-meeting-recordings-now-stop-after-a-calendar-meeting-ends-an.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-meeting-transcripts-now-use-a-clean-agent-chat-style-reading.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-13-screen-recordings-use-less-processing-power-during-longer-ca.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +5 -3
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +17 -14
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +8 -2
- package/corpus/templates/clips/desktop/README.md +3 -0
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -2
- package/corpus/templates/clips/desktop/src/lib/silence-events.ts +1 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +5 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +134 -5
- package/corpus/templates/clips/desktop/src/lib/upload-video-stream.ts +28 -0
- package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +10 -3
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +42 -9
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -2
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +6 -1
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +77 -1
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +104 -25
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +4 -0
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +287 -32
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
- package/corpus/templates/clips/server/lib/calendar-event-classification.ts +28 -0
- package/corpus/templates/clips/server/routes/[...page].get.ts +1 -59
- package/corpus/templates/clips/shared/recording-capture.ts +37 -0
- package/corpus/templates/content/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/content/agent-native.app-skill.json +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +18 -16
- package/corpus/templates/content/server/routes/[...page].get.ts +1 -15
- package/corpus/templates/design/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/design/actions/connect-assets-mcp.ts +1 -1
- package/corpus/templates/design/agent-native.app-skill.json +1 -1
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +88 -12
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4 -1
- package/corpus/templates/design/changelog/2026-07-13-adding-shapes-preserves-canvas-background.md +6 -0
- package/corpus/templates/design/changelog/2026-07-13-clicking-quickly-between-overlapping-elements-no-longer-bounc.md +6 -0
- package/corpus/templates/design/server/plugins/assets-mcp.ts +1 -1
- package/corpus/templates/design/server/routes/[...page].get.ts +0 -2
- package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/forms/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/macros/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/mail/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/plan/.agents/skills/security/SKILL.md +10 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +1 -1
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +2 -2
- package/corpus/templates/plan/agent-native.app-skill.json +1 -1
- package/corpus/templates/plan/app/lib/plan-local-bridge.ts +6 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +15 -6
- package/corpus/templates/plan/changelog/2026-07-13-fixed-local-plan-previews-continuously-flickering-while-revi.md +6 -0
- package/corpus/templates/plan/server/routes/[...page].get.ts +0 -2
- package/corpus/templates/slides/.agents/skills/security/SKILL.md +10 -0
- package/dist/a2a/client.d.ts +2 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -0
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +84 -7
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/agent/production-agent.d.ts +9 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +12 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/connect.d.ts +2 -2
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +45 -23
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +7 -0
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.js +5 -3
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +1 -1
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/skills-content/assets-skill.d.ts +1 -1
- package/dist/cli/skills-content/assets-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/assets-skill.js +1 -1
- package/dist/cli/skills-content/assets-skill.js.map +1 -1
- package/dist/cli/skills-content/design-exploration-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-exploration-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-exploration-skill.js +1 -1
- package/dist/cli/skills-content/design-exploration-skill.js.map +1 -1
- package/dist/cli/skills-content/help.d.ts +1 -1
- package/dist/cli/skills-content/help.d.ts.map +1 -1
- package/dist/cli/skills-content/help.js +1 -1
- package/dist/cli/skills-content/help.js.map +1 -1
- package/dist/cli/skills-content/plan-setup-auth.d.ts +1 -1
- package/dist/cli/skills-content/plan-setup-auth.d.ts.map +1 -1
- package/dist/cli/skills-content/plan-setup-auth.js +1 -1
- package/dist/cli/skills-content/plan-setup-auth.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +2 -2
- package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +16 -12
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +11 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +1 -1
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +14 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/embedding/agent.d.ts.map +1 -1
- package/dist/embedding/agent.js +6 -7
- package/dist/embedding/agent.js.map +1 -1
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +5 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/ask-app-inline-tasks.d.ts +47 -0
- package/dist/mcp/ask-app-inline-tasks.d.ts.map +1 -0
- package/dist/mcp/ask-app-inline-tasks.js +87 -0
- package/dist/mcp/ask-app-inline-tasks.js.map +1 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +56 -3
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +141 -21
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/mcp/connect-route.d.ts +12 -10
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +17 -14
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/mcp/oauth-route.d.ts +1 -1
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +30 -13
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/route-paths.d.ts +13 -0
- package/dist/mcp/route-paths.d.ts.map +1 -0
- package/dist/mcp/route-paths.js +27 -0
- package/dist/mcp/route-paths.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts +7 -6
- package/dist/mcp/stdio.d.ts.map +1 -1
- package/dist/mcp/stdio.js +27 -15
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp/workspace-resolve.d.ts +2 -1
- package/dist/mcp/workspace-resolve.d.ts.map +1 -1
- package/dist/mcp/workspace-resolve.js +2 -1
- package/dist/mcp/workspace-resolve.js.map +1 -1
- package/dist/mcp-client/manager.js +6 -3
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.js +5 -7
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +11 -1
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +43 -11
- 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/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +15 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +16 -6
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +4 -3
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +20 -15
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +11 -0
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +8 -2
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-oauth.d.ts +2 -0
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +11 -2
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/http-response-telemetry.d.ts.map +1 -1
- package/dist/server/http-response-telemetry.js +4 -1
- package/dist/server/http-response-telemetry.js.map +1 -1
- package/dist/server/recap-image-route.js +3 -3
- package/dist/server/recap-image-route.js.map +1 -1
- package/dist/server/security-headers.d.ts.map +1 -1
- package/dist/server/security-headers.js +4 -1
- package/dist/server/security-headers.js.map +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +3 -1
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/shared/cache-control.d.ts +7 -6
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +4 -3
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/templates/default/.agents/skills/security/SKILL.md +10 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
- package/docs/content/actions.mdx +1 -1
- package/docs/content/authentication.mdx +1 -1
- package/docs/content/dispatch.mdx +3 -3
- package/docs/content/external-agents.mdx +30 -19
- package/docs/content/locales/ar-SA/actions.mdx +1 -1
- package/docs/content/locales/ar-SA/authentication.mdx +1 -1
- package/docs/content/locales/ar-SA/dispatch.mdx +3 -3
- package/docs/content/locales/ar-SA/external-agents.mdx +23 -19
- package/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
- package/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
- package/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
- package/docs/content/locales/ar-SA/server.mdx +2 -2
- package/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
- package/docs/content/locales/ar-SA/template-assets.mdx +1 -1
- package/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
- package/docs/content/locales/ar-SA/template-plan.mdx +3 -3
- package/docs/content/locales/de-DE/actions.mdx +1 -1
- package/docs/content/locales/de-DE/authentication.mdx +1 -1
- package/docs/content/locales/de-DE/dispatch.mdx +3 -3
- package/docs/content/locales/de-DE/external-agents.mdx +23 -19
- package/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
- package/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
- package/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
- package/docs/content/locales/de-DE/server.mdx +2 -2
- package/docs/content/locales/de-DE/skills-guide.mdx +1 -1
- package/docs/content/locales/de-DE/template-assets.mdx +1 -1
- package/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
- package/docs/content/locales/de-DE/template-plan.mdx +3 -3
- package/docs/content/locales/es-ES/actions.mdx +1 -1
- package/docs/content/locales/es-ES/authentication.mdx +1 -1
- package/docs/content/locales/es-ES/dispatch.mdx +3 -3
- package/docs/content/locales/es-ES/external-agents.mdx +32 -19
- package/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
- package/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
- package/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
- package/docs/content/locales/es-ES/server.mdx +2 -2
- package/docs/content/locales/es-ES/skills-guide.mdx +1 -1
- package/docs/content/locales/es-ES/template-assets.mdx +1 -1
- package/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
- package/docs/content/locales/es-ES/template-plan.mdx +3 -3
- package/docs/content/locales/fr-FR/actions.mdx +1 -1
- package/docs/content/locales/fr-FR/authentication.mdx +1 -1
- package/docs/content/locales/fr-FR/dispatch.mdx +3 -3
- package/docs/content/locales/fr-FR/external-agents.mdx +23 -19
- package/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
- package/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
- package/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
- package/docs/content/locales/fr-FR/server.mdx +2 -2
- package/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
- package/docs/content/locales/fr-FR/template-assets.mdx +1 -1
- package/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
- package/docs/content/locales/fr-FR/template-plan.mdx +3 -3
- package/docs/content/locales/hi-IN/actions.mdx +1 -1
- package/docs/content/locales/hi-IN/authentication.mdx +1 -1
- package/docs/content/locales/hi-IN/dispatch.mdx +3 -3
- package/docs/content/locales/hi-IN/external-agents.mdx +31 -19
- package/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
- package/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
- package/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
- package/docs/content/locales/hi-IN/server.mdx +2 -2
- package/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
- package/docs/content/locales/hi-IN/template-assets.mdx +1 -1
- package/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
- package/docs/content/locales/hi-IN/template-plan.mdx +3 -3
- package/docs/content/locales/ja-JP/actions.mdx +1 -1
- package/docs/content/locales/ja-JP/authentication.mdx +1 -1
- package/docs/content/locales/ja-JP/dispatch.mdx +3 -3
- package/docs/content/locales/ja-JP/external-agents.mdx +23 -19
- package/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
- package/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
- package/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
- package/docs/content/locales/ja-JP/server.mdx +2 -2
- package/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
- package/docs/content/locales/ja-JP/template-assets.mdx +1 -1
- package/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
- package/docs/content/locales/ja-JP/template-plan.mdx +3 -3
- package/docs/content/locales/ko-KR/actions.mdx +1 -1
- package/docs/content/locales/ko-KR/authentication.mdx +1 -1
- package/docs/content/locales/ko-KR/dispatch.mdx +3 -3
- package/docs/content/locales/ko-KR/external-agents.mdx +30 -19
- package/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
- package/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
- package/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
- package/docs/content/locales/ko-KR/server.mdx +2 -2
- package/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
- package/docs/content/locales/ko-KR/template-assets.mdx +1 -1
- package/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
- package/docs/content/locales/ko-KR/template-plan.mdx +3 -3
- package/docs/content/locales/pt-BR/actions.mdx +1 -1
- package/docs/content/locales/pt-BR/authentication.mdx +1 -1
- package/docs/content/locales/pt-BR/dispatch.mdx +3 -3
- package/docs/content/locales/pt-BR/external-agents.mdx +32 -19
- package/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
- package/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
- package/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
- package/docs/content/locales/pt-BR/server.mdx +2 -2
- package/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
- package/docs/content/locales/pt-BR/template-assets.mdx +1 -1
- package/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
- package/docs/content/locales/pt-BR/template-plan.mdx +3 -3
- package/docs/content/locales/zh-CN/actions.mdx +1 -1
- package/docs/content/locales/zh-CN/authentication.mdx +1 -1
- package/docs/content/locales/zh-CN/dispatch.mdx +3 -3
- package/docs/content/locales/zh-CN/external-agents.mdx +23 -19
- package/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
- package/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
- package/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
- package/docs/content/locales/zh-CN/server.mdx +2 -2
- package/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
- package/docs/content/locales/zh-CN/template-assets.mdx +1 -1
- package/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
- package/docs/content/locales/zh-CN/template-plan.mdx +3 -3
- package/docs/content/locales/zh-TW/actions.mdx +1 -1
- package/docs/content/locales/zh-TW/authentication.mdx +1 -1
- package/docs/content/locales/zh-TW/dispatch.mdx +3 -3
- package/docs/content/locales/zh-TW/external-agents.mdx +23 -19
- package/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
- package/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
- package/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
- package/docs/content/locales/zh-TW/server.mdx +2 -2
- package/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
- package/docs/content/locales/zh-TW/template-assets.mdx +1 -1
- package/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
- package/docs/content/locales/zh-TW/template-plan.mdx +3 -3
- package/docs/content/mcp-clients.mdx +31 -4
- package/docs/content/mcp-protocol.mdx +35 -15
- package/docs/content/plan-plugin.mdx +3 -3
- package/docs/content/server.mdx +2 -2
- package/docs/content/skills-guide.mdx +1 -1
- package/docs/content/template-assets.mdx +1 -1
- package/docs/content/template-dispatch.mdx +2 -2
- package/docs/content/template-plan.mdx +3 -3
- package/package.json +2 -2
- package/src/templates/default/.agents/skills/security/SKILL.md +10 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
|
@@ -24,6 +24,7 @@ pub async fn whisper_transcription_start(
|
|
|
24
24
|
mic_device_label: Option<String>,
|
|
25
25
|
capture_system: bool,
|
|
26
26
|
voice_processing: bool,
|
|
27
|
+
emit_partials: bool,
|
|
27
28
|
owner: Option<String>,
|
|
28
29
|
) -> Result<(), String> {
|
|
29
30
|
if !crate::config::feature_config(&app).whisper_model_enabled {
|
|
@@ -38,6 +39,7 @@ pub async fn whisper_transcription_start(
|
|
|
38
39
|
mic_device_label,
|
|
39
40
|
capture_system,
|
|
40
41
|
voice_processing,
|
|
42
|
+
emit_partials,
|
|
41
43
|
macos::SessionOwner::from_param(owner),
|
|
42
44
|
)
|
|
43
45
|
.await
|
|
@@ -51,6 +53,7 @@ pub async fn whisper_transcription_start(
|
|
|
51
53
|
mic_device_label,
|
|
52
54
|
capture_system,
|
|
53
55
|
voice_processing,
|
|
56
|
+
emit_partials,
|
|
54
57
|
owner,
|
|
55
58
|
);
|
|
56
59
|
Err("Whisper transcription is only supported on macOS.".into())
|
|
@@ -161,7 +164,14 @@ mod macos {
|
|
|
161
164
|
let path_str = path
|
|
162
165
|
.to_str()
|
|
163
166
|
.ok_or_else(|| "model path is not valid UTF-8".to_string())?;
|
|
164
|
-
let
|
|
167
|
+
let mut params = WhisperContextParameters::default();
|
|
168
|
+
// The `metal` Cargo feature defaults `use_gpu` to true for every mac
|
|
169
|
+
// (Intel included) via whisper-rs's `_gpu` cfg. Metal offload only
|
|
170
|
+
// pays off on Apple Silicon's unified-memory GPU, so pin this
|
|
171
|
+
// explicitly instead of trusting that default — Intel Macs keep
|
|
172
|
+
// today's CPU decode path.
|
|
173
|
+
params.use_gpu(cfg!(target_arch = "aarch64"));
|
|
174
|
+
let ctx = WhisperContext::new_with_params(path_str, params)
|
|
165
175
|
.map_err(|e| format!("whisper model load failed: {e}"))?;
|
|
166
176
|
let ctx = Arc::new(ctx);
|
|
167
177
|
*guard = Some(ctx.clone());
|
|
@@ -177,8 +187,25 @@ mod macos {
|
|
|
177
187
|
|
|
178
188
|
// ---- resampling -------------------------------------------------------
|
|
179
189
|
|
|
190
|
+
/// One linearly-interpolated 16 kHz output sample at output index `i`,
|
|
191
|
+
/// given `ratio = 16000 / src_rate`. Shared by `resample_to_16k` (one-shot,
|
|
192
|
+
/// full buffer) and `IncrementalResample` (append-only, growing buffer) so
|
|
193
|
+
/// both produce byte-identical values for the same input.
|
|
194
|
+
fn resample_linear_at(input: &[f32], ratio: f64, i: usize) -> f32 {
|
|
195
|
+
let src_pos = i as f64 / ratio;
|
|
196
|
+
let idx = src_pos as usize;
|
|
197
|
+
let frac = (src_pos - idx as f64) as f32;
|
|
198
|
+
let a = input.get(idx).copied().unwrap_or(0.0);
|
|
199
|
+
let b = input.get(idx + 1).copied().unwrap_or(a);
|
|
200
|
+
a + (b - a) * frac
|
|
201
|
+
}
|
|
202
|
+
|
|
180
203
|
/// Linear-resample mono f32 to 16 kHz (Whisper's required rate). Per-buffer
|
|
181
|
-
/// resampling introduces negligible boundary error for speech.
|
|
204
|
+
/// resampling introduces negligible boundary error for speech. One-shot —
|
|
205
|
+
/// used only for the final flush on stop. The hot per-utterance path (an
|
|
206
|
+
/// utterance can be resampled repeatedly as it grows toward the 25 s cap)
|
|
207
|
+
/// uses `IncrementalResample` instead so it doesn't redo the whole buffer
|
|
208
|
+
/// every time.
|
|
182
209
|
fn resample_to_16k(input: &[f32], src_rate: f64) -> Vec<f32> {
|
|
183
210
|
if input.is_empty() {
|
|
184
211
|
return Vec::new();
|
|
@@ -190,16 +217,95 @@ mod macos {
|
|
|
190
217
|
let out_len = ((input.len() as f64) * ratio).floor() as usize;
|
|
191
218
|
let mut out = Vec::with_capacity(out_len);
|
|
192
219
|
for i in 0..out_len {
|
|
193
|
-
|
|
194
|
-
let idx = src_pos as usize;
|
|
195
|
-
let frac = (src_pos - idx as f64) as f32;
|
|
196
|
-
let a = input.get(idx).copied().unwrap_or(0.0);
|
|
197
|
-
let b = input.get(idx + 1).copied().unwrap_or(a);
|
|
198
|
-
out.push(a + (b - a) * frac);
|
|
220
|
+
out.push(resample_linear_at(input, ratio, i));
|
|
199
221
|
}
|
|
200
222
|
out
|
|
201
223
|
}
|
|
202
224
|
|
|
225
|
+
/// Incrementally maintains a 16 kHz resample of a growing raw-sample
|
|
226
|
+
/// buffer so repeated inference calls (partials, then the final) within
|
|
227
|
+
/// one utterance only resample the audio that arrived since the last
|
|
228
|
+
/// call, not the whole utterance from scratch. Lives entirely on the
|
|
229
|
+
/// worker thread — not shared, no locking needed.
|
|
230
|
+
struct IncrementalResample {
|
|
231
|
+
src_rate: f32,
|
|
232
|
+
/// 16 kHz samples resampled so far. A prefix of what
|
|
233
|
+
/// `resample_to_16k(raw, src_rate)` would produce for the current
|
|
234
|
+
/// `raw`; `sync` extends it in place.
|
|
235
|
+
out: Vec<f32>,
|
|
236
|
+
/// Length of `out` that's permanent: every sample up to this point
|
|
237
|
+
/// used two real interpolation neighbors (never the same-sample
|
|
238
|
+
/// fallback `resample_to_16k` falls back to at the true tail), so it
|
|
239
|
+
/// can never change as more raw samples arrive. `sync` recomputes
|
|
240
|
+
/// anything past this on every call.
|
|
241
|
+
committed_len: usize,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
impl IncrementalResample {
|
|
245
|
+
fn new() -> Self {
|
|
246
|
+
Self {
|
|
247
|
+
src_rate: -1.0,
|
|
248
|
+
out: Vec::new(),
|
|
249
|
+
committed_len: 0,
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/// Discard all cached state. Call this everywhere the raw buffer it
|
|
254
|
+
/// tracks is cleared or front-drained (finalize, timeline reset) —
|
|
255
|
+
/// after either, raw sample indices no longer line up with what's
|
|
256
|
+
/// cached here, so the cheapest correct move is a clean rebuild on
|
|
257
|
+
/// the next `sync` (bounded by however little raw audio is left).
|
|
258
|
+
fn drop_all(&mut self) {
|
|
259
|
+
self.out.clear();
|
|
260
|
+
self.committed_len = 0;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/// Extend the cached resample to cover all of `raw`, byte-identical to
|
|
264
|
+
/// calling `resample_to_16k(raw, src_rate)` fresh. Only the samples
|
|
265
|
+
/// that arrived since the last call are actually resampled.
|
|
266
|
+
fn sync(&mut self, raw: &[f32], src_rate: f32) {
|
|
267
|
+
if (src_rate - self.src_rate).abs() > 0.5 {
|
|
268
|
+
self.src_rate = src_rate;
|
|
269
|
+
self.drop_all();
|
|
270
|
+
}
|
|
271
|
+
// Drop the small uncommitted tail from the previous call (its
|
|
272
|
+
// fallback neighbor may since have become a real sample) before
|
|
273
|
+
// recomputing it with the now-current buffer.
|
|
274
|
+
self.out.truncate(self.committed_len);
|
|
275
|
+
|
|
276
|
+
if raw.is_empty() {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (src_rate as f64 - 16000.0).abs() < 1.0 {
|
|
280
|
+
if raw.len() > self.out.len() {
|
|
281
|
+
self.out.extend_from_slice(&raw[self.out.len()..]);
|
|
282
|
+
}
|
|
283
|
+
self.committed_len = self.out.len();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let ratio = 16000.0 / src_rate as f64;
|
|
288
|
+
let full_len = ((raw.len() as f64) * ratio).floor() as usize;
|
|
289
|
+
while self.out.len() < full_len {
|
|
290
|
+
let i = self.out.len();
|
|
291
|
+
self.out.push(resample_linear_at(raw, ratio, i));
|
|
292
|
+
}
|
|
293
|
+
// Reserve the last couple of raw samples as lookahead: an output
|
|
294
|
+
// sample this close to the end may have used the same-sample
|
|
295
|
+
// fallback above because its true second neighbor hasn't arrived
|
|
296
|
+
// yet. Only commit up to where both neighbors are guaranteed
|
|
297
|
+
// real, so that sample gets redone (cheaply) once more audio
|
|
298
|
+
// confirms it instead of freezing the fallback value forever.
|
|
299
|
+
let safe_raw_len = raw.len().saturating_sub(2);
|
|
300
|
+
let safe_len = ((safe_raw_len as f64) * ratio).floor() as usize;
|
|
301
|
+
self.committed_len = safe_len.min(self.out.len());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
fn samples(&self) -> &[f32] {
|
|
305
|
+
&self.out
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
203
309
|
// ---- per-stream worker ------------------------------------------------
|
|
204
310
|
|
|
205
311
|
/// One transcription stream (mic or system). Buffers raw capture samples
|
|
@@ -228,6 +334,10 @@ mod macos {
|
|
|
228
334
|
/// local counters that must be reset after the realtime callback clears
|
|
229
335
|
/// the shared sample buffer.
|
|
230
336
|
reset_generation: AtomicU32,
|
|
337
|
+
/// Whether this consumer renders live partial transcript updates.
|
|
338
|
+
/// Recording capture only persists finals and disables this expensive
|
|
339
|
+
/// repeated inference; meeting capture keeps it enabled.
|
|
340
|
+
emit_partials: bool,
|
|
231
341
|
}
|
|
232
342
|
|
|
233
343
|
impl WhisperStream {
|
|
@@ -238,6 +348,7 @@ mod macos {
|
|
|
238
348
|
language: Option<String>,
|
|
239
349
|
ctx: Arc<WhisperContext>,
|
|
240
350
|
stream_start: Instant,
|
|
351
|
+
emit_partials: bool,
|
|
241
352
|
) -> Arc<Self> {
|
|
242
353
|
let done = Arc::new(AtomicBool::new(false));
|
|
243
354
|
let stream = Arc::new(WhisperStream {
|
|
@@ -253,6 +364,7 @@ mod macos {
|
|
|
253
364
|
buffer_start: stream_start,
|
|
254
365
|
}),
|
|
255
366
|
reset_generation: AtomicU32::new(0),
|
|
367
|
+
emit_partials,
|
|
256
368
|
});
|
|
257
369
|
let worker_stream = stream.clone();
|
|
258
370
|
std::thread::spawn(move || {
|
|
@@ -372,6 +484,7 @@ mod macos {
|
|
|
372
484
|
params.set_language(language);
|
|
373
485
|
params.set_translate(false);
|
|
374
486
|
params.set_no_context(true);
|
|
487
|
+
params.set_suppress_nst(true);
|
|
375
488
|
params.set_print_special(false);
|
|
376
489
|
params.set_print_progress(false);
|
|
377
490
|
params.set_print_realtime(false);
|
|
@@ -382,7 +495,7 @@ mod macos {
|
|
|
382
495
|
let mut out = Vec::new();
|
|
383
496
|
for segment in state.as_iter() {
|
|
384
497
|
let text = segment.to_string();
|
|
385
|
-
if is_speech(&text) {
|
|
498
|
+
if is_speech(&text) && segment.no_speech_probability() < MAX_NO_SPEECH_PROBABILITY {
|
|
386
499
|
// whisper timestamps are in centiseconds → ms.
|
|
387
500
|
out.push((
|
|
388
501
|
segment.start_timestamp() * 10,
|
|
@@ -415,6 +528,24 @@ mod macos {
|
|
|
415
528
|
const SAMPLE_RATE_16K: f32 = 16000.0;
|
|
416
529
|
/// RMS above this counts as speech for the silence/end-of-utterance timer.
|
|
417
530
|
const VOICE_RMS_THRESHOLD: f32 = 0.006;
|
|
531
|
+
/// A second, model-level gate for ambient/no-speech Whisper segments.
|
|
532
|
+
const MAX_NO_SPEECH_PROBABILITY: f32 = 0.72;
|
|
533
|
+
|
|
534
|
+
fn partial_inference_due(
|
|
535
|
+
emit_partials: bool,
|
|
536
|
+
had_voice: bool,
|
|
537
|
+
have_secs: f32,
|
|
538
|
+
since_last_infer: Duration,
|
|
539
|
+
) -> bool {
|
|
540
|
+
emit_partials
|
|
541
|
+
&& had_voice
|
|
542
|
+
&& have_secs > 0.5
|
|
543
|
+
&& since_last_infer > Duration::from_millis(1200)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
fn utterance_finalize_due(have_secs: f32, silence: Duration) -> bool {
|
|
547
|
+
(have_secs > 0.4 && silence > Duration::from_millis(800)) || have_secs > 25.0
|
|
548
|
+
}
|
|
418
549
|
|
|
419
550
|
fn worker(stream: Arc<WhisperStream>, ctx: Arc<WhisperContext>) {
|
|
420
551
|
let mut state = match ctx.create_state() {
|
|
@@ -429,7 +560,7 @@ mod macos {
|
|
|
429
560
|
}
|
|
430
561
|
};
|
|
431
562
|
let lang = stream.language.as_deref();
|
|
432
|
-
let mut
|
|
563
|
+
let mut last_raw_len = 0usize;
|
|
433
564
|
let mut last_infer = Instant::now() - Duration::from_secs(10);
|
|
434
565
|
let mut last_voice = Instant::now();
|
|
435
566
|
// Whether the CURRENT utterance buffer ever crossed the voice
|
|
@@ -437,6 +568,8 @@ mod macos {
|
|
|
437
568
|
// silent audio, so we NEVER run inference on a buffer with no voice.
|
|
438
569
|
let mut had_voice = false;
|
|
439
570
|
let mut seen_reset_generation = stream.reset_generation.load(Ordering::SeqCst);
|
|
571
|
+
// Growing-utterance resample cache — see `IncrementalResample`.
|
|
572
|
+
let mut resample_state = IncrementalResample::new();
|
|
440
573
|
|
|
441
574
|
while stream.running.load(Ordering::SeqCst) {
|
|
442
575
|
std::thread::sleep(Duration::from_millis(250));
|
|
@@ -444,59 +577,83 @@ mod macos {
|
|
|
444
577
|
let reset_generation = stream.reset_generation.load(Ordering::SeqCst);
|
|
445
578
|
if reset_generation != seen_reset_generation {
|
|
446
579
|
seen_reset_generation = reset_generation;
|
|
447
|
-
|
|
580
|
+
last_raw_len = 0;
|
|
448
581
|
last_voice = Instant::now();
|
|
449
582
|
last_infer = Instant::now() - Duration::from_secs(10);
|
|
450
583
|
had_voice = false;
|
|
584
|
+
resample_state.drop_all();
|
|
451
585
|
continue;
|
|
452
586
|
}
|
|
453
587
|
|
|
454
|
-
//
|
|
455
|
-
//
|
|
456
|
-
|
|
457
|
-
|
|
588
|
+
// Voice activity only needs the samples that arrived since the last
|
|
589
|
+
// poll. Inspect that tail in place instead of cloning + resampling
|
|
590
|
+
// the entire growing utterance four times per second. Full snapshots
|
|
591
|
+
// are reserved for an inference that is actually due.
|
|
592
|
+
let (raw_len, new_rms) = match stream.buf.lock() {
|
|
593
|
+
Ok(b) => {
|
|
594
|
+
let raw_len = b.len();
|
|
595
|
+
let new_rms = if raw_len > last_raw_len {
|
|
596
|
+
let new = &b[last_raw_len..];
|
|
597
|
+
Some((new.iter().map(|x| x * x).sum::<f32>() / new.len() as f32).sqrt())
|
|
598
|
+
} else {
|
|
599
|
+
None
|
|
600
|
+
};
|
|
601
|
+
(raw_len, new_rms)
|
|
602
|
+
}
|
|
458
603
|
Err(_) => continue,
|
|
459
604
|
};
|
|
460
|
-
let src_rate = stream.src_rate.load(Ordering::SeqCst) as f64;
|
|
461
|
-
let samples = resample_to_16k(&raw, src_rate);
|
|
462
605
|
if stream.reset_generation.load(Ordering::SeqCst) != seen_reset_generation {
|
|
463
606
|
continue;
|
|
464
607
|
}
|
|
465
|
-
let
|
|
466
|
-
|
|
467
|
-
// Track voice activity over the newly-arrived region.
|
|
468
|
-
if len > last_len {
|
|
469
|
-
let new = &samples[last_len..];
|
|
470
|
-
let rms = (new.iter().map(|x| x * x).sum::<f32>() / new.len() as f32).sqrt();
|
|
608
|
+
if let Some(rms) = new_rms {
|
|
471
609
|
if rms > VOICE_RMS_THRESHOLD {
|
|
472
610
|
last_voice = Instant::now();
|
|
473
611
|
had_voice = true;
|
|
474
612
|
}
|
|
475
|
-
last_len = len;
|
|
476
613
|
}
|
|
614
|
+
last_raw_len = raw_len;
|
|
477
615
|
|
|
478
|
-
let
|
|
616
|
+
let src_rate = (stream.src_rate.load(Ordering::SeqCst) as f32).max(1.0);
|
|
617
|
+
let have_secs = raw_len as f32 / src_rate;
|
|
479
618
|
let silence = last_voice.elapsed();
|
|
480
619
|
|
|
481
620
|
// Finalize on a real pause (>0.8 s silence with >0.4 s speech) or
|
|
482
621
|
// when the buffer grows too long to keep as one utterance.
|
|
483
|
-
if (have_secs
|
|
622
|
+
if utterance_finalize_due(have_secs, silence) {
|
|
484
623
|
// Only transcribe if the utterance actually contained voice —
|
|
485
624
|
// otherwise we'd feed whisper silence and get a hallucinated
|
|
486
625
|
// "you" / "Thank you.".
|
|
626
|
+
let mut n_processed = raw_len;
|
|
487
627
|
if had_voice && have_secs > 0.4 {
|
|
488
|
-
|
|
628
|
+
match stream.buf.lock() {
|
|
629
|
+
Ok(b) => {
|
|
630
|
+
// Hold the lock only long enough to extend the
|
|
631
|
+
// resample cache with the new tail (cheap) — NOT
|
|
632
|
+
// through inference, so the realtime capture
|
|
633
|
+
// callback (`push`) never blocks on whisper.
|
|
634
|
+
resample_state.sync(&b, src_rate);
|
|
635
|
+
n_processed = b.len();
|
|
636
|
+
}
|
|
637
|
+
Err(_) => continue,
|
|
638
|
+
}
|
|
639
|
+
if stream.reset_generation.load(Ordering::SeqCst) != seen_reset_generation {
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
let segs = infer(&mut state, resample_state.samples(), lang);
|
|
489
643
|
stream.emit_transcript("voice:final-transcript", &segs, stream.offset_ms());
|
|
490
644
|
}
|
|
491
|
-
let n_processed = raw.len();
|
|
492
645
|
if let Ok(mut b) = stream.buf.lock() {
|
|
493
646
|
let to_drain = n_processed.min(b.len());
|
|
494
647
|
b.drain(..to_drain);
|
|
495
648
|
}
|
|
649
|
+
// Raw indices shift after the drain above (front-truncated),
|
|
650
|
+
// so the resample cache is invalid regardless of whether this
|
|
651
|
+
// utterance ran inference — rebuild fresh from whatever's left.
|
|
652
|
+
resample_state.drop_all();
|
|
496
653
|
// New buffer begins now — advance the timeline offset so the
|
|
497
654
|
// next utterance's whisper timestamps map correctly.
|
|
498
655
|
stream.reset_buffer_start();
|
|
499
|
-
|
|
656
|
+
last_raw_len = 0;
|
|
500
657
|
had_voice = false;
|
|
501
658
|
last_infer = Instant::now();
|
|
502
659
|
continue;
|
|
@@ -504,8 +661,20 @@ mod macos {
|
|
|
504
661
|
|
|
505
662
|
// Partial while speech is still accruing (only once real voice has
|
|
506
663
|
// been heard in this utterance).
|
|
507
|
-
if
|
|
508
|
-
|
|
664
|
+
if partial_inference_due(
|
|
665
|
+
stream.emit_partials,
|
|
666
|
+
had_voice,
|
|
667
|
+
have_secs,
|
|
668
|
+
last_infer.elapsed(),
|
|
669
|
+
) {
|
|
670
|
+
match stream.buf.lock() {
|
|
671
|
+
Ok(b) => resample_state.sync(&b, src_rate),
|
|
672
|
+
Err(_) => continue,
|
|
673
|
+
}
|
|
674
|
+
if stream.reset_generation.load(Ordering::SeqCst) != seen_reset_generation {
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
let segs = infer(&mut state, resample_state.samples(), lang);
|
|
509
678
|
stream.emit_transcript("voice:partial-transcript", &segs, stream.offset_ms());
|
|
510
679
|
last_infer = Instant::now();
|
|
511
680
|
}
|
|
@@ -644,6 +813,7 @@ mod macos {
|
|
|
644
813
|
mic_device_label: Option<String>,
|
|
645
814
|
capture_system: bool,
|
|
646
815
|
voice_processing: bool,
|
|
816
|
+
emit_partials: bool,
|
|
647
817
|
owner: SessionOwner,
|
|
648
818
|
) -> Result<(), String> {
|
|
649
819
|
// Priority rule (D10): a meeting-owned session must never be
|
|
@@ -701,6 +871,7 @@ mod macos {
|
|
|
701
871
|
lang.clone(),
|
|
702
872
|
ctx.clone(),
|
|
703
873
|
session_start,
|
|
874
|
+
emit_partials,
|
|
704
875
|
);
|
|
705
876
|
let sys_stream = capture_system.then(|| {
|
|
706
877
|
WhisperStream::new(
|
|
@@ -710,6 +881,7 @@ mod macos {
|
|
|
710
881
|
lang.clone(),
|
|
711
882
|
ctx.clone(),
|
|
712
883
|
session_start,
|
|
884
|
+
emit_partials,
|
|
713
885
|
)
|
|
714
886
|
});
|
|
715
887
|
let mic_for_cb = mic_stream.clone();
|
|
@@ -863,9 +1035,92 @@ mod macos {
|
|
|
863
1035
|
|
|
864
1036
|
#[cfg(test)]
|
|
865
1037
|
mod tests {
|
|
866
|
-
use
|
|
1038
|
+
use std::time::Duration;
|
|
1039
|
+
|
|
1040
|
+
use super::{
|
|
1041
|
+
partial_inference_due, resample_to_16k, should_use_combined_sck_capture,
|
|
1042
|
+
split_mic_capture_options, utterance_finalize_due, IncrementalResample, SessionOwner,
|
|
1043
|
+
};
|
|
867
1044
|
use crate::native_speech::macos::MicVoiceProcessingMode;
|
|
868
1045
|
|
|
1046
|
+
#[test]
|
|
1047
|
+
fn incremental_resample_matches_one_shot_resample_as_buffer_grows() {
|
|
1048
|
+
let mut state = IncrementalResample::new();
|
|
1049
|
+
let src_rate = 48000.0_f32;
|
|
1050
|
+
let mut raw: Vec<f32> = Vec::new();
|
|
1051
|
+
// Simulate audio arriving in small chunks and syncing after each —
|
|
1052
|
+
// mirrors the worker polling `stream.buf` every 250 ms. A non-integer
|
|
1053
|
+
// chunk size (137) deliberately avoids landing on a 48k/16k=3 boundary.
|
|
1054
|
+
for chunk in 0..40u32 {
|
|
1055
|
+
for i in 0..137u32 {
|
|
1056
|
+
raw.push(((chunk * 137 + i) as f32 * 0.013).sin());
|
|
1057
|
+
}
|
|
1058
|
+
state.sync(&raw, src_rate);
|
|
1059
|
+
let expected = resample_to_16k(&raw, src_rate as f64);
|
|
1060
|
+
assert_eq!(
|
|
1061
|
+
state.samples(),
|
|
1062
|
+
expected.as_slice(),
|
|
1063
|
+
"diverged after {} raw samples",
|
|
1064
|
+
raw.len()
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
#[test]
|
|
1070
|
+
fn incremental_resample_rebuilds_cleanly_after_drop_all() {
|
|
1071
|
+
let mut state = IncrementalResample::new();
|
|
1072
|
+
let src_rate = 44100.0_f32;
|
|
1073
|
+
let mut raw: Vec<f32> = (0..2_000).map(|i| (i as f32 * 0.02).sin()).collect();
|
|
1074
|
+
state.sync(&raw, src_rate);
|
|
1075
|
+
assert_eq!(
|
|
1076
|
+
state.samples(),
|
|
1077
|
+
resample_to_16k(&raw, src_rate as f64).as_slice()
|
|
1078
|
+
);
|
|
1079
|
+
|
|
1080
|
+
// Utterance finalize: raw buffer is front-drained (indices shift),
|
|
1081
|
+
// so the cache must be dropped, not incrementally patched.
|
|
1082
|
+
raw.drain(..1_500);
|
|
1083
|
+
state.drop_all();
|
|
1084
|
+
state.sync(&raw, src_rate);
|
|
1085
|
+
assert_eq!(
|
|
1086
|
+
state.samples(),
|
|
1087
|
+
resample_to_16k(&raw, src_rate as f64).as_slice()
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
#[test]
|
|
1092
|
+
fn recording_mode_never_runs_live_partial_inference() {
|
|
1093
|
+
assert!(!partial_inference_due(
|
|
1094
|
+
false,
|
|
1095
|
+
true,
|
|
1096
|
+
10.0,
|
|
1097
|
+
Duration::from_secs(10)
|
|
1098
|
+
));
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
#[test]
|
|
1102
|
+
fn meeting_mode_keeps_existing_partial_inference_cadence() {
|
|
1103
|
+
assert!(partial_inference_due(
|
|
1104
|
+
true,
|
|
1105
|
+
true,
|
|
1106
|
+
1.0,
|
|
1107
|
+
Duration::from_millis(1201)
|
|
1108
|
+
));
|
|
1109
|
+
assert!(!partial_inference_due(
|
|
1110
|
+
true,
|
|
1111
|
+
true,
|
|
1112
|
+
1.0,
|
|
1113
|
+
Duration::from_millis(1200)
|
|
1114
|
+
));
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
#[test]
|
|
1118
|
+
fn recording_mode_keeps_silence_and_long_utterance_finalization() {
|
|
1119
|
+
assert!(utterance_finalize_due(1.0, Duration::from_millis(801)));
|
|
1120
|
+
assert!(utterance_finalize_due(25.1, Duration::ZERO));
|
|
1121
|
+
assert!(!utterance_finalize_due(25.0, Duration::from_millis(100)));
|
|
1122
|
+
}
|
|
1123
|
+
|
|
869
1124
|
#[test]
|
|
870
1125
|
fn combined_sck_capture_is_only_selected_for_supported_meetings() {
|
|
871
1126
|
assert!(should_use_combined_sck_capture(SessionOwner::Meeting, true));
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"targets": ["dmg", "app", "msi"],
|
|
23
23
|
"icon": ["icons/icon.png", "icons/icon.ico", "icons/icon.icns"],
|
|
24
24
|
"macOS": {
|
|
25
|
-
"minimumSystemVersion": "
|
|
25
|
+
"minimumSystemVersion": "13.0",
|
|
26
26
|
"entitlements": "./Entitlements.plist",
|
|
27
27
|
"files": {
|
|
28
28
|
"Resources/Assets.car": "Assets.car"
|
|
@@ -77,3 +77,31 @@ export function isPersonalSoloCalendarEvent(args: {
|
|
|
77
77
|
return Boolean(email && selfEmails.has(email));
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* True when a calendar event has no active attendee besides the current user.
|
|
83
|
+
* This is intentionally broader than the title-based personal-event helper:
|
|
84
|
+
* desktop meeting reminders should not surface for any self-only event.
|
|
85
|
+
*/
|
|
86
|
+
export function isSoloCalendarEvent(args: {
|
|
87
|
+
account: CalendarAccountForEventClassification;
|
|
88
|
+
event: CalendarEvent;
|
|
89
|
+
currentUserEmail?: string | null;
|
|
90
|
+
}): boolean {
|
|
91
|
+
const selfEmails = new Set(
|
|
92
|
+
[args.currentUserEmail, args.account.email, args.account.ownerEmail]
|
|
93
|
+
.map(normalizeEmail)
|
|
94
|
+
.filter((email): email is string => Boolean(email)),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const organizerEmail = normalizeEmail(args.event.organizer?.email);
|
|
98
|
+
if (organizerEmail && !selfEmails.has(organizerEmail)) return false;
|
|
99
|
+
|
|
100
|
+
const activeAttendees = (args.event.attendees ?? []).filter(
|
|
101
|
+
(attendee) => attendee.responseStatus !== "declined",
|
|
102
|
+
);
|
|
103
|
+
return activeAttendees.every((attendee) => {
|
|
104
|
+
const email = normalizeEmail(attendee.email);
|
|
105
|
+
return Boolean(email && selfEmails.has(email));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import { getOrgContext } from "@agent-native/core/org";
|
|
2
|
-
import { getSession, runWithRequestContext } from "@agent-native/core/server";
|
|
3
1
|
import { createH3SSRHandler } from "@agent-native/core/server/ssr-handler";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
defineEventHandler,
|
|
7
|
-
getRequestURL,
|
|
8
|
-
setResponseHeader,
|
|
9
|
-
type H3Event,
|
|
10
|
-
} from "h3";
|
|
2
|
+
import { defineEventHandler, setResponseHeader } from "h3";
|
|
11
3
|
|
|
12
4
|
import {
|
|
13
5
|
MEDIA_CAPTURE_PERMISSIONS_POLICY,
|
|
@@ -18,57 +10,7 @@ const ssrHandler = createH3SSRHandler(
|
|
|
18
10
|
() => import("virtual:react-router/server-build"),
|
|
19
11
|
);
|
|
20
12
|
|
|
21
|
-
function recordingIdFromAuthenticatedPath(pathname: string): string | null {
|
|
22
|
-
const match = pathname.match(/^\/r\/([^/]+)\/?$/);
|
|
23
|
-
if (!match?.[1]) return null;
|
|
24
|
-
try {
|
|
25
|
-
return decodeURIComponent(match[1]);
|
|
26
|
-
} catch {
|
|
27
|
-
return match[1];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function shareRedirect(recordingId: string, search: string): Response {
|
|
32
|
-
return new Response(null, {
|
|
33
|
-
status: 302,
|
|
34
|
-
headers: {
|
|
35
|
-
location: `/share/${encodeURIComponent(recordingId)}${search}`,
|
|
36
|
-
"Permissions-Policy": MEDIA_CAPTURE_PERMISSIONS_POLICY,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function redirectNonOwnerRecordingPath(
|
|
42
|
-
event: H3Event,
|
|
43
|
-
): Promise<Response | null> {
|
|
44
|
-
const url = getRequestURL(event);
|
|
45
|
-
const recordingId = recordingIdFromAuthenticatedPath(url.pathname);
|
|
46
|
-
if (!recordingId) return null;
|
|
47
|
-
|
|
48
|
-
const session = await getSession(event).catch(() => null);
|
|
49
|
-
if (!session?.email) return shareRedirect(recordingId, url.search);
|
|
50
|
-
|
|
51
|
-
const orgCtx = await getOrgContext(event).catch(() => null);
|
|
52
|
-
const orgId = orgCtx?.orgId ?? session.orgId ?? undefined;
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
const access = await runWithRequestContext(
|
|
56
|
-
{ userEmail: session.email, orgId },
|
|
57
|
-
() => resolveAccess("recording", recordingId),
|
|
58
|
-
);
|
|
59
|
-
if (access?.role === "owner") return null;
|
|
60
|
-
} catch {
|
|
61
|
-
// Treat missing/inaccessible recordings the same as no access here;
|
|
62
|
-
// the share route can render the canonical public/not-found state.
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return shareRedirect(recordingId, url.search);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
13
|
export default defineEventHandler(async (event) => {
|
|
69
|
-
const redirect = await redirectNonOwnerRecordingPath(event);
|
|
70
|
-
if (redirect) return redirect;
|
|
71
|
-
|
|
72
14
|
const response = (await ssrHandler(event)) as Response;
|
|
73
15
|
setResponseHeader(
|
|
74
16
|
event,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared screen-capture quality policy for browser-based Clips recorders.
|
|
3
|
+
*
|
|
4
|
+
* Display capture constraints are applied after the user chooses a surface. We
|
|
5
|
+
* use `max` envelopes (never `min`/`exact`) so Retina and 4K sources are
|
|
6
|
+
* downscaled before MediaRecorder has to encode them.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const SCREEN_CAPTURE_FRAME_RATE = 24;
|
|
10
|
+
export const SCREEN_CAPTURE_MAX_WIDTH = 1920;
|
|
11
|
+
export const SCREEN_CAPTURE_MAX_HEIGHT = 1080;
|
|
12
|
+
|
|
13
|
+
export type ScreenCaptureSurface = "browser" | "window" | "monitor";
|
|
14
|
+
|
|
15
|
+
export type ScreenCaptureVideoConstraints = MediaTrackConstraints & {
|
|
16
|
+
displaySurface: ScreenCaptureSurface;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function screenCaptureVideoConstraints(
|
|
20
|
+
displaySurface: ScreenCaptureSurface,
|
|
21
|
+
): ScreenCaptureVideoConstraints {
|
|
22
|
+
return {
|
|
23
|
+
frameRate: {
|
|
24
|
+
ideal: SCREEN_CAPTURE_FRAME_RATE,
|
|
25
|
+
max: SCREEN_CAPTURE_FRAME_RATE,
|
|
26
|
+
},
|
|
27
|
+
width: {
|
|
28
|
+
ideal: SCREEN_CAPTURE_MAX_WIDTH,
|
|
29
|
+
max: SCREEN_CAPTURE_MAX_WIDTH,
|
|
30
|
+
},
|
|
31
|
+
height: {
|
|
32
|
+
ideal: SCREEN_CAPTURE_MAX_HEIGHT,
|
|
33
|
+
max: SCREEN_CAPTURE_MAX_HEIGHT,
|
|
34
|
+
},
|
|
35
|
+
displaySurface,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -147,6 +147,16 @@ export default defineEventHandler(async (event) => {
|
|
|
147
147
|
|
|
148
148
|
- Never create unprotected routes that modify data.
|
|
149
149
|
|
|
150
|
+
**Exception — the SSR HTML/`.data` catch-all is deliberately session-blind.**
|
|
151
|
+
The rule above is for routes that read or mutate user data. The SSR page
|
|
152
|
+
render and React Router `.data` route are different: they serve one
|
|
153
|
+
impersonal, public-cacheable shell to every visitor by design, and loaders on
|
|
154
|
+
that path render no user data. Do not "fix" this by adding `getSession`,
|
|
155
|
+
`private`, or `no-store` to it — that regresses the CDN cache contract for the
|
|
156
|
+
whole site. Data scoping lives in actions and API routes; the client gates
|
|
157
|
+
private UI after the shell loads. See the `authentication` skill and
|
|
158
|
+
`guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
|
|
159
|
+
|
|
150
160
|
## Human-in-the-Loop Approval for High-Consequence Actions
|
|
151
161
|
|
|
152
162
|
For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"description": "Create and manage docs plus Notion-style databases, boards, structured intake forms, and request records through Content, including repo-backed Markdown/MDX.",
|
|
6
6
|
"hosted": {
|
|
7
7
|
"url": "https://content.agent-native.com",
|
|
8
|
-
"mcpUrl": "https://content.agent-native.com/
|
|
8
|
+
"mcpUrl": "https://content.agent-native.com/mcp"
|
|
9
9
|
},
|
|
10
10
|
"mcp": {
|
|
11
11
|
"serverName": "agent-native-content"
|