@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
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-07
4
+ ---
5
+
6
+ Zoom stays selected after connecting it from a draft event.
@@ -181,6 +181,7 @@ export const getEvent = defineEventHandler(async (event: H3Event) => {
181
181
  responseStatus: a.responseStatus || undefined,
182
182
  organizer: a.organizer || undefined,
183
183
  self: a.self || undefined,
184
+ optional: a.optional === true ? true : undefined,
184
185
  })),
185
186
  remindersUseDefault: evt.reminders?.useDefault ?? true,
186
187
  reminders: evt.reminders?.overrides?.map((r: any) => ({
@@ -228,6 +228,7 @@ function mapAttendees(event: any): CalendarEvent["attendees"] {
228
228
  responseStatus: attendee.responseStatus || undefined,
229
229
  organizer: attendee.organizer || undefined,
230
230
  self: attendee.self || undefined,
231
+ optional: attendee.optional === true ? true : undefined,
231
232
  }));
232
233
  }
233
234
 
@@ -1094,6 +1095,7 @@ export async function createEvent(
1094
1095
  email: a.email,
1095
1096
  ...(a.displayName ? { displayName: a.displayName } : {}),
1096
1097
  ...(a.comment ? { comment: a.comment } : {}),
1098
+ ...(a.optional === true ? { optional: true } : {}),
1097
1099
  }));
1098
1100
  }
1099
1101
 
@@ -1204,6 +1206,7 @@ export async function updateEvent(
1204
1206
  ...(a.displayName ? { displayName: a.displayName } : {}),
1205
1207
  ...(a.comment ? { comment: a.comment } : {}),
1206
1208
  ...(a.responseStatus ? { responseStatus: a.responseStatus } : {}),
1209
+ ...(a.optional === true ? { optional: true } : { optional: false }),
1207
1210
  }));
1208
1211
  }
1209
1212
  if (eventPatch.recurrence !== undefined) {
@@ -1241,6 +1244,7 @@ export async function updateEvent(
1241
1244
  responseStatus: a.responseStatus || undefined,
1242
1245
  organizer: a.organizer || undefined,
1243
1246
  self: a.self || undefined,
1247
+ optional: a.optional === true ? true : undefined,
1244
1248
  })),
1245
1249
  };
1246
1250
  }
@@ -107,7 +107,7 @@ Provider-specific Calendar actions are shortcuts, not limits. If a first-class a
107
107
  - \`pnpm action search-events --query "term" --from YYYY-MM-DD --to YYYY-MM-DD\` — Convenience bounded search by title, attendees, organizer, location, or description. For relationship history, all-calendar discovery, exact attendee/domain search, or custom pagination, prefer provider-api-request with provider=google_calendar.
108
108
  - \`pnpm action provider-api-catalog\` / \`provider-api-docs\` / \`provider-api-request\` — Inspect and call the real Google Calendar, Apollo, Gong, HubSpot, and Pylon APIs directly. For Google Calendar events.list pagination use provider=google_calendar, path=/calendars/primary/events, query={...}, fetchAllPages={cursorPath:"nextPageToken",cursorParam:"pageToken",itemsPath:"items"}. For large relationship-history scans, pass stageAs and pagination={nextCursorPath:"nextPageToken",cursorParam:"pageToken",maxPages:N} with itemsPath="items", then use query-staged-dataset.
109
109
  - \`pnpm action create-event --title "..." --start "ISO" --end "ISO"\` — Create a new event. Use \`--eventType outOfOffice\` for OOO, \`--eventType focusTime\` for focus time, \`--eventType workingLocation\` for working location, \`--transparency transparent\` to show as Free, \`--visibility private\` for private events, \`--startTimeZone America/Los_Angeles\` for timezone anchoring, \`--colorId 9\` for Google event color, \`--reminders '[{"method":"popup","minutes":10}]'\` for alerts, and \`--attachments '[{"fileUrl":"https://...","title":"Agenda"}]'\` for Drive/HTTPS file links.
110
- - \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests, or generated video links. Use \`addAttendees\` when inviting more people so existing RSVP metadata is preserved. Use \`--scope all\` to update an entire recurring series from one occurrence.
110
+ - \`pnpm action update-event --id "google-..." --transparency opaque|transparent --visibility default|public|private --reminderMinutes 10 --addAttendees "alice@example.com" --scope single|all\` — Update event availability, visibility, reminders, timezone, color, attachments, recurrence, guests, or generated video links. Use \`addAttendees\` when inviting more people so existing RSVP metadata is preserved. Pass attendee objects with \`optional:true\` to mark optional guests. Use \`--scope all\` to update an entire recurring series from one occurrence.
111
111
  - \`pnpm action navigate --view=calendar --calendarViewMode=day\` — Navigate the UI (day/week/month views, dates)
112
112
  - \`pnpm action navigate --view=calendar --date=YYYY-MM-DD\` — Navigate to a specific date
113
113
  - \`pnpm action navigate --view=availability\` — Show availability settings
@@ -45,6 +45,8 @@ export interface CalendarEvent {
45
45
  responseStatus?: "accepted" | "declined" | "tentative" | "needsAction";
46
46
  organizer?: boolean;
47
47
  self?: boolean;
48
+ /** When true, the attendee is optional (Google Calendar `optional`). */
49
+ optional?: boolean;
48
50
  }>;
49
51
  reminders?: Array<{ method: "popup" | "email"; minutes: number }>;
50
52
  /** Whether this event uses the calendar's default reminder policy. */
@@ -27,15 +27,41 @@ The agent is already the user's primary interface — it has full project contex
27
27
 
28
28
  | Feature | Trigger | What the action does |
29
29
  | ------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
30
- | Default title | Native transcript is saved and the recording still has the default title | `regenerate-title --recordingId=<id>`writes `clips-ai-request-:id`; the UI bridge sends it to the agent chat |
30
+ | Include full video | User toggles "Include full video" in the AI tools menu | `update-clips-ai-prefs --includeFullVideoInAi=true\|false`stored in `clips-user-prefs`; default off |
31
+ | Default title | Native transcript is saved and the recording still has the default title | `regenerate-title --recordingId=<id>` → writes `clips-ai-request-:id`; the UI bridge sends it to the agent chat. If Include full video is on, skips the transcript-only Gemini fast path and always delegates so the agent watches the recording |
31
32
  | Manual title suggestion | User asks the agent "rename this" | Agent reads transcript and calls `update-recording --id=<id> --title=...` |
32
- | Summary / description | Upload completes, or user clicks "Summarize" | `generate-ai-metadata --id=<id> --kind=summary` → agent writes `update-recording --description=...` |
33
- | Chapters | User clicks "Add chapters" or transcript > 3 minutes | `generate-chapters --id=<id>` → agent writes `chapters_json` |
33
+ | Summary / description | Upload completes, or user clicks "Summarize" / "Regenerate description" | `regenerate-summary` / `generate-ai-metadata --id=<id> --kind=summary` → agent writes `update-recording --description=...`. With Include full video, agent must watch the clip, not transcript alone |
34
+ | Chapters | User clicks "Add chapters" or transcript > 3 minutes | `generate-chapters --id=<id>` / `regenerate-chapters` → agent writes `chapters_json` (same full-video preference) |
34
35
  | Tags | On upload complete | `generate-ai-metadata --id=<id> --kind=tags` → agent inserts `recording_tags` rows |
35
36
  | Filler-word removal | User clicks "Remove ums and uhs" | `generate-filler-removal --id=<id>` → agent writes proposed cuts into `editor-draft` for user review |
36
37
  | Comment auto-reply | User types "reply with …" in the agent chat | agent calls `add-comment` directly |
37
38
  | **Transcription** | On upload complete (automatic) + live during recording | `request-transcript` → native (Web Speech / macOS SFSpeech) first, then cloud fallback Builder.io managed Gemini → Groq; `save-browser-transcript` for instant Web Speech result — see "Transcription" section below |
38
39
 
40
+ ## Include full video
41
+
42
+ Screen recordings often have thin or misleading audio ("real quick", "um this
43
+ thing"). Titles, descriptions, chapters, and workflow docs (PR / SOP / ticket /
44
+ email) are more accurate when the agent can **see** the UI, product names, and
45
+ on-screen text.
46
+
47
+ - Preference key: `includeFullVideoInAi` on user setting `clips-user-prefs`.
48
+ - UI: checkbox at the top of the recording-page **AI tools** dropdown (copy
49
+ notes Gemini-only).
50
+ - Actions: `get-clips-ai-prefs`, `update-clips-ai-prefs`.
51
+ - **Gemini only:** sending / understanding the full recording video requires a
52
+ Gemini model (Builder Gemini or `GEMINI_API_KEY`). Claude and OpenAI cannot
53
+ ingest the MP4/WebM. When the preference is on, the AI-request bridge prefers
54
+ Builder `gemini-3-5-flash` for that turn.
55
+ - When on, queued `clips-ai-request-*` messages include instructions to attach
56
+ or upload the recording to Gemini when possible, otherwise use
57
+ `get-recording-player-data` / `create-recording-agent-link` and follow
58
+ recommended frames / the frame API across the timeline — not transcript only.
59
+ - Default title generation also honors this: `regenerate-title` skips the
60
+ transcript-only Gemini cleanup path and always queues the agent.
61
+
62
+ Do not invent a parallel "video LLM" path in the UI. Keep the preference on the
63
+ shared user-prefs object and keep delegation through the agent chat.
64
+
39
65
  ## The delegation pattern
40
66
 
41
67
  From an action, kick work over to the agent chat in **background mode** so the user doesn't see a new message bubble mid-playback:
@@ -111,7 +111,11 @@ export default defineAction({
111
111
  await setResumableSession(id, {
112
112
  providerId: uploadProvider.id,
113
113
  sessionId: session.sessionId,
114
- meta: { ...session.meta, skipCompressionWait: true },
114
+ meta: {
115
+ ...session.meta,
116
+ skipCompressionWait: true,
117
+ recordAsset: false,
118
+ },
115
119
  bytesUploaded: 0,
116
120
  lastCommittedIndex: -1,
117
121
  });
@@ -98,6 +98,9 @@ function concatBytes(parts: Uint8Array[]): Uint8Array {
98
98
 
99
99
  const RECORDING_TOO_LARGE_REASON =
100
100
  "Recording is too large to process after automatic compression. Please update the app and try again, or record a shorter clip.";
101
+ const MEDIA_SERVE_VERIFICATION_TIMEOUT_MS = 8_000;
102
+ const MEDIA_SERVE_VERIFICATION_ATTEMPTS = 3;
103
+ const MEDIA_SERVE_VERIFICATION_BACKOFF_MS = 350;
101
104
 
102
105
  function stateNumber(
103
106
  value: Record<string, unknown> | null | undefined,
@@ -124,6 +127,78 @@ const cliBoolean = z.preprocess((value) => {
124
127
  return value;
125
128
  }, z.boolean());
126
129
 
130
+ function sleep(ms: number): Promise<void> {
131
+ return new Promise((resolve) => setTimeout(resolve, ms));
132
+ }
133
+
134
+ function shouldVerifyServedMediaUrl(value: string): boolean {
135
+ try {
136
+ const url = new URL(value);
137
+ return url.protocol === "http:" || url.protocol === "https:";
138
+ } catch {
139
+ return false;
140
+ }
141
+ }
142
+
143
+ async function responseHasReadableMediaBytes(
144
+ response: Response,
145
+ ): Promise<boolean> {
146
+ const reader = response.body?.getReader();
147
+ if (!reader) {
148
+ const body = await response.arrayBuffer().catch(() => new ArrayBuffer(0));
149
+ return body.byteLength > 0;
150
+ }
151
+
152
+ try {
153
+ const { value } = await reader.read();
154
+ return (value?.byteLength ?? 0) > 0;
155
+ } catch {
156
+ return false;
157
+ } finally {
158
+ await reader.cancel().catch(() => undefined);
159
+ }
160
+ }
161
+
162
+ async function verifyServedMediaUrl(videoUrl: string): Promise<void> {
163
+ if (!shouldVerifyServedMediaUrl(videoUrl)) return;
164
+
165
+ let lastFailure = "media URL did not serve readable bytes";
166
+ for (
167
+ let attempt = 1;
168
+ attempt <= MEDIA_SERVE_VERIFICATION_ATTEMPTS;
169
+ attempt++
170
+ ) {
171
+ const controller = new AbortController();
172
+ const timeout = setTimeout(
173
+ () => controller.abort(),
174
+ MEDIA_SERVE_VERIFICATION_TIMEOUT_MS,
175
+ );
176
+ try {
177
+ const response = await fetch(videoUrl, {
178
+ method: "GET",
179
+ headers: { Range: "bytes=0-1023" },
180
+ signal: controller.signal,
181
+ });
182
+ const statusOk = response.status === 200 || response.status === 206;
183
+ if (statusOk && (await responseHasReadableMediaBytes(response))) {
184
+ return;
185
+ }
186
+ lastFailure = `media URL returned HTTP ${response.status}`;
187
+ if (response.status < 500) break;
188
+ } catch (err) {
189
+ lastFailure = err instanceof Error ? err.message : String(err);
190
+ } finally {
191
+ clearTimeout(timeout);
192
+ }
193
+
194
+ if (attempt < MEDIA_SERVE_VERIFICATION_ATTEMPTS) {
195
+ await sleep(MEDIA_SERVE_VERIFICATION_BACKOFF_MS * attempt);
196
+ }
197
+ }
198
+
199
+ throw new Error(`Upload was stored-but-unservable: ${lastFailure}`);
200
+ }
201
+
127
202
  function queueBackgroundBuilderCompression(args: {
128
203
  recordingId: string;
129
204
  ownerEmail: string;
@@ -142,6 +217,44 @@ function queueBackgroundBuilderCompression(args: {
142
217
  });
143
218
  }
144
219
 
220
+ async function failStoredButUnservableRecording(params: {
221
+ id: string;
222
+ ownerEmail: string;
223
+ failureReason: string;
224
+ }): Promise<void> {
225
+ const { id, ownerEmail, failureReason } = params;
226
+ const now = new Date().toISOString();
227
+ const db = getDb();
228
+ await db
229
+ .update(schema.recordings)
230
+ .set({
231
+ status: "failed",
232
+ failureReason,
233
+ updatedAt: now,
234
+ })
235
+ .where(
236
+ and(
237
+ eq(schema.recordings.id, id),
238
+ ownerEmailMatches(schema.recordings.ownerEmail, ownerEmail),
239
+ ),
240
+ );
241
+ const uploadStateRaw = await readAppState(`recording-upload-${id}`).catch(
242
+ () => null,
243
+ );
244
+ const uploadState =
245
+ uploadStateRaw && typeof uploadStateRaw === "object"
246
+ ? (uploadStateRaw as Record<string, unknown>)
247
+ : {};
248
+ await writeAppState(`recording-upload-${id}`, {
249
+ ...uploadState,
250
+ recordingId: id,
251
+ status: "failed",
252
+ failureReason,
253
+ updatedAt: now,
254
+ });
255
+ await writeAppState("refresh-signal", { ts: Date.now() });
256
+ }
257
+
145
258
  // Flip recording to 'ready', seed transcript row, fire background transcript,
146
259
  // emit clip.created. Used by both the resumable and buffered upload paths.
147
260
  async function markRecordingReady(params: {
@@ -483,9 +596,21 @@ export default defineAction({
483
596
  typeof resumableSession.meta.filename === "string"
484
597
  ? resumableSession.meta.filename
485
598
  : "",
486
- { skipCompressionWait: true },
599
+ { skipCompressionWait: true, recordAsset: false },
487
600
  );
488
601
  debugLog("[finalize] resumable upload completed", { id, videoUrl });
602
+ try {
603
+ await verifyServedMediaUrl(videoUrl);
604
+ } catch (err) {
605
+ const failureReason =
606
+ err instanceof Error ? err.message : String(err);
607
+ await failStoredButUnservableRecording({
608
+ id,
609
+ ownerEmail,
610
+ failureReason,
611
+ });
612
+ throw err;
613
+ }
489
614
  const result = await markRecordingReady({
490
615
  ...readyParams,
491
616
  videoUrl,
@@ -580,6 +705,7 @@ export default defineAction({
580
705
  })
581
706
  .where(eq(schema.recordings.id, id));
582
707
  await writeAppState(`recording-upload-${id}`, {
708
+ ...(uploadState ?? {}),
583
709
  recordingId: id,
584
710
  status: "failed",
585
711
  failureReason,
@@ -841,6 +967,7 @@ export default defineAction({
841
967
  mimeType,
842
968
  ownerEmail,
843
969
  skipCompressionWait: true,
970
+ recordAsset: false,
844
971
  });
845
972
  } catch (err) {
846
973
  // Capture structured context so a "Builder.io upload failed (500)" can
@@ -993,6 +1120,18 @@ export default defineAction({
993
1120
  videoUrl: upload.url,
994
1121
  bytes: uploadData.byteLength,
995
1122
  });
1123
+ try {
1124
+ await verifyServedMediaUrl(upload.url);
1125
+ } catch (err) {
1126
+ chunkKeysToPurge = [];
1127
+ const failureReason = err instanceof Error ? err.message : String(err);
1128
+ await failStoredButUnservableRecording({
1129
+ id,
1130
+ ownerEmail,
1131
+ failureReason,
1132
+ });
1133
+ throw err;
1134
+ }
996
1135
  const result = await markRecordingReady({
997
1136
  ...readyParams,
998
1137
  // Use the audio-probe-corrected value, not the raw client claim in
@@ -21,6 +21,8 @@ import { eq } from "drizzle-orm";
21
21
  import { z } from "zod";
22
22
 
23
23
  import { getDb, schema } from "../server/db/index.js";
24
+ import { withFullVideoAiInstructions } from "../shared/clips-ai-prefs.js";
25
+ import { readIncludeFullVideoInAi } from "./lib/clips-ai-prefs.js";
24
26
 
25
27
  const KIND_PROMPTS = {
26
28
  pr: `Compose a pull-request description. Include:
@@ -51,7 +53,7 @@ Keep it concise, warm, and professional.`,
51
53
 
52
54
  export default defineAction({
53
55
  description:
54
- "Ask the agent to generate a structured workflow doc (pr/sop/ticket/email) from this recording's transcript. The agent writes the result to clips-workflow-<recordingId> in application_state.",
56
+ "Ask the agent to generate a structured workflow doc (pr/sop/ticket/email) from this recording's transcript (and the full video when Include full video is enabled). The agent writes the result to clips-workflow-<recordingId> in application_state.",
55
57
  schema: z.object({
56
58
  recordingId: z.string().describe("Recording ID"),
57
59
  kind: z.enum(["pr", "sop", "ticket", "email"]).describe("Workflow kind"),
@@ -74,6 +76,7 @@ export default defineAction({
74
76
  .limit(1);
75
77
 
76
78
  const stateKey = `clips-workflow-${args.recordingId}`;
79
+ const includeFullVideoInAi = await readIncludeFullVideoInAi();
77
80
 
78
81
  // Seed the output state with a "generating" placeholder so the UI can show
79
82
  // a loading state immediately.
@@ -84,6 +87,14 @@ export default defineAction({
84
87
  requestedAt: new Date().toISOString(),
85
88
  } as any);
86
89
 
90
+ const baseMessage =
91
+ `Generate a ${args.kind.toUpperCase()} workflow document from recording ${args.recordingId} ` +
92
+ `(title: "${rec.title}"). Read the transcript from this request's context. ` +
93
+ `${KIND_PROMPTS[args.kind]} ` +
94
+ `Then write the final markdown to application_state key "${stateKey}" as ` +
95
+ `\`{ kind: "${args.kind}", status: "ready", content: "...", recordingId: "${args.recordingId}" }\`. ` +
96
+ `Finish by replying in chat with the same generated markdown so the user can read it immediately.`;
97
+
87
98
  const request = {
88
99
  kind: "generate-workflow" as const,
89
100
  workflowKind: args.kind,
@@ -95,13 +106,12 @@ export default defineAction({
95
106
  transcriptText: transcript?.fullText ?? "",
96
107
  stateKey,
97
108
  instructions: KIND_PROMPTS[args.kind],
98
- message:
99
- `Generate a ${args.kind.toUpperCase()} workflow document from recording ${args.recordingId} ` +
100
- `(title: "${rec.title}"). Read the transcript from this request's context. ` +
101
- `${KIND_PROMPTS[args.kind]} ` +
102
- `Then write the final markdown to application_state key "${stateKey}" as ` +
103
- `\`{ kind: "${args.kind}", status: "ready", content: "...", recordingId: "${args.recordingId}" }\`. ` +
104
- `Finish by replying in chat with the same generated markdown so the user can read it immediately.`,
109
+ includeFullVideoInAi,
110
+ message: withFullVideoAiInstructions(
111
+ baseMessage,
112
+ args.recordingId,
113
+ includeFullVideoInAi,
114
+ ),
105
115
  };
106
116
 
107
117
  await writeAppState(`clips-ai-request-${args.recordingId}`, request as any);
@@ -115,6 +125,7 @@ export default defineAction({
115
125
  recordingId: args.recordingId,
116
126
  kind: args.kind,
117
127
  stateKey,
128
+ includeFullVideoInAi,
118
129
  };
119
130
  },
120
131
  });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Read Clips AI preferences for the current user (include-full-video switch).
3
+ *
4
+ * Usage:
5
+ * pnpm action get-clips-ai-prefs
6
+ */
7
+
8
+ import { defineAction } from "@agent-native/core";
9
+ import { getRequestUserEmail } from "@agent-native/core/server/request-context";
10
+ import { getUserSetting } from "@agent-native/core/settings";
11
+ import { z } from "zod";
12
+
13
+ import {
14
+ CLIPS_USER_PREFS_KEY,
15
+ isIncludeFullVideoInAiEnabled,
16
+ type ClipsUserPrefs,
17
+ } from "../shared/clips-ai-prefs.js";
18
+
19
+ export default defineAction({
20
+ description:
21
+ "Get Clips AI tool preferences for the current user, including whether AI tools should watch the full recording with Gemini instead of transcript-only.",
22
+ schema: z.object({}),
23
+ http: { method: "GET" },
24
+ readOnly: true,
25
+ run: async () => {
26
+ const email = getRequestUserEmail();
27
+ if (!email) {
28
+ return { includeFullVideoInAi: false };
29
+ }
30
+ const prefs = ((await getUserSetting(email, CLIPS_USER_PREFS_KEY)) ??
31
+ {}) as ClipsUserPrefs;
32
+ return {
33
+ includeFullVideoInAi: isIncludeFullVideoInAiEnabled(prefs),
34
+ };
35
+ },
36
+ });
@@ -297,6 +297,7 @@ export default defineAction({
297
297
  mimeType: media.mimeType,
298
298
  ownerEmail,
299
299
  skipCompressionWait: true,
300
+ recordAsset: false,
300
301
  });
301
302
 
302
303
  const recordingValues = buildRecordingValues(media.sizeBytes);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Server helper: load the current user's "include full video in AI" preference.
3
+ */
4
+
5
+ import { getRequestUserEmail } from "@agent-native/core/server/request-context";
6
+ import { getUserSetting } from "@agent-native/core/settings";
7
+
8
+ import {
9
+ CLIPS_USER_PREFS_KEY,
10
+ isIncludeFullVideoInAiEnabled,
11
+ type ClipsUserPrefs,
12
+ } from "../../shared/clips-ai-prefs.js";
13
+
14
+ export async function readIncludeFullVideoInAi(
15
+ email?: string | null,
16
+ ): Promise<boolean> {
17
+ const userEmail = email ?? getRequestUserEmail();
18
+ if (!userEmail) return false;
19
+ try {
20
+ const prefs = (await getUserSetting(
21
+ userEmail,
22
+ CLIPS_USER_PREFS_KEY,
23
+ )) as ClipsUserPrefs | null;
24
+ return isIncludeFullVideoInAiEnabled(prefs);
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
@@ -219,6 +219,7 @@ export async function ensureRecordingSeekable(params: {
219
219
  mimeType,
220
220
  ownerEmail,
221
221
  skipCompressionWait: true,
222
+ recordAsset: false,
222
223
  });
223
224
 
224
225
  if (!upload?.url) {
@@ -15,10 +15,12 @@ import { eq } from "drizzle-orm";
15
15
  import { z } from "zod";
16
16
 
17
17
  import { getDb, schema } from "../server/db/index.js";
18
+ import { withFullVideoAiInstructions } from "../shared/clips-ai-prefs.js";
19
+ import { readIncludeFullVideoInAi } from "./lib/clips-ai-prefs.js";
18
20
 
19
21
  export default defineAction({
20
22
  description:
21
- "Ask the agent to generate chapters for this recording based on its transcript. The agent identifies topic transitions and calls set-chapters.",
23
+ "Ask the agent to generate chapters for this recording based on its transcript (and the full video when Include full video is enabled). The agent identifies topic transitions and calls set-chapters.",
22
24
  schema: z.object({
23
25
  recordingId: z.string().describe("Recording ID"),
24
26
  }),
@@ -39,6 +41,13 @@ export default defineAction({
39
41
  .where(eq(schema.recordingTranscripts.recordingId, args.recordingId))
40
42
  .limit(1);
41
43
 
44
+ const includeFullVideoInAi = await readIncludeFullVideoInAi();
45
+ const baseMessage =
46
+ `Generate chapters for recording ${args.recordingId} (duration ${rec.durationMs}ms). ` +
47
+ `Read the transcript segments in this request's context, identify topic transitions, ` +
48
+ `and call \`set-chapters --recordingId=${args.recordingId} --chapters='[{ "startMs": 0, "title": "Intro" }, ...]'\`. ` +
49
+ `Aim for 3–8 chapters. Each chapter title should be 3–6 words and capture the essence of that section.`;
50
+
42
51
  const request = {
43
52
  kind: "regenerate-chapters" as const,
44
53
  recordingId: args.recordingId,
@@ -47,11 +56,12 @@ export default defineAction({
47
56
  transcriptStatus: transcript?.status ?? "pending",
48
57
  segmentsJson: transcript?.segmentsJson ?? "[]",
49
58
  transcriptText: transcript?.fullText ?? "",
50
- message:
51
- `Generate chapters for recording ${args.recordingId} (duration ${rec.durationMs}ms). ` +
52
- `Read the transcript segments in this request's context, identify topic transitions, ` +
53
- `and call \`set-chapters --recordingId=${args.recordingId} --chapters='[{ "startMs": 0, "title": "Intro" }, ...]'\`. ` +
54
- `Aim for 3–8 chapters. Each chapter title should be 3–6 words and capture the essence of that section.`,
59
+ includeFullVideoInAi,
60
+ message: withFullVideoAiInstructions(
61
+ baseMessage,
62
+ args.recordingId,
63
+ includeFullVideoInAi,
64
+ ),
55
65
  };
56
66
 
57
67
  await writeAppState(`clips-ai-request-${args.recordingId}`, request as any);
@@ -60,6 +70,10 @@ export default defineAction({
60
70
  console.log(
61
71
  `Delegation queued: regenerate-chapters for ${args.recordingId}`,
62
72
  );
63
- return { queued: true, recordingId: args.recordingId };
73
+ return {
74
+ queued: true,
75
+ recordingId: args.recordingId,
76
+ includeFullVideoInAi,
77
+ };
64
78
  },
65
79
  });
@@ -14,10 +14,12 @@ import { eq } from "drizzle-orm";
14
14
  import { z } from "zod";
15
15
 
16
16
  import { getDb, schema } from "../server/db/index.js";
17
+ import { withFullVideoAiInstructions } from "../shared/clips-ai-prefs.js";
18
+ import { readIncludeFullVideoInAi } from "./lib/clips-ai-prefs.js";
17
19
 
18
20
  export default defineAction({
19
21
  description:
20
- "Ask the agent to regenerate this recording's description/summary based on its transcript.",
22
+ "Ask the agent to regenerate this recording's description/summary based on its transcript (and the full video when Include full video is enabled).",
21
23
  schema: z.object({
22
24
  recordingId: z.string().describe("Recording ID"),
23
25
  }),
@@ -42,7 +44,12 @@ export default defineAction({
42
44
  .where(eq(schema.recordingTranscripts.recordingId, args.recordingId))
43
45
  .limit(1);
44
46
 
45
- if (transcript?.status !== "ready" || !transcript.fullText?.trim()) {
47
+ const includeFullVideoInAi = await readIncludeFullVideoInAi();
48
+
49
+ if (
50
+ !includeFullVideoInAi &&
51
+ (transcript?.status !== "ready" || !transcript.fullText?.trim())
52
+ ) {
46
53
  return {
47
54
  updated: false,
48
55
  skipped: true,
@@ -52,6 +59,12 @@ export default defineAction({
52
59
  };
53
60
  }
54
61
 
62
+ const baseMessage =
63
+ `Regenerate the description for recording ${args.recordingId}. ` +
64
+ `Read the transcript in this request's context and call ` +
65
+ `\`update-recording --id=${args.recordingId} --description="..."\` with a 2–4 ` +
66
+ `sentence summary of what the recording covers. Title: "${rec.title}".`;
67
+
55
68
  const request = {
56
69
  kind: "regenerate-summary" as const,
57
70
  recordingId: args.recordingId,
@@ -60,11 +73,12 @@ export default defineAction({
60
73
  currentDescription: rec.description,
61
74
  transcriptStatus: transcript?.status ?? "pending",
62
75
  transcriptText: transcript?.fullText ?? "",
63
- message:
64
- `Regenerate the description for recording ${args.recordingId}. ` +
65
- `Read the transcript in this request's context and call ` +
66
- `\`update-recording --id=${args.recordingId} --description="..."\` with a 2–4 ` +
67
- `sentence summary of what the recording covers. Title: "${rec.title}".`,
76
+ includeFullVideoInAi,
77
+ message: withFullVideoAiInstructions(
78
+ baseMessage,
79
+ args.recordingId,
80
+ includeFullVideoInAi,
81
+ ),
68
82
  };
69
83
 
70
84
  await writeAppState(`clips-ai-request-${args.recordingId}`, request as any);
@@ -73,6 +87,10 @@ export default defineAction({
73
87
  console.log(
74
88
  `Delegation queued: regenerate-summary for ${args.recordingId}`,
75
89
  );
76
- return { queued: true, recordingId: args.recordingId };
90
+ return {
91
+ queued: true,
92
+ recordingId: args.recordingId,
93
+ includeFullVideoInAi,
94
+ };
77
95
  },
78
96
  });