@agent-native/core 0.98.17 → 0.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +15 -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/cli/connect.ts +50 -24
  139. package/corpus/core/src/cli/mcp-config-writers.ts +10 -0
  140. package/corpus/core/src/cli/mcp.ts +5 -5
  141. package/corpus/core/src/cli/skills-content/assets-skill.ts +1 -1
  142. package/corpus/core/src/cli/skills-content/design-exploration-skill.ts +1 -1
  143. package/corpus/core/src/cli/skills-content/help.ts +1 -1
  144. package/corpus/core/src/cli/skills-content/plan-setup-auth.ts +1 -1
  145. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +1 -1
  146. package/corpus/core/src/cli/skills-content/visual-recap-skill.ts +2 -2
  147. package/corpus/core/src/cli/skills.ts +23 -12
  148. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +5 -0
  149. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +17 -0
  150. package/corpus/core/src/embedding/agent.ts +8 -6
  151. package/corpus/core/src/localization/default-messages.ts +7 -0
  152. package/corpus/core/src/mcp/ask-app-inline-tasks.ts +125 -0
  153. package/corpus/core/src/mcp/build-server.ts +65 -3
  154. package/corpus/core/src/mcp/builtin-tools.ts +186 -22
  155. package/corpus/core/src/mcp/connect-route.ts +17 -14
  156. package/corpus/core/src/mcp/oauth-route.ts +38 -13
  157. package/corpus/core/src/mcp/route-paths.ts +34 -0
  158. package/corpus/core/src/mcp/server.ts +21 -10
  159. package/corpus/core/src/mcp/stdio.ts +34 -16
  160. package/corpus/core/src/mcp/workspace-resolve.ts +2 -1
  161. package/corpus/core/src/mcp-client/manager.ts +5 -3
  162. package/corpus/core/src/mcp-client/remote-store.ts +10 -10
  163. package/corpus/core/src/server/agent-chat-plugin.ts +42 -9
  164. package/corpus/core/src/server/auth.ts +22 -6
  165. package/corpus/core/src/server/core-routes-plugin.ts +30 -24
  166. package/corpus/core/src/server/csrf.ts +17 -0
  167. package/corpus/core/src/server/framework-request-handler.ts +8 -2
  168. package/corpus/core/src/server/google-oauth.ts +6 -0
  169. package/corpus/core/src/server/http-response-telemetry.ts +6 -1
  170. package/corpus/core/src/server/recap-image-route.ts +3 -3
  171. package/corpus/core/src/server/security-headers.ts +7 -1
  172. package/corpus/core/src/server/ssr-handler.ts +2 -0
  173. package/corpus/core/src/shared/cache-control.ts +6 -4
  174. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  175. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  176. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  177. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  178. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  179. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +10 -0
  180. package/corpus/templates/analytics/app/global.css +63 -4
  181. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +8 -5
  182. package/corpus/templates/analytics/changelog/2026-07-13-daily-dashboard-emails-recover-more-reliably-from-serverless.md +6 -0
  183. package/corpus/templates/analytics/changelog/2026-07-13-session-replays-keep-a-visible-mac-style-cursor-over-the-vis.md +6 -0
  184. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -2
  185. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +57 -1
  186. package/corpus/templates/analytics/server/lib/dashboard-report.ts +266 -28
  187. package/corpus/templates/analytics/server/routes/[...page].get.ts +0 -2
  188. package/corpus/templates/assets/.agents/skills/security/SKILL.md +10 -0
  189. package/corpus/templates/assets/agent-native.app-skill.json +1 -1
  190. package/corpus/templates/brain/.agents/skills/security/SKILL.md +10 -0
  191. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +10 -0
  192. package/corpus/templates/calendar/AGENTS.md +2 -1
  193. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -19
  194. package/corpus/templates/calendar/app/lib/attendee-local-time.ts +14 -5
  195. package/corpus/templates/calendar/changelog/2026-07-13-your-local-time-now-follows-your-browser-timezone-and-event-.md +6 -0
  196. package/corpus/templates/chat/.agents/skills/security/SKILL.md +10 -0
  197. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +7 -2
  198. package/corpus/templates/clips/.agents/skills/security/SKILL.md +10 -0
  199. package/corpus/templates/clips/AGENTS.md +7 -0
  200. package/corpus/templates/clips/actions/list-meetings.ts +19 -4
  201. package/corpus/templates/clips/actions/start-meeting-recording.ts +7 -1
  202. package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +75 -78
  203. package/corpus/templates/clips/app/components/recorder/confetti-canvas.tsx +18 -1
  204. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +6 -12
  205. package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +19 -2
  206. package/corpus/templates/clips/app/lib/camera-composite.ts +70 -10
  207. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -1
  208. package/corpus/templates/clips/app/routes/record.tsx +5 -25
  209. package/corpus/templates/clips/changelog/2026-07-13-clips-desktop-now-requires-macos-13-for-native-capture.md +6 -0
  210. package/corpus/templates/clips/changelog/2026-07-13-clips-hide-solo-meeting-reminders.md +6 -0
  211. package/corpus/templates/clips/changelog/2026-07-13-clips-now-removes-duplicate-mic-and-system-transcript-turns-.md +6 -0
  212. package/corpus/templates/clips/changelog/2026-07-13-desktop-recordings-run-cooler-and-quieter-live-transcription.md +6 -0
  213. package/corpus/templates/clips/changelog/2026-07-13-meeting-recordings-now-stop-after-a-calendar-meeting-ends-an.md +6 -0
  214. package/corpus/templates/clips/changelog/2026-07-13-meeting-transcripts-now-use-a-clean-agent-chat-style-reading.md +6 -0
  215. package/corpus/templates/clips/changelog/2026-07-13-screen-recordings-use-less-processing-power-during-longer-ca.md +6 -0
  216. package/corpus/templates/clips/chrome-extension/src/background.ts +5 -3
  217. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +17 -14
  218. package/corpus/templates/clips/chrome-extension/src/overlay.ts +8 -2
  219. package/corpus/templates/clips/desktop/README.md +3 -0
  220. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -0
  221. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -2
  222. package/corpus/templates/clips/desktop/src/lib/silence-events.ts +1 -0
  223. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +5 -0
  224. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +134 -5
  225. package/corpus/templates/clips/desktop/src/lib/upload-video-stream.ts +28 -0
  226. package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +10 -3
  227. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +42 -9
  228. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +10 -2
  229. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +6 -1
  230. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +77 -1
  231. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +104 -25
  232. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +4 -0
  233. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +287 -32
  234. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
  235. package/corpus/templates/clips/server/lib/calendar-event-classification.ts +28 -0
  236. package/corpus/templates/clips/server/routes/[...page].get.ts +1 -59
  237. package/corpus/templates/clips/shared/recording-capture.ts +37 -0
  238. package/corpus/templates/content/.agents/skills/security/SKILL.md +10 -0
  239. package/corpus/templates/content/agent-native.app-skill.json +1 -1
  240. package/corpus/templates/content/server/routes/[...page].get.ts +1 -15
  241. package/corpus/templates/design/.agents/skills/security/SKILL.md +10 -0
  242. package/corpus/templates/design/actions/connect-assets-mcp.ts +1 -1
  243. package/corpus/templates/design/agent-native.app-skill.json +1 -1
  244. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +88 -12
  245. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1 -0
  246. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4 -1
  247. package/corpus/templates/design/changelog/2026-07-13-adding-shapes-preserves-canvas-background.md +6 -0
  248. package/corpus/templates/design/changelog/2026-07-13-clicking-quickly-between-overlapping-elements-no-longer-bounc.md +6 -0
  249. package/corpus/templates/design/server/plugins/assets-mcp.ts +1 -1
  250. package/corpus/templates/design/server/routes/[...page].get.ts +0 -2
  251. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +10 -0
  252. package/corpus/templates/forms/.agents/skills/security/SKILL.md +10 -0
  253. package/corpus/templates/macros/.agents/skills/security/SKILL.md +10 -0
  254. package/corpus/templates/mail/.agents/skills/security/SKILL.md +10 -0
  255. package/corpus/templates/plan/.agents/skills/security/SKILL.md +10 -0
  256. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +1 -1
  257. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +2 -2
  258. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  259. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +6 -1
  260. package/corpus/templates/plan/app/pages/PlansPage.tsx +15 -6
  261. package/corpus/templates/plan/changelog/2026-07-13-fixed-local-plan-previews-continuously-flickering-while-revi.md +6 -0
  262. package/corpus/templates/plan/server/routes/[...page].get.ts +0 -2
  263. package/corpus/templates/slides/.agents/skills/security/SKILL.md +10 -0
  264. package/dist/a2a/client.d.ts +2 -0
  265. package/dist/a2a/client.d.ts.map +1 -1
  266. package/dist/a2a/client.js +2 -0
  267. package/dist/a2a/client.js.map +1 -1
  268. package/dist/a2a/handlers.d.ts.map +1 -1
  269. package/dist/a2a/handlers.js +84 -7
  270. package/dist/a2a/handlers.js.map +1 -1
  271. package/dist/cli/connect.d.ts +2 -2
  272. package/dist/cli/connect.d.ts.map +1 -1
  273. package/dist/cli/connect.js +45 -23
  274. package/dist/cli/connect.js.map +1 -1
  275. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  276. package/dist/cli/mcp-config-writers.js +7 -0
  277. package/dist/cli/mcp-config-writers.js.map +1 -1
  278. package/dist/cli/mcp.js +5 -3
  279. package/dist/cli/mcp.js.map +1 -1
  280. package/dist/cli/skills-content/assets-skill.d.ts +1 -1
  281. package/dist/cli/skills-content/assets-skill.d.ts.map +1 -1
  282. package/dist/cli/skills-content/assets-skill.js +1 -1
  283. package/dist/cli/skills-content/assets-skill.js.map +1 -1
  284. package/dist/cli/skills-content/design-exploration-skill.d.ts +1 -1
  285. package/dist/cli/skills-content/design-exploration-skill.d.ts.map +1 -1
  286. package/dist/cli/skills-content/design-exploration-skill.js +1 -1
  287. package/dist/cli/skills-content/design-exploration-skill.js.map +1 -1
  288. package/dist/cli/skills-content/help.d.ts +1 -1
  289. package/dist/cli/skills-content/help.d.ts.map +1 -1
  290. package/dist/cli/skills-content/help.js +1 -1
  291. package/dist/cli/skills-content/help.js.map +1 -1
  292. package/dist/cli/skills-content/plan-setup-auth.d.ts +1 -1
  293. package/dist/cli/skills-content/plan-setup-auth.d.ts.map +1 -1
  294. package/dist/cli/skills-content/plan-setup-auth.js +1 -1
  295. package/dist/cli/skills-content/plan-setup-auth.js.map +1 -1
  296. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  297. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  298. package/dist/cli/skills-content/visual-plan-skill.js +1 -1
  299. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  300. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  301. package/dist/cli/skills-content/visual-recap-skill.d.ts.map +1 -1
  302. package/dist/cli/skills-content/visual-recap-skill.js +2 -2
  303. package/dist/cli/skills-content/visual-recap-skill.js.map +1 -1
  304. package/dist/cli/skills.d.ts.map +1 -1
  305. package/dist/cli/skills.js +16 -12
  306. package/dist/cli/skills.js.map +1 -1
  307. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  308. package/dist/client/resources/McpIntegrationDialog.js +1 -1
  309. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  310. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  311. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  312. package/dist/client/resources/mcp-integration-catalog.js +14 -0
  313. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  314. package/dist/collab/routes.d.ts +2 -2
  315. package/dist/collab/struct-routes.d.ts +1 -1
  316. package/dist/embedding/agent.d.ts.map +1 -1
  317. package/dist/embedding/agent.js +6 -7
  318. package/dist/embedding/agent.js.map +1 -1
  319. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  320. package/dist/localization/default-messages.d.ts +5 -0
  321. package/dist/localization/default-messages.d.ts.map +1 -1
  322. package/dist/localization/default-messages.js +5 -0
  323. package/dist/localization/default-messages.js.map +1 -1
  324. package/dist/mcp/ask-app-inline-tasks.d.ts +47 -0
  325. package/dist/mcp/ask-app-inline-tasks.d.ts.map +1 -0
  326. package/dist/mcp/ask-app-inline-tasks.js +87 -0
  327. package/dist/mcp/ask-app-inline-tasks.js.map +1 -0
  328. package/dist/mcp/build-server.d.ts.map +1 -1
  329. package/dist/mcp/build-server.js +56 -3
  330. package/dist/mcp/build-server.js.map +1 -1
  331. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  332. package/dist/mcp/builtin-tools.js +141 -21
  333. package/dist/mcp/builtin-tools.js.map +1 -1
  334. package/dist/mcp/connect-route.d.ts +12 -10
  335. package/dist/mcp/connect-route.d.ts.map +1 -1
  336. package/dist/mcp/connect-route.js +17 -14
  337. package/dist/mcp/connect-route.js.map +1 -1
  338. package/dist/mcp/oauth-route.d.ts +1 -1
  339. package/dist/mcp/oauth-route.d.ts.map +1 -1
  340. package/dist/mcp/oauth-route.js +30 -13
  341. package/dist/mcp/oauth-route.js.map +1 -1
  342. package/dist/mcp/route-paths.d.ts +13 -0
  343. package/dist/mcp/route-paths.d.ts.map +1 -0
  344. package/dist/mcp/route-paths.js +27 -0
  345. package/dist/mcp/route-paths.js.map +1 -0
  346. package/dist/mcp/server.d.ts +2 -1
  347. package/dist/mcp/server.d.ts.map +1 -1
  348. package/dist/mcp/server.js +14 -6
  349. package/dist/mcp/server.js.map +1 -1
  350. package/dist/mcp/stdio.d.ts +7 -6
  351. package/dist/mcp/stdio.d.ts.map +1 -1
  352. package/dist/mcp/stdio.js +27 -15
  353. package/dist/mcp/stdio.js.map +1 -1
  354. package/dist/mcp/workspace-resolve.d.ts +2 -1
  355. package/dist/mcp/workspace-resolve.d.ts.map +1 -1
  356. package/dist/mcp/workspace-resolve.js +2 -1
  357. package/dist/mcp/workspace-resolve.js.map +1 -1
  358. package/dist/mcp-client/manager.js +6 -3
  359. package/dist/mcp-client/manager.js.map +1 -1
  360. package/dist/mcp-client/remote-store.js +5 -7
  361. package/dist/mcp-client/remote-store.js.map +1 -1
  362. package/dist/notifications/routes.d.ts +3 -3
  363. package/dist/observability/routes.d.ts +5 -5
  364. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  365. package/dist/resources/handlers.d.ts +2 -2
  366. package/dist/secrets/routes.d.ts +9 -9
  367. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  368. package/dist/server/agent-chat-plugin.js +43 -11
  369. package/dist/server/agent-chat-plugin.js.map +1 -1
  370. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  371. package/dist/server/auth.d.ts.map +1 -1
  372. package/dist/server/auth.js +16 -6
  373. package/dist/server/auth.js.map +1 -1
  374. package/dist/server/core-routes-plugin.d.ts +4 -3
  375. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  376. package/dist/server/core-routes-plugin.js +20 -15
  377. package/dist/server/core-routes-plugin.js.map +1 -1
  378. package/dist/server/csrf.d.ts.map +1 -1
  379. package/dist/server/csrf.js +11 -0
  380. package/dist/server/csrf.js.map +1 -1
  381. package/dist/server/framework-request-handler.d.ts.map +1 -1
  382. package/dist/server/framework-request-handler.js +8 -2
  383. package/dist/server/framework-request-handler.js.map +1 -1
  384. package/dist/server/google-oauth.d.ts +2 -0
  385. package/dist/server/google-oauth.d.ts.map +1 -1
  386. package/dist/server/google-oauth.js +5 -0
  387. package/dist/server/google-oauth.js.map +1 -1
  388. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  389. package/dist/server/http-response-telemetry.js +4 -1
  390. package/dist/server/http-response-telemetry.js.map +1 -1
  391. package/dist/server/recap-image-route.js +3 -3
  392. package/dist/server/recap-image-route.js.map +1 -1
  393. package/dist/server/security-headers.d.ts.map +1 -1
  394. package/dist/server/security-headers.js +4 -1
  395. package/dist/server/security-headers.js.map +1 -1
  396. package/dist/server/ssr-handler.d.ts.map +1 -1
  397. package/dist/server/ssr-handler.js +3 -1
  398. package/dist/server/ssr-handler.js.map +1 -1
  399. package/dist/shared/cache-control.d.ts +7 -6
  400. package/dist/shared/cache-control.d.ts.map +1 -1
  401. package/dist/shared/cache-control.js +4 -3
  402. package/dist/shared/cache-control.js.map +1 -1
  403. package/dist/templates/default/.agents/skills/security/SKILL.md +10 -0
  404. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  405. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  406. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  407. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
  408. package/docs/content/actions.mdx +1 -1
  409. package/docs/content/authentication.mdx +1 -1
  410. package/docs/content/dispatch.mdx +3 -3
  411. package/docs/content/external-agents.mdx +30 -19
  412. package/docs/content/locales/ar-SA/actions.mdx +1 -1
  413. package/docs/content/locales/ar-SA/authentication.mdx +1 -1
  414. package/docs/content/locales/ar-SA/dispatch.mdx +3 -3
  415. package/docs/content/locales/ar-SA/external-agents.mdx +23 -19
  416. package/docs/content/locales/ar-SA/mcp-clients.mdx +31 -3
  417. package/docs/content/locales/ar-SA/mcp-protocol.mdx +29 -15
  418. package/docs/content/locales/ar-SA/plan-plugin.mdx +3 -3
  419. package/docs/content/locales/ar-SA/server.mdx +2 -2
  420. package/docs/content/locales/ar-SA/skills-guide.mdx +1 -1
  421. package/docs/content/locales/ar-SA/template-assets.mdx +1 -1
  422. package/docs/content/locales/ar-SA/template-dispatch.mdx +2 -2
  423. package/docs/content/locales/ar-SA/template-plan.mdx +3 -3
  424. package/docs/content/locales/de-DE/actions.mdx +1 -1
  425. package/docs/content/locales/de-DE/authentication.mdx +1 -1
  426. package/docs/content/locales/de-DE/dispatch.mdx +3 -3
  427. package/docs/content/locales/de-DE/external-agents.mdx +23 -19
  428. package/docs/content/locales/de-DE/mcp-clients.mdx +37 -3
  429. package/docs/content/locales/de-DE/mcp-protocol.mdx +29 -15
  430. package/docs/content/locales/de-DE/plan-plugin.mdx +3 -3
  431. package/docs/content/locales/de-DE/server.mdx +2 -2
  432. package/docs/content/locales/de-DE/skills-guide.mdx +1 -1
  433. package/docs/content/locales/de-DE/template-assets.mdx +1 -1
  434. package/docs/content/locales/de-DE/template-dispatch.mdx +2 -2
  435. package/docs/content/locales/de-DE/template-plan.mdx +3 -3
  436. package/docs/content/locales/es-ES/actions.mdx +1 -1
  437. package/docs/content/locales/es-ES/authentication.mdx +1 -1
  438. package/docs/content/locales/es-ES/dispatch.mdx +3 -3
  439. package/docs/content/locales/es-ES/external-agents.mdx +32 -19
  440. package/docs/content/locales/es-ES/mcp-clients.mdx +17 -3
  441. package/docs/content/locales/es-ES/mcp-protocol.mdx +38 -15
  442. package/docs/content/locales/es-ES/plan-plugin.mdx +3 -3
  443. package/docs/content/locales/es-ES/server.mdx +2 -2
  444. package/docs/content/locales/es-ES/skills-guide.mdx +1 -1
  445. package/docs/content/locales/es-ES/template-assets.mdx +1 -1
  446. package/docs/content/locales/es-ES/template-dispatch.mdx +2 -2
  447. package/docs/content/locales/es-ES/template-plan.mdx +3 -3
  448. package/docs/content/locales/fr-FR/actions.mdx +1 -1
  449. package/docs/content/locales/fr-FR/authentication.mdx +1 -1
  450. package/docs/content/locales/fr-FR/dispatch.mdx +3 -3
  451. package/docs/content/locales/fr-FR/external-agents.mdx +23 -19
  452. package/docs/content/locales/fr-FR/mcp-clients.mdx +17 -3
  453. package/docs/content/locales/fr-FR/mcp-protocol.mdx +29 -15
  454. package/docs/content/locales/fr-FR/plan-plugin.mdx +3 -3
  455. package/docs/content/locales/fr-FR/server.mdx +2 -2
  456. package/docs/content/locales/fr-FR/skills-guide.mdx +1 -1
  457. package/docs/content/locales/fr-FR/template-assets.mdx +1 -1
  458. package/docs/content/locales/fr-FR/template-dispatch.mdx +2 -2
  459. package/docs/content/locales/fr-FR/template-plan.mdx +3 -3
  460. package/docs/content/locales/hi-IN/actions.mdx +1 -1
  461. package/docs/content/locales/hi-IN/authentication.mdx +1 -1
  462. package/docs/content/locales/hi-IN/dispatch.mdx +3 -3
  463. package/docs/content/locales/hi-IN/external-agents.mdx +31 -19
  464. package/docs/content/locales/hi-IN/mcp-clients.mdx +17 -3
  465. package/docs/content/locales/hi-IN/mcp-protocol.mdx +36 -15
  466. package/docs/content/locales/hi-IN/plan-plugin.mdx +3 -3
  467. package/docs/content/locales/hi-IN/server.mdx +2 -2
  468. package/docs/content/locales/hi-IN/skills-guide.mdx +1 -1
  469. package/docs/content/locales/hi-IN/template-assets.mdx +1 -1
  470. package/docs/content/locales/hi-IN/template-dispatch.mdx +2 -2
  471. package/docs/content/locales/hi-IN/template-plan.mdx +3 -3
  472. package/docs/content/locales/ja-JP/actions.mdx +1 -1
  473. package/docs/content/locales/ja-JP/authentication.mdx +1 -1
  474. package/docs/content/locales/ja-JP/dispatch.mdx +3 -3
  475. package/docs/content/locales/ja-JP/external-agents.mdx +23 -19
  476. package/docs/content/locales/ja-JP/mcp-clients.mdx +34 -3
  477. package/docs/content/locales/ja-JP/mcp-protocol.mdx +29 -15
  478. package/docs/content/locales/ja-JP/plan-plugin.mdx +3 -3
  479. package/docs/content/locales/ja-JP/server.mdx +2 -2
  480. package/docs/content/locales/ja-JP/skills-guide.mdx +1 -1
  481. package/docs/content/locales/ja-JP/template-assets.mdx +1 -1
  482. package/docs/content/locales/ja-JP/template-dispatch.mdx +2 -2
  483. package/docs/content/locales/ja-JP/template-plan.mdx +3 -3
  484. package/docs/content/locales/ko-KR/actions.mdx +1 -1
  485. package/docs/content/locales/ko-KR/authentication.mdx +1 -1
  486. package/docs/content/locales/ko-KR/dispatch.mdx +3 -3
  487. package/docs/content/locales/ko-KR/external-agents.mdx +30 -19
  488. package/docs/content/locales/ko-KR/mcp-clients.mdx +33 -3
  489. package/docs/content/locales/ko-KR/mcp-protocol.mdx +36 -15
  490. package/docs/content/locales/ko-KR/plan-plugin.mdx +3 -3
  491. package/docs/content/locales/ko-KR/server.mdx +2 -2
  492. package/docs/content/locales/ko-KR/skills-guide.mdx +1 -1
  493. package/docs/content/locales/ko-KR/template-assets.mdx +1 -1
  494. package/docs/content/locales/ko-KR/template-dispatch.mdx +2 -2
  495. package/docs/content/locales/ko-KR/template-plan.mdx +3 -3
  496. package/docs/content/locales/pt-BR/actions.mdx +1 -1
  497. package/docs/content/locales/pt-BR/authentication.mdx +1 -1
  498. package/docs/content/locales/pt-BR/dispatch.mdx +3 -3
  499. package/docs/content/locales/pt-BR/external-agents.mdx +32 -19
  500. package/docs/content/locales/pt-BR/mcp-clients.mdx +34 -3
  501. package/docs/content/locales/pt-BR/mcp-protocol.mdx +32 -15
  502. package/docs/content/locales/pt-BR/plan-plugin.mdx +3 -3
  503. package/docs/content/locales/pt-BR/server.mdx +2 -2
  504. package/docs/content/locales/pt-BR/skills-guide.mdx +1 -1
  505. package/docs/content/locales/pt-BR/template-assets.mdx +1 -1
  506. package/docs/content/locales/pt-BR/template-dispatch.mdx +2 -2
  507. package/docs/content/locales/pt-BR/template-plan.mdx +3 -3
  508. package/docs/content/locales/zh-CN/actions.mdx +1 -1
  509. package/docs/content/locales/zh-CN/authentication.mdx +1 -1
  510. package/docs/content/locales/zh-CN/dispatch.mdx +3 -3
  511. package/docs/content/locales/zh-CN/external-agents.mdx +23 -19
  512. package/docs/content/locales/zh-CN/mcp-clients.mdx +28 -3
  513. package/docs/content/locales/zh-CN/mcp-protocol.mdx +29 -15
  514. package/docs/content/locales/zh-CN/plan-plugin.mdx +3 -3
  515. package/docs/content/locales/zh-CN/server.mdx +2 -2
  516. package/docs/content/locales/zh-CN/skills-guide.mdx +1 -1
  517. package/docs/content/locales/zh-CN/template-assets.mdx +1 -1
  518. package/docs/content/locales/zh-CN/template-dispatch.mdx +2 -2
  519. package/docs/content/locales/zh-CN/template-plan.mdx +3 -3
  520. package/docs/content/locales/zh-TW/actions.mdx +1 -1
  521. package/docs/content/locales/zh-TW/authentication.mdx +1 -1
  522. package/docs/content/locales/zh-TW/dispatch.mdx +3 -3
  523. package/docs/content/locales/zh-TW/external-agents.mdx +23 -19
  524. package/docs/content/locales/zh-TW/mcp-clients.mdx +28 -3
  525. package/docs/content/locales/zh-TW/mcp-protocol.mdx +30 -15
  526. package/docs/content/locales/zh-TW/plan-plugin.mdx +3 -3
  527. package/docs/content/locales/zh-TW/server.mdx +2 -2
  528. package/docs/content/locales/zh-TW/skills-guide.mdx +1 -1
  529. package/docs/content/locales/zh-TW/template-assets.mdx +1 -1
  530. package/docs/content/locales/zh-TW/template-dispatch.mdx +2 -2
  531. package/docs/content/locales/zh-TW/template-plan.mdx +3 -3
  532. package/docs/content/mcp-clients.mdx +31 -4
  533. package/docs/content/mcp-protocol.mdx +35 -15
  534. package/docs/content/plan-plugin.mdx +3 -3
  535. package/docs/content/server.mdx +2 -2
  536. package/docs/content/skills-guide.mdx +1 -1
  537. package/docs/content/template-assets.mdx +1 -1
  538. package/docs/content/template-dispatch.mdx +2 -2
  539. package/docs/content/template-plan.mdx +3 -3
  540. package/package.json +1 -1
  541. package/src/templates/default/.agents/skills/security/SKILL.md +10 -0
  542. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +15 -6
  543. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -10
  544. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +20 -1
  545. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +10 -0
@@ -843,7 +843,6 @@ export default function RecordRoute() {
843
843
  const [error, setError] = useState<string | null>(null);
844
844
  const [isPaused, setIsPaused] = useState(false);
845
845
  const visibilityAutoPausedRef = useRef(false);
846
- const [elapsedMs, setElapsedMs] = useState(0);
847
846
  const [cameraStream, setCameraStream] = useState<MediaStream | null>(null);
848
847
  const [cameraSize, setCameraSize] = useState<CameraBubbleSize>(
849
848
  () => loadRecorderPreferences().cameraSize ?? "md",
@@ -985,35 +984,15 @@ export default function RecordRoute() {
985
984
  micDeviceLabel?: string | null;
986
985
  cameraDeviceId: string | null;
987
986
  } | null>(null);
988
- const tickRef = useRef<number | null>(null);
989
987
  const previewVideoRef = useRef<HTMLVideoElement>(null);
990
988
  const fileUploadAbortRef = useRef<AbortController | null>(null);
991
989
  const browserDiagnosticsRef = useRef<BrowserDiagnosticsCapture | null>(null);
992
990
  // Bumped by doCancel() to invalidate any in-flight startFlow().
993
991
  const startSessionRef = useRef(0);
994
992
 
995
- // -------------------------------------------------------------------------
996
- // Timer
997
- // -------------------------------------------------------------------------
998
- useEffect(() => {
999
- if (uiState !== "recording") {
1000
- if (tickRef.current !== null) {
1001
- window.clearInterval(tickRef.current);
1002
- tickRef.current = null;
1003
- }
1004
- return;
1005
- }
1006
- tickRef.current = window.setInterval(() => {
1007
- const e = engineRef.current?.getElapsedMs() ?? 0;
1008
- setElapsedMs(e);
1009
- }, 250);
1010
- return () => {
1011
- if (tickRef.current !== null) {
1012
- window.clearInterval(tickRef.current);
1013
- tickRef.current = null;
1014
- }
1015
- };
1016
- }, [uiState]);
993
+ // Elapsed-time display now ticks inside RecordingToolbar itself (via
994
+ // `active` + `getElapsedMs`) so the ~4x/sec poll doesn't re-render this
995
+ // whole route — see the `active`/`getElapsedMs` props passed below.
1017
996
 
1018
997
  // -------------------------------------------------------------------------
1019
998
  // Wire preview stream into its video element.
@@ -2671,7 +2650,8 @@ export default function RecordRoute() {
2671
2650
  {/* Floating toolbar */}
2672
2651
  {showRecordingUi && (
2673
2652
  <RecordingToolbar
2674
- elapsedMs={elapsedMs}
2653
+ active={uiState === "recording"}
2654
+ getElapsedMs={() => engineRef.current?.getElapsedMs() ?? 0}
2675
2655
  isPaused={isPaused}
2676
2656
  onTogglePause={togglePause}
2677
2657
  onStop={() => void doStop()}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Clips Desktop now declares its macOS 13 minimum consistently with the native ScreenCaptureKit and Metal capture stack.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Clips no longer shows meeting-notes reminders for calendar events attended only by you.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Clips now removes duplicate mic and system transcript turns and filters more silent-audio hallucinations.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Desktop recordings run cooler and quieter: live transcription now uses the GPU on Apple Silicon
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Meeting recordings now stop after a calendar meeting ends and goes quiet
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Meeting transcripts now use a clean, agent-chat-style reading layout instead of chat bubbles.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Screen recordings use less processing power during longer captures
@@ -258,9 +258,11 @@ type OverlayPart = "bubble" | "countdown" | "toolbar" | "saving";
258
258
  let overlayPhase: OverlayPhase = "idle";
259
259
  let overlayBaseElapsedMs = 0;
260
260
  let overlayBaseEpochMs = 0;
261
- // Bubble during the countdown preview (any camera). During recording, the face
262
- // is composited into the video by the offscreen for screen+camera, so we only
263
- // show the on-page bubble for camera-only mode (recordingShowsBubble).
261
+ // Bubble during the countdown preview (any camera). The offscreen document does
262
+ // NOT composite the camera into screen recordings that compositor code path is
263
+ // unreachable because screen mode never acquires a camera stream (see
264
+ // offscreen.ts acquire()). So the on-page bubble is the only place the face shows
265
+ // up, for both camera-only AND screen+camera recording (recordingShowsBubble).
264
266
  let overlayShowsBubble = false;
265
267
  let recordingShowsBubble = false;
266
268
  // Cross-tab follow: when true, the overlay is pushed to whatever tab the user
@@ -23,6 +23,11 @@ import {
23
23
  type AudioInputFallback,
24
24
  } from "@shared/media-device-selection";
25
25
  import { scheduleReadyChime } from "@shared/recording-audio";
26
+ import {
27
+ SCREEN_CAPTURE_FRAME_RATE,
28
+ screenCaptureVideoConstraints,
29
+ type ScreenCaptureSurface,
30
+ } from "@shared/recording-capture";
26
31
  import {
27
32
  chunkUploadUrl,
28
33
  pickMimeType,
@@ -300,19 +305,10 @@ async function streamDimensions(
300
305
  }
301
306
 
302
307
  function displayConstraints(
303
- surface: "browser" | "window" | "monitor",
308
+ surface: ScreenCaptureSurface,
304
309
  ): MediaStreamConstraints {
305
- const displaySurface =
306
- surface === "browser"
307
- ? "browser"
308
- : surface === "window"
309
- ? "window"
310
- : "monitor";
311
310
  return {
312
- video: {
313
- frameRate: { ideal: 30, max: 30 },
314
- ...({ displaySurface } as object),
315
- },
311
+ video: screenCaptureVideoConstraints(surface),
316
312
  audio: {
317
313
  echoCancellation: false,
318
314
  noiseSuppression: false,
@@ -373,6 +369,10 @@ function cameraConstraints(deviceId: string): MediaTrackConstraints {
373
369
  const base: MediaTrackConstraints = {
374
370
  width: { ideal: 1280 },
375
371
  height: { ideal: 720 },
372
+ frameRate: {
373
+ ideal: SCREEN_CAPTURE_FRAME_RATE,
374
+ max: SCREEN_CAPTURE_FRAME_RATE,
375
+ },
376
376
  };
377
377
  if (deviceId) base.deviceId = { exact: deviceId };
378
378
  else base.facingMode = "user";
@@ -750,7 +750,7 @@ async function buildCompositor(
750
750
  };
751
751
  raf = requestAnimationFrame(draw);
752
752
 
753
- const canvasStream = canvas.captureStream(30);
753
+ const canvasStream = canvas.captureStream(SCREEN_CAPTURE_FRAME_RATE);
754
754
  return {
755
755
  videoTrack: canvasStream.getVideoTracks()[0],
756
756
  canvasStream,
@@ -1194,8 +1194,11 @@ async function begin(message: BeginMessage): Promise<{
1194
1194
  const mimeType = pickMimeType() || "video/webm";
1195
1195
  const recorder = new MediaRecorder(outputStream, {
1196
1196
  mimeType,
1197
- // Crisp 1080p capture — matches the web/desktop recorders. Files upload
1198
- // directly (no client-side shrink), so we favor sharpness over a budget.
1197
+ // Crisp 1080p capture — matches the web/desktop recorders. displayConstraints()
1198
+ // (see screenCaptureVideoConstraints in @shared/recording-capture) caps retina/5K
1199
+ // surfaces down to 1920x1080 before this point, so the software VP8 encoder is
1200
+ // never fed native-resolution frames. Files upload directly (no client-side
1201
+ // shrink), so within that cap we favor sharpness over a bitrate budget.
1199
1202
  videoBitsPerSecond: 8_000_000,
1200
1203
  audioBitsPerSecond: 128_000,
1201
1204
  });
@@ -1,4 +1,6 @@
1
1
  import "./overlay.css";
2
+ import { SCREEN_CAPTURE_FRAME_RATE } from "@shared/recording-capture";
3
+
2
4
  import { captureExtensionError, initExtensionSentry } from "./sentry";
3
5
 
4
6
  initExtensionSentry("overlay");
@@ -31,8 +33,12 @@ function isDeviceUnavailableError(error: unknown): boolean {
31
33
 
32
34
  function cameraConstraint(deviceId: string): MediaTrackConstraints {
33
35
  const video: MediaTrackConstraints = {
34
- width: { ideal: 640 },
35
- height: { ideal: 640 },
36
+ width: { ideal: 480 },
37
+ height: { ideal: 480 },
38
+ frameRate: {
39
+ ideal: SCREEN_CAPTURE_FRAME_RATE,
40
+ max: SCREEN_CAPTURE_FRAME_RATE,
41
+ },
36
42
  };
37
43
  if (deviceId) video.deviceId = { exact: deviceId };
38
44
  else video.facingMode = "user";
@@ -2,6 +2,9 @@
2
2
 
3
3
  A small Tauri 2.x tray app for macOS, Windows, and Linux. Click the icon — or press the global shortcut `Cmd/Ctrl+Shift+L` — to open a popover with:
4
4
 
5
+ The macOS desktop build requires macOS 13 or newer because its native
6
+ ScreenCaptureKit and Metal transcription dependencies target that SDK.
7
+
5
8
  - **New recording** button (opens `/record` on your configured Clips server)
6
9
  - **Recent** — your three most recent recordings
7
10
  - Quick links to **Open library** and **Settings**
@@ -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"}`}