@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.
Files changed (583) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +25 -0
  3. package/corpus/core/docs/content/actions.mdx +1 -1
  4. package/corpus/core/docs/content/authentication.mdx +1 -1
  5. package/corpus/core/docs/content/dispatch.mdx +3 -3
  6. package/corpus/core/docs/content/external-agents.mdx +30 -19
  7. package/corpus/core/docs/content/locales/ar-SA/actions.mdx +1 -1
  8. package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +1 -1
  9. package/corpus/core/docs/content/locales/ar-SA/dispatch.mdx +3 -3
  10. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +23 -19
  11. package/corpus/core/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
  12. package/corpus/core/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
  13. package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
  14. package/corpus/core/docs/content/locales/ar-SA/server.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
  16. package/corpus/core/docs/content/locales/ar-SA/template-assets.mdx +1 -1
  17. package/corpus/core/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
  18. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +3 -3
  19. package/corpus/core/docs/content/locales/de-DE/actions.mdx +1 -1
  20. package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
  21. package/corpus/core/docs/content/locales/de-DE/dispatch.mdx +3 -3
  22. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +23 -19
  23. package/corpus/core/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
  24. package/corpus/core/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
  25. package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
  26. package/corpus/core/docs/content/locales/de-DE/server.mdx +2 -2
  27. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +1 -1
  28. package/corpus/core/docs/content/locales/de-DE/template-assets.mdx +1 -1
  29. package/corpus/core/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
  30. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +3 -3
  31. package/corpus/core/docs/content/locales/es-ES/actions.mdx +1 -1
  32. package/corpus/core/docs/content/locales/es-ES/authentication.mdx +1 -1
  33. package/corpus/core/docs/content/locales/es-ES/dispatch.mdx +3 -3
  34. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +32 -19
  35. package/corpus/core/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
  36. package/corpus/core/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
  37. package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
  38. package/corpus/core/docs/content/locales/es-ES/server.mdx +2 -2
  39. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +1 -1
  40. package/corpus/core/docs/content/locales/es-ES/template-assets.mdx +1 -1
  41. package/corpus/core/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
  42. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +3 -3
  43. package/corpus/core/docs/content/locales/fr-FR/actions.mdx +1 -1
  44. package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
  45. package/corpus/core/docs/content/locales/fr-FR/dispatch.mdx +3 -3
  46. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +23 -19
  47. package/corpus/core/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
  48. package/corpus/core/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
  49. package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
  50. package/corpus/core/docs/content/locales/fr-FR/server.mdx +2 -2
  51. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
  52. package/corpus/core/docs/content/locales/fr-FR/template-assets.mdx +1 -1
  53. package/corpus/core/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
  54. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +3 -3
  55. package/corpus/core/docs/content/locales/hi-IN/actions.mdx +1 -1
  56. package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +1 -1
  57. package/corpus/core/docs/content/locales/hi-IN/dispatch.mdx +3 -3
  58. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +31 -19
  59. package/corpus/core/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
  60. package/corpus/core/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
  61. package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
  62. package/corpus/core/docs/content/locales/hi-IN/server.mdx +2 -2
  63. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
  64. package/corpus/core/docs/content/locales/hi-IN/template-assets.mdx +1 -1
  65. package/corpus/core/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
  66. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +3 -3
  67. package/corpus/core/docs/content/locales/ja-JP/actions.mdx +1 -1
  68. package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +1 -1
  69. package/corpus/core/docs/content/locales/ja-JP/dispatch.mdx +3 -3
  70. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +23 -19
  71. package/corpus/core/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
  72. package/corpus/core/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
  73. package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
  74. package/corpus/core/docs/content/locales/ja-JP/server.mdx +2 -2
  75. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
  76. package/corpus/core/docs/content/locales/ja-JP/template-assets.mdx +1 -1
  77. package/corpus/core/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
  78. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +3 -3
  79. package/corpus/core/docs/content/locales/ko-KR/actions.mdx +1 -1
  80. package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +1 -1
  81. package/corpus/core/docs/content/locales/ko-KR/dispatch.mdx +3 -3
  82. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +30 -19
  83. package/corpus/core/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
  84. package/corpus/core/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
  85. package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
  86. package/corpus/core/docs/content/locales/ko-KR/server.mdx +2 -2
  87. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
  88. package/corpus/core/docs/content/locales/ko-KR/template-assets.mdx +1 -1
  89. package/corpus/core/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
  90. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +3 -3
  91. package/corpus/core/docs/content/locales/pt-BR/actions.mdx +1 -1
  92. package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +1 -1
  93. package/corpus/core/docs/content/locales/pt-BR/dispatch.mdx +3 -3
  94. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +32 -19
  95. package/corpus/core/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
  96. package/corpus/core/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
  97. package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
  98. package/corpus/core/docs/content/locales/pt-BR/server.mdx +2 -2
  99. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
  100. package/corpus/core/docs/content/locales/pt-BR/template-assets.mdx +1 -1
  101. package/corpus/core/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
  102. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +3 -3
  103. package/corpus/core/docs/content/locales/zh-CN/actions.mdx +1 -1
  104. package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +1 -1
  105. package/corpus/core/docs/content/locales/zh-CN/dispatch.mdx +3 -3
  106. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +23 -19
  107. package/corpus/core/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
  108. package/corpus/core/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
  109. package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
  110. package/corpus/core/docs/content/locales/zh-CN/server.mdx +2 -2
  111. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
  112. package/corpus/core/docs/content/locales/zh-CN/template-assets.mdx +1 -1
  113. package/corpus/core/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
  114. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +3 -3
  115. package/corpus/core/docs/content/locales/zh-TW/actions.mdx +1 -1
  116. package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +1 -1
  117. package/corpus/core/docs/content/locales/zh-TW/dispatch.mdx +3 -3
  118. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +23 -19
  119. package/corpus/core/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
  120. package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
  121. package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
  122. package/corpus/core/docs/content/locales/zh-TW/server.mdx +2 -2
  123. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
  124. package/corpus/core/docs/content/locales/zh-TW/template-assets.mdx +1 -1
  125. package/corpus/core/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
  126. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +3 -3
  127. package/corpus/core/docs/content/mcp-clients.mdx +31 -4
  128. package/corpus/core/docs/content/mcp-protocol.mdx +35 -15
  129. package/corpus/core/docs/content/plan-plugin.mdx +3 -3
  130. package/corpus/core/docs/content/server.mdx +2 -2
  131. package/corpus/core/docs/content/skills-guide.mdx +1 -1
  132. package/corpus/core/docs/content/template-assets.mdx +1 -1
  133. package/corpus/core/docs/content/template-dispatch.mdx +2 -2
  134. package/corpus/core/docs/content/template-plan.mdx +3 -3
  135. package/corpus/core/package.json +1 -1
  136. package/corpus/core/src/a2a/client.ts +3 -0
  137. package/corpus/core/src/a2a/handlers.ts +95 -7
  138. package/corpus/core/src/agent/production-agent.ts +21 -0
  139. package/corpus/core/src/cli/connect.ts +50 -24
  140. package/corpus/core/src/cli/mcp-config-writers.ts +10 -0
  141. package/corpus/core/src/cli/mcp.ts +5 -5
  142. package/corpus/core/src/cli/pr-visual-recap-workflow.ts +1 -1
  143. package/corpus/core/src/cli/skills-content/assets-skill.ts +1 -1
  144. package/corpus/core/src/cli/skills-content/design-exploration-skill.ts +1 -1
  145. package/corpus/core/src/cli/skills-content/help.ts +1 -1
  146. package/corpus/core/src/cli/skills-content/plan-setup-auth.ts +1 -1
  147. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +1 -1
  148. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +2 -2
  149. package/corpus/core/src/cli/skills.ts +23 -12
  150. package/corpus/core/src/client/analytics.ts +13 -0
  151. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +5 -0
  152. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +17 -0
  153. package/corpus/core/src/embedding/agent.ts +8 -6
  154. package/corpus/core/src/localization/default-messages.ts +7 -0
  155. package/corpus/core/src/mcp/ask-app-inline-tasks.ts +125 -0
  156. package/corpus/core/src/mcp/build-server.ts +65 -3
  157. package/corpus/core/src/mcp/builtin-tools.ts +186 -22
  158. package/corpus/core/src/mcp/connect-route.ts +17 -14
  159. package/corpus/core/src/mcp/oauth-route.ts +38 -13
  160. package/corpus/core/src/mcp/route-paths.ts +34 -0
  161. package/corpus/core/src/mcp/server.ts +21 -10
  162. package/corpus/core/src/mcp/stdio.ts +34 -16
  163. package/corpus/core/src/mcp/workspace-resolve.ts +2 -1
  164. package/corpus/core/src/mcp-client/manager.ts +5 -3
  165. package/corpus/core/src/mcp-client/remote-store.ts +10 -10
  166. package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +13 -0
  167. package/corpus/core/src/server/agent-chat-plugin.ts +42 -9
  168. package/corpus/core/src/server/agent-teams.ts +17 -0
  169. package/corpus/core/src/server/auth.ts +22 -6
  170. package/corpus/core/src/server/core-routes-plugin.ts +30 -24
  171. package/corpus/core/src/server/csrf.ts +17 -0
  172. package/corpus/core/src/server/framework-request-handler.ts +8 -2
  173. package/corpus/core/src/server/google-oauth.ts +12 -2
  174. package/corpus/core/src/server/http-response-telemetry.ts +6 -1
  175. package/corpus/core/src/server/recap-image-route.ts +3 -3
  176. package/corpus/core/src/server/security-headers.ts +7 -1
  177. package/corpus/core/src/server/ssr-handler.ts +2 -0
  178. package/corpus/core/src/shared/cache-control.ts +6 -4
  179. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  180. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  181. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  182. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  183. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  184. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +10 -0
  185. package/corpus/templates/analytics/app/assets/replay-cursor.svg +17 -0
  186. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -3
  187. package/corpus/templates/analytics/app/global.css +71 -4
  188. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +32 -4
  189. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +1 -1
  190. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +49 -11
  191. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
  192. package/corpus/templates/analytics/changelog/2026-07-13-all-time-dashboard-filters-no-longer-send-invalid-dates-to-b.md +6 -0
  193. package/corpus/templates/analytics/changelog/2026-07-13-daily-dashboard-emails-recover-more-reliably-from-serverless.md +6 -0
  194. package/corpus/templates/analytics/changelog/2026-07-13-error-issue-titles-wrap-instead-of-overflowing.md +6 -0
  195. package/corpus/templates/analytics/changelog/2026-07-13-saving-a-new-dashboard-view-no-longer-fails-with-a-server-er.md +6 -0
  196. package/corpus/templates/analytics/changelog/2026-07-13-session-replay-cursors-stay-hidden-until-their-first-recorde.md +6 -0
  197. package/corpus/templates/analytics/changelog/2026-07-13-session-replay-links-now-support-cmd-click-and-middle-click-.md +6 -0
  198. package/corpus/templates/analytics/changelog/2026-07-13-session-replays-keep-a-visible-mac-style-cursor-over-the-vis.md +6 -0
  199. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -2
  200. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +57 -1
  201. package/corpus/templates/analytics/server/lib/dashboard-report.ts +266 -28
  202. package/corpus/templates/analytics/server/lib/dashboards-store.ts +43 -4
  203. package/corpus/templates/analytics/server/lib/error-capture.ts +24 -5
  204. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  205. package/corpus/templates/analytics/server/routes/[...page].get.ts +0 -2
  206. package/corpus/templates/assets/.agents/skills/security/SKILL.md +10 -0
  207. package/corpus/templates/assets/agent-native.app-skill.json +1 -1
  208. package/corpus/templates/brain/.agents/skills/security/SKILL.md +10 -0
  209. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +10 -0
  210. package/corpus/templates/calendar/AGENTS.md +2 -1
  211. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -19
  212. package/corpus/templates/calendar/app/lib/attendee-local-time.ts +14 -5
  213. package/corpus/templates/calendar/changelog/2026-07-13-your-local-time-now-follows-your-browser-timezone-and-event-.md +6 -0
  214. package/corpus/templates/chat/.agents/skills/security/SKILL.md +10 -0
  215. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -2
  216. package/corpus/templates/clips/.agents/skills/security/SKILL.md +10 -0
  217. package/corpus/templates/clips/AGENTS.md +7 -0
  218. package/corpus/templates/clips/actions/list-meetings.ts +19 -4
  219. package/corpus/templates/clips/actions/start-meeting-recording.ts +7 -1
  220. package/corpus/templates/clips/app/components/library/recording-card.tsx +27 -26
  221. package/corpus/templates/clips/app/components/library/space-card.tsx +4 -6
  222. package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +75 -78
  223. package/corpus/templates/clips/app/components/recorder/confetti-canvas.tsx +18 -1
  224. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +6 -12
  225. package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +19 -2
  226. package/corpus/templates/clips/app/lib/camera-composite.ts +70 -10
  227. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -1
  228. package/corpus/templates/clips/app/routes/record.tsx +5 -25
  229. package/corpus/templates/clips/changelog/2026-07-13-clips-desktop-now-requires-macos-13-for-native-capture.md +6 -0
  230. package/corpus/templates/clips/changelog/2026-07-13-clips-hide-solo-meeting-reminders.md +6 -0
  231. package/corpus/templates/clips/changelog/2026-07-13-clips-now-removes-duplicate-mic-and-system-transcript-turns-.md +6 -0
  232. package/corpus/templates/clips/changelog/2026-07-13-desktop-recordings-run-cooler-and-quieter-live-transcription.md +6 -0
  233. package/corpus/templates/clips/changelog/2026-07-13-meeting-recordings-now-stop-after-a-calendar-meeting-ends-an.md +6 -0
  234. package/corpus/templates/clips/changelog/2026-07-13-meeting-transcripts-now-use-a-clean-agent-chat-style-reading.md +6 -0
  235. package/corpus/templates/clips/changelog/2026-07-13-screen-recordings-use-less-processing-power-during-longer-ca.md +6 -0
  236. package/corpus/templates/clips/chrome-extension/src/background.ts +5 -3
  237. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +17 -14
  238. package/corpus/templates/clips/chrome-extension/src/overlay.ts +8 -2
  239. package/corpus/templates/clips/desktop/README.md +3 -0
  240. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -0
  241. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -2
  242. package/corpus/templates/clips/desktop/src/lib/silence-events.ts +1 -0
  243. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +5 -0
  244. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +134 -5
  245. package/corpus/templates/clips/desktop/src/lib/upload-video-stream.ts +28 -0
  246. package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +10 -3
  247. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +42 -9
  248. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -2
  249. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +6 -1
  250. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +77 -1
  251. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +104 -25
  252. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +4 -0
  253. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +287 -32
  254. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
  255. package/corpus/templates/clips/server/lib/calendar-event-classification.ts +28 -0
  256. package/corpus/templates/clips/server/routes/[...page].get.ts +1 -59
  257. package/corpus/templates/clips/shared/recording-capture.ts +37 -0
  258. package/corpus/templates/content/.agents/skills/security/SKILL.md +10 -0
  259. package/corpus/templates/content/agent-native.app-skill.json +1 -1
  260. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +18 -16
  261. package/corpus/templates/content/server/routes/[...page].get.ts +1 -15
  262. package/corpus/templates/design/.agents/skills/security/SKILL.md +10 -0
  263. package/corpus/templates/design/actions/connect-assets-mcp.ts +1 -1
  264. package/corpus/templates/design/agent-native.app-skill.json +1 -1
  265. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +88 -12
  266. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1 -0
  267. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4 -1
  268. package/corpus/templates/design/changelog/2026-07-13-adding-shapes-preserves-canvas-background.md +6 -0
  269. package/corpus/templates/design/changelog/2026-07-13-clicking-quickly-between-overlapping-elements-no-longer-bounc.md +6 -0
  270. package/corpus/templates/design/server/plugins/assets-mcp.ts +1 -1
  271. package/corpus/templates/design/server/routes/[...page].get.ts +0 -2
  272. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +10 -0
  273. package/corpus/templates/forms/.agents/skills/security/SKILL.md +10 -0
  274. package/corpus/templates/macros/.agents/skills/security/SKILL.md +10 -0
  275. package/corpus/templates/mail/.agents/skills/security/SKILL.md +10 -0
  276. package/corpus/templates/plan/.agents/skills/security/SKILL.md +10 -0
  277. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +1 -1
  278. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +2 -2
  279. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  280. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +6 -1
  281. package/corpus/templates/plan/app/pages/PlansPage.tsx +15 -6
  282. package/corpus/templates/plan/changelog/2026-07-13-fixed-local-plan-previews-continuously-flickering-while-revi.md +6 -0
  283. package/corpus/templates/plan/server/routes/[...page].get.ts +0 -2
  284. package/corpus/templates/slides/.agents/skills/security/SKILL.md +10 -0
  285. package/dist/a2a/client.d.ts +2 -0
  286. package/dist/a2a/client.d.ts.map +1 -1
  287. package/dist/a2a/client.js +2 -0
  288. package/dist/a2a/client.js.map +1 -1
  289. package/dist/a2a/handlers.d.ts.map +1 -1
  290. package/dist/a2a/handlers.js +84 -7
  291. package/dist/a2a/handlers.js.map +1 -1
  292. package/dist/agent/production-agent.d.ts +9 -0
  293. package/dist/agent/production-agent.d.ts.map +1 -1
  294. package/dist/agent/production-agent.js +12 -0
  295. package/dist/agent/production-agent.js.map +1 -1
  296. package/dist/cli/connect.d.ts +2 -2
  297. package/dist/cli/connect.d.ts.map +1 -1
  298. package/dist/cli/connect.js +45 -23
  299. package/dist/cli/connect.js.map +1 -1
  300. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  301. package/dist/cli/mcp-config-writers.js +7 -0
  302. package/dist/cli/mcp-config-writers.js.map +1 -1
  303. package/dist/cli/mcp.js +5 -3
  304. package/dist/cli/mcp.js.map +1 -1
  305. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  306. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  307. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  308. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  309. package/dist/cli/skills-content/assets-skill.d.ts +1 -1
  310. package/dist/cli/skills-content/assets-skill.d.ts.map +1 -1
  311. package/dist/cli/skills-content/assets-skill.js +1 -1
  312. package/dist/cli/skills-content/assets-skill.js.map +1 -1
  313. package/dist/cli/skills-content/design-exploration-skill.d.ts +1 -1
  314. package/dist/cli/skills-content/design-exploration-skill.d.ts.map +1 -1
  315. package/dist/cli/skills-content/design-exploration-skill.js +1 -1
  316. package/dist/cli/skills-content/design-exploration-skill.js.map +1 -1
  317. package/dist/cli/skills-content/help.d.ts +1 -1
  318. package/dist/cli/skills-content/help.d.ts.map +1 -1
  319. package/dist/cli/skills-content/help.js +1 -1
  320. package/dist/cli/skills-content/help.js.map +1 -1
  321. package/dist/cli/skills-content/plan-setup-auth.d.ts +1 -1
  322. package/dist/cli/skills-content/plan-setup-auth.d.ts.map +1 -1
  323. package/dist/cli/skills-content/plan-setup-auth.js +1 -1
  324. package/dist/cli/skills-content/plan-setup-auth.js.map +1 -1
  325. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  326. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  327. package/dist/cli/skills-content/visual-plan-skill.js +1 -1
  328. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  329. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  330. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  331. package/dist/cli/skills-content/visual-recap-skill.js +2 -2
  332. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  333. package/dist/cli/skills.d.ts.map +1 -1
  334. package/dist/cli/skills.js +16 -12
  335. package/dist/cli/skills.js.map +1 -1
  336. package/dist/client/analytics.d.ts.map +1 -1
  337. package/dist/client/analytics.js +11 -0
  338. package/dist/client/analytics.js.map +1 -1
  339. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  340. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  341. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  342. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  343. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  344. package/dist/client/resources/mcp-integration-catalog.js +14 -0
  345. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  346. package/dist/collab/awareness.d.ts +2 -2
  347. package/dist/collab/awareness.d.ts.map +1 -1
  348. package/dist/collab/routes.d.ts +1 -1
  349. package/dist/collab/struct-routes.d.ts +1 -1
  350. package/dist/embedding/agent.d.ts.map +1 -1
  351. package/dist/embedding/agent.js +6 -7
  352. package/dist/embedding/agent.js.map +1 -1
  353. package/dist/localization/default-messages.d.ts +5 -0
  354. package/dist/localization/default-messages.d.ts.map +1 -1
  355. package/dist/localization/default-messages.js +5 -0
  356. package/dist/localization/default-messages.js.map +1 -1
  357. package/dist/mcp/ask-app-inline-tasks.d.ts +47 -0
  358. package/dist/mcp/ask-app-inline-tasks.d.ts.map +1 -0
  359. package/dist/mcp/ask-app-inline-tasks.js +87 -0
  360. package/dist/mcp/ask-app-inline-tasks.js.map +1 -0
  361. package/dist/mcp/build-server.d.ts.map +1 -1
  362. package/dist/mcp/build-server.js +56 -3
  363. package/dist/mcp/build-server.js.map +1 -1
  364. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  365. package/dist/mcp/builtin-tools.js +141 -21
  366. package/dist/mcp/builtin-tools.js.map +1 -1
  367. package/dist/mcp/connect-route.d.ts +12 -10
  368. package/dist/mcp/connect-route.d.ts.map +1 -1
  369. package/dist/mcp/connect-route.js +17 -14
  370. package/dist/mcp/connect-route.js.map +1 -1
  371. package/dist/mcp/oauth-route.d.ts +1 -1
  372. package/dist/mcp/oauth-route.d.ts.map +1 -1
  373. package/dist/mcp/oauth-route.js +30 -13
  374. package/dist/mcp/oauth-route.js.map +1 -1
  375. package/dist/mcp/route-paths.d.ts +13 -0
  376. package/dist/mcp/route-paths.d.ts.map +1 -0
  377. package/dist/mcp/route-paths.js +27 -0
  378. package/dist/mcp/route-paths.js.map +1 -0
  379. package/dist/mcp/server.d.ts +2 -1
  380. package/dist/mcp/server.d.ts.map +1 -1
  381. package/dist/mcp/server.js +14 -6
  382. package/dist/mcp/server.js.map +1 -1
  383. package/dist/mcp/stdio.d.ts +7 -6
  384. package/dist/mcp/stdio.d.ts.map +1 -1
  385. package/dist/mcp/stdio.js +27 -15
  386. package/dist/mcp/stdio.js.map +1 -1
  387. package/dist/mcp/workspace-resolve.d.ts +2 -1
  388. package/dist/mcp/workspace-resolve.d.ts.map +1 -1
  389. package/dist/mcp/workspace-resolve.js +2 -1
  390. package/dist/mcp/workspace-resolve.js.map +1 -1
  391. package/dist/mcp-client/manager.js +6 -3
  392. package/dist/mcp-client/manager.js.map +1 -1
  393. package/dist/mcp-client/remote-store.js +5 -7
  394. package/dist/mcp-client/remote-store.js.map +1 -1
  395. package/dist/notifications/routes.d.ts +3 -3
  396. package/dist/progress/routes.d.ts +1 -1
  397. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  398. package/dist/resources/handlers.d.ts +2 -2
  399. package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
  400. package/dist/server/agent-chat/action-filters-a2a.js +11 -1
  401. package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
  402. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  403. package/dist/server/agent-chat-plugin.js +43 -11
  404. package/dist/server/agent-chat-plugin.js.map +1 -1
  405. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  406. package/dist/server/agent-teams.d.ts.map +1 -1
  407. package/dist/server/agent-teams.js +15 -1
  408. package/dist/server/agent-teams.js.map +1 -1
  409. package/dist/server/auth.d.ts.map +1 -1
  410. package/dist/server/auth.js +16 -6
  411. package/dist/server/auth.js.map +1 -1
  412. package/dist/server/core-routes-plugin.d.ts +4 -3
  413. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  414. package/dist/server/core-routes-plugin.js +20 -15
  415. package/dist/server/core-routes-plugin.js.map +1 -1
  416. package/dist/server/csrf.d.ts.map +1 -1
  417. package/dist/server/csrf.js +11 -0
  418. package/dist/server/csrf.js.map +1 -1
  419. package/dist/server/framework-request-handler.d.ts.map +1 -1
  420. package/dist/server/framework-request-handler.js +8 -2
  421. package/dist/server/framework-request-handler.js.map +1 -1
  422. package/dist/server/google-oauth.d.ts +2 -0
  423. package/dist/server/google-oauth.d.ts.map +1 -1
  424. package/dist/server/google-oauth.js +11 -2
  425. package/dist/server/google-oauth.js.map +1 -1
  426. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  427. package/dist/server/http-response-telemetry.js +4 -1
  428. package/dist/server/http-response-telemetry.js.map +1 -1
  429. package/dist/server/recap-image-route.js +3 -3
  430. package/dist/server/recap-image-route.js.map +1 -1
  431. package/dist/server/security-headers.d.ts.map +1 -1
  432. package/dist/server/security-headers.js +4 -1
  433. package/dist/server/security-headers.js.map +1 -1
  434. package/dist/server/ssr-handler.d.ts.map +1 -1
  435. package/dist/server/ssr-handler.js +3 -1
  436. package/dist/server/ssr-handler.js.map +1 -1
  437. package/dist/shared/cache-control.d.ts +7 -6
  438. package/dist/shared/cache-control.d.ts.map +1 -1
  439. package/dist/shared/cache-control.js +4 -3
  440. package/dist/shared/cache-control.js.map +1 -1
  441. package/dist/templates/default/.agents/skills/security/SKILL.md +10 -0
  442. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  443. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  444. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  445. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  446. package/docs/content/actions.mdx +1 -1
  447. package/docs/content/authentication.mdx +1 -1
  448. package/docs/content/dispatch.mdx +3 -3
  449. package/docs/content/external-agents.mdx +30 -19
  450. package/docs/content/locales/ar-SA/actions.mdx +1 -1
  451. package/docs/content/locales/ar-SA/authentication.mdx +1 -1
  452. package/docs/content/locales/ar-SA/dispatch.mdx +3 -3
  453. package/docs/content/locales/ar-SA/external-agents.mdx +23 -19
  454. package/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
  455. package/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
  456. package/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
  457. package/docs/content/locales/ar-SA/server.mdx +2 -2
  458. package/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
  459. package/docs/content/locales/ar-SA/template-assets.mdx +1 -1
  460. package/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
  461. package/docs/content/locales/ar-SA/template-plan.mdx +3 -3
  462. package/docs/content/locales/de-DE/actions.mdx +1 -1
  463. package/docs/content/locales/de-DE/authentication.mdx +1 -1
  464. package/docs/content/locales/de-DE/dispatch.mdx +3 -3
  465. package/docs/content/locales/de-DE/external-agents.mdx +23 -19
  466. package/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
  467. package/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
  468. package/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
  469. package/docs/content/locales/de-DE/server.mdx +2 -2
  470. package/docs/content/locales/de-DE/skills-guide.mdx +1 -1
  471. package/docs/content/locales/de-DE/template-assets.mdx +1 -1
  472. package/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
  473. package/docs/content/locales/de-DE/template-plan.mdx +3 -3
  474. package/docs/content/locales/es-ES/actions.mdx +1 -1
  475. package/docs/content/locales/es-ES/authentication.mdx +1 -1
  476. package/docs/content/locales/es-ES/dispatch.mdx +3 -3
  477. package/docs/content/locales/es-ES/external-agents.mdx +32 -19
  478. package/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
  479. package/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
  480. package/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
  481. package/docs/content/locales/es-ES/server.mdx +2 -2
  482. package/docs/content/locales/es-ES/skills-guide.mdx +1 -1
  483. package/docs/content/locales/es-ES/template-assets.mdx +1 -1
  484. package/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
  485. package/docs/content/locales/es-ES/template-plan.mdx +3 -3
  486. package/docs/content/locales/fr-FR/actions.mdx +1 -1
  487. package/docs/content/locales/fr-FR/authentication.mdx +1 -1
  488. package/docs/content/locales/fr-FR/dispatch.mdx +3 -3
  489. package/docs/content/locales/fr-FR/external-agents.mdx +23 -19
  490. package/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
  491. package/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
  492. package/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
  493. package/docs/content/locales/fr-FR/server.mdx +2 -2
  494. package/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
  495. package/docs/content/locales/fr-FR/template-assets.mdx +1 -1
  496. package/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
  497. package/docs/content/locales/fr-FR/template-plan.mdx +3 -3
  498. package/docs/content/locales/hi-IN/actions.mdx +1 -1
  499. package/docs/content/locales/hi-IN/authentication.mdx +1 -1
  500. package/docs/content/locales/hi-IN/dispatch.mdx +3 -3
  501. package/docs/content/locales/hi-IN/external-agents.mdx +31 -19
  502. package/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
  503. package/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
  504. package/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
  505. package/docs/content/locales/hi-IN/server.mdx +2 -2
  506. package/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
  507. package/docs/content/locales/hi-IN/template-assets.mdx +1 -1
  508. package/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
  509. package/docs/content/locales/hi-IN/template-plan.mdx +3 -3
  510. package/docs/content/locales/ja-JP/actions.mdx +1 -1
  511. package/docs/content/locales/ja-JP/authentication.mdx +1 -1
  512. package/docs/content/locales/ja-JP/dispatch.mdx +3 -3
  513. package/docs/content/locales/ja-JP/external-agents.mdx +23 -19
  514. package/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
  515. package/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
  516. package/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
  517. package/docs/content/locales/ja-JP/server.mdx +2 -2
  518. package/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
  519. package/docs/content/locales/ja-JP/template-assets.mdx +1 -1
  520. package/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
  521. package/docs/content/locales/ja-JP/template-plan.mdx +3 -3
  522. package/docs/content/locales/ko-KR/actions.mdx +1 -1
  523. package/docs/content/locales/ko-KR/authentication.mdx +1 -1
  524. package/docs/content/locales/ko-KR/dispatch.mdx +3 -3
  525. package/docs/content/locales/ko-KR/external-agents.mdx +30 -19
  526. package/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
  527. package/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
  528. package/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
  529. package/docs/content/locales/ko-KR/server.mdx +2 -2
  530. package/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
  531. package/docs/content/locales/ko-KR/template-assets.mdx +1 -1
  532. package/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
  533. package/docs/content/locales/ko-KR/template-plan.mdx +3 -3
  534. package/docs/content/locales/pt-BR/actions.mdx +1 -1
  535. package/docs/content/locales/pt-BR/authentication.mdx +1 -1
  536. package/docs/content/locales/pt-BR/dispatch.mdx +3 -3
  537. package/docs/content/locales/pt-BR/external-agents.mdx +32 -19
  538. package/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
  539. package/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
  540. package/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
  541. package/docs/content/locales/pt-BR/server.mdx +2 -2
  542. package/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
  543. package/docs/content/locales/pt-BR/template-assets.mdx +1 -1
  544. package/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
  545. package/docs/content/locales/pt-BR/template-plan.mdx +3 -3
  546. package/docs/content/locales/zh-CN/actions.mdx +1 -1
  547. package/docs/content/locales/zh-CN/authentication.mdx +1 -1
  548. package/docs/content/locales/zh-CN/dispatch.mdx +3 -3
  549. package/docs/content/locales/zh-CN/external-agents.mdx +23 -19
  550. package/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
  551. package/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
  552. package/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
  553. package/docs/content/locales/zh-CN/server.mdx +2 -2
  554. package/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
  555. package/docs/content/locales/zh-CN/template-assets.mdx +1 -1
  556. package/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
  557. package/docs/content/locales/zh-CN/template-plan.mdx +3 -3
  558. package/docs/content/locales/zh-TW/actions.mdx +1 -1
  559. package/docs/content/locales/zh-TW/authentication.mdx +1 -1
  560. package/docs/content/locales/zh-TW/dispatch.mdx +3 -3
  561. package/docs/content/locales/zh-TW/external-agents.mdx +23 -19
  562. package/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
  563. package/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
  564. package/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
  565. package/docs/content/locales/zh-TW/server.mdx +2 -2
  566. package/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
  567. package/docs/content/locales/zh-TW/template-assets.mdx +1 -1
  568. package/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
  569. package/docs/content/locales/zh-TW/template-plan.mdx +3 -3
  570. package/docs/content/mcp-clients.mdx +31 -4
  571. package/docs/content/mcp-protocol.mdx +35 -15
  572. package/docs/content/plan-plugin.mdx +3 -3
  573. package/docs/content/server.mdx +2 -2
  574. package/docs/content/skills-guide.mdx +1 -1
  575. package/docs/content/template-assets.mdx +1 -1
  576. package/docs/content/template-dispatch.mdx +2 -2
  577. package/docs/content/template-plan.mdx +3 -3
  578. package/package.json +2 -2
  579. package/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  580. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  581. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  582. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  583. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
@@ -260,6 +260,7 @@ export function useMeetingTranscription({
260
260
  try {
261
261
  const result = await callClipsAction<{
262
262
  meetingId?: string;
263
+ scheduledEnd?: string | null;
263
264
  recording?: { id?: string | null } | null;
264
265
  }>("start-meeting-recording", { meetingId });
265
266
  const resolvedMeetingId = result.meetingId ?? meetingId;
@@ -268,6 +269,13 @@ export function useMeetingTranscription({
268
269
  throw new Error("Could not create a transcript session.");
269
270
  }
270
271
 
272
+ const parsedScheduledEndMs = result.scheduledEnd
273
+ ? Date.parse(result.scheduledEnd)
274
+ : Number.NaN;
275
+ const scheduledEndMs = Number.isFinite(parsedScheduledEndMs)
276
+ ? parsedScheduledEndMs
277
+ : null;
278
+
271
279
  const session: MeetingTranscriptionSession = {
272
280
  meetingId: resolvedMeetingId,
273
281
  recordingId,
@@ -366,6 +374,7 @@ export function useMeetingTranscription({
366
374
  silenceThreshold: 0.05,
367
375
  silenceMs: 15 * 60 * 1000,
368
376
  callEndedMs: 2 * 60 * 1000,
377
+ scheduledEndMs,
369
378
  watchSleep: true,
370
379
  watchCallEnded: true,
371
380
  };
@@ -81,6 +81,7 @@ import {
81
81
  type CapturedTranscript,
82
82
  type TranscriptionCapture,
83
83
  } from "./transcription-capture";
84
+ import { shouldResampleVideoForUpload } from "./upload-video-stream";
84
85
 
85
86
  export type { LocalExportedFile } from "./local-export";
86
87
  export { planNativeFullscreenWarmOverlap } from "./native-recording-warm";
@@ -98,7 +99,7 @@ export interface RegionCaptureRect {
98
99
  const NATIVE_FULLSCREEN_RECORDING_FLAG = "clips:native-fullscreen-recording";
99
100
  const DEV_SYNTHETIC_CAPTURE_FLAG = "clips:dev-synthetic-capture";
100
101
  const LEGACY_DEV_REAL_CAPTURE_FLAG = "clips:dev-real-capture";
101
- const LIVE_UPLOAD_CHUNK_MS = 1_000;
102
+ const LIVE_UPLOAD_CHUNK_MS = 2_000;
102
103
  const NATIVE_FULLSCREEN_SEGMENT_MS = 5 * 60_000;
103
104
  const NATIVE_FULLSCREEN_MIME_TYPE = "video/mp4";
104
105
  // GCS resumable uploads require every non-final chunk to be a multiple of
@@ -302,6 +303,11 @@ function createUploadOptimizedVideoStream(
302
303
  }
303
304
 
304
305
  const sourceSize = videoTrackDimensions(source);
306
+ if (
307
+ !shouldResampleVideoForUpload(sourceSize, CLOUD_RECORDING_MAX_LONG_EDGE)
308
+ ) {
309
+ return { stream: source, cleanup() {} };
310
+ }
305
311
  const initial = scaledVideoDimensions(
306
312
  sourceSize.width ?? 1280,
307
313
  sourceSize.height ?? 720,
@@ -3216,8 +3222,8 @@ async function startRecordingInner(
3216
3222
  // resumable session with the correct content type when the server supports
3217
3223
  // streaming uploads.
3218
3224
  const mimeCandidates = [
3219
- "video/webm;codecs=vp9,opus",
3220
3225
  "video/webm;codecs=vp8,opus",
3226
+ "video/webm;codecs=vp9,opus",
3221
3227
  "video/webm",
3222
3228
  ];
3223
3229
  const mimeType =
@@ -23,6 +23,7 @@ export interface SilenceConfig {
23
23
  silenceThreshold?: number;
24
24
  silenceMs?: number;
25
25
  callEndedMs?: number;
26
+ scheduledEndMs?: number | null;
26
27
  watchSleep?: boolean;
27
28
  watchCallEnded?: boolean;
28
29
  }
@@ -337,6 +337,10 @@ export async function startTranscriptionCapture(
337
337
  mic,
338
338
  captureSystem,
339
339
  voiceProcessing: opts?.voiceProcessing,
340
+ // Recordings only persist final segments. Meetings use the same engine
341
+ // directly and retain live partials, but repeatedly inferring partials
342
+ // here burns CPU without any recording UI consuming them.
343
+ emitPartials: false,
340
344
  });
341
345
  console.log(
342
346
  `[clips-recorder] transcription started (${engine} mic${captureSystem ? "+system" : ""})`,
@@ -367,6 +371,7 @@ export async function startTranscriptionCapture(
367
371
  mic,
368
372
  captureSystem,
369
373
  voiceProcessing: opts?.voiceProcessing,
374
+ emitPartials: false,
370
375
  });
371
376
  // stop()/cancel() can run during the await above; if it did, the new
372
377
  // engine would leak (mic/system capture stays live). Tear it down.
@@ -30,6 +30,9 @@ export interface SourcedTranscriptSegment extends TranscriptSegment {
30
30
  source: TranscriptSource;
31
31
  }
32
32
 
33
+ const DUPLICATE_TOKEN_OVERLAP = 0.72;
34
+ const DUPLICATE_TIME_OVERLAP = 0.35;
35
+
33
36
  export interface FinalTranscriptEvent {
34
37
  /** Raw text (not trimmed); callers decide whether to skip empties. */
35
38
  text: string;
@@ -70,6 +73,97 @@ export function speakerFor(
70
73
  return source === "system" ? "Them" : "Me";
71
74
  }
72
75
 
76
+ function normalizedTranscriptText(text: string): string {
77
+ return text
78
+ .normalize("NFKC")
79
+ .toLocaleLowerCase()
80
+ .replace(/[^\p{L}\p{N}]+/gu, " ")
81
+ .trim();
82
+ }
83
+
84
+ function transcriptWords(text: string): string[] {
85
+ const normalized = normalizedTranscriptText(text);
86
+ return normalized ? normalized.split(/\s+/) : [];
87
+ }
88
+
89
+ function tokenOverlap(left: string[], right: string[]): number {
90
+ if (left.length === 0 || right.length === 0) return 0;
91
+
92
+ const rightWords = new Set(right);
93
+ const sharedWords = new Set(left.filter((word) => rightWords.has(word)));
94
+ return sharedWords.size / Math.min(new Set(left).size, new Set(right).size);
95
+ }
96
+
97
+ function timeOverlapRatio(
98
+ left: SourcedTranscriptSegment,
99
+ right: SourcedTranscriptSegment,
100
+ ): number {
101
+ const overlapStart = Math.max(left.startMs, right.startMs);
102
+ const overlapEnd = Math.min(left.endMs, right.endMs);
103
+ const overlapMs = Math.max(0, overlapEnd - overlapStart);
104
+ const shorterDuration = Math.max(
105
+ 1,
106
+ Math.min(left.endMs - left.startMs, right.endMs - right.startMs),
107
+ );
108
+
109
+ return overlapMs / shorterDuration;
110
+ }
111
+
112
+ function isDuplicateTranscriptSegment(
113
+ existing: SourcedTranscriptSegment,
114
+ incoming: SourcedTranscriptSegment,
115
+ ): boolean {
116
+ if (existing.source === incoming.source) return false;
117
+
118
+ const existingText = normalizedTranscriptText(existing.text);
119
+ const incomingText = normalizedTranscriptText(incoming.text);
120
+ const existingWords = transcriptWords(existing.text);
121
+ const incomingWords = transcriptWords(incoming.text);
122
+
123
+ if (
124
+ !existingText ||
125
+ !incomingText ||
126
+ existingWords.length < 3 ||
127
+ incomingWords.length < 3
128
+ ) {
129
+ return false;
130
+ }
131
+
132
+ if (timeOverlapRatio(existing, incoming) < DUPLICATE_TIME_OVERLAP) {
133
+ return false;
134
+ }
135
+
136
+ return (
137
+ existingText === incomingText ||
138
+ tokenOverlap(existingWords, incomingWords) >= DUPLICATE_TOKEN_OVERLAP
139
+ );
140
+ }
141
+
142
+ function isDuplicateTranscriptLine(
143
+ lines: string[],
144
+ source: TranscriptSource,
145
+ text: string,
146
+ ): boolean {
147
+ const words = transcriptWords(text);
148
+ if (words.length < 4) return false;
149
+
150
+ const speaker = speakerFor(source);
151
+ return lines.some((line) => {
152
+ const separatorIndex = line.indexOf(":");
153
+ if (separatorIndex === -1 || line.slice(0, separatorIndex) === speaker) {
154
+ return false;
155
+ }
156
+
157
+ const existingText = line.slice(separatorIndex + 1);
158
+ const existingWords = transcriptWords(existingText);
159
+ return (
160
+ normalizedTranscriptText(existingText) ===
161
+ normalizedTranscriptText(text) ||
162
+ tokenOverlap(existingWords, words) >= DUPLICATE_TOKEN_OVERLAP
163
+ );
164
+ });
165
+ }
166
+
73
167
  /**
74
168
  * Fold a final-transcript event into a running transcript: appends a
75
169
  * speaker-labelled line and the event's (non-empty) segments tagged with the
@@ -83,14 +177,39 @@ export function appendFinalTranscript(
83
177
  ): boolean {
84
178
  const text = event.text.trim();
85
179
  if (!text) return false;
86
- lines.push(`${speakerFor(event.source)}: ${text}`);
87
- for (const seg of event.segments) {
88
- const segText = seg.text?.trim();
89
- if (!segText) continue;
180
+
181
+ if (event.segments.length === 0) {
182
+ if (isDuplicateTranscriptLine(lines, event.source, text)) return false;
183
+
184
+ lines.push(`${speakerFor(event.source)}: ${text}`);
185
+ return true;
186
+ }
187
+
188
+ const uniqueSegments = event.segments.filter((segment) => {
189
+ const segText = segment.text?.trim();
190
+ if (!segText) return false;
191
+
192
+ return !segments.some((existing) =>
193
+ isDuplicateTranscriptSegment(existing, {
194
+ ...segment,
195
+ text: segText,
196
+ source: event.source,
197
+ }),
198
+ );
199
+ });
200
+
201
+ if (uniqueSegments.length === 0) return false;
202
+
203
+ lines.push(
204
+ `${speakerFor(event.source)}: ${uniqueSegments
205
+ .map((segment) => segment.text.trim())
206
+ .join(" ")}`,
207
+ );
208
+ for (const seg of uniqueSegments) {
90
209
  segments.push({
91
210
  startMs: seg.startMs,
92
211
  endMs: seg.endMs,
93
- text: segText,
212
+ text: seg.text.trim(),
94
213
  source: event.source,
95
214
  });
96
215
  }
@@ -120,6 +239,7 @@ export async function restartTranscriptionEngine(
120
239
  mic?: MicSelection,
121
240
  captureSystem: boolean = true,
122
241
  voiceProcessing: boolean = false,
242
+ emitPartials: boolean = true,
123
243
  ): Promise<void> {
124
244
  if (engine === "whisper") {
125
245
  await invoke("audio_transcription_start", {
@@ -129,6 +249,7 @@ export async function restartTranscriptionEngine(
129
249
  micDeviceLabel: mic?.label || null,
130
250
  captureSystem,
131
251
  voiceProcessing,
252
+ emitPartials,
132
253
  owner: "meeting",
133
254
  });
134
255
  } else {
@@ -157,15 +278,23 @@ export async function startTranscriptionEngine(opts: {
157
278
  * only when combined ScreenCaptureKit capture is unavailable or fails.
158
279
  */
159
280
  voiceProcessing?: boolean;
281
+ /**
282
+ * Emit recurring live partial transcripts while speech is in progress.
283
+ * Meetings render these updates; recordings only persist final segments and
284
+ * disable them to avoid repeatedly transcribing the same growing buffer.
285
+ */
286
+ emitPartials?: boolean;
160
287
  }): Promise<TranscriptionEngine> {
161
288
  const captureSystem = opts.captureSystem ?? true;
162
289
  const voiceProcessing = opts.voiceProcessing ?? false;
290
+ const emitPartials = opts.emitPartials ?? true;
163
291
  try {
164
292
  await restartTranscriptionEngine(
165
293
  "whisper",
166
294
  opts.mic,
167
295
  captureSystem,
168
296
  voiceProcessing,
297
+ emitPartials,
169
298
  );
170
299
  return "whisper";
171
300
  } catch (err) {
@@ -0,0 +1,28 @@
1
+ export interface VideoDimensions {
2
+ width: number | null;
3
+ height: number | null;
4
+ }
5
+
6
+ function isPositiveNumber(value: number | null): value is number {
7
+ return value !== null && Number.isFinite(value) && value > 0;
8
+ }
9
+
10
+ /**
11
+ * Whether upload capture needs a canvas-backed resize pass.
12
+ *
13
+ * Unknown dimensions stay on the defensive resize path. A source that is
14
+ * already within the upload budget can go straight to MediaRecorder, avoiding
15
+ * a full-frame draw on the renderer thread for every captured frame.
16
+ */
17
+ export function shouldResampleVideoForUpload(
18
+ dimensions: VideoDimensions,
19
+ maxLongEdge: number,
20
+ ): boolean {
21
+ if (
22
+ !isPositiveNumber(dimensions.width) ||
23
+ !isPositiveNumber(dimensions.height)
24
+ ) {
25
+ return true;
26
+ }
27
+ return Math.max(dimensions.width, dimensions.height) > maxLongEdge;
28
+ }
@@ -83,8 +83,17 @@ export function FlowBar() {
83
83
  const BAR_COUNT = 14;
84
84
  const BAR_WIDTH = 2;
85
85
  const BAR_GAP = 3;
86
+ // A bar waveform reads the same well below display refresh rate
87
+ // (60-120Hz); cap the actual draw work to ~20fps while still scheduling
88
+ // via rAF every frame so the loop still pauses when the bar is hidden.
89
+ const FRAME_INTERVAL_MS = 1000 / 20;
90
+ let lastDrawMs = 0;
91
+
92
+ function draw(timestamp: number) {
93
+ rafRef.current = requestAnimationFrame(draw);
94
+ if (timestamp - lastDrawMs < FRAME_INTERVAL_MS) return;
95
+ lastDrawMs = timestamp;
86
96
 
87
- function draw() {
88
97
  const canvas = canvasRef.current;
89
98
  if (!canvas) return;
90
99
  const ctx = canvas.getContext("2d");
@@ -119,8 +128,6 @@ export function FlowBar() {
119
128
  ctx.roundRect(x, y, BAR_WIDTH, h, 1);
120
129
  ctx.fill();
121
130
  }
122
-
123
- rafRef.current = requestAnimationFrame(draw);
124
131
  }
125
132
 
126
133
  rafRef.current = requestAnimationFrame(draw);
@@ -128,6 +128,16 @@ export function MeetingNotification() {
128
128
  const [pending, setPending] = useState(false);
129
129
  const autoHideTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
130
130
  const dataRef = useRef<NotificationData | null>(null);
131
+ // Real DOM hover only fires while this overlay window is key, which macOS
132
+ // won't grant it without a click (`show_without_activation` never
133
+ // activates). `polledHovered` mirrors the Rust-side global cursor poll
134
+ // (`meetings:notification-hover`, see `start_meeting_notification_hover_tracking`
135
+ // in notifications.rs) so the X still reveals on hover while another app is
136
+ // focused — same fallback pattern as the recording pill's `clips:pill-hover`.
137
+ const [domHovered, setDomHovered] = useState(false);
138
+ const [polledHovered, setPolledHovered] = useState(false);
139
+ const hovered = domHovered || polledHovered;
140
+ const prevHoveredRef = useRef(false);
131
141
 
132
142
  useEffect(() => {
133
143
  dataRef.current = data;
@@ -150,6 +160,30 @@ export function MeetingNotification() {
150
160
  }
151
161
  }, [data]);
152
162
 
163
+ useEffect(() => {
164
+ if (!data) {
165
+ // Dismissing doesn't guarantee mouseleave/hovered:false fires first
166
+ // (e.g. dismissed while the cursor is still over the card), so clear
167
+ // every hover source here — otherwise the next notification can
168
+ // inherit hovered === true and open with its close button already
169
+ // showing and auto-hide already cancelled.
170
+ prevHoveredRef.current = false;
171
+ setDomHovered(false);
172
+ setPolledHovered(false);
173
+ setShowClose(false);
174
+ return;
175
+ }
176
+ if (hovered === prevHoveredRef.current) return;
177
+ prevHoveredRef.current = hovered;
178
+ setShowClose(hovered);
179
+ if (hovered) {
180
+ clearAutoHide();
181
+ } else {
182
+ setMenuOpen(false);
183
+ resumeAutoHide();
184
+ }
185
+ }, [data, hovered]);
186
+
153
187
  function showNotification(
154
188
  payload: NotificationData,
155
189
  options?: { hydrated?: boolean },
@@ -191,6 +225,12 @@ export function MeetingNotification() {
191
225
  }),
192
226
  );
193
227
 
228
+ trackListen(
229
+ listen<{ hovered: boolean }>("meetings:notification-hover", (ev) => {
230
+ setPolledHovered(ev.payload.hovered);
231
+ }),
232
+ );
233
+
194
234
  // Cold overlay boot: hydrate any payload stored before this webview
195
235
  // mounted (calendar or adhoc).
196
236
  invoke<NotificationData | null>("take_pending_meeting_notification")
@@ -329,15 +369,8 @@ export function MeetingNotification() {
329
369
  <div className="meeting-notification-root">
330
370
  <div
331
371
  className="meeting-notification"
332
- onMouseEnter={() => {
333
- setShowClose(true);
334
- clearAutoHide();
335
- }}
336
- onMouseLeave={() => {
337
- setShowClose(false);
338
- setMenuOpen(false);
339
- resumeAutoHide();
340
- }}
372
+ onMouseEnter={() => setDomHovered(true)}
373
+ onMouseLeave={() => setDomHovered(false)}
341
374
  >
342
375
  <div
343
376
  className={`meeting-notification-bar ${isCalendar ? "meeting-notification-bar-calendar" : "meeting-notification-bar-adhoc"}`}
@@ -352,9 +352,18 @@ export function RecordingPill() {
352
352
  );
353
353
 
354
354
  const startMs = Date.now();
355
+ let lastDrawMs = 0;
356
+ // A bar meter reads the same to the eye well below display refresh rate
357
+ // (60-120Hz); cap the actual draw work to ~20fps while still scheduling
358
+ // via rAF every frame so the loop still pauses when the pill is hidden.
359
+ const FRAME_INTERVAL_MS = 1000 / 20;
355
360
  const tick = () => {
361
+ rafRef.current = requestAnimationFrame(tick);
362
+ const nowMs = Date.now();
363
+ if (nowMs - lastDrawMs < FRAME_INTERVAL_MS) return;
364
+ lastDrawMs = nowMs;
356
365
  // Modulo prevents float precision loss on long recordings.
357
- const t = (Date.now() - startMs) % 1_000_000;
366
+ const t = (nowMs - startMs) % 1_000_000;
358
367
  for (const s of setups) {
359
368
  const target = Math.min(1, s.levelRef.current * s.gain);
360
369
 
@@ -385,7 +394,6 @@ export function RecordingPill() {
385
394
  }
386
395
  s.ctx2d.shadowBlur = 0;
387
396
  }
388
- rafRef.current = requestAnimationFrame(tick);
389
397
  };
390
398
  tick();
391
399
  return () => {
@@ -124,7 +124,12 @@ screencapturekit = { version = "2.0.0", features = ["macos_15_0"] }
124
124
  # AudioBufferList type so we can hand SCK's CMSampleBuffer audio bytes to
125
125
  # AVAudioPCMBuffer for the speech recognizer.
126
126
  objc2-core-audio-types = "0.3"
127
- whisper-rs = { version = "0.16.0" }
127
+ # `metal` builds whisper.cpp's ggml-metal backend and links it in (the sys
128
+ # crate's build script embeds the compiled metallib, so no app-bundle/runtime
129
+ # asset changes are needed). Without it, whisper.cpp decode runs CPU-only.
130
+ # `use_gpu` is still set explicitly per-arch in whisper_speech.rs so Intel
131
+ # Macs don't exercise Metal even though the feature is compiled in.
132
+ whisper-rs = { version = "0.16.0", features = ["metal"] }
128
133
  # NOTE: We hand-roll the few EventKit selectors we need via raw `objc2`
129
134
  # msg_send! in `eventkit.rs` rather than depending on the `objc2-event-kit`
130
135
  # crate. Its API surface drifts between minor 0.3.x releases (and not
@@ -6,8 +6,13 @@
6
6
 
7
7
  use serde::{Deserialize, Serialize};
8
8
  use serde_json::Value;
9
+ use std::sync::atomic::{AtomicBool, Ordering};
9
10
  use std::sync::Mutex;
10
- use tauri::{AppHandle, Emitter, Manager, PhysicalPosition, PhysicalSize, WebviewWindowBuilder};
11
+ use std::time::Duration;
12
+ use tauri::{
13
+ AppHandle, Emitter, Manager, PhysicalPosition, PhysicalSize, WebviewWindow,
14
+ WebviewWindowBuilder,
15
+ };
11
16
 
12
17
  use crate::dlog;
13
18
  use crate::util::{
@@ -54,6 +59,75 @@ fn notification_rect(app: &AppHandle) -> (u32, u32, i32, i32) {
54
59
  (w, h, x, top.max(0))
55
60
  }
56
61
 
62
+ static MEETING_NOTIF_HOVER_TRACKING: AtomicBool = AtomicBool::new(false);
63
+
64
+ /// True when the global cursor sits inside the notification window's frame.
65
+ /// Mirrors `cursor_inside_pill_frame` in `recording_indicator.rs`: cursor and
66
+ /// frame both come from Tauri (physical px, desktop top-left origin), so the
67
+ /// test is a plain point-in-rect with no AppKit hop.
68
+ fn cursor_inside_notification_frame(window: &WebviewWindow) -> bool {
69
+ let (Ok(c), Ok(p), Ok(s)) = (
70
+ window.cursor_position(),
71
+ window.outer_position(),
72
+ window.outer_size(),
73
+ ) else {
74
+ return false;
75
+ };
76
+ c.x >= p.x as f64
77
+ && c.x <= (p.x + s.width as i32) as f64
78
+ && c.y >= p.y as f64
79
+ && c.y <= (p.y + s.height as i32) as f64
80
+ }
81
+
82
+ /// Poll the cursor against the notification frame and emit
83
+ /// `meetings:notification-hover` on transitions. The window never becomes key
84
+ /// (`show_without_activation` uses `orderFrontRegardless`, not
85
+ /// `makeKeyAndOrderFront:`), so CSS `:hover`/`onMouseEnter` only fires once
86
+ /// the user's first click makes it key — this poll is the fallback that
87
+ /// reveals the close button on real hover before that click, same pattern as
88
+ /// `start_pill_hover_tracking`. Idempotent — a second call is a no-op while a
89
+ /// loop is already running.
90
+ fn start_meeting_notification_hover_tracking(app: &AppHandle) {
91
+ if MEETING_NOTIF_HOVER_TRACKING.swap(true, Ordering::SeqCst) {
92
+ return;
93
+ }
94
+ let app = app.clone();
95
+ tauri::async_runtime::spawn(async move {
96
+ let mut prev = false;
97
+ while MEETING_NOTIF_HOVER_TRACKING.load(Ordering::Relaxed) {
98
+ let Some(win) = app.get_webview_window(MEETING_NOTIFICATION_LABEL) else {
99
+ break;
100
+ };
101
+ // The window is reused across notifications (hidden/shown from
102
+ // the frontend, never destroyed), so this loop runs for the rest
103
+ // of the app session. Skip the cursor/frame queries entirely
104
+ // while hidden — no notification is on screen to hover — and
105
+ // back off to a slower idle tick until it's shown again.
106
+ if !win.is_visible().unwrap_or(false) {
107
+ if prev {
108
+ prev = false;
109
+ let _ = win.emit(
110
+ "meetings:notification-hover",
111
+ serde_json::json!({ "hovered": false }),
112
+ );
113
+ }
114
+ tokio::time::sleep(Duration::from_millis(250)).await;
115
+ continue;
116
+ }
117
+ let inside = cursor_inside_notification_frame(&win);
118
+ if inside != prev {
119
+ prev = inside;
120
+ let _ = win.emit(
121
+ "meetings:notification-hover",
122
+ serde_json::json!({ "hovered": inside }),
123
+ );
124
+ }
125
+ tokio::time::sleep(Duration::from_millis(80)).await;
126
+ }
127
+ MEETING_NOTIF_HOVER_TRACKING.store(false, Ordering::SeqCst);
128
+ });
129
+ }
130
+
57
131
  pub fn show_meeting_notification_window(app: &AppHandle) -> Result<(), String> {
58
132
  let (w, h, x, y) = notification_rect(app);
59
133
  if let Some(existing) = app.get_webview_window(MEETING_NOTIFICATION_LABEL) {
@@ -61,6 +135,7 @@ pub fn show_meeting_notification_window(app: &AppHandle) -> Result<(), String> {
61
135
  let _ = existing.set_position(PhysicalPosition::new(x, y));
62
136
  configure_overlay_behavior(&existing);
63
137
  show_without_activation(&existing);
138
+ start_meeting_notification_hover_tracking(&app);
64
139
  return Ok(());
65
140
  }
66
141
 
@@ -97,6 +172,7 @@ pub fn show_meeting_notification_window(app: &AppHandle) -> Result<(), String> {
97
172
  // own recording chrome is still excluded elsewhere so it won't leak.)
98
173
  configure_overlay_behavior(&win);
99
174
  show_without_activation(&win);
175
+ start_meeting_notification_hover_tracking(&app);
100
176
  Ok(())
101
177
  }
102
178