@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
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  IconAlertTriangle,
3
3
  IconArrowLeft,
4
+ IconCalendarEvent,
4
5
  IconCircleCheck,
5
6
  IconDownload,
6
7
  IconExternalLink,
7
8
  IconFolderOpen,
8
9
  IconPencil,
9
10
  IconInfoCircle,
11
+ IconMicrophone2,
10
12
  IconRefresh,
11
13
  IconTrash,
12
14
  IconUpload,
@@ -16,6 +18,7 @@ import { emit, listen } from "@tauri-apps/api/event";
16
18
  import { getCurrentWindow } from "@tauri-apps/api/window";
17
19
  import { open as openExternal } from "@tauri-apps/plugin-shell";
18
20
  import {
21
+ type ReactNode,
19
22
  type RefObject,
20
23
  useCallback,
21
24
  useEffect,
@@ -26,7 +29,6 @@ import {
26
29
  import { FeedbackButton } from "./components/FeedbackButton";
27
30
  import {
28
31
  CamIcon,
29
- ClockIcon,
30
32
  CloseIcon,
31
33
  GoogleIcon,
32
34
  LibraryIcon,
@@ -57,6 +59,7 @@ import {
57
59
  MACOS_CAPTURE_PERMISSION_MESSAGE,
58
60
  MACOS_SCREEN_PERMISSION_MESSAGE,
59
61
  MACOS_SPEECH_PERMISSION_MESSAGE,
62
+ MACOS_UPDATE_RESTART_MESSAGE,
60
63
  } from "./lib/permissions";
61
64
  import { isMacPlatform, isWindowsPlatform } from "./lib/platform";
62
65
  import {
@@ -78,6 +81,7 @@ import {
78
81
  saveBool,
79
82
  saveString,
80
83
  } from "./lib/storage";
84
+ import { installAndRestart, isUpdatePendingRestart } from "./lib/updater";
81
85
  import { normalizeServerUrl } from "./lib/url";
82
86
  import {
83
87
  installDesktopVoiceDictation,
@@ -91,14 +95,6 @@ import {
91
95
  type ScreenMemoryStatus,
92
96
  } from "./shared/config";
93
97
 
94
- interface RecordingSummary {
95
- id: string;
96
- title: string;
97
- durationMs: number;
98
- thumbnailUrl: string | null;
99
- updatedAt: string;
100
- }
101
-
102
98
  interface PendingNativeUpload {
103
99
  kind: "native";
104
100
  recordingId: string;
@@ -119,6 +115,18 @@ interface PendingNativeUpload {
119
115
 
120
116
  type PendingDesktopUpload = PendingNativeUpload | PendingBrowserRecordingUpload;
121
117
 
118
+ type PopoverView = "recorder" | "settings" | "meetings" | "dictation";
119
+
120
+ interface PopoverMeeting {
121
+ id: string;
122
+ title: string;
123
+ scheduledStart: string | null;
124
+ scheduledEnd: string | null;
125
+ joinUrl: string | null;
126
+ platform: string | null;
127
+ transcriptStatus: string | null;
128
+ }
129
+
122
130
  interface LocalRecordingNotice {
123
131
  folderPath?: string;
124
132
  files: LocalExportedFile[];
@@ -182,25 +190,6 @@ const DEFAULT_URL = import.meta.env.DEV
182
190
  ? "http://localhost:8094"
183
191
  : "https://clips.agent-native.com";
184
192
 
185
- function resolveDesktopThumbnailUrl(
186
- rawUrl: string | null | undefined,
187
- serverUrl: string,
188
- ): string | null {
189
- if (!rawUrl) return null;
190
- if (
191
- rawUrl.startsWith("http://") ||
192
- rawUrl.startsWith("https://") ||
193
- rawUrl.startsWith("data:") ||
194
- rawUrl.startsWith("blob:")
195
- ) {
196
- return rawUrl;
197
- }
198
- if (rawUrl.startsWith("/")) {
199
- return `${serverUrl.replace(/\/+$/, "")}${rawUrl}`;
200
- }
201
- return rawUrl;
202
- }
203
-
204
193
  function normalizeCaptureSource(value: string): CaptureSource {
205
194
  if (value === "region" && isMacPlatform()) return "region";
206
195
  return value === "window" ? "window" : "full-screen";
@@ -465,6 +454,78 @@ function formatAgo(iso: string): string {
465
454
  }
466
455
  }
467
456
 
457
+ function formatMeetingWhen(meeting: PopoverMeeting): string {
458
+ const startMs = Date.parse(meeting.scheduledStart ?? "");
459
+ if (Number.isNaN(startMs)) return "Upcoming";
460
+
461
+ const endMs = Date.parse(meeting.scheduledEnd ?? "");
462
+ const now = Date.now();
463
+ if (startMs <= now && (Number.isNaN(endMs) || endMs >= now)) {
464
+ return "Now";
465
+ }
466
+
467
+ if (startMs > now && startMs - now < 60 * 60 * 1000) {
468
+ return `in ${Math.max(1, Math.round((startMs - now) / 60000))}m`;
469
+ }
470
+
471
+ const start = new Date(startMs);
472
+ const time = start.toLocaleTimeString([], {
473
+ hour: "numeric",
474
+ minute: "2-digit",
475
+ });
476
+ const today = new Date(now);
477
+ const tomorrow = new Date(now + 24 * 60 * 60 * 1000);
478
+ if (start.toDateString() === today.toDateString()) return `Today ${time}`;
479
+ if (start.toDateString() === tomorrow.toDateString()) {
480
+ return `Tomorrow ${time}`;
481
+ }
482
+
483
+ return `${start.toLocaleDateString([], {
484
+ weekday: "short",
485
+ month: "short",
486
+ day: "numeric",
487
+ })} ${time}`;
488
+ }
489
+
490
+ function meetingCanStartNotes(meeting: PopoverMeeting): boolean {
491
+ const startMs = Date.parse(meeting.scheduledStart ?? "");
492
+ if (Number.isNaN(startMs)) return false;
493
+ const endMs = Date.parse(meeting.scheduledEnd ?? "");
494
+ const now = Date.now();
495
+ return (
496
+ startMs <= now + 10 * 60 * 1000 && (Number.isNaN(endMs) || endMs >= now)
497
+ );
498
+ }
499
+
500
+ function voiceShortcutLabel(
501
+ shortcut: VoiceShortcutPreference,
502
+ customShortcut: string,
503
+ ): string {
504
+ switch (shortcut) {
505
+ case "fn":
506
+ return "Fn";
507
+ case "cmd-shift-space":
508
+ return "Cmd+Shift+Space";
509
+ case "ctrl-shift-space":
510
+ return "Ctrl+Shift+Space";
511
+ case "custom":
512
+ return customShortcut || "Custom shortcut";
513
+ case "both":
514
+ return "Fn, Cmd+Shift+Space, or Ctrl+Shift+Space";
515
+ }
516
+ }
517
+
518
+ function voiceProviderLabel(provider: VoiceProvider): string {
519
+ if (provider === "whisper") return "Local Whisper";
520
+ if (provider === "builder" || provider === "builder-gemini") {
521
+ return "Builder.io cleanup";
522
+ }
523
+ if (provider === "gemini") return "Google Gemini";
524
+ if (provider === "groq") return "Groq";
525
+ if (provider === "macos-native") return "macOS on-device";
526
+ return "Browser speech";
527
+ }
528
+
468
529
  function formatFileSize(bytes: number): string {
469
530
  if (!Number.isFinite(bytes) || bytes <= 0) return "";
470
531
  if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
@@ -626,7 +687,6 @@ export function App() {
626
687
  const localRecordingMode: LocalRecordingMode =
627
688
  featureConfig?.localRecordingMode ?? "off";
628
689
 
629
- const [recordings, setRecordings] = useState<RecordingSummary[]>([]);
630
690
  const [pendingUploads, setPendingUploads] = useState<PendingDesktopUpload[]>(
631
691
  [],
632
692
  );
@@ -639,11 +699,16 @@ export function App() {
639
699
  );
640
700
  const [localRecordingNotice, setLocalRecordingNotice] =
641
701
  useState<LocalRecordingNotice | null>(null);
642
- const [showRecent, setShowRecent] = useState(false);
702
+ const [popoverView, setPopoverView] = useState<PopoverView>("recorder");
703
+ const [meetings, setMeetings] = useState<PopoverMeeting[]>([]);
704
+ const [meetingsLoading, setMeetingsLoading] = useState(false);
705
+ const [meetingsError, setMeetingsError] = useState<string | null>(null);
706
+ const [meetingStartMessage, setMeetingStartMessage] = useState<string | null>(
707
+ null,
708
+ );
643
709
  const [readinessOpen, setReadinessOpen] = useState<boolean>(
644
710
  () => !loadBool(READINESS_REVIEWED_KEY, false),
645
711
  );
646
- const [showSettings, setShowSettings] = useState(false);
647
712
  const [recorder, setRecorder] = useState<RecorderHandle | null>(null);
648
713
  const [recError, setRecError] = useState<string | null>(null);
649
714
  const [cameraError, setCameraError] = useState<string | null>(null);
@@ -1027,6 +1092,58 @@ export function App() {
1027
1092
  [serverUrl],
1028
1093
  );
1029
1094
 
1095
+ const fetchUpcomingMeetings = useCallback(async () => {
1096
+ if (authStatus !== "authed") {
1097
+ setMeetings([]);
1098
+ setMeetingsError(null);
1099
+ return;
1100
+ }
1101
+
1102
+ setMeetingsLoading(true);
1103
+ setMeetingsError(null);
1104
+ try {
1105
+ const result = await callClipsAction<{ meetings?: unknown[] }>(
1106
+ "list-meetings",
1107
+ { view: "upcoming", limit: 3, upcomingWithinMin: 24 * 60 },
1108
+ { method: "GET" },
1109
+ );
1110
+ const list = Array.isArray(result.meetings) ? result.meetings : [];
1111
+ setMeetings(
1112
+ list.slice(0, 3).map((raw) => {
1113
+ const meeting = raw as Partial<PopoverMeeting>;
1114
+ return {
1115
+ id: String(meeting.id ?? ""),
1116
+ title: meeting.title || "Untitled meeting",
1117
+ scheduledStart: meeting.scheduledStart ?? null,
1118
+ scheduledEnd: meeting.scheduledEnd ?? null,
1119
+ joinUrl: meeting.joinUrl ?? null,
1120
+ platform: meeting.platform ?? null,
1121
+ transcriptStatus: meeting.transcriptStatus ?? null,
1122
+ };
1123
+ }),
1124
+ );
1125
+ } catch (err) {
1126
+ setMeetings([]);
1127
+ setMeetingsError(
1128
+ err instanceof Error ? err.message : "Could not load meetings.",
1129
+ );
1130
+ } finally {
1131
+ setMeetingsLoading(false);
1132
+ }
1133
+ }, [authStatus, callClipsAction]);
1134
+
1135
+ const startMeetingNotes = useCallback((meeting: PopoverMeeting) => {
1136
+ setMeetingStartMessage(`Starting notes for ${meeting.title}…`);
1137
+ emit("meetings:start-transcription", {
1138
+ meetingId: meeting.id,
1139
+ joinUrl: meeting.joinUrl,
1140
+ reason: "user",
1141
+ }).catch((err) => {
1142
+ console.error("[clips-popover] start meeting notes failed:", err);
1143
+ setMeetingStartMessage("Could not start notes. Try again from Meetings.");
1144
+ });
1145
+ }, []);
1146
+
1030
1147
  useMeetingTranscription({
1031
1148
  callClipsAction,
1032
1149
  serverUrl,
@@ -1153,7 +1270,7 @@ export function App() {
1153
1270
  }
1154
1271
  clearDesktopAuthToken(serverUrl);
1155
1272
  await checkAuth();
1156
- setShowSettings(false);
1273
+ setPopoverView("recorder");
1157
1274
  }
1158
1275
 
1159
1276
  // ---- Esc closes the popover --------------------------------------------
@@ -1527,33 +1644,9 @@ export function App() {
1527
1644
  const appRef = useRef<HTMLDivElement | null>(null);
1528
1645
  usePopoverAutoSize(appRef, {
1529
1646
  disabled: !popoverVisible || isRecording || recordingFlowActive,
1530
- width: showSettings ? 440 : 360,
1647
+ width: popoverView === "settings" ? 440 : 360,
1531
1648
  });
1532
1649
 
1533
- // ---- recent list --------------------------------------------------------
1534
-
1535
- const fetchRecent = useCallback(async () => {
1536
- if (authStatus !== "authed") return; // don't bother; would just 401
1537
- try {
1538
- const url = `${serverUrl.replace(/\/+$/, "")}/_agent-native/actions/list-recordings?limit=3&sort=recent`;
1539
- const res = await fetch(url, { credentials: "include" });
1540
- if (!res.ok) return;
1541
- const json = await res.json();
1542
- const list = Array.isArray(json?.recordings) ? json.recordings : [];
1543
- setRecordings(
1544
- list.slice(0, 3).map((r: any) => ({
1545
- id: r.id,
1546
- title: r.title ?? "Untitled",
1547
- durationMs: r.durationMs ?? 0,
1548
- thumbnailUrl: r.thumbnailUrl ?? null,
1549
- updatedAt: r.updatedAt ?? r.createdAt,
1550
- })),
1551
- );
1552
- } catch {
1553
- // ignore — server may be unreachable, we still render the chrome
1554
- }
1555
- }, [serverUrl, authStatus]);
1556
-
1557
1650
  const loadPendingUploads = useCallback(async () => {
1558
1651
  try {
1559
1652
  const nativeList = await invoke<Omit<PendingNativeUpload, "kind">[]>(
@@ -1578,8 +1671,10 @@ export function App() {
1578
1671
  }, []);
1579
1672
 
1580
1673
  useEffect(() => {
1581
- fetchRecent();
1582
- }, [fetchRecent]);
1674
+ if (popoverView === "meetings" && popoverVisible) {
1675
+ void fetchUpcomingMeetings();
1676
+ }
1677
+ }, [fetchUpcomingMeetings, popoverView, popoverVisible]);
1583
1678
 
1584
1679
  useEffect(() => {
1585
1680
  loadPendingUploads();
@@ -1649,7 +1744,6 @@ export function App() {
1649
1744
  });
1650
1745
  }
1651
1746
  await loadPendingUploads();
1652
- await fetchRecent();
1653
1747
  await openExternal(`${targetServerUrl}/r/${upload.recordingId}`);
1654
1748
  getCurrentWindow()
1655
1749
  .hide()
@@ -1976,7 +2070,16 @@ export function App() {
1976
2070
  return;
1977
2071
  }
1978
2072
  if (isHardCapturePermissionError(message)) {
1979
- setRecError(MACOS_CAPTURE_PERMISSION_MESSAGE);
2073
+ // If an update has finished downloading and is waiting to install, the
2074
+ // safe next step is to restart (which applies the update and gives the
2075
+ // process a clean binary + permission state). Prefer that hint over the
2076
+ // "grant permissions" banner, which is misleading when the readiness
2077
+ // checkmarks are already green.
2078
+ setRecError(
2079
+ isUpdatePendingRestart()
2080
+ ? MACOS_UPDATE_RESTART_MESSAGE
2081
+ : MACOS_CAPTURE_PERMISSION_MESSAGE,
2082
+ );
1980
2083
  return;
1981
2084
  }
1982
2085
  if (isStorageSetupFailureMessage(message)) {
@@ -1997,7 +2100,7 @@ export function App() {
1997
2100
  return;
1998
2101
  }
1999
2102
 
2000
- setShowSettings(false);
2103
+ setPopoverView("recorder");
2001
2104
  if (authStatus === "anon" && localRecordingMode === "off") {
2002
2105
  setRecError("Sign in to Clips before using the recording shortcut.");
2003
2106
  invoke("show_popover").catch(() => {});
@@ -2137,9 +2240,6 @@ export function App() {
2137
2240
  .catch(() => {});
2138
2241
  emit("clips:popover-visible", false).catch(() => {});
2139
2242
  }
2140
- if (!stopResult?.localOnly) {
2141
- fetchRecent();
2142
- }
2143
2243
  }
2144
2244
  }
2145
2245
  }),
@@ -2199,7 +2299,7 @@ export function App() {
2199
2299
  });
2200
2300
  unlisteners.length = 0;
2201
2301
  };
2202
- }, [recorder, fetchRecent, loadPendingUploads]);
2302
+ }, [recorder, loadPendingUploads]);
2203
2303
 
2204
2304
  // Auto-hide on blur is handled on the Rust side (tauri::WindowEvent::Focused).
2205
2305
 
@@ -2213,7 +2313,7 @@ export function App() {
2213
2313
  // we just render the normal pre-record panel so the user at least knows
2214
2314
  // where they are. No recording-only UI lives here.
2215
2315
 
2216
- if (showSettings) {
2316
+ if (popoverView === "settings") {
2217
2317
  return (
2218
2318
  <div className="app app-settings" ref={appRef}>
2219
2319
  <Setup
@@ -2239,9 +2339,48 @@ export function App() {
2239
2339
  onConnect={(url) => {
2240
2340
  saveString(STORAGE_KEY, url.replace(/\/+$/, ""));
2241
2341
  setServerUrl(url.replace(/\/+$/, ""));
2242
- setShowSettings(false);
2342
+ setPopoverView("recorder");
2243
2343
  }}
2244
- onCancel={() => setShowSettings(false)}
2344
+ onCancel={() => setPopoverView("recorder")}
2345
+ />
2346
+ </div>
2347
+ );
2348
+ }
2349
+
2350
+ if (popoverView === "meetings") {
2351
+ return (
2352
+ <div className="app app-popover-view" ref={appRef}>
2353
+ <MeetingsPopoverView
2354
+ meetings={meetings}
2355
+ loading={meetingsLoading}
2356
+ error={meetingsError}
2357
+ startMessage={meetingStartMessage}
2358
+ meetingsEnabled={featureConfig?.meetingsEnabled !== false}
2359
+ onBack={() => setPopoverView("recorder")}
2360
+ onRefresh={fetchUpcomingMeetings}
2361
+ onOpenMeetings={() => openInBrowser("/meetings")}
2362
+ onOpenMeeting={(meetingId) =>
2363
+ openInBrowser(`/meetings/${encodeURIComponent(meetingId)}`)
2364
+ }
2365
+ onOpenSettings={() => setPopoverView("settings")}
2366
+ onStartNotes={startMeetingNotes}
2367
+ />
2368
+ </div>
2369
+ );
2370
+ }
2371
+
2372
+ if (popoverView === "dictation") {
2373
+ return (
2374
+ <div className="app app-popover-view" ref={appRef}>
2375
+ <DictationPopoverView
2376
+ voiceEnabled={voiceDictationEnabled}
2377
+ voiceShortcut={voiceShortcut}
2378
+ voiceCustomShortcut={voiceCustomShortcut}
2379
+ voiceMode={voiceMode}
2380
+ voiceProvider={voiceProvider}
2381
+ onBack={() => setPopoverView("recorder")}
2382
+ onOpenDictate={() => openInBrowser("/dictate")}
2383
+ onOpenSettings={() => setPopoverView("settings")}
2245
2384
  />
2246
2385
  </div>
2247
2386
  );
@@ -2298,7 +2437,7 @@ export function App() {
2298
2437
  </>
2299
2438
  )}
2300
2439
  <div className="footer">
2301
- <a className="footer-link" onClick={() => setShowSettings(true)}>
2440
+ <a className="footer-link" onClick={() => setPopoverView("settings")}>
2302
2441
  Settings
2303
2442
  </a>
2304
2443
  </div>
@@ -2414,8 +2553,10 @@ export function App() {
2414
2553
  : "Start local recording"}
2415
2554
  </button>
2416
2555
  {recError ? (
2417
- recError === MACOS_CAPTURE_PERMISSION_MESSAGE ||
2418
- recError === MACOS_SCREEN_PERMISSION_MESSAGE ? (
2556
+ recError === MACOS_UPDATE_RESTART_MESSAGE ? (
2557
+ <UpdateRestartBanner message={recError} />
2558
+ ) : recError === MACOS_CAPTURE_PERMISSION_MESSAGE ||
2559
+ recError === MACOS_SCREEN_PERMISSION_MESSAGE ? (
2419
2560
  <PermissionRecoveryBanner
2420
2561
  kind="recording"
2421
2562
  message={recError}
@@ -2459,45 +2600,22 @@ export function App() {
2459
2600
  onClick={() => openInBrowser("/")}
2460
2601
  />
2461
2602
  <BottomButton
2462
- icon="settings"
2463
- label="Settings"
2464
- onClick={() => setShowSettings(true)}
2603
+ icon="meetings"
2604
+ label="Meetings"
2605
+ onClick={() => setPopoverView("meetings")}
2465
2606
  />
2466
2607
  <BottomButton
2467
- icon="recent"
2468
- label="Recent"
2608
+ icon="dictation"
2609
+ label="Dictate"
2469
2610
  badge={undefined}
2470
- onClick={() => setShowRecent((v) => !v)}
2611
+ onClick={() => setPopoverView("dictation")}
2612
+ />
2613
+ <BottomButton
2614
+ icon="settings"
2615
+ label="Settings"
2616
+ onClick={() => setPopoverView("settings")}
2471
2617
  />
2472
2618
  </div>
2473
-
2474
- {showRecent && recordings.length > 0 ? (
2475
- <div className="recent-list">
2476
- {recordings.map((r) => (
2477
- <button
2478
- key={r.id}
2479
- className="recent-item"
2480
- onClick={() => openInBrowser(`/r/${r.id}`)}
2481
- >
2482
- {r.thumbnailUrl ? (
2483
- <img
2484
- className="thumb"
2485
- src={
2486
- resolveDesktopThumbnailUrl(r.thumbnailUrl, serverUrl) ?? ""
2487
- }
2488
- alt=""
2489
- />
2490
- ) : (
2491
- <div className="thumb thumb-placeholder" />
2492
- )}
2493
- <div className="recent-meta">
2494
- <div className="recent-title">{r.title}</div>
2495
- <div className="recent-sub">{formatAgo(r.updatedAt)}</div>
2496
- </div>
2497
- </button>
2498
- ))}
2499
- </div>
2500
- ) : null}
2501
2619
  </div>
2502
2620
  );
2503
2621
  }
@@ -2579,6 +2697,30 @@ function PermissionRecoveryBanner({
2579
2697
  );
2580
2698
  }
2581
2699
 
2700
+ function UpdateRestartBanner({ message }: { message: string }) {
2701
+ return (
2702
+ <div className="error-banner permission-banner">
2703
+ <div className="permission-copy">
2704
+ <div className="permission-title">Restart to finish updating</div>
2705
+ <div>{message}</div>
2706
+ </div>
2707
+ <div className="permission-actions">
2708
+ <button
2709
+ type="button"
2710
+ className="permission-retry"
2711
+ onClick={() => {
2712
+ installAndRestart().catch((err) => {
2713
+ console.error("[clips-updater] relaunch failed:", err);
2714
+ });
2715
+ }}
2716
+ >
2717
+ Restart Clips
2718
+ </button>
2719
+ </div>
2720
+ </div>
2721
+ );
2722
+ }
2723
+
2582
2724
  function StorageConnectionBanner({ onConnect }: { onConnect: () => void }) {
2583
2725
  return (
2584
2726
  <div className="storage-flow-banner">
@@ -3089,13 +3231,236 @@ function SignInForm({
3089
3231
  );
3090
3232
  }
3091
3233
 
3234
+ function PopoverSubViewHeader({
3235
+ title,
3236
+ onBack,
3237
+ action,
3238
+ }: {
3239
+ title: string;
3240
+ onBack: () => void;
3241
+ action?: ReactNode;
3242
+ }) {
3243
+ return (
3244
+ <div className="setup-header popover-view-header">
3245
+ <button
3246
+ type="button"
3247
+ className="setup-back"
3248
+ onClick={onBack}
3249
+ aria-label="Back"
3250
+ >
3251
+ <IconArrowLeft size={18} stroke={1.75} />
3252
+ </button>
3253
+ <h2>{title}</h2>
3254
+ <div className="popover-view-header-spacer" />
3255
+ {action}
3256
+ </div>
3257
+ );
3258
+ }
3259
+
3260
+ function MeetingsPopoverView({
3261
+ meetings,
3262
+ loading,
3263
+ error,
3264
+ startMessage,
3265
+ meetingsEnabled,
3266
+ onBack,
3267
+ onRefresh,
3268
+ onOpenMeetings,
3269
+ onOpenMeeting,
3270
+ onOpenSettings,
3271
+ onStartNotes,
3272
+ }: {
3273
+ meetings: PopoverMeeting[];
3274
+ loading: boolean;
3275
+ error: string | null;
3276
+ startMessage: string | null;
3277
+ meetingsEnabled: boolean;
3278
+ onBack: () => void;
3279
+ onRefresh: () => void;
3280
+ onOpenMeetings: () => void;
3281
+ onOpenMeeting: (meetingId: string) => void;
3282
+ onOpenSettings: () => void;
3283
+ onStartNotes: (meeting: PopoverMeeting) => void;
3284
+ }) {
3285
+ return (
3286
+ <div className="setup popover-view">
3287
+ <PopoverSubViewHeader
3288
+ title="Meetings"
3289
+ onBack={onBack}
3290
+ action={
3291
+ <button
3292
+ type="button"
3293
+ className="link-button popover-view-link"
3294
+ onClick={onOpenMeetings}
3295
+ >
3296
+ Open web
3297
+ </button>
3298
+ }
3299
+ />
3300
+
3301
+ <div className="setup-section">
3302
+ <p className="setup-hint">
3303
+ Start Granola-style live notes from calendar meetings without hunting
3304
+ through Settings.
3305
+ </p>
3306
+ </div>
3307
+
3308
+ {!meetingsEnabled ? (
3309
+ <div className="popover-empty-card">
3310
+ <strong>Meeting notes are off</strong>
3311
+ <p>Turn them on to show reminders and start live transcription.</p>
3312
+ <button type="button" className="secondary" onClick={onOpenSettings}>
3313
+ Open meeting settings
3314
+ </button>
3315
+ </div>
3316
+ ) : error ? (
3317
+ <div className="popover-empty-card">
3318
+ <strong>Could not load meetings</strong>
3319
+ <p>{error}</p>
3320
+ <button type="button" className="secondary" onClick={onRefresh}>
3321
+ Try again
3322
+ </button>
3323
+ </div>
3324
+ ) : loading ? (
3325
+ <div className="popover-empty-card">
3326
+ <strong>Loading meetings…</strong>
3327
+ <p>Checking your connected calendar.</p>
3328
+ </div>
3329
+ ) : meetings.length === 0 ? (
3330
+ <div className="popover-empty-card">
3331
+ <strong>No meetings ready</strong>
3332
+ <p>Connect Google Calendar or open the Meetings page to see setup.</p>
3333
+ <button type="button" className="secondary" onClick={onOpenMeetings}>
3334
+ Open Meetings
3335
+ </button>
3336
+ </div>
3337
+ ) : (
3338
+ <div className="popover-list">
3339
+ {meetings.map((meeting) => {
3340
+ const canStart = meetingCanStartNotes(meeting);
3341
+ return (
3342
+ <div className="popover-list-item" key={meeting.id}>
3343
+ <div className="popover-list-icon">
3344
+ <IconCalendarEvent size={17} stroke={1.75} />
3345
+ </div>
3346
+ <div className="popover-list-main">
3347
+ <div className="popover-list-title">{meeting.title}</div>
3348
+ <div className="popover-list-sub">
3349
+ {formatMeetingWhen(meeting)}
3350
+ {meeting.platform ? ` · ${meeting.platform}` : ""}
3351
+ </div>
3352
+ </div>
3353
+ {canStart ? (
3354
+ <button
3355
+ type="button"
3356
+ className="popover-list-action popover-list-action-primary"
3357
+ onClick={() => onStartNotes(meeting)}
3358
+ >
3359
+ Start notes
3360
+ </button>
3361
+ ) : (
3362
+ <button
3363
+ type="button"
3364
+ className="popover-list-action"
3365
+ onClick={() => onOpenMeeting(meeting.id)}
3366
+ >
3367
+ Open
3368
+ </button>
3369
+ )}
3370
+ </div>
3371
+ );
3372
+ })}
3373
+ </div>
3374
+ )}
3375
+
3376
+ {startMessage ? <p className="setup-success">{startMessage}</p> : null}
3377
+ </div>
3378
+ );
3379
+ }
3380
+
3381
+ function DictationPopoverView({
3382
+ voiceEnabled,
3383
+ voiceShortcut,
3384
+ voiceCustomShortcut,
3385
+ voiceMode,
3386
+ voiceProvider,
3387
+ onBack,
3388
+ onOpenDictate,
3389
+ onOpenSettings,
3390
+ }: {
3391
+ voiceEnabled: boolean;
3392
+ voiceShortcut: VoiceShortcutPreference;
3393
+ voiceCustomShortcut: string;
3394
+ voiceMode: VoiceMode;
3395
+ voiceProvider: VoiceProvider;
3396
+ onBack: () => void;
3397
+ onOpenDictate: () => void;
3398
+ onOpenSettings: () => void;
3399
+ }) {
3400
+ const shortcut = voiceShortcutLabel(voiceShortcut, voiceCustomShortcut);
3401
+ return (
3402
+ <div className="setup popover-view">
3403
+ <PopoverSubViewHeader
3404
+ title="Dictate"
3405
+ onBack={onBack}
3406
+ action={
3407
+ <button
3408
+ type="button"
3409
+ className="link-button popover-view-link"
3410
+ onClick={onOpenDictate}
3411
+ >
3412
+ Open web
3413
+ </button>
3414
+ }
3415
+ />
3416
+
3417
+ <div className="popover-empty-card">
3418
+ <div className="popover-card-heading">
3419
+ <IconMicrophone2 size={18} stroke={1.75} />
3420
+ <strong>
3421
+ {voiceEnabled ? "Ready to dictate" : "Dictation is off"}
3422
+ </strong>
3423
+ </div>
3424
+ {voiceEnabled ? (
3425
+ <>
3426
+ <p>
3427
+ {voiceMode === "toggle"
3428
+ ? "Press once to start, then press again to stop."
3429
+ : "Hold the shortcut while speaking; release to paste."}
3430
+ </p>
3431
+ <div className="popover-kv">
3432
+ <span>Shortcut</span>
3433
+ <strong>{shortcut}</strong>
3434
+ </div>
3435
+ <div className="popover-kv">
3436
+ <span>Provider</span>
3437
+ <strong>{voiceProviderLabel(voiceProvider)}</strong>
3438
+ </div>
3439
+ </>
3440
+ ) : (
3441
+ <p>Turn on voice dictation to speak to type anywhere on your Mac.</p>
3442
+ )}
3443
+ </div>
3444
+
3445
+ <div className="setup-button-row">
3446
+ <button type="button" className="secondary" onClick={onOpenDictate}>
3447
+ Open Dictate history
3448
+ </button>
3449
+ <button type="button" className="secondary" onClick={onOpenSettings}>
3450
+ Dictation settings
3451
+ </button>
3452
+ </div>
3453
+ </div>
3454
+ );
3455
+ }
3456
+
3092
3457
  function BottomButton({
3093
3458
  icon,
3094
3459
  label,
3095
3460
  badge,
3096
3461
  onClick,
3097
3462
  }: {
3098
- icon: "library" | "settings" | "recent";
3463
+ icon: "library" | "settings" | "meetings" | "dictation";
3099
3464
  label: string;
3100
3465
  badge?: string;
3101
3466
  onClick: () => void;
@@ -3107,8 +3472,10 @@ function BottomButton({
3107
3472
  <LibraryIcon />
3108
3473
  ) : icon === "settings" ? (
3109
3474
  <SettingsIcon />
3475
+ ) : icon === "meetings" ? (
3476
+ <IconCalendarEvent size={18} stroke={1.75} />
3110
3477
  ) : (
3111
- <ClockIcon />
3478
+ <IconMicrophone2 size={18} stroke={1.75} />
3112
3479
  )}
3113
3480
  {badge ? <span className="badge">{badge}</span> : null}
3114
3481
  </span>