@agent-native/core 0.90.2 → 0.90.4

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 (530) hide show
  1. package/bin/agent-native.js +25 -3
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +21 -0
  4. package/corpus/core/bin/agent-native.js +25 -3
  5. package/corpus/core/docs/content/agent-native-toolkit.mdx +87 -80
  6. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  7. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  8. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  9. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  10. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  11. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  12. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  13. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  14. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  15. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  16. package/corpus/core/docs/content/toolkit-agent-ux.mdx +43 -0
  17. package/corpus/core/docs/content/toolkit-app-adapters.mdx +9 -0
  18. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +12 -0
  19. package/corpus/core/docs/content/toolkit-collaboration.mdx +74 -0
  20. package/corpus/core/docs/content/toolkit-command-navigation.mdx +106 -0
  21. package/corpus/core/docs/content/toolkit-comments-review.mdx +98 -0
  22. package/corpus/core/docs/content/toolkit-history.mdx +95 -0
  23. package/corpus/core/docs/content/toolkit-observability.mdx +41 -0
  24. package/corpus/core/docs/content/toolkit-org-team.mdx +80 -0
  25. package/corpus/core/docs/content/toolkit-resources.mdx +57 -0
  26. package/corpus/core/docs/content/toolkit-settings.mdx +65 -0
  27. package/corpus/core/docs/content/toolkit-setup-connections.mdx +109 -0
  28. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +18 -6
  29. package/corpus/core/docs/content/toolkit-sharing.mdx +81 -0
  30. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +9 -0
  31. package/corpus/core/docs/content/toolkit-ui.mdx +9 -0
  32. package/corpus/core/package.json +35 -1
  33. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +19 -1
  34. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -1
  35. package/corpus/core/src/agent/engine/index.ts +1 -0
  36. package/corpus/core/src/agent/engine/registry.ts +86 -18
  37. package/corpus/core/src/agent/production-agent.ts +37 -6
  38. package/corpus/core/src/cli/create.ts +35 -0
  39. package/corpus/core/src/cli/design-connect.ts +248 -0
  40. package/corpus/core/src/cli/index.ts +84 -7
  41. package/corpus/core/src/cli/workspacify.ts +34 -0
  42. package/corpus/core/src/client/command-navigation/index.ts +15 -0
  43. package/corpus/core/src/client/comments-review/index.ts +1 -0
  44. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +175 -0
  45. package/corpus/core/src/client/history/index.ts +21 -0
  46. package/corpus/core/src/client/history/use-history.ts +114 -0
  47. package/corpus/core/src/client/index.ts +84 -9
  48. package/corpus/core/src/client/org/OrgSwitcher.tsx +6 -6
  49. package/corpus/core/src/client/org/RequireActiveOrg.tsx +2 -2
  50. package/corpus/core/src/client/org/TeamPage.tsx +3 -3
  51. package/corpus/core/src/client/org/hooks.ts +32 -0
  52. package/corpus/core/src/client/org/index.ts +30 -1
  53. package/corpus/core/src/client/org-team/index.ts +1 -0
  54. package/corpus/core/src/client/review/ReviewStatusBadge.tsx +39 -0
  55. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +278 -0
  56. package/corpus/core/src/client/review/index.ts +30 -0
  57. package/corpus/core/src/client/review/use-review.ts +152 -0
  58. package/corpus/core/src/client/settings/index.ts +11 -1
  59. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +94 -0
  60. package/corpus/core/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  61. package/corpus/core/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  62. package/corpus/core/src/client/setup-connections/index.ts +46 -0
  63. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -14
  64. package/corpus/core/src/client/sharing/ShareDialog.tsx +3 -3
  65. package/corpus/core/src/command-navigation/actions.ts +100 -0
  66. package/corpus/core/src/command-navigation/index.ts +12 -0
  67. package/corpus/core/src/comments-review/index.ts +1 -0
  68. package/corpus/core/src/file-upload/builder.ts +24 -3
  69. package/corpus/core/src/file-upload/types.ts +3 -1
  70. package/corpus/core/src/history/actions/create-resource-version.ts +92 -0
  71. package/corpus/core/src/history/actions/get-resource-version.ts +60 -0
  72. package/corpus/core/src/history/actions/list-resource-history.ts +53 -0
  73. package/corpus/core/src/history/actions/list-resource-versions.ts +43 -0
  74. package/corpus/core/src/history/actions/restore-resource-version.ts +96 -0
  75. package/corpus/core/src/history/index.ts +26 -0
  76. package/corpus/core/src/history/registry.ts +111 -0
  77. package/corpus/core/src/history/store.ts +379 -0
  78. package/corpus/core/src/history/types.ts +69 -0
  79. package/corpus/core/src/index.ts +10 -0
  80. package/corpus/core/src/navigation/index.ts +170 -0
  81. package/corpus/core/src/org/index.ts +8 -0
  82. package/corpus/core/src/org/permissions.ts +30 -0
  83. package/corpus/core/src/org-team/index.ts +1 -0
  84. package/corpus/core/src/private-blob/registry.ts +1 -0
  85. package/corpus/core/src/review/actions/consume-review-feedback.ts +48 -0
  86. package/corpus/core/src/review/actions/create-review-comment.ts +107 -0
  87. package/corpus/core/src/review/actions/delete-review-comment.ts +67 -0
  88. package/corpus/core/src/review/actions/get-review-feedback.ts +54 -0
  89. package/corpus/core/src/review/actions/list-review-comments.ts +53 -0
  90. package/corpus/core/src/review/actions/reply-review-comment.ts +107 -0
  91. package/corpus/core/src/review/actions/resolve-review-thread.ts +67 -0
  92. package/corpus/core/src/review/actions/set-review-status.ts +58 -0
  93. package/corpus/core/src/review/index.ts +31 -0
  94. package/corpus/core/src/review/mentions.ts +44 -0
  95. package/corpus/core/src/review/registry.ts +111 -0
  96. package/corpus/core/src/review/store.ts +690 -0
  97. package/corpus/core/src/review/types.ts +97 -0
  98. package/corpus/core/src/server/action-discovery.ts +54 -0
  99. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  100. package/corpus/core/src/server/agent-engine-api-key-route.ts +5 -0
  101. package/corpus/core/src/server/credential-provider.ts +118 -0
  102. package/corpus/core/src/setup-connections/index.ts +89 -0
  103. package/corpus/core/src/setup-connections/onboarding.ts +47 -0
  104. package/corpus/core/src/transcription/builder-transcription.ts +9 -2
  105. package/corpus/core/src/vite/action-types-plugin.ts +52 -0
  106. package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -1
  107. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -2
  108. package/corpus/templates/analytics/app/global.css +22 -10
  109. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -1
  110. package/corpus/templates/analytics/app/i18n-data.ts +81 -13
  111. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  112. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  113. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +528 -108
  114. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +466 -183
  115. package/corpus/templates/analytics/changelog/2026-07-07-session-replays-load-sooner-show-clearer-activity-timelines-.md +6 -0
  116. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +11 -11
  117. package/corpus/templates/assets/actions/generate-image.ts +64 -28
  118. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +1 -1
  119. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +91 -74
  120. package/corpus/templates/assets/server/lib/generation.ts +29 -4
  121. package/corpus/templates/assets/server/lib/image-processing.ts +131 -0
  122. package/corpus/templates/brain/app/routes/settings.tsx +2 -2
  123. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +24 -2
  124. package/corpus/templates/calendar/AGENTS.md +3 -0
  125. package/corpus/templates/calendar/actions/create-event.ts +8 -34
  126. package/corpus/templates/calendar/actions/event-action-helpers.ts +52 -0
  127. package/corpus/templates/calendar/actions/manage-event-draft.ts +7 -34
  128. package/corpus/templates/calendar/actions/update-event.ts +10 -23
  129. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +79 -6
  130. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +23 -0
  131. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +59 -2
  132. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +40 -1
  133. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +154 -41
  134. package/corpus/templates/calendar/app/hooks/use-events.ts +6 -0
  135. package/corpus/templates/calendar/app/hooks/use-people.ts +55 -0
  136. package/corpus/templates/calendar/app/i18n/zh-TW.ts +4 -0
  137. package/corpus/templates/calendar/app/i18n-data.ts +40 -0
  138. package/corpus/templates/calendar/changelog/2026-07-07-guest-suggestions-now-find-coworkers-from-your-google-worksp.md +6 -0
  139. package/corpus/templates/calendar/changelog/2026-07-07-you-can-mark-event-guests-as-optional-while-inviting-them-or.md +6 -0
  140. package/corpus/templates/calendar/changelog/2026-07-07-zoom-stays-selected-after-connecting-it-from-a-draft-event.md +6 -0
  141. package/corpus/templates/calendar/server/handlers/events.ts +1 -0
  142. package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -0
  143. package/corpus/templates/calendar/server/plugins/agent-chat.ts +1 -1
  144. package/corpus/templates/calendar/shared/api.ts +2 -0
  145. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +29 -3
  146. package/corpus/templates/clips/actions/create-recording.ts +5 -1
  147. package/corpus/templates/clips/actions/finalize-recording.ts +140 -1
  148. package/corpus/templates/clips/actions/generate-workflow.ts +19 -8
  149. package/corpus/templates/clips/actions/get-clips-ai-prefs.ts +36 -0
  150. package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
  151. package/corpus/templates/clips/actions/lib/clips-ai-prefs.ts +28 -0
  152. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -0
  153. package/corpus/templates/clips/actions/regenerate-chapters.ts +21 -7
  154. package/corpus/templates/clips/actions/regenerate-summary.ts +26 -8
  155. package/corpus/templates/clips/actions/regenerate-title.ts +44 -7
  156. package/corpus/templates/clips/actions/request-transcript.ts +31 -0
  157. package/corpus/templates/clips/actions/set-thumbnail.ts +2 -0
  158. package/corpus/templates/clips/actions/update-clips-ai-prefs.ts +50 -0
  159. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  160. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +7 -2
  161. package/corpus/templates/clips/app/components/player/scrubber-position.ts +9 -0
  162. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -2
  163. package/corpus/templates/clips/app/components/player/share-dialog.tsx +69 -41
  164. package/corpus/templates/clips/app/components/player/video-player.tsx +38 -1
  165. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -3
  166. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +9 -19
  167. package/corpus/templates/clips/app/hooks/use-auto-title.ts +25 -10
  168. package/corpus/templates/clips/app/i18n/ar-SA.ts +28 -6
  169. package/corpus/templates/clips/app/i18n/de-DE.ts +28 -6
  170. package/corpus/templates/clips/app/i18n/en-US.ts +29 -6
  171. package/corpus/templates/clips/app/i18n/es-ES.ts +29 -6
  172. package/corpus/templates/clips/app/i18n/fr-FR.ts +30 -6
  173. package/corpus/templates/clips/app/i18n/hi-IN.ts +26 -6
  174. package/corpus/templates/clips/app/i18n/ja-JP.ts +27 -6
  175. package/corpus/templates/clips/app/i18n/ko-KR.ts +28 -6
  176. package/corpus/templates/clips/app/i18n/pt-BR.ts +28 -6
  177. package/corpus/templates/clips/app/i18n/zh-CN.ts +26 -6
  178. package/corpus/templates/clips/app/i18n/zh-TW.ts +25 -6
  179. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +73 -0
  180. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -0
  181. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +79 -5
  182. package/corpus/templates/clips/app/routes/record.tsx +21 -12
  183. package/corpus/templates/clips/changelog/2026-07-02-recordings-now-wait-for-storage-media-to-serve-before-finishing.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-07-a-pending-app-update-no-longer-blocks-screen-recording-updat.md +6 -0
  185. package/corpus/templates/clips/changelog/2026-07-07-ai-tools-can-include-the-full-video-not-just-the-transcript-.md +6 -0
  186. package/corpus/templates/clips/changelog/2026-07-07-chrome-extension-recordings-keep-audio-after-refreshing-tab.md +6 -0
  187. package/corpus/templates/clips/changelog/2026-07-07-clip-playback-progress-now-starts-and-finishes-at-the-right-times.md +6 -0
  188. package/corpus/templates/clips/changelog/2026-07-07-clips-desktop-now-surfaces-meetings-and-dictate-directly-in-.md +6 -0
  189. package/corpus/templates/clips/changelog/2026-07-07-meeting-notes-now-explain-exactly-how-to-start-granola-style.md +6 -0
  190. package/corpus/templates/clips/changelog/2026-07-07-meeting-start-alerts-now-include-separate-start-notes-and-jo.md +6 -0
  191. package/corpus/templates/clips/changelog/2026-07-07-recordings-start-more-predictably-and-newly-saved-clips-refr.md +6 -0
  192. package/corpus/templates/clips/changelog/2026-07-07-sharing-public-clips-now-stays-focused-on-the-normal-link-wi.md +6 -0
  193. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  194. package/corpus/templates/clips/chrome-extension/src/background.ts +18 -0
  195. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +23 -8
  196. package/corpus/templates/clips/desktop/src/app.tsx +475 -108
  197. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +19 -7
  198. package/corpus/templates/clips/desktop/src/lib/permissions.ts +2 -0
  199. package/corpus/templates/clips/desktop/src/lib/recorder.ts +27 -21
  200. package/corpus/templates/clips/desktop/src/lib/updater.ts +25 -2
  201. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -22
  202. package/corpus/templates/clips/desktop/src/styles.css +167 -2
  203. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +8 -1
  204. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -7
  205. package/corpus/templates/clips/desktop/src-tauri/src/tray_meetings.rs +5 -4
  206. package/corpus/templates/clips/server/routes/_agent-native/clips/user-prefs.put.ts +16 -8
  207. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +1 -0
  208. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +22 -5
  209. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +8 -0
  210. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +13 -6
  211. package/corpus/templates/clips/shared/clips-ai-prefs.ts +81 -0
  212. package/corpus/templates/clips/shared/finalize-recovery.ts +12 -0
  213. package/corpus/templates/content/actions/delete-document.ts +337 -52
  214. package/corpus/templates/content/changelog/2026-07-07-permanently-deleting-trashed-databases-now-finishes-reliably.md +6 -0
  215. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +16 -1
  216. package/corpus/templates/design/actions/add-localhost-screens.ts +1 -0
  217. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -11
  218. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +89 -14
  219. package/corpus/templates/design/app/components/design/bridge-security.ts +7 -1
  220. package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -1
  221. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  222. package/corpus/templates/design/app/i18n-data.ts +41 -0
  223. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-uses-live-app-iframes-for-click-to-edit-pr.md +6 -0
  224. package/corpus/templates/slides/app/pages/DeckEditor.tsx +2 -2
  225. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  226. package/dist/agent/engine/ai-sdk-engine.js +15 -1
  227. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  228. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  229. package/dist/agent/engine/anthropic-engine.js +20 -1
  230. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  231. package/dist/agent/engine/index.d.ts +1 -1
  232. package/dist/agent/engine/index.d.ts.map +1 -1
  233. package/dist/agent/engine/index.js +1 -1
  234. package/dist/agent/engine/index.js.map +1 -1
  235. package/dist/agent/engine/registry.d.ts +14 -0
  236. package/dist/agent/engine/registry.d.ts.map +1 -1
  237. package/dist/agent/engine/registry.js +78 -16
  238. package/dist/agent/engine/registry.js.map +1 -1
  239. package/dist/agent/production-agent.d.ts.map +1 -1
  240. package/dist/agent/production-agent.js +27 -7
  241. package/dist/agent/production-agent.js.map +1 -1
  242. package/dist/cli/create.d.ts.map +1 -1
  243. package/dist/cli/create.js +31 -0
  244. package/dist/cli/create.js.map +1 -1
  245. package/dist/cli/design-connect.d.ts.map +1 -1
  246. package/dist/cli/design-connect.js +186 -0
  247. package/dist/cli/design-connect.js.map +1 -1
  248. package/dist/cli/index.js +76 -9
  249. package/dist/cli/index.js.map +1 -1
  250. package/dist/cli/workspacify.d.ts.map +1 -1
  251. package/dist/cli/workspacify.js +30 -0
  252. package/dist/cli/workspacify.js.map +1 -1
  253. package/dist/client/command-navigation/index.d.ts +4 -0
  254. package/dist/client/command-navigation/index.d.ts.map +1 -0
  255. package/dist/client/command-navigation/index.js +4 -0
  256. package/dist/client/command-navigation/index.js.map +1 -0
  257. package/dist/client/comments-review/index.d.ts +2 -0
  258. package/dist/client/comments-review/index.d.ts.map +1 -0
  259. package/dist/client/comments-review/index.js +2 -0
  260. package/dist/client/comments-review/index.js.map +1 -0
  261. package/dist/client/history/VersionHistoryPanel.d.ts +18 -0
  262. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -0
  263. package/dist/client/history/VersionHistoryPanel.js +31 -0
  264. package/dist/client/history/VersionHistoryPanel.js.map +1 -0
  265. package/dist/client/history/index.d.ts +3 -0
  266. package/dist/client/history/index.d.ts.map +1 -0
  267. package/dist/client/history/index.js +3 -0
  268. package/dist/client/history/index.js.map +1 -0
  269. package/dist/client/history/use-history.d.ts +58 -0
  270. package/dist/client/history/use-history.d.ts.map +1 -0
  271. package/dist/client/history/use-history.js +24 -0
  272. package/dist/client/history/use-history.js.map +1 -0
  273. package/dist/client/index.d.ts +6 -4
  274. package/dist/client/index.d.ts.map +1 -1
  275. package/dist/client/index.js +6 -4
  276. package/dist/client/index.js.map +1 -1
  277. package/dist/client/org/OrgSwitcher.js +5 -5
  278. package/dist/client/org/OrgSwitcher.js.map +1 -1
  279. package/dist/client/org/RequireActiveOrg.js +2 -2
  280. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  281. package/dist/client/org/TeamPage.js +3 -3
  282. package/dist/client/org/TeamPage.js.map +1 -1
  283. package/dist/client/org/hooks.d.ts +12 -1
  284. package/dist/client/org/hooks.d.ts.map +1 -1
  285. package/dist/client/org/hooks.js +15 -0
  286. package/dist/client/org/hooks.js.map +1 -1
  287. package/dist/client/org/index.d.ts +4 -2
  288. package/dist/client/org/index.d.ts.map +1 -1
  289. package/dist/client/org/index.js +3 -1
  290. package/dist/client/org/index.js.map +1 -1
  291. package/dist/client/org-team/index.d.ts +2 -0
  292. package/dist/client/org-team/index.d.ts.map +1 -0
  293. package/dist/client/org-team/index.js +2 -0
  294. package/dist/client/org-team/index.js.map +1 -0
  295. package/dist/client/review/ReviewStatusBadge.d.ts +7 -0
  296. package/dist/client/review/ReviewStatusBadge.d.ts.map +1 -0
  297. package/dist/client/review/ReviewStatusBadge.js +19 -0
  298. package/dist/client/review/ReviewStatusBadge.js.map +1 -0
  299. package/dist/client/review/ReviewThreadPanel.d.ts +20 -0
  300. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -0
  301. package/dist/client/review/ReviewThreadPanel.js +84 -0
  302. package/dist/client/review/ReviewThreadPanel.js.map +1 -0
  303. package/dist/client/review/index.d.ts +4 -0
  304. package/dist/client/review/index.d.ts.map +1 -0
  305. package/dist/client/review/index.js +4 -0
  306. package/dist/client/review/index.js.map +1 -0
  307. package/dist/client/review/use-review.d.ts +91 -0
  308. package/dist/client/review/use-review.d.ts.map +1 -0
  309. package/dist/client/review/use-review.js +30 -0
  310. package/dist/client/review/use-review.js.map +1 -0
  311. package/dist/client/settings/index.d.ts +1 -1
  312. package/dist/client/settings/index.d.ts.map +1 -1
  313. package/dist/client/settings/index.js +1 -1
  314. package/dist/client/settings/index.js.map +1 -1
  315. package/dist/client/setup-connections/BuilderConnectCard.d.ts +9 -0
  316. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -0
  317. package/dist/client/setup-connections/BuilderConnectCard.js +25 -0
  318. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -0
  319. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts +8 -0
  320. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts.map +1 -0
  321. package/dist/client/setup-connections/ProviderReadinessBadge.js +32 -0
  322. package/dist/client/setup-connections/ProviderReadinessBadge.js.map +1 -0
  323. package/dist/client/setup-connections/SetupConnectionsPage.d.ts +17 -0
  324. package/dist/client/setup-connections/SetupConnectionsPage.d.ts.map +1 -0
  325. package/dist/client/setup-connections/SetupConnectionsPage.js +10 -0
  326. package/dist/client/setup-connections/SetupConnectionsPage.js.map +1 -0
  327. package/dist/client/setup-connections/index.d.ts +7 -0
  328. package/dist/client/setup-connections/index.d.ts.map +1 -0
  329. package/dist/client/setup-connections/index.js +7 -0
  330. package/dist/client/setup-connections/index.js.map +1 -0
  331. package/dist/client/sharing/ShareButton.d.ts +4 -4
  332. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  333. package/dist/client/sharing/ShareButton.js +13 -7
  334. package/dist/client/sharing/ShareButton.js.map +1 -1
  335. package/dist/client/sharing/ShareDialog.js +3 -3
  336. package/dist/client/sharing/ShareDialog.js.map +1 -1
  337. package/dist/collab/awareness.d.ts +2 -2
  338. package/dist/collab/awareness.d.ts.map +1 -1
  339. package/dist/collab/routes.d.ts +1 -1
  340. package/dist/collab/struct-routes.d.ts +1 -1
  341. package/dist/command-navigation/actions.d.ts +25 -0
  342. package/dist/command-navigation/actions.d.ts.map +1 -0
  343. package/dist/command-navigation/actions.js +64 -0
  344. package/dist/command-navigation/actions.js.map +1 -0
  345. package/dist/command-navigation/index.d.ts +4 -0
  346. package/dist/command-navigation/index.d.ts.map +1 -0
  347. package/dist/command-navigation/index.js +4 -0
  348. package/dist/command-navigation/index.js.map +1 -0
  349. package/dist/comments-review/index.d.ts +2 -0
  350. package/dist/comments-review/index.d.ts.map +1 -0
  351. package/dist/comments-review/index.js +2 -0
  352. package/dist/comments-review/index.js.map +1 -0
  353. package/dist/file-upload/builder.d.ts.map +1 -1
  354. package/dist/file-upload/builder.js +18 -2
  355. package/dist/file-upload/builder.js.map +1 -1
  356. package/dist/file-upload/types.d.ts +3 -0
  357. package/dist/file-upload/types.d.ts.map +1 -1
  358. package/dist/file-upload/types.js.map +1 -1
  359. package/dist/history/actions/create-resource-version.d.ts +10 -0
  360. package/dist/history/actions/create-resource-version.d.ts.map +1 -0
  361. package/dist/history/actions/create-resource-version.js +68 -0
  362. package/dist/history/actions/create-resource-version.js.map +1 -0
  363. package/dist/history/actions/get-resource-version.d.ts +10 -0
  364. package/dist/history/actions/get-resource-version.d.ts.map +1 -0
  365. package/dist/history/actions/get-resource-version.js +38 -0
  366. package/dist/history/actions/get-resource-version.js.map +1 -0
  367. package/dist/history/actions/list-resource-history.d.ts +10 -0
  368. package/dist/history/actions/list-resource-history.d.ts.map +1 -0
  369. package/dist/history/actions/list-resource-history.js +45 -0
  370. package/dist/history/actions/list-resource-history.js.map +1 -0
  371. package/dist/history/actions/list-resource-versions.d.ts +10 -0
  372. package/dist/history/actions/list-resource-versions.d.ts.map +1 -0
  373. package/dist/history/actions/list-resource-versions.js +35 -0
  374. package/dist/history/actions/list-resource-versions.js.map +1 -0
  375. package/dist/history/actions/restore-resource-version.d.ts +11 -0
  376. package/dist/history/actions/restore-resource-version.d.ts.map +1 -0
  377. package/dist/history/actions/restore-resource-version.js +59 -0
  378. package/dist/history/actions/restore-resource-version.js.map +1 -0
  379. package/dist/history/index.d.ts +4 -0
  380. package/dist/history/index.d.ts.map +1 -0
  381. package/dist/history/index.js +3 -0
  382. package/dist/history/index.js.map +1 -0
  383. package/dist/history/registry.d.ts +10 -0
  384. package/dist/history/registry.d.ts.map +1 -0
  385. package/dist/history/registry.js +63 -0
  386. package/dist/history/registry.js.map +1 -0
  387. package/dist/history/store.d.ts +34 -0
  388. package/dist/history/store.d.ts.map +1 -0
  389. package/dist/history/store.js +290 -0
  390. package/dist/history/store.js.map +1 -0
  391. package/dist/history/types.d.ts +55 -0
  392. package/dist/history/types.d.ts.map +1 -0
  393. package/dist/history/types.js +2 -0
  394. package/dist/history/types.js.map +1 -0
  395. package/dist/index.d.ts +6 -0
  396. package/dist/index.d.ts.map +1 -1
  397. package/dist/index.js +6 -0
  398. package/dist/index.js.map +1 -1
  399. package/dist/navigation/index.d.ts +53 -0
  400. package/dist/navigation/index.d.ts.map +1 -0
  401. package/dist/navigation/index.js +105 -0
  402. package/dist/navigation/index.js.map +1 -0
  403. package/dist/observability/routes.d.ts +3 -3
  404. package/dist/org/index.d.ts +1 -0
  405. package/dist/org/index.d.ts.map +1 -1
  406. package/dist/org/index.js +1 -0
  407. package/dist/org/index.js.map +1 -1
  408. package/dist/org/permissions.d.ts +7 -0
  409. package/dist/org/permissions.d.ts.map +1 -0
  410. package/dist/org/permissions.js +21 -0
  411. package/dist/org/permissions.js.map +1 -0
  412. package/dist/org-team/index.d.ts +2 -0
  413. package/dist/org-team/index.d.ts.map +1 -0
  414. package/dist/org-team/index.js +2 -0
  415. package/dist/org-team/index.js.map +1 -0
  416. package/dist/private-blob/registry.d.ts.map +1 -1
  417. package/dist/private-blob/registry.js +1 -0
  418. package/dist/private-blob/registry.js.map +1 -1
  419. package/dist/progress/routes.d.ts +1 -1
  420. package/dist/resources/handlers.d.ts +2 -2
  421. package/dist/review/actions/consume-review-feedback.d.ts +10 -0
  422. package/dist/review/actions/consume-review-feedback.d.ts.map +1 -0
  423. package/dist/review/actions/consume-review-feedback.js +35 -0
  424. package/dist/review/actions/consume-review-feedback.js.map +1 -0
  425. package/dist/review/actions/create-review-comment.d.ts +18 -0
  426. package/dist/review/actions/create-review-comment.d.ts.map +1 -0
  427. package/dist/review/actions/create-review-comment.js +81 -0
  428. package/dist/review/actions/create-review-comment.js.map +1 -0
  429. package/dist/review/actions/delete-review-comment.d.ts +11 -0
  430. package/dist/review/actions/delete-review-comment.d.ts.map +1 -0
  431. package/dist/review/actions/delete-review-comment.js +53 -0
  432. package/dist/review/actions/delete-review-comment.js.map +1 -0
  433. package/dist/review/actions/get-review-feedback.d.ts +10 -0
  434. package/dist/review/actions/get-review-feedback.d.ts.map +1 -0
  435. package/dist/review/actions/get-review-feedback.js +45 -0
  436. package/dist/review/actions/get-review-feedback.js.map +1 -0
  437. package/dist/review/actions/list-review-comments.d.ts +13 -0
  438. package/dist/review/actions/list-review-comments.d.ts.map +1 -0
  439. package/dist/review/actions/list-review-comments.js +44 -0
  440. package/dist/review/actions/list-review-comments.js.map +1 -0
  441. package/dist/review/actions/reply-review-comment.d.ts +16 -0
  442. package/dist/review/actions/reply-review-comment.d.ts.map +1 -0
  443. package/dist/review/actions/reply-review-comment.js +84 -0
  444. package/dist/review/actions/reply-review-comment.js.map +1 -0
  445. package/dist/review/actions/resolve-review-thread.d.ts +12 -0
  446. package/dist/review/actions/resolve-review-thread.d.ts.map +1 -0
  447. package/dist/review/actions/resolve-review-thread.js +49 -0
  448. package/dist/review/actions/resolve-review-thread.js.map +1 -0
  449. package/dist/review/actions/set-review-status.d.ts +9 -0
  450. package/dist/review/actions/set-review-status.d.ts.map +1 -0
  451. package/dist/review/actions/set-review-status.js +43 -0
  452. package/dist/review/actions/set-review-status.js.map +1 -0
  453. package/dist/review/index.d.ts +5 -0
  454. package/dist/review/index.d.ts.map +1 -0
  455. package/dist/review/index.js +4 -0
  456. package/dist/review/index.js.map +1 -0
  457. package/dist/review/mentions.d.ts +4 -0
  458. package/dist/review/mentions.d.ts.map +1 -0
  459. package/dist/review/mentions.js +39 -0
  460. package/dist/review/mentions.js.map +1 -0
  461. package/dist/review/registry.d.ts +10 -0
  462. package/dist/review/registry.d.ts.map +1 -0
  463. package/dist/review/registry.js +63 -0
  464. package/dist/review/registry.js.map +1 -0
  465. package/dist/review/store.d.ts +63 -0
  466. package/dist/review/store.d.ts.map +1 -0
  467. package/dist/review/store.js +561 -0
  468. package/dist/review/store.js.map +1 -0
  469. package/dist/review/types.d.ts +77 -0
  470. package/dist/review/types.d.ts.map +1 -0
  471. package/dist/review/types.js +2 -0
  472. package/dist/review/types.js.map +1 -0
  473. package/dist/secrets/routes.d.ts +9 -9
  474. package/dist/server/action-discovery.d.ts.map +1 -1
  475. package/dist/server/action-discovery.js +54 -0
  476. package/dist/server/action-discovery.js.map +1 -1
  477. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  478. package/dist/server/agent-chat-plugin.js +5 -0
  479. package/dist/server/agent-chat-plugin.js.map +1 -1
  480. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  481. package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
  482. package/dist/server/agent-engine-api-key-route.js +5 -0
  483. package/dist/server/agent-engine-api-key-route.js.map +1 -1
  484. package/dist/server/credential-provider.d.ts +28 -0
  485. package/dist/server/credential-provider.d.ts.map +1 -1
  486. package/dist/server/credential-provider.js +92 -0
  487. package/dist/server/credential-provider.js.map +1 -1
  488. package/dist/setup-connections/index.d.ts +6 -0
  489. package/dist/setup-connections/index.d.ts.map +1 -0
  490. package/dist/setup-connections/index.js +6 -0
  491. package/dist/setup-connections/index.js.map +1 -0
  492. package/dist/setup-connections/onboarding.d.ts +14 -0
  493. package/dist/setup-connections/onboarding.d.ts.map +1 -0
  494. package/dist/setup-connections/onboarding.js +23 -0
  495. package/dist/setup-connections/onboarding.js.map +1 -0
  496. package/dist/transcription/builder-transcription.d.ts +1 -0
  497. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  498. package/dist/transcription/builder-transcription.js +5 -2
  499. package/dist/transcription/builder-transcription.js.map +1 -1
  500. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  501. package/dist/vite/action-types-plugin.js +52 -0
  502. package/dist/vite/action-types-plugin.js.map +1 -1
  503. package/docs/content/agent-native-toolkit.mdx +87 -80
  504. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  505. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  506. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  507. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  508. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  509. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  510. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  511. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  512. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  513. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  514. package/docs/content/toolkit-agent-ux.mdx +43 -0
  515. package/docs/content/toolkit-app-adapters.mdx +9 -0
  516. package/docs/content/toolkit-collaboration-ui.mdx +12 -0
  517. package/docs/content/toolkit-collaboration.mdx +74 -0
  518. package/docs/content/toolkit-command-navigation.mdx +106 -0
  519. package/docs/content/toolkit-comments-review.mdx +98 -0
  520. package/docs/content/toolkit-history.mdx +95 -0
  521. package/docs/content/toolkit-observability.mdx +41 -0
  522. package/docs/content/toolkit-org-team.mdx +80 -0
  523. package/docs/content/toolkit-resources.mdx +57 -0
  524. package/docs/content/toolkit-settings.mdx +65 -0
  525. package/docs/content/toolkit-setup-connections.mdx +109 -0
  526. package/docs/content/toolkit-sharing-ui.mdx +18 -6
  527. package/docs/content/toolkit-sharing.mdx +81 -0
  528. package/docs/content/toolkit-shell-hooks.mdx +9 -0
  529. package/docs/content/toolkit-ui.mdx +9 -0
  530. package/package.json +36 -2
@@ -10,7 +10,6 @@ import {
10
10
 
11
11
  import {
12
12
  chooseFallbackAudioInput,
13
- findAudioInputBySavedLabel,
14
13
  isPseudoMediaDeviceId,
15
14
  isSelectableAudioInputDevice,
16
15
  normalizedMediaDeviceId,
@@ -272,17 +271,30 @@ export function useMediaDevices({
272
271
  useEffect(() => {
273
272
  if (isPseudoMediaDeviceId(micId) || !micId || mics.length === 0) return;
274
273
  if (mics.some((d) => d.deviceId === micId)) return;
275
- const rematch = findAudioInputBySavedLabel(mics, {
274
+ // The selected mic (e.g. Bluetooth headset unplugged mid-session) is gone.
275
+ // Prefer rematching by saved label, then fall back to the best available
276
+ // input so we don't stay pinned to a device that no longer exists.
277
+ const fallback = chooseFallbackAudioInput(mics, {
276
278
  savedLabel: micLabel,
277
279
  avoidDeviceIds: [micId],
278
280
  });
279
- if (!rematch) return;
281
+ if (!fallback) {
282
+ // Nothing concrete left; drop to the OS default rather than keeping the
283
+ // disconnected device selected.
284
+ setMicId("");
285
+ setMicLabel("");
286
+ return;
287
+ }
280
288
  console.warn(
281
- "[clips-recorder] saved mic id was missing; rematched by label",
282
- { previousDeviceId: micId, nextDeviceId: rematch.deviceId },
289
+ "[clips-recorder] saved mic id was missing; fell back to available input",
290
+ {
291
+ previousDeviceId: micId,
292
+ nextDeviceId: fallback.deviceId,
293
+ reason: fallback.reason,
294
+ },
283
295
  );
284
- setMicId(rematch.deviceId);
285
- setMicLabel(rematch.label);
296
+ setMicId(fallback.deviceId);
297
+ setMicLabel(fallback.label);
286
298
  }, [micId, micLabel, mics]);
287
299
 
288
300
  useEffect(() => saveString(CAM_KEY, cameraId), [cameraId]);
@@ -8,6 +8,8 @@ export const MACOS_SCREEN_PERMISSION_MESSAGE =
8
8
  "Grant Screen Recording permission in macOS Settings, then restart Clips and try again.";
9
9
  export const MACOS_SPEECH_PERMISSION_MESSAGE =
10
10
  "Grant Speech Recognition and Microphone access, then try again. If you just changed access, restart Clips before retrying.";
11
+ export const MACOS_UPDATE_RESTART_MESSAGE =
12
+ "An update was downloaded and needs a restart to finish installing. Restart Clips, then record again.";
11
13
 
12
14
  export function isHardCapturePermissionError(message: string): boolean {
13
15
  return /permission denied by system|blocked by system|system settings|screen recording|privacy|sandbox/i.test(
@@ -999,7 +999,6 @@ async function captureTitleForRecording(params: {
999
999
  }
1000
1000
 
1001
1001
  const COUNTDOWN_EVENT_TIMEOUT_MS = 5000;
1002
- const COUNTDOWN_OVERLAY_SETTLE_MS = 120;
1003
1002
 
1004
1003
  function wait(ms: number): Promise<void> {
1005
1004
  return new Promise((resolve) => window.setTimeout(resolve, ms));
@@ -1652,10 +1651,6 @@ async function runRecordingCountdown(wantsScreen: boolean) {
1652
1651
  console.warn("[clips-recorder] countdown timed out — proceeding");
1653
1652
  return;
1654
1653
  }
1655
- // The countdown webview emits before it finishes closing. Give macOS a
1656
- // brief beat to remove the overlay and any shortcut handling before capture
1657
- // starts, so the first frame/audio sample is the real recording.
1658
- await wait(COUNTDOWN_OVERLAY_SETTLE_MS);
1659
1654
  }
1660
1655
 
1661
1656
  function showFinalizingFeedback() {
@@ -1852,29 +1847,35 @@ async function startNativeFullscreenRecording(
1852
1847
  }).catch((err) => {
1853
1848
  console.warn("[clips-recorder] mic warm failed:", err);
1854
1849
  });
1855
- const countdownPromise = runRecordingCountdown(true);
1856
1850
  if (localOnly) {
1851
+ const countdownPromise = runRecordingCountdown(true);
1857
1852
  id = localFolderName;
1858
1853
  await Promise.all([countdownPromise, warmMic(id)]);
1859
1854
  } else {
1860
- const captureTitle = await captureTitleForRecording({
1855
+ const captureTitlePromise = captureTitleForRecording({
1861
1856
  mode: params.mode,
1862
1857
  source: params.source,
1863
1858
  });
1864
- console.time("[clips-recorder] createServerRecording duration");
1865
- const recordingPromise = createServerRecording(
1866
- params.serverUrl,
1867
- wantsCamera,
1868
- wantsRecordedAudio,
1869
- captureTitle,
1870
- {
1871
- mimeType: NATIVE_FULLSCREEN_MIME_TYPE,
1872
- requestStreaming: true,
1873
- streamingUploadClient: "desktop-native",
1874
- },
1875
- ).finally(() => {
1876
- console.timeEnd("[clips-recorder] createServerRecording duration");
1877
- });
1859
+ const countdownPromise = runRecordingCountdown(true);
1860
+ const recordingPromise = (async () => {
1861
+ const captureTitle = await captureTitlePromise;
1862
+ console.time("[clips-recorder] createServerRecording duration");
1863
+ try {
1864
+ return await createServerRecording(
1865
+ params.serverUrl,
1866
+ wantsCamera,
1867
+ wantsRecordedAudio,
1868
+ captureTitle,
1869
+ {
1870
+ mimeType: NATIVE_FULLSCREEN_MIME_TYPE,
1871
+ requestStreaming: true,
1872
+ streamingUploadClient: "desktop-native",
1873
+ },
1874
+ );
1875
+ } finally {
1876
+ console.timeEnd("[clips-recorder] createServerRecording duration");
1877
+ }
1878
+ })();
1878
1879
  // The recording id usually lands well before the countdown ends — warm
1879
1880
  // native capture as soon as it does so setup overlaps the 3-2-1.
1880
1881
  const warmAndId = (async () => {
@@ -1918,6 +1919,11 @@ async function startNativeFullscreenRecording(
1918
1919
  // Capture is now live — after rebasing the transcript timeline, stamp the
1919
1920
  // timer baseline so the toolbar clock lines up with the real start.
1920
1921
  startedAt = Date.now();
1922
+ emit("clips:toolbar-enabled", true).catch(() => {});
1923
+ emit("clips:recorder-state", {
1924
+ paused: false,
1925
+ elapsedMs: 0,
1926
+ }).catch(() => {});
1921
1927
  localCameraExport?.start(2_000);
1922
1928
  } catch (err) {
1923
1929
  await localCameraExport?.cancel().catch(() => {});
@@ -45,9 +45,15 @@ async function runCheck() {
45
45
  const notes = update.body ?? undefined;
46
46
  setStatus({ state: "available", version, notes });
47
47
 
48
+ // Download ONLY — do not install here. On macOS `install` swaps the .app
49
+ // bundle on disk while this process keeps running, which invalidates the
50
+ // running process's Screen Recording (TCC) grant and breaks capture until
51
+ // relaunch. We defer the swap to `installAndRestart()` so a downloaded-but-
52
+ // not-yet-installed update leaves the running app fully functional; the
53
+ // user records normally until they choose to restart.
48
54
  let total = 0;
49
55
  let downloaded = 0;
50
- await update.downloadAndInstall((event) => {
56
+ await update.download((event) => {
51
57
  if (event.event === "Started") {
52
58
  total = event.data.contentLength ?? 0;
53
59
  downloaded = 0;
@@ -98,10 +104,27 @@ export function useUpdateStatus(): UpdateStatus {
98
104
  }
99
105
 
100
106
  export async function installAndRestart(): Promise<void> {
101
- // downloadAndInstall already applied the bundle; relaunch completes it.
107
+ // Perform the deferred bundle swap now, then relaunch onto the new binary.
108
+ // Installing immediately before relaunch keeps the window where the on-disk
109
+ // bundle no longer matches the running process as short as possible — the
110
+ // process is torn down by `relaunch()` right after, so capture never runs
111
+ // against a swapped-out bundle.
112
+ if (pendingUpdate) {
113
+ await pendingUpdate.install();
114
+ }
102
115
  await relaunch();
103
116
  }
104
117
 
118
+ /**
119
+ * True once an update has been downloaded and is waiting for the user to
120
+ * restart. The recording flow uses this to explain a post-download capture
121
+ * failure as "restart to finish updating" instead of a misleading "grant
122
+ * permissions" message — see `app.tsx` recError routing.
123
+ */
124
+ export function isUpdatePendingRestart(): boolean {
125
+ return cachedStatus.state === "downloaded";
126
+ }
127
+
105
128
  /**
106
129
  * Manual retry entry point. Used by the UpdateBanner's error state to let
107
130
  * users re-attempt after a signature-verification / download / network
@@ -23,9 +23,8 @@ const DEFAULT_AUTO_HIDE_MS = 30_000;
23
23
  const SNOOZE_MS = 5 * 60_000;
24
24
 
25
25
  /**
26
- * Open a meeting join URL via the Tauri shell plugin. Centralized here so
27
- * both the notification's "Take Notes" and the watcher's
28
- * `meetings:start-transcription` event use the same path.
26
+ * Open a meeting join URL via the Tauri shell plugin. Used by the
27
+ * notification's dedicated Join CTA (notes start is a separate action).
29
28
  */
30
29
  async function openJoinUrl(url: string | null | undefined): Promise<void> {
31
30
  if (!url) return;
@@ -41,7 +40,7 @@ async function openJoinUrl(url: string | null | undefined): Promise<void> {
41
40
  * Variants:
42
41
  *
43
42
  * - Calendar event: solid left bar (green), meeting title, time,
44
- * "Start notes" + "Snooze 5 min" buttons.
43
+ * "Start notes" + optional "Join" + "Snooze 5 min" buttons.
45
44
  * - Ad-hoc call: dashed left bar (slate), "Call detected", app name,
46
45
  * same controls.
47
46
  *
@@ -170,11 +169,6 @@ export function MeetingNotification() {
170
169
  if (!data || pending) return;
171
170
  setPending(true);
172
171
  setError(null);
173
- // Open the join URL right away so the user feels the click — the
174
- // recording action runs in parallel.
175
- if (data.joinUrl) {
176
- openJoinUrl(data.joinUrl);
177
- }
178
172
  emit("meetings:start-transcription", {
179
173
  meetingId: data.meetingId,
180
174
  joinUrl: data.joinUrl,
@@ -185,25 +179,20 @@ export function MeetingNotification() {
185
179
  });
186
180
  }
187
181
 
182
+ async function joinMeeting() {
183
+ if (!data?.joinUrl) return;
184
+ await openJoinUrl(data.joinUrl);
185
+ }
186
+
188
187
  function snooze() {
189
188
  if (!data) return;
190
189
  // Hand the snooze to the Rust watcher so the reminder re-fires after the
191
190
  // delay even though this overlay window closes right away. A setTimeout
192
- // here would be torn down with the window and never fire, and re-emitting
193
- // immediately (as before) just re-showed the same banner instantly.
191
+ // here would be torn down with the window and never fire.
194
192
  invoke("meetings_snooze", {
195
193
  meetingId: data.meetingId,
196
194
  minutes: Math.round(SNOOZE_MS / 60_000),
197
195
  }).catch(() => {});
198
- const payload = data;
199
- // Hide the current banner and re-fire the same payload after the snooze
200
- // delay. We re-emit through Tauri so the in-app banner overlay window
201
- // (which is what hosts this React component) can rerender with a fresh
202
- // auto-hide timer.
203
- emit("meetings:show-notification", {
204
- ...payload,
205
- subtitle: `${payload.subtitle} (snoozed)`,
206
- } as NotificationData).catch(() => {});
207
196
  hideNotification();
208
197
  }
209
198
 
@@ -212,6 +201,7 @@ export function MeetingNotification() {
212
201
  }
213
202
 
214
203
  const isCalendar = data.type === "calendar";
204
+ const hasJoin = Boolean(data.joinUrl);
215
205
 
216
206
  return (
217
207
  <div
@@ -227,7 +217,9 @@ export function MeetingNotification() {
227
217
  scheduleAutoHide(DEFAULT_AUTO_HIDE_MS);
228
218
  }}
229
219
  >
230
- <div className="meeting-notification">
220
+ <div
221
+ className={`meeting-notification${hasJoin ? " meeting-notification-with-join" : ""}`}
222
+ >
231
223
  <div
232
224
  className={`meeting-notification-bar ${isCalendar ? "meeting-notification-bar-calendar" : "meeting-notification-bar-adhoc"}`}
233
225
  />
@@ -243,13 +235,22 @@ export function MeetingNotification() {
243
235
  </div>
244
236
  <div className="meeting-notification-actions">
245
237
  <button
246
- className="meeting-notification-btn"
238
+ className="meeting-notification-btn meeting-notification-btn-primary"
247
239
  onClick={takeNotes}
248
240
  disabled={pending}
249
241
  data-no-drag
250
242
  >
251
243
  {pending ? "Starting…" : "Start notes"}
252
244
  </button>
245
+ {hasJoin ? (
246
+ <button
247
+ className="meeting-notification-btn meeting-notification-btn-secondary"
248
+ onClick={joinMeeting}
249
+ data-no-drag
250
+ >
251
+ Join
252
+ </button>
253
+ ) : null}
253
254
  <button
254
255
  className="meeting-notification-btn meeting-notification-btn-secondary"
255
256
  onClick={snooze}
@@ -1096,7 +1096,7 @@ body[data-clips-route="recording-pill"] #root {
1096
1096
 
1097
1097
  .bottom-row {
1098
1098
  display: grid;
1099
- grid-template-columns: repeat(3, 1fr);
1099
+ grid-template-columns: repeat(4, 1fr);
1100
1100
  gap: 4px;
1101
1101
  }
1102
1102
 
@@ -1138,6 +1138,145 @@ body[data-clips-route="recording-pill"] #root {
1138
1138
  font-weight: 500;
1139
1139
  }
1140
1140
 
1141
+ /* ------------------------------------------------------------------------- */
1142
+ /* Popover drill-in views */
1143
+ /* ------------------------------------------------------------------------- */
1144
+
1145
+ .app-popover-view {
1146
+ gap: 0;
1147
+ padding: 0;
1148
+ }
1149
+
1150
+ .popover-view {
1151
+ min-height: 260px;
1152
+ }
1153
+
1154
+ .popover-view-header {
1155
+ margin-bottom: 2px;
1156
+ }
1157
+
1158
+ .popover-view-header-spacer {
1159
+ flex: 1;
1160
+ }
1161
+
1162
+ .popover-view-link {
1163
+ font-size: 11px;
1164
+ }
1165
+
1166
+ .popover-empty-card {
1167
+ display: flex;
1168
+ flex-direction: column;
1169
+ gap: 8px;
1170
+ padding: 12px;
1171
+ border: 1px solid var(--border);
1172
+ border-radius: var(--radius);
1173
+ background: var(--surface);
1174
+ }
1175
+
1176
+ .popover-empty-card strong {
1177
+ font-size: 13px;
1178
+ color: var(--fg);
1179
+ }
1180
+
1181
+ .popover-card-heading {
1182
+ display: flex;
1183
+ align-items: center;
1184
+ gap: 8px;
1185
+ }
1186
+
1187
+ .popover-list {
1188
+ display: flex;
1189
+ flex-direction: column;
1190
+ gap: 6px;
1191
+ }
1192
+
1193
+ .popover-list-item {
1194
+ display: flex;
1195
+ align-items: center;
1196
+ gap: 9px;
1197
+ padding: 9px;
1198
+ border: 1px solid var(--border);
1199
+ border-radius: var(--radius);
1200
+ background: var(--surface);
1201
+ }
1202
+
1203
+ .popover-list-icon {
1204
+ display: inline-flex;
1205
+ align-items: center;
1206
+ justify-content: center;
1207
+ color: var(--fg-muted);
1208
+ flex-shrink: 0;
1209
+ }
1210
+
1211
+ .popover-list-main {
1212
+ flex: 1;
1213
+ min-width: 0;
1214
+ }
1215
+
1216
+ .popover-list-title {
1217
+ font-size: 12px;
1218
+ font-weight: 600;
1219
+ color: var(--fg);
1220
+ white-space: nowrap;
1221
+ overflow: hidden;
1222
+ text-overflow: ellipsis;
1223
+ }
1224
+
1225
+ .popover-list-sub {
1226
+ margin-top: 1px;
1227
+ font-size: 11px;
1228
+ color: var(--fg-subtle);
1229
+ white-space: nowrap;
1230
+ overflow: hidden;
1231
+ text-overflow: ellipsis;
1232
+ }
1233
+
1234
+ .popover-list-action {
1235
+ flex-shrink: 0;
1236
+ border: 1px solid var(--border-strong);
1237
+ border-radius: var(--radius-sm);
1238
+ background: var(--bg);
1239
+ color: var(--fg);
1240
+ padding: 6px 8px;
1241
+ font-size: 11px;
1242
+ font-weight: 600;
1243
+ cursor: pointer;
1244
+ }
1245
+
1246
+ .popover-list-action:hover {
1247
+ background: var(--surface-hover);
1248
+ }
1249
+
1250
+ .popover-list-action-primary {
1251
+ border-color: var(--brand);
1252
+ background: var(--brand);
1253
+ color: var(--bg);
1254
+ }
1255
+
1256
+ .popover-list-action-primary:hover {
1257
+ background: var(--brand-hover);
1258
+ }
1259
+
1260
+ .popover-kv {
1261
+ display: flex;
1262
+ align-items: center;
1263
+ justify-content: space-between;
1264
+ gap: 12px;
1265
+ padding-top: 6px;
1266
+ border-top: 1px solid var(--border);
1267
+ font-size: 11px;
1268
+ }
1269
+
1270
+ .popover-kv span {
1271
+ color: var(--fg-subtle);
1272
+ }
1273
+
1274
+ .popover-kv strong {
1275
+ min-width: 0;
1276
+ text-align: right;
1277
+ font-size: 11px;
1278
+ }
1279
+
1141
1280
  .badge {
1142
1281
  position: absolute;
1143
1282
  top: -4px;
@@ -3468,7 +3607,19 @@ body[data-clips-route="recording-pill"] #root {
3468
3607
  color: white;
3469
3608
  pointer-events: auto;
3470
3609
  min-width: 280px;
3471
- max-width: 320px;
3610
+ max-width: 400px;
3611
+ }
3612
+
3613
+ .meeting-notification-with-join {
3614
+ flex-wrap: wrap;
3615
+ align-items: flex-start;
3616
+ row-gap: 10px;
3617
+ }
3618
+
3619
+ .meeting-notification-with-join .meeting-notification-actions {
3620
+ flex: 1 1 100%;
3621
+ justify-content: flex-end;
3622
+ padding-left: 13px; /* align under content past the bar */
3472
3623
  }
3473
3624
 
3474
3625
  .meeting-notification-bar {
@@ -3536,6 +3687,20 @@ body[data-clips-route="recording-pill"] #root {
3536
3687
  cursor: progress;
3537
3688
  }
3538
3689
 
3690
+ .meeting-notification-btn-primary {
3691
+ background: #ffffff;
3692
+ color: #111827;
3693
+ }
3694
+
3695
+ .meeting-notification-btn-primary:hover {
3696
+ background: #f3f4f6;
3697
+ }
3698
+
3699
+ .meeting-notification-btn-primary:disabled {
3700
+ background: rgba(255, 255, 255, 0.7);
3701
+ color: #374151;
3702
+ }
3703
+
3539
3704
  .meeting-notification-actions {
3540
3705
  display: inline-flex;
3541
3706
  align-items: center;
@@ -648,7 +648,7 @@ pub async fn native_fullscreen_recording_available() -> Result<bool, String> {
648
648
  /// the countdown by now; this is just a safety net so a slow/denied mic can't
649
649
  /// stall the start.
650
650
  #[cfg(target_os = "macos")]
651
- const MIC_WARM_TIMEOUT_MS: u64 = 1500;
651
+ const MIC_WARM_TIMEOUT_MS: u64 = 250;
652
652
 
653
653
  /// Acquire a backend (ScreenCaptureKit, or the screencapture fallback) and
654
654
  /// store it as the active session. Shared by the immediate-start command and
@@ -1538,6 +1538,13 @@ fn take_and_finalize_active_session(
1538
1538
  session.lost_segment_duration.as_secs()
1539
1539
  );
1540
1540
  }
1541
+
1542
+ if let Some(paused_at) = session.paused_at.take() {
1543
+ session.paused_total = session
1544
+ .paused_total
1545
+ .checked_add(paused_at.elapsed())
1546
+ .unwrap_or(session.paused_total);
1547
+ }
1541
1548
  let duration_ms = session
1542
1549
  .started_at
1543
1550
  .elapsed()
@@ -16,8 +16,8 @@ use crate::util::{
16
16
  };
17
17
 
18
18
  const MEETING_NOTIFICATION_LABEL: &str = "meeting-notif";
19
- const NOTIFICATION_W_LOGICAL: u32 = 380;
20
- const NOTIFICATION_H_LOGICAL: u32 = 132;
19
+ const NOTIFICATION_W_LOGICAL: u32 = 420;
20
+ const NOTIFICATION_H_LOGICAL: u32 = 148;
21
21
  const NOTIFICATION_TOP_MARGIN_LOGICAL: u32 = 44;
22
22
  const NOTIFICATION_RIGHT_MARGIN_LOGICAL: u32 = 24;
23
23
 
@@ -125,11 +125,7 @@ pub async fn notify_meeting_starting(
125
125
  } else {
126
126
  format!("in {} min", (starts_in_secs / 60).max(1))
127
127
  };
128
- let body = if join_url.is_some() {
129
- format!("{} — Start notes", pretty_in)
130
- } else {
131
- format!("Starts {}", pretty_in)
132
- };
128
+ let body = format!("Starts {}", pretty_in);
133
129
  dlog!(
134
130
  "[clips-tray] notify_meeting_starting id={} title={} body={}",
135
131
  meeting_id,
@@ -25,21 +25,22 @@ pub struct MeetingItem {
25
25
 
26
26
  pub const MEETING_ID_PREFIX: &str = "meeting:";
27
27
 
28
- /// Build the "Upcoming Meetings" submenu populated with up to 3 events. If
28
+ /// Build the "Start Meeting Notes" submenu populated with up to 3 events. If
29
29
  /// the list is empty, returns a submenu containing a single disabled "No
30
- /// upcoming meetings" item — keeps the menu structure stable.
30
+ /// meetings ready" item — keeps the menu structure stable. Selecting a real
31
+ /// meeting starts live notes immediately.
31
32
  pub fn build_meetings_section(
32
33
  app: &AppHandle,
33
34
  upcoming: Vec<MeetingItem>,
34
35
  ) -> Result<Submenu<Wry>, Box<dyn std::error::Error>> {
35
36
  let mut builder: SubmenuBuilder<'_, Wry, AppHandle> =
36
- SubmenuBuilder::new(app, "Upcoming Meetings");
37
+ SubmenuBuilder::new(app, "Start Meeting Notes");
37
38
 
38
39
  if upcoming.is_empty() {
39
40
  let placeholder = MenuItem::with_id(
40
41
  app,
41
42
  "meeting:none",
42
- "No upcoming meetings",
43
+ "No meetings ready",
43
44
  false,
44
45
  None::<&str>,
45
46
  )?;
@@ -1,5 +1,5 @@
1
1
  import { getSession } from "@agent-native/core/server";
2
- import { putUserSetting } from "@agent-native/core/settings";
2
+ import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
3
3
  import { defineEventHandler, getHeader, readBody, setResponseStatus } from "h3";
4
4
 
5
5
  const CLIPS_USER_PREFS_KEY = "clips-user-prefs";
@@ -17,11 +17,19 @@ export default defineEventHandler(async (event) => {
17
17
  return { error: "Invalid settings payload" };
18
18
  }
19
19
 
20
- await putUserSetting(
21
- session.email,
22
- CLIPS_USER_PREFS_KEY,
23
- body as Record<string, unknown>,
24
- { requestSource: getHeader(event, "x-request-source") || undefined },
25
- );
26
- return body;
20
+ // Merge so partial Settings saves (playback, notifications, …) don't wipe
21
+ // AI-tool prefs written from the recording page popover.
22
+ const existing =
23
+ (await getUserSetting(session.email, CLIPS_USER_PREFS_KEY)) ?? {};
24
+ const next = {
25
+ ...(typeof existing === "object" && existing && !Array.isArray(existing)
26
+ ? existing
27
+ : {}),
28
+ ...(body as Record<string, unknown>),
29
+ };
30
+
31
+ await putUserSetting(session.email, CLIPS_USER_PREFS_KEY, next, {
32
+ requestSource: getHeader(event, "x-request-source") || undefined,
33
+ });
34
+ return next;
27
35
  });
@@ -165,6 +165,7 @@ export default defineEventHandler(async (event: H3Event) => {
165
165
  mimeType,
166
166
  filename: `thumb-${recordingId}.${ext}`,
167
167
  ownerEmail,
168
+ recordAsset: false,
168
169
  });
169
170
 
170
171
  let url: string;
@@ -6,10 +6,12 @@
6
6
  */
7
7
 
8
8
  import {
9
+ readAppState,
9
10
  writeAppState,
10
11
  deleteAppStateByPrefix,
11
12
  } from "@agent-native/core/application-state";
12
13
  import { runWithRequestContext } from "@agent-native/core/server";
14
+ import { isStoredButUnservableFinalizeError } from "@shared/finalize-recovery.js";
13
15
  import { and, eq } from "drizzle-orm";
14
16
  import {
15
17
  defineEventHandler,
@@ -50,6 +52,7 @@ export default defineEventHandler(async (event: H3Event) => {
50
52
  id: schema.recordings.id,
51
53
  status: schema.recordings.status,
52
54
  videoUrl: schema.recordings.videoUrl,
55
+ failureReason: schema.recordings.failureReason,
53
56
  })
54
57
  .from(schema.recordings)
55
58
  .where(
@@ -68,10 +71,14 @@ export default defineEventHandler(async (event: H3Event) => {
68
71
  return { ok: true, recordingId, alreadyReady: true, chunksCleared: 0 };
69
72
  }
70
73
 
74
+ const preserveRecoveryState =
75
+ isStoredButUnservableFinalizeError(failureReason) ||
76
+ isStoredButUnservableFinalizeError(existing.failureReason);
77
+
71
78
  // Already a terminal failure (e.g. a duplicate/retried abort call, or
72
79
  // finalize's own failChunkAssembly already flipped it) — no-op instead of
73
80
  // re-clearing chunk state and overwriting the original failureReason.
74
- if (existing.status === "failed") {
81
+ if (existing.status === "failed" && !preserveRecoveryState) {
75
82
  return { ok: true, recordingId, alreadyFailed: true, chunksCleared: 0 };
76
83
  }
77
84
 
@@ -85,17 +92,27 @@ export default defineEventHandler(async (event: H3Event) => {
85
92
  })
86
93
  .where(eq(schema.recordings.id, recordingId));
87
94
 
95
+ const existingUploadStateRaw = await readAppState(
96
+ `recording-upload-${recordingId}`,
97
+ ).catch(() => null);
98
+ const existingUploadState =
99
+ existingUploadStateRaw && typeof existingUploadStateRaw === "object"
100
+ ? (existingUploadStateRaw as Record<string, unknown>)
101
+ : {};
88
102
  await writeAppState(`recording-upload-${recordingId}`, {
103
+ ...existingUploadState,
89
104
  recordingId,
90
105
  status: "failed",
91
106
  failureReason,
92
107
  updatedAt: now,
93
108
  });
94
109
 
95
- const cleared = await deleteAppStateByPrefix(
96
- `recording-chunks-${recordingId}-`,
97
- );
98
- await deleteResumableSession(recordingId).catch(() => {});
110
+ const cleared = preserveRecoveryState
111
+ ? 0
112
+ : await deleteAppStateByPrefix(`recording-chunks-${recordingId}-`);
113
+ if (!preserveRecoveryState) {
114
+ await deleteResumableSession(recordingId).catch(() => {});
115
+ }
99
116
  await writeAppState("refresh-signal", { ts: Date.now() });
100
117
 
101
118
  return { ok: true, recordingId, chunksCleared: cleared };