@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
@@ -310,92 +310,89 @@ export function TranscriptBubbles({
310
310
  )}
311
311
  </div>
312
312
  <div ref={containerRef} className="flex-1 overflow-y-auto p-4">
313
- <div className="space-y-3">
313
+ <div className="mx-auto max-w-3xl space-y-6">
314
314
  {groups.map((group, gi) => {
315
315
  const isMe = group.source === "mic";
316
316
  return (
317
- <div
318
- key={gi}
319
- className={cn(
320
- "flex flex-col gap-1",
321
- isMe ? "items-end" : "items-start",
322
- )}
323
- >
324
- <div
325
- className={cn(
326
- "text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70 px-1",
327
- )}
328
- >
317
+ <section key={gi} className="space-y-1.5">
318
+ <div className="flex items-center gap-2 px-1 text-[11px] font-medium tracking-wide text-muted-foreground">
319
+ <span
320
+ aria-hidden="true"
321
+ className={cn(
322
+ "h-1.5 w-1.5 rounded-full",
323
+ isMe ? "bg-primary" : "bg-muted-foreground/50",
324
+ )}
325
+ />
329
326
  {isMe
330
327
  ? t("transcriptBubbles.me")
331
328
  : t("transcriptBubbles.them")}
332
329
  </div>
333
- {group.segments.map(({ seg, index }) => {
334
- const clickable = !!recordingId;
335
- return (
336
- <Tooltip key={index}>
337
- <TooltipTrigger asChild>
338
- <div
339
- ref={(el) => {
340
- segmentRefs.current[index] = el;
341
- }}
342
- role={clickable ? "button" : undefined}
343
- tabIndex={clickable ? 0 : -1}
344
- onClick={() => clickable && onSeek(seg.startMs)}
345
- onKeyDown={(e) => {
346
- if (
330
+ <div className="space-y-0.5">
331
+ {group.segments.map(({ seg, index }) => {
332
+ const clickable = !!recordingId;
333
+ return (
334
+ <Tooltip key={index}>
335
+ <TooltipTrigger asChild>
336
+ <div
337
+ ref={(el) => {
338
+ segmentRefs.current[index] = el;
339
+ }}
340
+ role={clickable ? "button" : undefined}
341
+ tabIndex={clickable ? 0 : -1}
342
+ onClick={() => clickable && onSeek(seg.startMs)}
343
+ onKeyDown={(e) => {
344
+ if (
345
+ clickable &&
346
+ (e.key === "Enter" || e.key === " ")
347
+ ) {
348
+ e.preventDefault();
349
+ onSeek(seg.startMs);
350
+ }
351
+ }}
352
+ className={cn(
353
+ "group/segment -mx-1 rounded-md px-1 py-1 text-left text-sm leading-relaxed text-foreground transition-colors",
347
354
  clickable &&
348
- (e.key === "Enter" || e.key === " ")
349
- ) {
350
- e.preventDefault();
351
- onSeek(seg.startMs);
352
- }
353
- }}
354
- className={cn(
355
- "max-w-[80%] rounded-2xl px-3.5 py-2 text-sm leading-relaxed transition-shadow",
356
- isMe
357
- ? "bg-primary text-primary-foreground"
358
- : "bg-muted text-foreground",
359
- clickable && "cursor-pointer hover:opacity-90",
360
- )}
361
- >
362
- {seg.speaker && !isMe && (
363
- <div className="text-[10px] font-medium opacity-70 mb-0.5">
364
- {seg.speaker}
365
- </div>
366
- )}
367
- <p className="whitespace-pre-wrap">
368
- {normalizedQuery
369
- ? highlightRuns(seg.text, normalizedQuery).map(
370
- (run, ri) =>
371
- run.match ? (
372
- <mark
373
- key={ri}
374
- className={cn(
375
- "rounded-sm bg-yellow-400/70 text-foreground",
376
- index === activeMatchIndex &&
377
- "bg-yellow-400 ring-1 ring-yellow-600",
378
- )}
379
- >
380
- {run.text}
381
- </mark>
382
- ) : (
383
- <span key={ri}>{run.text}</span>
384
- ),
385
- )
386
- : seg.text}
387
- </p>
388
- </div>
389
- </TooltipTrigger>
390
- <TooltipContent side={isMe ? "left" : "right"}>
391
- <span className="font-mono tabular-nums text-[11px]">
392
- {formatTimestamp(seg.startMs)}
393
- </span>
394
- </TooltipContent>
395
- </Tooltip>
396
- );
397
- })}
398
- </div>
355
+ "cursor-pointer hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
356
+ )}
357
+ >
358
+ {seg.speaker && !isMe && (
359
+ <span className="me-2 text-[11px] font-medium text-muted-foreground">
360
+ {seg.speaker}
361
+ </span>
362
+ )}
363
+ <span className="whitespace-pre-wrap">
364
+ {normalizedQuery
365
+ ? highlightRuns(seg.text, normalizedQuery).map(
366
+ (run, ri) =>
367
+ run.match ? (
368
+ <mark
369
+ key={ri}
370
+ className={cn(
371
+ "rounded-sm bg-yellow-400/70 text-foreground",
372
+ index === activeMatchIndex &&
373
+ "bg-yellow-400 ring-1 ring-yellow-600",
374
+ )}
375
+ >
376
+ {run.text}
377
+ </mark>
378
+ ) : (
379
+ <span key={ri}>{run.text}</span>
380
+ ),
381
+ )
382
+ : seg.text}
383
+ </span>
384
+ </div>
385
+ </TooltipTrigger>
386
+ <TooltipContent side="right">
387
+ <span className="font-mono tabular-nums text-[11px]">
388
+ {formatTimestamp(seg.startMs)}
389
+ </span>
390
+ </TooltipContent>
391
+ </Tooltip>
392
+ );
393
+ })}
394
+ </div>
395
+ </section>
399
396
  );
400
397
  })}
401
398
  <div ref={liveEndRef} />
@@ -34,6 +34,7 @@ export const ConfettiCanvas = forwardRef<ConfettiHandle>(
34
34
  const canvasRef = useRef<HTMLCanvasElement>(null);
35
35
  const particlesRef = useRef<Particle[]>([]);
36
36
  const rafRef = useRef<number | null>(null);
37
+ const startTickRef = useRef<() => void>(() => {});
37
38
 
38
39
  useEffect(() => {
39
40
  const canvas = canvasRef.current;
@@ -93,9 +94,24 @@ export const ConfettiCanvas = forwardRef<ConfettiHandle>(
93
94
  live.push(p);
94
95
  }
95
96
  particlesRef.current = live;
97
+
98
+ // Stop instead of redrawing an empty canvas at full refresh rate for
99
+ // the rest of the page's lifetime — burst() restarts the loop.
100
+ if (live.length === 0) {
101
+ rafRef.current = null;
102
+ return;
103
+ }
96
104
  rafRef.current = window.requestAnimationFrame(tick);
97
105
  }
98
- rafRef.current = window.requestAnimationFrame(tick);
106
+
107
+ startTickRef.current = () => {
108
+ if (rafRef.current !== null) return;
109
+ // Reset the dt baseline so the first frame after a restart doesn't
110
+ // see a huge elapsed gap from the idle period.
111
+ lastTs = performance.now();
112
+ rafRef.current = window.requestAnimationFrame(tick);
113
+ };
114
+
99
115
  return () => {
100
116
  if (rafRef.current !== null)
101
117
  window.cancelAnimationFrame(rafRef.current);
@@ -129,6 +145,7 @@ export const ConfettiCanvas = forwardRef<ConfettiHandle>(
129
145
  life: 1.6 + Math.random() * 0.6,
130
146
  });
131
147
  }
148
+ startTickRef.current();
132
149
  },
133
150
  }));
134
151
 
@@ -18,6 +18,10 @@ import {
18
18
  isLikelyPhoneMicLabel,
19
19
  type AudioInputFallback,
20
20
  } from "@shared/media-device-selection";
21
+ import {
22
+ SCREEN_CAPTURE_FRAME_RATE,
23
+ screenCaptureVideoConstraints,
24
+ } from "@shared/recording-capture";
21
25
  import {
22
26
  chunkUploadUrl,
23
27
  pickMimeType,
@@ -234,9 +238,6 @@ const FINAL_CHUNK_UPLOAD_TIMEOUT_MS = 180_000;
234
238
  const RETRYABLE_CHUNK_UPLOAD_STATUSES = new Set([
235
239
  408, 425, 429, 500, 502, 503, 504,
236
240
  ]);
237
- const SCREEN_CAPTURE_FRAME_RATE = 24;
238
- const SCREEN_CAPTURE_MAX_WIDTH = 1920;
239
- const SCREEN_CAPTURE_MAX_HEIGHT = 1080;
240
241
  // Capture quality for the browser MediaRecorder. We no longer shrink files
241
242
  // client-side (ffmpeg.wasm re-encode is disabled — see COMPRESSION_ENABLED in
242
243
  // `@/lib/compress`) and the upload provider streams large files directly, so we
@@ -907,15 +908,7 @@ export class RecorderEngine {
907
908
  this.opts.displaySurface ?? "window",
908
909
  );
909
910
  const displayOptions: ExtendedDisplayMediaOptions = {
910
- video: {
911
- frameRate: {
912
- ideal: SCREEN_CAPTURE_FRAME_RATE,
913
- max: SCREEN_CAPTURE_FRAME_RATE,
914
- },
915
- width: { ideal: SCREEN_CAPTURE_MAX_WIDTH },
916
- height: { ideal: SCREEN_CAPTURE_MAX_HEIGHT },
917
- displaySurface,
918
- },
911
+ video: screenCaptureVideoConstraints(displaySurface),
919
912
  audio: wantsMic,
920
913
  // Let "Browser tab" open the tab picker. preferCurrentTab turns it
921
914
  // into a current-tab shortcut, which makes choosing another tab harder.
@@ -1834,6 +1827,7 @@ export class RecorderEngine {
1834
1827
  displayStream: this.displayStream!,
1835
1828
  cameraStream: this.cameraStream!,
1836
1829
  bubbleSizeRatio: this.cameraBubbleSizeRatio(),
1830
+ frameRate: SCREEN_CAPTURE_FRAME_RATE,
1837
1831
  });
1838
1832
  const combined = new MediaStream();
1839
1833
  for (const t of this.cameraComposite.stream.getVideoTracks())
@@ -16,7 +16,11 @@ import {
16
16
  import { clampRectToViewport, type BubblePosition } from "./camera-positioner";
17
17
 
18
18
  export interface RecordingToolbarProps {
19
- elapsedMs: number;
19
+ /** Whether the elapsed-time ticker should run — true only while actively
20
+ * recording (not during upload/compress, which freeze the last value). */
21
+ active: boolean;
22
+ /** Reads the current elapsed time from the recorder engine on each tick. */
23
+ getElapsedMs: () => number;
20
24
  isPaused: boolean;
21
25
  onTogglePause: () => void;
22
26
  onStop: () => void;
@@ -38,7 +42,8 @@ function formatElapsed(ms: number): string {
38
42
  }
39
43
 
40
44
  export function RecordingToolbar({
41
- elapsedMs,
45
+ active,
46
+ getElapsedMs,
42
47
  isPaused,
43
48
  onTogglePause,
44
49
  onStop,
@@ -46,6 +51,18 @@ export function RecordingToolbar({
46
51
  }: RecordingToolbarProps) {
47
52
  const t = useT();
48
53
  const rootRef = useRef<HTMLDivElement>(null);
54
+ // Own the elapsed-time poll here instead of in the route component, so the
55
+ // 4x/sec tick only re-renders this toolbar rather than the whole record page.
56
+ const [elapsedMs, setElapsedMs] = useState(0);
57
+ const getElapsedMsRef = useRef(getElapsedMs);
58
+ getElapsedMsRef.current = getElapsedMs;
59
+ useEffect(() => {
60
+ if (!active) return;
61
+ const id = window.setInterval(() => {
62
+ setElapsedMs(getElapsedMsRef.current());
63
+ }, 250);
64
+ return () => window.clearInterval(id);
65
+ }, [active]);
49
66
  const [pos, setPos] = useState<BubblePosition>(() =>
50
67
  typeof window === "undefined"
51
68
  ? { left: 16, top: 16, corner: "tl" }
@@ -128,16 +128,79 @@ function drawCover(
128
128
  ctx.restore();
129
129
  }
130
130
 
131
+ // Hard ceiling on the composite canvas regardless of source resolution — keeps
132
+ // the per-frame drawImage + encode at 1080p-class cost even on a Retina/4K
133
+ // display or if a browser ignores getDisplayMedia's `max` constraint.
134
+ const MAX_CANVAS_DIMENSION_PX = 1920;
135
+
136
+ export function clampToMaxDimension(
137
+ width: number,
138
+ height: number,
139
+ ): { width: number; height: number } {
140
+ const longest = Math.max(width, height);
141
+ if (longest <= MAX_CANVAS_DIMENSION_PX) {
142
+ return { width, height };
143
+ }
144
+ const scale = MAX_CANVAS_DIMENSION_PX / longest;
145
+ // Round to even numbers — odd canvas dimensions can trip up video encoders.
146
+ return {
147
+ width: Math.round((width * scale) / 2) * 2,
148
+ height: Math.round((height * scale) / 2) * 2,
149
+ };
150
+ }
151
+
131
152
  function resizeCanvasToDisplay(
132
153
  canvas: HTMLCanvasElement,
133
154
  displayVideo: HTMLVideoElement,
134
155
  displayStream: MediaStream,
135
156
  ): void {
136
- const { width, height } = videoDimensions(displayVideo, displayStream);
157
+ const source = videoDimensions(displayVideo, displayStream);
158
+ const { width, height } = clampToMaxDimension(source.width, source.height);
137
159
  if (canvas.width !== width) canvas.width = width;
138
160
  if (canvas.height !== height) canvas.height = height;
139
161
  }
140
162
 
163
+ interface BubbleShadowSprite {
164
+ size: number;
165
+ canvas: HTMLCanvasElement;
166
+ pad: number;
167
+ }
168
+
169
+ // The drop shadow is a per-frame gaussian blur, which is expensive to redraw
170
+ // every frame. Cache the rendered shadow in an offscreen sprite keyed by
171
+ // bubble size — margin only shifts where the sprite is later placed, not its
172
+ // bitmap — and only re-render when the size actually changes.
173
+ let bubbleShadowSprite: BubbleShadowSprite | null = null;
174
+
175
+ function getBubbleShadowSprite(size: number): BubbleShadowSprite {
176
+ if (bubbleShadowSprite && bubbleShadowSprite.size === size) {
177
+ return bubbleShadowSprite;
178
+ }
179
+ const blur = Math.max(16, size * 0.12);
180
+ const offsetY = Math.max(8, size * 0.05);
181
+ // Padding wide enough that the blurred, offset shadow never clips at the
182
+ // sprite's edge.
183
+ const pad = Math.ceil(blur * 2 + offsetY);
184
+ const spriteSize = size + pad * 2;
185
+ const sprite = document.createElement("canvas");
186
+ sprite.width = spriteSize;
187
+ sprite.height = spriteSize;
188
+ const sctx = sprite.getContext("2d");
189
+ if (sctx) {
190
+ const radius = size / 2;
191
+ const center = pad + radius;
192
+ sctx.shadowColor = "rgba(0, 0, 0, 0.35)";
193
+ sctx.shadowBlur = blur;
194
+ sctx.shadowOffsetY = offsetY;
195
+ sctx.fillStyle = "#000";
196
+ sctx.beginPath();
197
+ sctx.arc(center, center, radius, 0, Math.PI * 2);
198
+ sctx.fill();
199
+ }
200
+ bubbleShadowSprite = { size, canvas: sprite, pad };
201
+ return bubbleShadowSprite;
202
+ }
203
+
141
204
  function drawCameraBubble(
142
205
  ctx: CanvasRenderingContext2D,
143
206
  cameraVideo: HTMLVideoElement,
@@ -172,15 +235,12 @@ function drawCameraBubble(
172
235
  const centerX = x + radius;
173
236
  const centerY = y + radius;
174
237
 
175
- ctx.save();
176
- ctx.shadowColor = "rgba(0, 0, 0, 0.35)";
177
- ctx.shadowBlur = Math.max(16, size * 0.12);
178
- ctx.shadowOffsetY = Math.max(8, size * 0.05);
179
- ctx.fillStyle = "#000";
180
- ctx.beginPath();
181
- ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
182
- ctx.fill();
183
- ctx.restore();
238
+ const shadow = getBubbleShadowSprite(size);
239
+ ctx.drawImage(
240
+ shadow.canvas,
241
+ centerX - shadow.pad - radius,
242
+ centerY - shadow.pad - radius,
243
+ );
184
244
 
185
245
  ctx.save();
186
246
  ctx.beginPath();
@@ -912,7 +912,7 @@ export default function MeetingDetailRoute() {
912
912
  </div>
913
913
  </div>
914
914
 
915
- {/* Transcript pane — chat-bubble layout */}
915
+ {/* Transcript pane — plain agent-chat-style text layout */}
916
916
  <div className="rounded-lg border border-border bg-background min-h-[480px] lg:min-h-0 overflow-hidden flex flex-col">
917
917
  <div className="flex shrink-0 items-center justify-between gap-2 border-b border-border px-4 py-2.5 bg-background">
918
918
  <div className="flex items-center gap-1.5 text-xs font-medium">
@@ -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**