@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
@@ -6,6 +6,9 @@
6
6
  * waiting for the agent chat bridge. If the fast path is unavailable, we still
7
7
  * queue the older agent-chat request as a fallback.
8
8
  *
9
+ * When the user enables Include full video, we skip the transcript-only fast
10
+ * path and always delegate so the agent can watch the recording.
11
+ *
9
12
  * Usage:
10
13
  * pnpm action regenerate-title --recordingId=<id>
11
14
  */
@@ -19,9 +22,11 @@ import { z } from "zod";
19
22
 
20
23
  import { getDb, schema } from "../server/db/index.js";
21
24
  import { isBuilderCreditsExhaustedMessage } from "../shared/builder-credits.js";
25
+ import { withFullVideoAiInstructions } from "../shared/clips-ai-prefs.js";
22
26
  import cleanupTranscript from "./cleanup-transcript.js";
23
27
  import { loadAgentsMdContext } from "./lib/agents-md-context.js";
24
28
  import { clearBuilderCreditsExhausted } from "./lib/builder-credits-state.js";
29
+ import { readIncludeFullVideoInAi } from "./lib/clips-ai-prefs.js";
25
30
  import {
26
31
  cleanGeneratedTitle,
27
32
  fallbackTitleFromTranscript,
@@ -66,6 +71,7 @@ export async function queueTitleRegenerationRequest({
66
71
  transcriptStatus = "ready",
67
72
  segmentsJson = "[]",
68
73
  ownerEmail,
74
+ includeFullVideoInAi,
69
75
  }: {
70
76
  recordingId: string;
71
77
  currentTitle: string | null | undefined;
@@ -73,11 +79,20 @@ export async function queueTitleRegenerationRequest({
73
79
  transcriptStatus?: string;
74
80
  segmentsJson?: string | null;
75
81
  ownerEmail?: string | null;
82
+ includeFullVideoInAi?: boolean;
76
83
  }) {
77
84
  const agentsContext = await loadAgentsMdContext({
78
85
  ownerEmail,
79
86
  purpose: "title",
80
87
  });
88
+ const useVideo =
89
+ includeFullVideoInAi ?? (await readIncludeFullVideoInAi(ownerEmail));
90
+ const baseMessage =
91
+ `Regenerate the title for recording ${recordingId}. ` +
92
+ `Read the native transcript and AGENTS.md context in this request's context and call ` +
93
+ `\`update-recording --id=${recordingId} --title="..."\` with a concise ` +
94
+ `4-9 word descriptive title. Current title: "${currentTitle ?? ""}". ` +
95
+ "Do not prompt the user.";
81
96
  const request = {
82
97
  kind: "regenerate-title" as const,
83
98
  recordingId,
@@ -87,12 +102,8 @@ export async function queueTitleRegenerationRequest({
87
102
  transcriptText,
88
103
  segmentsJson: segmentsJson ?? "[]",
89
104
  agentsContext,
90
- message:
91
- `Regenerate the title for recording ${recordingId}. ` +
92
- `Read the native transcript and AGENTS.md context in this request's context and call ` +
93
- `\`update-recording --id=${recordingId} --title="..."\` with a concise ` +
94
- `4-9 word descriptive title. Current title: "${currentTitle ?? ""}". ` +
95
- "Do not prompt the user.",
105
+ includeFullVideoInAi: useVideo,
106
+ message: withFullVideoAiInstructions(baseMessage, recordingId, useVideo),
96
107
  };
97
108
 
98
109
  await writeAppState(`clips-ai-request-${recordingId}`, request as any);
@@ -102,7 +113,7 @@ export async function queueTitleRegenerationRequest({
102
113
 
103
114
  export default defineAction({
104
115
  description:
105
- "Regenerate this recording's title from its transcript using the configured cleanup/title path, falling back to a local transcript title when unavailable.",
116
+ "Regenerate this recording's title from its transcript using the configured cleanup/title path, falling back to a local transcript title when unavailable. When the user has enabled Include full video, delegates to the agent so it can watch the recording.",
106
117
  schema: z.object({
107
118
  recordingId: z.string().describe("Recording ID"),
108
119
  transcriptText: z
@@ -137,6 +148,31 @@ export default defineAction({
137
148
  args.transcriptText?.trim() ||
138
149
  transcript?.fullText?.trim() ||
139
150
  transcriptTextFromSegments(transcript?.segmentsJson);
151
+
152
+ const includeFullVideoInAi = await readIncludeFullVideoInAi();
153
+
154
+ // Full-video mode needs the agent to watch the clip; skip the transcript-
155
+ // only Gemini fast path so we don't generate titles from audio alone.
156
+ if (includeFullVideoInAi) {
157
+ await queueTitleRegenerationRequest({
158
+ recordingId: args.recordingId,
159
+ currentTitle: rec.title,
160
+ transcriptStatus: transcript?.status ?? "pending",
161
+ transcriptText: transcriptText || "",
162
+ segmentsJson: transcript?.segmentsJson ?? "[]",
163
+ ownerEmail: getRequestUserEmail() ?? transcript?.ownerEmail,
164
+ includeFullVideoInAi: true,
165
+ });
166
+ console.log(
167
+ `Delegation queued: regenerate-title (full video) for ${args.recordingId}`,
168
+ );
169
+ return {
170
+ queued: true,
171
+ recordingId: args.recordingId,
172
+ includeFullVideoInAi: true,
173
+ };
174
+ }
175
+
140
176
  if (
141
177
  (!args.transcriptText && transcript?.status !== "ready") ||
142
178
  !transcriptText
@@ -279,6 +315,7 @@ export default defineAction({
279
315
  transcriptText,
280
316
  segmentsJson: transcript?.segmentsJson ?? "[]",
281
317
  ownerEmail: getRequestUserEmail() ?? transcript?.ownerEmail,
318
+ includeFullVideoInAi: false,
282
319
  });
283
320
 
284
321
  console.log(`Delegation queued: regenerate-title for ${args.recordingId}`);
@@ -123,6 +123,36 @@ const SPEECH_ONLY_TRANSCRIPTION_INSTRUCTIONS =
123
123
  "Auto-detect the spoken language from the audio. Transcribe only words spoken in the audio, in the same language they were spoken. Do not translate. Do not infer language from screen text, filenames, account settings, browser locale, or these instructions. Do not describe screen activity, UI changes, silence, music, or non-speech sounds. Return an empty transcript when there are no spoken words.";
124
124
  const CLIPS_USER_PREFS_KEY = "clips-user-prefs";
125
125
  const RECENT_PENDING_TRANSCRIPT_MS = 2 * 60 * 1000;
126
+ const BUILDER_TRANSCRIPTION_MIN_TIMEOUT_MS = 45_000;
127
+ const BUILDER_TRANSCRIPTION_MAX_TIMEOUT_MS = 65_000;
128
+ const BUILDER_TRANSCRIPTION_BASE_TIMEOUT_MS = 30_000;
129
+ const BUILDER_TRANSCRIPTION_PER_MINUTE_MS = 3_000;
130
+
131
+ function clampTimeoutMs(value: number): number {
132
+ return Math.max(
133
+ BUILDER_TRANSCRIPTION_MIN_TIMEOUT_MS,
134
+ Math.min(BUILDER_TRANSCRIPTION_MAX_TIMEOUT_MS, Math.floor(value)),
135
+ );
136
+ }
137
+
138
+ export function builderTranscriptionTimeoutMs(
139
+ durationMs: number | null | undefined,
140
+ ): number {
141
+ const override = Number(process.env.CLIPS_BUILDER_TRANSCRIPTION_TIMEOUT_MS);
142
+ if (Number.isFinite(override) && override > 0) {
143
+ return clampTimeoutMs(override);
144
+ }
145
+
146
+ if (!durationMs || !Number.isFinite(durationMs) || durationMs <= 0) {
147
+ return BUILDER_TRANSCRIPTION_MIN_TIMEOUT_MS;
148
+ }
149
+
150
+ const durationMinutes = Math.ceil(durationMs / 60_000);
151
+ return clampTimeoutMs(
152
+ BUILDER_TRANSCRIPTION_BASE_TIMEOUT_MS +
153
+ durationMinutes * BUILDER_TRANSCRIPTION_PER_MINUTE_MS,
154
+ );
155
+ }
126
156
 
127
157
  // Bounded automatic retry for transient failures (ffmpeg timeout, transient
128
158
  // provider network/5xx errors) — NOT for permanent failures like "no audio
@@ -1075,6 +1105,7 @@ const requestTranscriptAction = defineAction({
1075
1105
  model: BUILDER_GEMINI_TRANSCRIPTION_MODEL,
1076
1106
  diarize: false,
1077
1107
  instructions: SPEECH_ONLY_TRANSCRIPTION_INSTRUCTIONS,
1108
+ timeoutMs: builderTranscriptionTimeoutMs(rec.durationMs),
1078
1109
  });
1079
1110
 
1080
1111
  const segments = (builderResult.segments ?? [])
@@ -116,6 +116,7 @@ export default defineAction({
116
116
  args.filename ??
117
117
  `thumb-${args.recordingId}.${mime.split("/")[1] ?? "png"}`,
118
118
  ownerEmail,
119
+ recordAsset: false,
119
120
  });
120
121
  const url = uploaded?.url ?? args.dataUrl; // fall back to inline storage
121
122
  basePatch.thumbnailUrl = url;
@@ -134,6 +135,7 @@ export default defineAction({
134
135
  mimeType: mime || "image/gif",
135
136
  filename: args.filename ?? `thumb-${args.recordingId}.gif`,
136
137
  ownerEmail,
138
+ recordAsset: false,
137
139
  });
138
140
  const url = uploaded?.url ?? args.dataUrl;
139
141
  basePatch.animatedThumbnailUrl = url;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Update Clips AI preferences for the current user.
3
+ *
4
+ * Merges into the shared `clips-user-prefs` object so playback/transcript
5
+ * preferences from Settings are preserved.
6
+ *
7
+ * Usage:
8
+ * pnpm action update-clips-ai-prefs --includeFullVideoInAi=true
9
+ */
10
+
11
+ import { defineAction } from "@agent-native/core";
12
+ import { getRequestUserEmail } from "@agent-native/core/server/request-context";
13
+ import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
14
+ import { z } from "zod";
15
+
16
+ import {
17
+ CLIPS_USER_PREFS_KEY,
18
+ type ClipsUserPrefs,
19
+ } from "../shared/clips-ai-prefs.js";
20
+
21
+ export default defineAction({
22
+ description:
23
+ "Update Clips AI tool preferences for the current user. When includeFullVideoInAi is true, default title/description generation and AI tools watch the full recording instead of relying on transcript alone. Full-video understanding requires a Gemini model (Builder Gemini or GEMINI_API_KEY).",
24
+ schema: z.object({
25
+ includeFullVideoInAi: z
26
+ .boolean()
27
+ .describe(
28
+ "When true, Clips AI tools watch the full video (screen + audio) with a Gemini model, not just the transcript.",
29
+ ),
30
+ }),
31
+ run: async (args) => {
32
+ const email = getRequestUserEmail();
33
+ if (!email) throw new Error("Sign in required");
34
+
35
+ const existing = ((await getUserSetting(email, CLIPS_USER_PREFS_KEY)) ??
36
+ {}) as ClipsUserPrefs;
37
+ const next: ClipsUserPrefs = {
38
+ ...existing,
39
+ includeFullVideoInAi: args.includeFullVideoInAi,
40
+ };
41
+ await putUserSetting(
42
+ email,
43
+ CLIPS_USER_PREFS_KEY,
44
+ next as Record<string, unknown>,
45
+ );
46
+ return {
47
+ includeFullVideoInAi: next.includeFullVideoInAi === true,
48
+ };
49
+ },
50
+ });
@@ -8,7 +8,7 @@ import {
8
8
  IconChevronDown,
9
9
  IconCheck,
10
10
  IconPlus,
11
- IconBuilding,
11
+ IconUsersGroup,
12
12
  } from "@tabler/icons-react";
13
13
  import { useState } from "react";
14
14
  import { toast } from "sonner";
@@ -86,7 +86,7 @@ export function OrganizationSwitcher({ className }: OrganizationSwitcherProps) {
86
86
  </DropdownMenuLabel>
87
87
  {orgs.length === 0 && (
88
88
  <DropdownMenuItem disabled>
89
- <IconBuilding className="h-3.5 w-3.5 me-2" />
89
+ <IconUsersGroup className="h-3.5 w-3.5 me-2" />
90
90
  <span className="text-xs">
91
91
  {t("organizationSwitcher.noOrganizations")}
92
92
  </span>
@@ -209,7 +209,7 @@ function relativeStartLabel(
209
209
  /**
210
210
  * <UpcomingMeetingCard /> — a not-yet-recorded calendar event (Granola-style).
211
211
  * Recording is a native Clips desktop-app gesture, so the card just opens the
212
- * meeting's notes ("Open") and links out to the call ("Join"). Buttons are
212
+ * meeting's notes ("Open notes") and links out to the call ("Join"). Buttons are
213
213
  * NavLink/<a> siblings (never nested anchors) so the markup stays valid.
214
214
  */
215
215
  export function UpcomingMeetingCard({
@@ -272,6 +272,11 @@ export function UpcomingMeetingCard({
272
272
  <span>– {formatTime(meeting.scheduledEnd)}</span>
273
273
  )}
274
274
  </div>
275
+ <p className="mt-1.5 text-[11px] leading-snug text-muted-foreground">
276
+ {soon || isLive
277
+ ? t("meetingCard.startFromDesktopNow")
278
+ : t("meetingCard.startFromDesktopLater")}
279
+ </p>
275
280
  </NavLink>
276
281
 
277
282
  <div className="flex items-center justify-between gap-2 pt-1">
@@ -302,7 +307,7 @@ export function UpcomingMeetingCard({
302
307
  className="h-7 gap-1 px-2.5 text-xs cursor-pointer"
303
308
  >
304
309
  <NavLink to={`/meetings/${meeting.id}`}>
305
- {isLive ? t("meetingCard.openNotes") : t("meetingCard.open")}
310
+ {t("meetingCard.openNotes")}
306
311
  </NavLink>
307
312
  </Button>
308
313
  </div>
@@ -12,3 +12,12 @@ export function scrubberPositionFromClientX(
12
12
  const ratio = rect.width > 0 ? x / rect.width : 0;
13
13
  return { ms: Math.floor(ratio * durationMs), x };
14
14
  }
15
+
16
+ export function scrubberFillPercent(
17
+ currentMs: number,
18
+ durationMs: number,
19
+ ): number {
20
+ if (!Number.isFinite(currentMs) || !Number.isFinite(durationMs)) return 0;
21
+ if (durationMs <= 0) return 0;
22
+ return Math.max(0, Math.min(100, (currentMs / durationMs) * 100));
23
+ }
@@ -2,7 +2,10 @@ import { useMemo, useRef, useState } from "react";
2
2
 
3
3
  import { cn } from "@/lib/utils";
4
4
 
5
- import { scrubberPositionFromClientX } from "./scrubber-position";
5
+ import {
6
+ scrubberFillPercent,
7
+ scrubberPositionFromClientX,
8
+ } from "./scrubber-position";
6
9
 
7
10
  export interface ScrubberProps {
8
11
  currentMs: number;
@@ -35,7 +38,7 @@ export function Scrubber(props: ScrubberProps) {
35
38
  | null
36
39
  >(null);
37
40
 
38
- const pct = durationMs > 0 ? (currentMs / durationMs) * 100 : 0;
41
+ const pct = scrubberFillPercent(currentMs, durationMs);
39
42
 
40
43
  const recentReactions = useMemo(
41
44
  () => (reactions ? reactions.slice(-50) : []),
@@ -7,6 +7,7 @@ import {
7
7
  } from "@agent-native/core/client";
8
8
  import {
9
9
  IconCode,
10
+ IconChevronDown,
10
11
  IconExternalLink,
11
12
  IconLink,
12
13
  IconMail,
@@ -34,6 +35,11 @@ import {
34
35
  } from "@/components/sharing/share-ui";
35
36
  import { SlackShareHint } from "@/components/sharing/slack-share-hint";
36
37
  import { Button } from "@/components/ui/button";
38
+ import {
39
+ Collapsible,
40
+ CollapsibleContent,
41
+ CollapsibleTrigger,
42
+ } from "@/components/ui/collapsible";
37
43
  import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
38
44
  import { Input } from "@/components/ui/input";
39
45
  import { Label } from "@/components/ui/label";
@@ -87,7 +93,6 @@ export function ShareRecordingPopover({
87
93
  videoUrl,
88
94
  animatedThumbnailUrl,
89
95
  isLoomRecording = false,
90
- hasPassword = false,
91
96
  children,
92
97
  open,
93
98
  onOpenChange,
@@ -106,7 +111,6 @@ export function ShareRecordingPopover({
106
111
  videoUrl={videoUrl}
107
112
  animatedThumbnailUrl={animatedThumbnailUrl}
108
113
  isLoomRecording={isLoomRecording}
109
- hasPassword={hasPassword}
110
114
  />
111
115
  </PopoverContent>
112
116
  </Popover>
@@ -124,7 +128,6 @@ export function ShareRecordingDialog({
124
128
  videoUrl,
125
129
  animatedThumbnailUrl,
126
130
  isLoomRecording = false,
127
- hasPassword = false,
128
131
  open,
129
132
  onOpenChange,
130
133
  }: ShareRecordingDialogProps) {
@@ -143,7 +146,6 @@ export function ShareRecordingDialog({
143
146
  videoUrl={videoUrl}
144
147
  animatedThumbnailUrl={animatedThumbnailUrl}
145
148
  isLoomRecording={isLoomRecording}
146
- hasPassword={hasPassword}
147
149
  reserveCloseButton
148
150
  />
149
151
  </DialogContent>
@@ -157,7 +159,6 @@ function ShareRecordingContent({
157
159
  videoUrl,
158
160
  animatedThumbnailUrl,
159
161
  isLoomRecording = false,
160
- hasPassword = false,
161
162
  reserveCloseButton = false,
162
163
  }: {
163
164
  recordingId: string;
@@ -165,7 +166,6 @@ function ShareRecordingContent({
165
166
  videoUrl?: string | null;
166
167
  animatedThumbnailUrl?: string | null;
167
168
  isLoomRecording?: boolean;
168
- hasPassword?: boolean;
169
169
  reserveCloseButton?: boolean;
170
170
  }) {
171
171
  const t = useT();
@@ -230,7 +230,6 @@ function ShareRecordingContent({
230
230
  videoUrl={videoUrl}
231
231
  animatedThumbnailUrl={animatedThumbnailUrl}
232
232
  isLoomRecording={isLoomRecording}
233
- hasPassword={hasPassword}
234
233
  />
235
234
  </TabsContent>
236
235
 
@@ -269,7 +268,6 @@ function LinkTab({
269
268
  videoUrl,
270
269
  animatedThumbnailUrl,
271
270
  isLoomRecording: isLoomRecordingProp,
272
- hasPassword,
273
271
  }: {
274
272
  recordingId: string;
275
273
  shareUrl: string;
@@ -278,7 +276,6 @@ function LinkTab({
278
276
  videoUrl?: string | null;
279
277
  animatedThumbnailUrl?: string | null;
280
278
  isLoomRecording?: boolean;
281
- hasPassword: boolean;
282
279
  }) {
283
280
  const t = useT();
284
281
  const { setResourceVisibility, isPending } = useResourceVisibilityMutation(
@@ -299,6 +296,7 @@ function LinkTab({
299
296
  const agentLinkRequestIdRef = useRef(0);
300
297
  const [agentContextUrl, setAgentContextUrl] = useState("");
301
298
  const [agentLinkError, setAgentLinkError] = useState(false);
299
+ const [agentShareOpen, setAgentShareOpen] = useState(false);
302
300
 
303
301
  useEffect(() => {
304
302
  createAgentLinkAsyncRef.current = createAgentLink.mutateAsync;
@@ -333,12 +331,21 @@ function LinkTab({
333
331
  setAgentLinkError(false);
334
332
  if (!sharesLoaded) return;
335
333
 
336
- void loadAgentContextUrl();
334
+ if (!isPublic && agentShareOpen) {
335
+ void loadAgentContextUrl();
336
+ }
337
337
 
338
338
  return () => {
339
339
  agentLinkRequestIdRef.current += 1;
340
340
  };
341
- }, [recordingId, visibility, sharesLoaded, loadAgentContextUrl]);
341
+ }, [
342
+ agentShareOpen,
343
+ isPublic,
344
+ loadAgentContextUrl,
345
+ recordingId,
346
+ sharesLoaded,
347
+ visibility,
348
+ ]);
342
349
 
343
350
  const agentShareDisabled =
344
351
  isPending || createAgentLink.isPending || !agentContextUrl;
@@ -366,41 +373,62 @@ function LinkTab({
366
373
  (and a connect link) instead of leaving it buried in Settings. */}
367
374
  {isPublic ? <SlackShareHint canManage={canManage} /> : null}
368
375
 
369
- <div className="space-y-2">
370
- <CopyField
371
- label={t("shareDialog.shareWithAgents")}
372
- value={agentContextUrl}
373
- disabled={agentShareDisabled}
374
- />
375
- {agentLinkError ? (
376
- <div className="flex items-center justify-between gap-2 rounded-md border border-border bg-muted/40 px-3 py-2">
377
- <p className="text-xs text-muted-foreground">
378
- {t("shareDialog.agentLinkUnavailable")}
379
- </p>
376
+ {!isPublic ? (
377
+ <Collapsible open={agentShareOpen} onOpenChange={setAgentShareOpen}>
378
+ <CollapsibleTrigger asChild>
380
379
  <Button
381
380
  type="button"
382
381
  variant="ghost"
383
- size="sm"
384
- className="h-7"
385
- onClick={() => void loadAgentContextUrl()}
386
- disabled={createAgentLink.isPending}
382
+ className="h-auto w-full justify-between px-0 py-1 text-left hover:bg-transparent"
387
383
  >
388
- {t("shareDialog.retryAgentLink")}
384
+ <span className="min-w-0">
385
+ <span className="block text-xs font-medium text-foreground">
386
+ {t("shareDialog.shareWithAgents")}
387
+ </span>
388
+ <span className="mt-0.5 block text-xs font-normal text-muted-foreground">
389
+ {t("shareDialog.agentTokenDescription")}
390
+ </span>
391
+ </span>
392
+ <IconChevronDown
393
+ className={`h-4 w-4 shrink-0 text-muted-foreground transition-transform ${
394
+ agentShareOpen ? "rotate-180" : ""
395
+ }`}
396
+ aria-hidden
397
+ />
389
398
  </Button>
390
- </div>
391
- ) : null}
392
- </div>
393
-
394
- <CopyField
395
- label={t("shareDialog.copyAgentPrompt")}
396
- value={agentPrompt}
397
- disabled={agentShareDisabled}
398
- />
399
-
400
- {agentContextUrl || hasPassword || !isPublic ? (
401
- <p className="text-xs text-muted-foreground">
402
- {t("shareDialog.agentTokenDescription")}
403
- </p>
399
+ </CollapsibleTrigger>
400
+ <CollapsibleContent className="pt-2">
401
+ <div className="space-y-3 rounded-md border border-border bg-muted/30 p-3">
402
+ <CopyField
403
+ label={t("shareDialog.shareWithAgents")}
404
+ value={agentContextUrl}
405
+ disabled={agentShareDisabled}
406
+ />
407
+ {agentLinkError ? (
408
+ <div className="flex items-center justify-between gap-2 rounded-md border border-border bg-background px-3 py-2">
409
+ <p className="text-xs text-muted-foreground">
410
+ {t("shareDialog.agentLinkUnavailable")}
411
+ </p>
412
+ <Button
413
+ type="button"
414
+ variant="ghost"
415
+ size="sm"
416
+ className="h-7"
417
+ onClick={() => void loadAgentContextUrl()}
418
+ disabled={createAgentLink.isPending}
419
+ >
420
+ {t("shareDialog.retryAgentLink")}
421
+ </Button>
422
+ </div>
423
+ ) : null}
424
+ <CopyField
425
+ label={t("shareDialog.copyAgentPrompt")}
426
+ value={agentPrompt}
427
+ disabled={agentShareDisabled}
428
+ />
429
+ </div>
430
+ </CollapsibleContent>
431
+ </Collapsible>
404
432
  ) : null}
405
433
 
406
434
  {!isPublic && canManage ? (
@@ -464,6 +464,21 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
464
464
  bumpControls();
465
465
  setPlayError(null);
466
466
 
467
+ if (
468
+ initialVisibleFrameSeekedRef.current &&
469
+ !hasPlaybackStarted &&
470
+ (!startMs || startMs <= 0) &&
471
+ v.currentTime > 0.05
472
+ ) {
473
+ try {
474
+ v.currentTime = 0;
475
+ setCurrentMs(0);
476
+ } catch {
477
+ // If the browser refuses the rewind, continue with the normal play
478
+ // attempt; playback is still better than blocking on a cosmetic seek.
479
+ }
480
+ }
481
+
467
482
  // A <video> element left in an error state (network/decode/unsupported
468
483
  // format) will just re-reject on `.play()` forever — it needs `.load()`
469
484
  // to reset `readyState`/`error` and re-fetch the source before playback
@@ -497,7 +512,9 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
497
512
  attachPlayPromise,
498
513
  bumpControls,
499
514
  currentMs,
515
+ hasPlaybackStarted,
500
516
  rejectPlayAttempt,
517
+ startMs,
501
518
  ]);
502
519
 
503
520
  const retryPendingPlay = useCallback(
@@ -858,7 +875,6 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
858
875
  initialVisibleFrameSeekedRef.current = true;
859
876
  try {
860
877
  v.currentTime = visibleMs / 1000;
861
- setCurrentMs(visibleMs);
862
878
  return true;
863
879
  } catch {
864
880
  return false;
@@ -1142,6 +1158,17 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1142
1158
  const ct =
1143
1159
  Number.isFinite(raw) && raw >= 0 && raw < 1e7 ? raw : 0;
1144
1160
  const ms = Math.floor(ct * 1000);
1161
+ if (
1162
+ initialVisibleFrameSeekedRef.current &&
1163
+ !hasPlaybackStarted &&
1164
+ !playAttemptPendingRef.current &&
1165
+ v.paused &&
1166
+ (!startMs || startMs <= 0)
1167
+ ) {
1168
+ setCurrentMs(0);
1169
+ onTimeUpdate?.(0, resolvedDurationMs);
1170
+ return;
1171
+ }
1145
1172
  const visibleMs = clampSeek(
1146
1173
  skipExcludedRange(ms, excludedRanges, resolvedDurationMs),
1147
1174
  v,
@@ -1169,10 +1196,20 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1169
1196
  onTimeUpdate?.(ms, resolvedDurationMs);
1170
1197
  }}
1171
1198
  onEnded={() => {
1199
+ const endedMs =
1200
+ resolvedDurationMs > 0
1201
+ ? resolvedDurationMs
1202
+ : videoRef.current &&
1203
+ Number.isFinite(videoRef.current.duration) &&
1204
+ videoRef.current.duration > 0
1205
+ ? Math.round(videoRef.current.duration * 1000)
1206
+ : currentMs;
1207
+ setCurrentMs(endedMs);
1172
1208
  setIsPlaying(false);
1173
1209
  setIsPlayPending(false);
1174
1210
  setIsBuffering(false);
1175
1211
  setIsPreparing(false);
1212
+ onTimeUpdate?.(endedMs, resolvedDurationMs);
1176
1213
  onEnded?.();
1177
1214
  }}
1178
1215
  onError={(e) => {
@@ -4,11 +4,11 @@ import {
4
4
  useT,
5
5
  } from "@agent-native/core/client";
6
6
  import {
7
- IconBuilding,
8
7
  IconCheck,
9
8
  IconCopy,
10
9
  IconLock,
11
10
  IconTrash,
11
+ IconUsersGroup,
12
12
  IconWorld,
13
13
  } from "@tabler/icons-react";
14
14
  import { useQueryClient } from "@tanstack/react-query";
@@ -55,7 +55,7 @@ export const VIS_META: Record<Visibility, { Icon: typeof IconLock }> = {
55
55
  Icon: IconLock,
56
56
  },
57
57
  org: {
58
- Icon: IconBuilding,
58
+ Icon: IconUsersGroup,
59
59
  },
60
60
  public: {
61
61
  Icon: IconWorld,
@@ -308,7 +308,7 @@ export function Avatar({ label, org }: { label: string; org?: boolean }) {
308
308
  className="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-[11px] font-semibold text-muted-foreground"
309
309
  >
310
310
  {org ? (
311
- <IconBuilding size={14} strokeWidth={1.75} />
311
+ <IconUsersGroup size={14} strokeWidth={1.75} />
312
312
  ) : (
313
313
  (label.split("@")[0]?.[0] ?? label[0] ?? "?").toUpperCase()
314
314
  )}
@@ -35,16 +35,11 @@ export function SlackShareHint({ canManage }: { canManage: boolean }) {
35
35
 
36
36
  if (connected) {
37
37
  return (
38
- <div className="flex items-center gap-2.5 rounded-md border border-border bg-muted/40 px-3 py-2">
38
+ <div className="flex items-center gap-2 rounded-md bg-muted/35 px-2.5 py-1.5 text-xs text-muted-foreground">
39
39
  <IconBrandSlack className="h-4 w-4 shrink-0 text-muted-foreground" />
40
- <div className="min-w-0">
41
- <div className="text-xs font-medium">
42
- {t("slackShareHint.playsInline")}
43
- </div>
44
- <p className="text-[11px] text-muted-foreground">
45
- {t("slackShareHint.connectedDescription")}
46
- </p>
47
- </div>
40
+ <span className="min-w-0 truncate">
41
+ {t("slackShareHint.playsInline")}
42
+ </span>
48
43
  </div>
49
44
  );
50
45
  }
@@ -59,18 +54,13 @@ export function SlackShareHint({ canManage }: { canManage: boolean }) {
59
54
  return (
60
55
  <a
61
56
  href={appPath("/settings#slack")}
62
- className="flex items-center gap-2.5 rounded-md border border-border px-3 py-2 transition-colors hover:bg-muted/50"
57
+ className="flex items-center gap-2 rounded-md bg-muted/35 px-2.5 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-muted/55"
63
58
  >
64
59
  <IconBrandSlack className="h-4 w-4 shrink-0 text-muted-foreground" />
65
- <div className="min-w-0 flex-1">
66
- <div className="text-xs font-medium">
67
- {t("slackShareHint.makeInline")}
68
- </div>
69
- <p className="text-[11px] text-muted-foreground">
70
- {t("slackShareHint.connectDescription")}
71
- </p>
72
- </div>
73
- <span className="shrink-0 text-xs font-medium text-primary">
60
+ <span className="min-w-0 flex-1 truncate">
61
+ {t("slackShareHint.makeInline")}
62
+ </span>
63
+ <span className="shrink-0 font-medium text-primary">
74
64
  {t("slackShareHint.connect")}
75
65
  </span>
76
66
  </a>