@agent-native/core 0.90.2 → 0.90.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. package/bin/agent-native.js +25 -3
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +21 -0
  4. package/corpus/core/bin/agent-native.js +25 -3
  5. package/corpus/core/docs/content/agent-native-toolkit.mdx +87 -80
  6. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  7. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  8. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  9. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  10. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  11. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  12. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  13. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  14. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  15. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  16. package/corpus/core/docs/content/toolkit-agent-ux.mdx +43 -0
  17. package/corpus/core/docs/content/toolkit-app-adapters.mdx +9 -0
  18. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +12 -0
  19. package/corpus/core/docs/content/toolkit-collaboration.mdx +74 -0
  20. package/corpus/core/docs/content/toolkit-command-navigation.mdx +106 -0
  21. package/corpus/core/docs/content/toolkit-comments-review.mdx +98 -0
  22. package/corpus/core/docs/content/toolkit-history.mdx +95 -0
  23. package/corpus/core/docs/content/toolkit-observability.mdx +41 -0
  24. package/corpus/core/docs/content/toolkit-org-team.mdx +80 -0
  25. package/corpus/core/docs/content/toolkit-resources.mdx +57 -0
  26. package/corpus/core/docs/content/toolkit-settings.mdx +65 -0
  27. package/corpus/core/docs/content/toolkit-setup-connections.mdx +109 -0
  28. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +18 -6
  29. package/corpus/core/docs/content/toolkit-sharing.mdx +81 -0
  30. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +9 -0
  31. package/corpus/core/docs/content/toolkit-ui.mdx +9 -0
  32. package/corpus/core/package.json +35 -1
  33. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +19 -1
  34. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -1
  35. package/corpus/core/src/agent/engine/index.ts +1 -0
  36. package/corpus/core/src/agent/engine/registry.ts +86 -18
  37. package/corpus/core/src/agent/production-agent.ts +37 -6
  38. package/corpus/core/src/cli/create.ts +35 -0
  39. package/corpus/core/src/cli/design-connect.ts +248 -0
  40. package/corpus/core/src/cli/index.ts +84 -7
  41. package/corpus/core/src/cli/workspacify.ts +34 -0
  42. package/corpus/core/src/client/command-navigation/index.ts +15 -0
  43. package/corpus/core/src/client/comments-review/index.ts +1 -0
  44. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +175 -0
  45. package/corpus/core/src/client/history/index.ts +21 -0
  46. package/corpus/core/src/client/history/use-history.ts +114 -0
  47. package/corpus/core/src/client/index.ts +84 -9
  48. package/corpus/core/src/client/org/OrgSwitcher.tsx +6 -6
  49. package/corpus/core/src/client/org/RequireActiveOrg.tsx +2 -2
  50. package/corpus/core/src/client/org/TeamPage.tsx +3 -3
  51. package/corpus/core/src/client/org/hooks.ts +32 -0
  52. package/corpus/core/src/client/org/index.ts +30 -1
  53. package/corpus/core/src/client/org-team/index.ts +1 -0
  54. package/corpus/core/src/client/review/ReviewStatusBadge.tsx +39 -0
  55. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +278 -0
  56. package/corpus/core/src/client/review/index.ts +30 -0
  57. package/corpus/core/src/client/review/use-review.ts +152 -0
  58. package/corpus/core/src/client/settings/index.ts +11 -1
  59. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +94 -0
  60. package/corpus/core/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  61. package/corpus/core/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  62. package/corpus/core/src/client/setup-connections/index.ts +46 -0
  63. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -14
  64. package/corpus/core/src/client/sharing/ShareDialog.tsx +3 -3
  65. package/corpus/core/src/command-navigation/actions.ts +100 -0
  66. package/corpus/core/src/command-navigation/index.ts +12 -0
  67. package/corpus/core/src/comments-review/index.ts +1 -0
  68. package/corpus/core/src/file-upload/builder.ts +24 -3
  69. package/corpus/core/src/file-upload/types.ts +3 -1
  70. package/corpus/core/src/history/actions/create-resource-version.ts +92 -0
  71. package/corpus/core/src/history/actions/get-resource-version.ts +60 -0
  72. package/corpus/core/src/history/actions/list-resource-history.ts +53 -0
  73. package/corpus/core/src/history/actions/list-resource-versions.ts +43 -0
  74. package/corpus/core/src/history/actions/restore-resource-version.ts +96 -0
  75. package/corpus/core/src/history/index.ts +26 -0
  76. package/corpus/core/src/history/registry.ts +111 -0
  77. package/corpus/core/src/history/store.ts +379 -0
  78. package/corpus/core/src/history/types.ts +69 -0
  79. package/corpus/core/src/index.ts +10 -0
  80. package/corpus/core/src/navigation/index.ts +170 -0
  81. package/corpus/core/src/org/index.ts +8 -0
  82. package/corpus/core/src/org/permissions.ts +30 -0
  83. package/corpus/core/src/org-team/index.ts +1 -0
  84. package/corpus/core/src/private-blob/registry.ts +1 -0
  85. package/corpus/core/src/review/actions/consume-review-feedback.ts +48 -0
  86. package/corpus/core/src/review/actions/create-review-comment.ts +107 -0
  87. package/corpus/core/src/review/actions/delete-review-comment.ts +67 -0
  88. package/corpus/core/src/review/actions/get-review-feedback.ts +54 -0
  89. package/corpus/core/src/review/actions/list-review-comments.ts +53 -0
  90. package/corpus/core/src/review/actions/reply-review-comment.ts +107 -0
  91. package/corpus/core/src/review/actions/resolve-review-thread.ts +67 -0
  92. package/corpus/core/src/review/actions/set-review-status.ts +58 -0
  93. package/corpus/core/src/review/index.ts +31 -0
  94. package/corpus/core/src/review/mentions.ts +44 -0
  95. package/corpus/core/src/review/registry.ts +111 -0
  96. package/corpus/core/src/review/store.ts +690 -0
  97. package/corpus/core/src/review/types.ts +97 -0
  98. package/corpus/core/src/server/action-discovery.ts +54 -0
  99. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  100. package/corpus/core/src/server/agent-engine-api-key-route.ts +5 -0
  101. package/corpus/core/src/server/credential-provider.ts +118 -0
  102. package/corpus/core/src/setup-connections/index.ts +89 -0
  103. package/corpus/core/src/setup-connections/onboarding.ts +47 -0
  104. package/corpus/core/src/transcription/builder-transcription.ts +9 -2
  105. package/corpus/core/src/vite/action-types-plugin.ts +52 -0
  106. package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -1
  107. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -2
  108. package/corpus/templates/analytics/app/global.css +22 -10
  109. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -1
  110. package/corpus/templates/analytics/app/i18n-data.ts +81 -13
  111. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  112. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  113. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +528 -108
  114. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +466 -183
  115. package/corpus/templates/analytics/changelog/2026-07-07-session-replays-load-sooner-show-clearer-activity-timelines-.md +6 -0
  116. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +11 -11
  117. package/corpus/templates/assets/actions/generate-image.ts +64 -28
  118. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +1 -1
  119. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +91 -74
  120. package/corpus/templates/assets/server/lib/generation.ts +29 -4
  121. package/corpus/templates/assets/server/lib/image-processing.ts +131 -0
  122. package/corpus/templates/brain/app/routes/settings.tsx +2 -2
  123. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +24 -2
  124. package/corpus/templates/calendar/AGENTS.md +3 -0
  125. package/corpus/templates/calendar/actions/create-event.ts +8 -34
  126. package/corpus/templates/calendar/actions/event-action-helpers.ts +52 -0
  127. package/corpus/templates/calendar/actions/manage-event-draft.ts +7 -34
  128. package/corpus/templates/calendar/actions/update-event.ts +10 -23
  129. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +79 -6
  130. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +23 -0
  131. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +59 -2
  132. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +40 -1
  133. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +154 -41
  134. package/corpus/templates/calendar/app/hooks/use-events.ts +6 -0
  135. package/corpus/templates/calendar/app/hooks/use-people.ts +55 -0
  136. package/corpus/templates/calendar/app/i18n/zh-TW.ts +4 -0
  137. package/corpus/templates/calendar/app/i18n-data.ts +40 -0
  138. package/corpus/templates/calendar/changelog/2026-07-07-guest-suggestions-now-find-coworkers-from-your-google-worksp.md +6 -0
  139. package/corpus/templates/calendar/changelog/2026-07-07-you-can-mark-event-guests-as-optional-while-inviting-them-or.md +6 -0
  140. package/corpus/templates/calendar/changelog/2026-07-07-zoom-stays-selected-after-connecting-it-from-a-draft-event.md +6 -0
  141. package/corpus/templates/calendar/server/handlers/events.ts +1 -0
  142. package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -0
  143. package/corpus/templates/calendar/server/plugins/agent-chat.ts +1 -1
  144. package/corpus/templates/calendar/shared/api.ts +2 -0
  145. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +29 -3
  146. package/corpus/templates/clips/actions/create-recording.ts +5 -1
  147. package/corpus/templates/clips/actions/finalize-recording.ts +140 -1
  148. package/corpus/templates/clips/actions/generate-workflow.ts +19 -8
  149. package/corpus/templates/clips/actions/get-clips-ai-prefs.ts +36 -0
  150. package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
  151. package/corpus/templates/clips/actions/lib/clips-ai-prefs.ts +28 -0
  152. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -0
  153. package/corpus/templates/clips/actions/regenerate-chapters.ts +21 -7
  154. package/corpus/templates/clips/actions/regenerate-summary.ts +26 -8
  155. package/corpus/templates/clips/actions/regenerate-title.ts +44 -7
  156. package/corpus/templates/clips/actions/request-transcript.ts +31 -0
  157. package/corpus/templates/clips/actions/set-thumbnail.ts +2 -0
  158. package/corpus/templates/clips/actions/update-clips-ai-prefs.ts +50 -0
  159. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  160. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +7 -2
  161. package/corpus/templates/clips/app/components/player/scrubber-position.ts +9 -0
  162. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -2
  163. package/corpus/templates/clips/app/components/player/share-dialog.tsx +69 -41
  164. package/corpus/templates/clips/app/components/player/video-player.tsx +38 -1
  165. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -3
  166. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +9 -19
  167. package/corpus/templates/clips/app/hooks/use-auto-title.ts +25 -10
  168. package/corpus/templates/clips/app/i18n/ar-SA.ts +28 -6
  169. package/corpus/templates/clips/app/i18n/de-DE.ts +28 -6
  170. package/corpus/templates/clips/app/i18n/en-US.ts +29 -6
  171. package/corpus/templates/clips/app/i18n/es-ES.ts +29 -6
  172. package/corpus/templates/clips/app/i18n/fr-FR.ts +30 -6
  173. package/corpus/templates/clips/app/i18n/hi-IN.ts +26 -6
  174. package/corpus/templates/clips/app/i18n/ja-JP.ts +27 -6
  175. package/corpus/templates/clips/app/i18n/ko-KR.ts +28 -6
  176. package/corpus/templates/clips/app/i18n/pt-BR.ts +28 -6
  177. package/corpus/templates/clips/app/i18n/zh-CN.ts +26 -6
  178. package/corpus/templates/clips/app/i18n/zh-TW.ts +25 -6
  179. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +73 -0
  180. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -0
  181. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +79 -5
  182. package/corpus/templates/clips/app/routes/record.tsx +21 -12
  183. package/corpus/templates/clips/changelog/2026-07-02-recordings-now-wait-for-storage-media-to-serve-before-finishing.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-07-a-pending-app-update-no-longer-blocks-screen-recording-updat.md +6 -0
  185. package/corpus/templates/clips/changelog/2026-07-07-ai-tools-can-include-the-full-video-not-just-the-transcript-.md +6 -0
  186. package/corpus/templates/clips/changelog/2026-07-07-chrome-extension-recordings-keep-audio-after-refreshing-tab.md +6 -0
  187. package/corpus/templates/clips/changelog/2026-07-07-clip-playback-progress-now-starts-and-finishes-at-the-right-times.md +6 -0
  188. package/corpus/templates/clips/changelog/2026-07-07-clips-desktop-now-surfaces-meetings-and-dictate-directly-in-.md +6 -0
  189. package/corpus/templates/clips/changelog/2026-07-07-meeting-notes-now-explain-exactly-how-to-start-granola-style.md +6 -0
  190. package/corpus/templates/clips/changelog/2026-07-07-meeting-start-alerts-now-include-separate-start-notes-and-jo.md +6 -0
  191. package/corpus/templates/clips/changelog/2026-07-07-recordings-start-more-predictably-and-newly-saved-clips-refr.md +6 -0
  192. package/corpus/templates/clips/changelog/2026-07-07-sharing-public-clips-now-stays-focused-on-the-normal-link-wi.md +6 -0
  193. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  194. package/corpus/templates/clips/chrome-extension/src/background.ts +18 -0
  195. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +23 -8
  196. package/corpus/templates/clips/desktop/src/app.tsx +475 -108
  197. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +19 -7
  198. package/corpus/templates/clips/desktop/src/lib/permissions.ts +2 -0
  199. package/corpus/templates/clips/desktop/src/lib/recorder.ts +27 -21
  200. package/corpus/templates/clips/desktop/src/lib/updater.ts +25 -2
  201. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -22
  202. package/corpus/templates/clips/desktop/src/styles.css +167 -2
  203. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +8 -1
  204. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -7
  205. package/corpus/templates/clips/desktop/src-tauri/src/tray_meetings.rs +5 -4
  206. package/corpus/templates/clips/server/routes/_agent-native/clips/user-prefs.put.ts +16 -8
  207. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +1 -0
  208. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +22 -5
  209. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +8 -0
  210. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +13 -6
  211. package/corpus/templates/clips/shared/clips-ai-prefs.ts +81 -0
  212. package/corpus/templates/clips/shared/finalize-recovery.ts +12 -0
  213. package/corpus/templates/content/actions/delete-document.ts +337 -52
  214. package/corpus/templates/content/changelog/2026-07-07-permanently-deleting-trashed-databases-now-finishes-reliably.md +6 -0
  215. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +16 -1
  216. package/corpus/templates/design/actions/add-localhost-screens.ts +1 -0
  217. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -11
  218. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +89 -14
  219. package/corpus/templates/design/app/components/design/bridge-security.ts +7 -1
  220. package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -1
  221. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  222. package/corpus/templates/design/app/i18n-data.ts +41 -0
  223. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-uses-live-app-iframes-for-click-to-edit-pr.md +6 -0
  224. package/corpus/templates/slides/app/pages/DeckEditor.tsx +2 -2
  225. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  226. package/dist/agent/engine/ai-sdk-engine.js +15 -1
  227. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  228. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  229. package/dist/agent/engine/anthropic-engine.js +20 -1
  230. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  231. package/dist/agent/engine/index.d.ts +1 -1
  232. package/dist/agent/engine/index.d.ts.map +1 -1
  233. package/dist/agent/engine/index.js +1 -1
  234. package/dist/agent/engine/index.js.map +1 -1
  235. package/dist/agent/engine/registry.d.ts +14 -0
  236. package/dist/agent/engine/registry.d.ts.map +1 -1
  237. package/dist/agent/engine/registry.js +78 -16
  238. package/dist/agent/engine/registry.js.map +1 -1
  239. package/dist/agent/production-agent.d.ts.map +1 -1
  240. package/dist/agent/production-agent.js +27 -7
  241. package/dist/agent/production-agent.js.map +1 -1
  242. package/dist/cli/create.d.ts.map +1 -1
  243. package/dist/cli/create.js +31 -0
  244. package/dist/cli/create.js.map +1 -1
  245. package/dist/cli/design-connect.d.ts.map +1 -1
  246. package/dist/cli/design-connect.js +186 -0
  247. package/dist/cli/design-connect.js.map +1 -1
  248. package/dist/cli/index.js +76 -9
  249. package/dist/cli/index.js.map +1 -1
  250. package/dist/cli/workspacify.d.ts.map +1 -1
  251. package/dist/cli/workspacify.js +30 -0
  252. package/dist/cli/workspacify.js.map +1 -1
  253. package/dist/client/command-navigation/index.d.ts +4 -0
  254. package/dist/client/command-navigation/index.d.ts.map +1 -0
  255. package/dist/client/command-navigation/index.js +4 -0
  256. package/dist/client/command-navigation/index.js.map +1 -0
  257. package/dist/client/comments-review/index.d.ts +2 -0
  258. package/dist/client/comments-review/index.d.ts.map +1 -0
  259. package/dist/client/comments-review/index.js +2 -0
  260. package/dist/client/comments-review/index.js.map +1 -0
  261. package/dist/client/history/VersionHistoryPanel.d.ts +18 -0
  262. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -0
  263. package/dist/client/history/VersionHistoryPanel.js +31 -0
  264. package/dist/client/history/VersionHistoryPanel.js.map +1 -0
  265. package/dist/client/history/index.d.ts +3 -0
  266. package/dist/client/history/index.d.ts.map +1 -0
  267. package/dist/client/history/index.js +3 -0
  268. package/dist/client/history/index.js.map +1 -0
  269. package/dist/client/history/use-history.d.ts +58 -0
  270. package/dist/client/history/use-history.d.ts.map +1 -0
  271. package/dist/client/history/use-history.js +24 -0
  272. package/dist/client/history/use-history.js.map +1 -0
  273. package/dist/client/index.d.ts +6 -4
  274. package/dist/client/index.d.ts.map +1 -1
  275. package/dist/client/index.js +6 -4
  276. package/dist/client/index.js.map +1 -1
  277. package/dist/client/org/OrgSwitcher.js +5 -5
  278. package/dist/client/org/OrgSwitcher.js.map +1 -1
  279. package/dist/client/org/RequireActiveOrg.js +2 -2
  280. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  281. package/dist/client/org/TeamPage.js +3 -3
  282. package/dist/client/org/TeamPage.js.map +1 -1
  283. package/dist/client/org/hooks.d.ts +12 -1
  284. package/dist/client/org/hooks.d.ts.map +1 -1
  285. package/dist/client/org/hooks.js +15 -0
  286. package/dist/client/org/hooks.js.map +1 -1
  287. package/dist/client/org/index.d.ts +4 -2
  288. package/dist/client/org/index.d.ts.map +1 -1
  289. package/dist/client/org/index.js +3 -1
  290. package/dist/client/org/index.js.map +1 -1
  291. package/dist/client/org-team/index.d.ts +2 -0
  292. package/dist/client/org-team/index.d.ts.map +1 -0
  293. package/dist/client/org-team/index.js +2 -0
  294. package/dist/client/org-team/index.js.map +1 -0
  295. package/dist/client/review/ReviewStatusBadge.d.ts +7 -0
  296. package/dist/client/review/ReviewStatusBadge.d.ts.map +1 -0
  297. package/dist/client/review/ReviewStatusBadge.js +19 -0
  298. package/dist/client/review/ReviewStatusBadge.js.map +1 -0
  299. package/dist/client/review/ReviewThreadPanel.d.ts +20 -0
  300. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -0
  301. package/dist/client/review/ReviewThreadPanel.js +84 -0
  302. package/dist/client/review/ReviewThreadPanel.js.map +1 -0
  303. package/dist/client/review/index.d.ts +4 -0
  304. package/dist/client/review/index.d.ts.map +1 -0
  305. package/dist/client/review/index.js +4 -0
  306. package/dist/client/review/index.js.map +1 -0
  307. package/dist/client/review/use-review.d.ts +91 -0
  308. package/dist/client/review/use-review.d.ts.map +1 -0
  309. package/dist/client/review/use-review.js +30 -0
  310. package/dist/client/review/use-review.js.map +1 -0
  311. package/dist/client/settings/index.d.ts +1 -1
  312. package/dist/client/settings/index.d.ts.map +1 -1
  313. package/dist/client/settings/index.js +1 -1
  314. package/dist/client/settings/index.js.map +1 -1
  315. package/dist/client/setup-connections/BuilderConnectCard.d.ts +9 -0
  316. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -0
  317. package/dist/client/setup-connections/BuilderConnectCard.js +25 -0
  318. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -0
  319. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts +8 -0
  320. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts.map +1 -0
  321. package/dist/client/setup-connections/ProviderReadinessBadge.js +32 -0
  322. package/dist/client/setup-connections/ProviderReadinessBadge.js.map +1 -0
  323. package/dist/client/setup-connections/SetupConnectionsPage.d.ts +17 -0
  324. package/dist/client/setup-connections/SetupConnectionsPage.d.ts.map +1 -0
  325. package/dist/client/setup-connections/SetupConnectionsPage.js +10 -0
  326. package/dist/client/setup-connections/SetupConnectionsPage.js.map +1 -0
  327. package/dist/client/setup-connections/index.d.ts +7 -0
  328. package/dist/client/setup-connections/index.d.ts.map +1 -0
  329. package/dist/client/setup-connections/index.js +7 -0
  330. package/dist/client/setup-connections/index.js.map +1 -0
  331. package/dist/client/sharing/ShareButton.d.ts +4 -4
  332. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  333. package/dist/client/sharing/ShareButton.js +13 -7
  334. package/dist/client/sharing/ShareButton.js.map +1 -1
  335. package/dist/client/sharing/ShareDialog.js +3 -3
  336. package/dist/client/sharing/ShareDialog.js.map +1 -1
  337. package/dist/collab/awareness.d.ts +2 -2
  338. package/dist/collab/awareness.d.ts.map +1 -1
  339. package/dist/collab/routes.d.ts +1 -1
  340. package/dist/collab/struct-routes.d.ts +1 -1
  341. package/dist/command-navigation/actions.d.ts +25 -0
  342. package/dist/command-navigation/actions.d.ts.map +1 -0
  343. package/dist/command-navigation/actions.js +64 -0
  344. package/dist/command-navigation/actions.js.map +1 -0
  345. package/dist/command-navigation/index.d.ts +4 -0
  346. package/dist/command-navigation/index.d.ts.map +1 -0
  347. package/dist/command-navigation/index.js +4 -0
  348. package/dist/command-navigation/index.js.map +1 -0
  349. package/dist/comments-review/index.d.ts +2 -0
  350. package/dist/comments-review/index.d.ts.map +1 -0
  351. package/dist/comments-review/index.js +2 -0
  352. package/dist/comments-review/index.js.map +1 -0
  353. package/dist/file-upload/builder.d.ts.map +1 -1
  354. package/dist/file-upload/builder.js +18 -2
  355. package/dist/file-upload/builder.js.map +1 -1
  356. package/dist/file-upload/types.d.ts +3 -0
  357. package/dist/file-upload/types.d.ts.map +1 -1
  358. package/dist/file-upload/types.js.map +1 -1
  359. package/dist/history/actions/create-resource-version.d.ts +10 -0
  360. package/dist/history/actions/create-resource-version.d.ts.map +1 -0
  361. package/dist/history/actions/create-resource-version.js +68 -0
  362. package/dist/history/actions/create-resource-version.js.map +1 -0
  363. package/dist/history/actions/get-resource-version.d.ts +10 -0
  364. package/dist/history/actions/get-resource-version.d.ts.map +1 -0
  365. package/dist/history/actions/get-resource-version.js +38 -0
  366. package/dist/history/actions/get-resource-version.js.map +1 -0
  367. package/dist/history/actions/list-resource-history.d.ts +10 -0
  368. package/dist/history/actions/list-resource-history.d.ts.map +1 -0
  369. package/dist/history/actions/list-resource-history.js +45 -0
  370. package/dist/history/actions/list-resource-history.js.map +1 -0
  371. package/dist/history/actions/list-resource-versions.d.ts +10 -0
  372. package/dist/history/actions/list-resource-versions.d.ts.map +1 -0
  373. package/dist/history/actions/list-resource-versions.js +35 -0
  374. package/dist/history/actions/list-resource-versions.js.map +1 -0
  375. package/dist/history/actions/restore-resource-version.d.ts +11 -0
  376. package/dist/history/actions/restore-resource-version.d.ts.map +1 -0
  377. package/dist/history/actions/restore-resource-version.js +59 -0
  378. package/dist/history/actions/restore-resource-version.js.map +1 -0
  379. package/dist/history/index.d.ts +4 -0
  380. package/dist/history/index.d.ts.map +1 -0
  381. package/dist/history/index.js +3 -0
  382. package/dist/history/index.js.map +1 -0
  383. package/dist/history/registry.d.ts +10 -0
  384. package/dist/history/registry.d.ts.map +1 -0
  385. package/dist/history/registry.js +63 -0
  386. package/dist/history/registry.js.map +1 -0
  387. package/dist/history/store.d.ts +34 -0
  388. package/dist/history/store.d.ts.map +1 -0
  389. package/dist/history/store.js +290 -0
  390. package/dist/history/store.js.map +1 -0
  391. package/dist/history/types.d.ts +55 -0
  392. package/dist/history/types.d.ts.map +1 -0
  393. package/dist/history/types.js +2 -0
  394. package/dist/history/types.js.map +1 -0
  395. package/dist/index.d.ts +6 -0
  396. package/dist/index.d.ts.map +1 -1
  397. package/dist/index.js +6 -0
  398. package/dist/index.js.map +1 -1
  399. package/dist/navigation/index.d.ts +53 -0
  400. package/dist/navigation/index.d.ts.map +1 -0
  401. package/dist/navigation/index.js +105 -0
  402. package/dist/navigation/index.js.map +1 -0
  403. package/dist/observability/routes.d.ts +3 -3
  404. package/dist/org/index.d.ts +1 -0
  405. package/dist/org/index.d.ts.map +1 -1
  406. package/dist/org/index.js +1 -0
  407. package/dist/org/index.js.map +1 -1
  408. package/dist/org/permissions.d.ts +7 -0
  409. package/dist/org/permissions.d.ts.map +1 -0
  410. package/dist/org/permissions.js +21 -0
  411. package/dist/org/permissions.js.map +1 -0
  412. package/dist/org-team/index.d.ts +2 -0
  413. package/dist/org-team/index.d.ts.map +1 -0
  414. package/dist/org-team/index.js +2 -0
  415. package/dist/org-team/index.js.map +1 -0
  416. package/dist/private-blob/registry.d.ts.map +1 -1
  417. package/dist/private-blob/registry.js +1 -0
  418. package/dist/private-blob/registry.js.map +1 -1
  419. package/dist/progress/routes.d.ts +1 -1
  420. package/dist/resources/handlers.d.ts +2 -2
  421. package/dist/review/actions/consume-review-feedback.d.ts +10 -0
  422. package/dist/review/actions/consume-review-feedback.d.ts.map +1 -0
  423. package/dist/review/actions/consume-review-feedback.js +35 -0
  424. package/dist/review/actions/consume-review-feedback.js.map +1 -0
  425. package/dist/review/actions/create-review-comment.d.ts +18 -0
  426. package/dist/review/actions/create-review-comment.d.ts.map +1 -0
  427. package/dist/review/actions/create-review-comment.js +81 -0
  428. package/dist/review/actions/create-review-comment.js.map +1 -0
  429. package/dist/review/actions/delete-review-comment.d.ts +11 -0
  430. package/dist/review/actions/delete-review-comment.d.ts.map +1 -0
  431. package/dist/review/actions/delete-review-comment.js +53 -0
  432. package/dist/review/actions/delete-review-comment.js.map +1 -0
  433. package/dist/review/actions/get-review-feedback.d.ts +10 -0
  434. package/dist/review/actions/get-review-feedback.d.ts.map +1 -0
  435. package/dist/review/actions/get-review-feedback.js +45 -0
  436. package/dist/review/actions/get-review-feedback.js.map +1 -0
  437. package/dist/review/actions/list-review-comments.d.ts +13 -0
  438. package/dist/review/actions/list-review-comments.d.ts.map +1 -0
  439. package/dist/review/actions/list-review-comments.js +44 -0
  440. package/dist/review/actions/list-review-comments.js.map +1 -0
  441. package/dist/review/actions/reply-review-comment.d.ts +16 -0
  442. package/dist/review/actions/reply-review-comment.d.ts.map +1 -0
  443. package/dist/review/actions/reply-review-comment.js +84 -0
  444. package/dist/review/actions/reply-review-comment.js.map +1 -0
  445. package/dist/review/actions/resolve-review-thread.d.ts +12 -0
  446. package/dist/review/actions/resolve-review-thread.d.ts.map +1 -0
  447. package/dist/review/actions/resolve-review-thread.js +49 -0
  448. package/dist/review/actions/resolve-review-thread.js.map +1 -0
  449. package/dist/review/actions/set-review-status.d.ts +9 -0
  450. package/dist/review/actions/set-review-status.d.ts.map +1 -0
  451. package/dist/review/actions/set-review-status.js +43 -0
  452. package/dist/review/actions/set-review-status.js.map +1 -0
  453. package/dist/review/index.d.ts +5 -0
  454. package/dist/review/index.d.ts.map +1 -0
  455. package/dist/review/index.js +4 -0
  456. package/dist/review/index.js.map +1 -0
  457. package/dist/review/mentions.d.ts +4 -0
  458. package/dist/review/mentions.d.ts.map +1 -0
  459. package/dist/review/mentions.js +39 -0
  460. package/dist/review/mentions.js.map +1 -0
  461. package/dist/review/registry.d.ts +10 -0
  462. package/dist/review/registry.d.ts.map +1 -0
  463. package/dist/review/registry.js +63 -0
  464. package/dist/review/registry.js.map +1 -0
  465. package/dist/review/store.d.ts +63 -0
  466. package/dist/review/store.d.ts.map +1 -0
  467. package/dist/review/store.js +561 -0
  468. package/dist/review/store.js.map +1 -0
  469. package/dist/review/types.d.ts +77 -0
  470. package/dist/review/types.d.ts.map +1 -0
  471. package/dist/review/types.js +2 -0
  472. package/dist/review/types.js.map +1 -0
  473. package/dist/secrets/routes.d.ts +9 -9
  474. package/dist/server/action-discovery.d.ts.map +1 -1
  475. package/dist/server/action-discovery.js +54 -0
  476. package/dist/server/action-discovery.js.map +1 -1
  477. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  478. package/dist/server/agent-chat-plugin.js +5 -0
  479. package/dist/server/agent-chat-plugin.js.map +1 -1
  480. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  481. package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
  482. package/dist/server/agent-engine-api-key-route.js +5 -0
  483. package/dist/server/agent-engine-api-key-route.js.map +1 -1
  484. package/dist/server/credential-provider.d.ts +28 -0
  485. package/dist/server/credential-provider.d.ts.map +1 -1
  486. package/dist/server/credential-provider.js +92 -0
  487. package/dist/server/credential-provider.js.map +1 -1
  488. package/dist/setup-connections/index.d.ts +6 -0
  489. package/dist/setup-connections/index.d.ts.map +1 -0
  490. package/dist/setup-connections/index.js +6 -0
  491. package/dist/setup-connections/index.js.map +1 -0
  492. package/dist/setup-connections/onboarding.d.ts +14 -0
  493. package/dist/setup-connections/onboarding.d.ts.map +1 -0
  494. package/dist/setup-connections/onboarding.js +23 -0
  495. package/dist/setup-connections/onboarding.js.map +1 -0
  496. package/dist/transcription/builder-transcription.d.ts +1 -0
  497. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  498. package/dist/transcription/builder-transcription.js +5 -2
  499. package/dist/transcription/builder-transcription.js.map +1 -1
  500. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  501. package/dist/vite/action-types-plugin.js +52 -0
  502. package/dist/vite/action-types-plugin.js.map +1 -1
  503. package/docs/content/agent-native-toolkit.mdx +87 -80
  504. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  505. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  506. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  507. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  508. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  509. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  510. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  511. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  512. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  513. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  514. package/docs/content/toolkit-agent-ux.mdx +43 -0
  515. package/docs/content/toolkit-app-adapters.mdx +9 -0
  516. package/docs/content/toolkit-collaboration-ui.mdx +12 -0
  517. package/docs/content/toolkit-collaboration.mdx +74 -0
  518. package/docs/content/toolkit-command-navigation.mdx +106 -0
  519. package/docs/content/toolkit-comments-review.mdx +98 -0
  520. package/docs/content/toolkit-history.mdx +95 -0
  521. package/docs/content/toolkit-observability.mdx +41 -0
  522. package/docs/content/toolkit-org-team.mdx +80 -0
  523. package/docs/content/toolkit-resources.mdx +57 -0
  524. package/docs/content/toolkit-settings.mdx +65 -0
  525. package/docs/content/toolkit-setup-connections.mdx +109 -0
  526. package/docs/content/toolkit-sharing-ui.mdx +18 -6
  527. package/docs/content/toolkit-sharing.mdx +81 -0
  528. package/docs/content/toolkit-shell-hooks.mdx +9 -0
  529. package/docs/content/toolkit-ui.mdx +9 -0
  530. package/package.json +36 -2
@@ -1,10 +1,16 @@
1
1
  import { useT } from "@agent-native/core/client";
2
2
  import type { CalendarEvent } from "@shared/api";
3
- import { IconMessageCircle, IconUser } from "@tabler/icons-react";
3
+ import { IconDots, IconMessageCircle, IconUser } from "@tabler/icons-react";
4
4
  import { useEffect, useId, useMemo, useState } from "react";
5
5
 
6
6
  import { AttendeeApolloPopover } from "@/components/calendar/ApolloPanel";
7
7
  import { Button } from "@/components/ui/button";
8
+ import {
9
+ DropdownMenu,
10
+ DropdownMenuContent,
11
+ DropdownMenuItem,
12
+ DropdownMenuTrigger,
13
+ } from "@/components/ui/dropdown-menu";
8
14
  import { Label } from "@/components/ui/label";
9
15
  import {
10
16
  Popover,
@@ -343,6 +349,8 @@ function AttendeeRow({
343
349
  currentNote,
344
350
  onResponseChange,
345
351
  isRecurring,
352
+ canEditOptional,
353
+ onToggleOptional,
346
354
  }: {
347
355
  attendee: Attendee;
348
356
  event: Pick<CalendarEvent, "id" | "accountEmail">;
@@ -352,15 +360,19 @@ function AttendeeRow({
352
360
  currentNote?: string;
353
361
  onResponseChange?: (status: RsvpStatus, note: string) => void;
354
362
  isRecurring?: boolean;
363
+ canEditOptional?: boolean;
364
+ onToggleOptional?: (email: string, optional: boolean) => void;
355
365
  }) {
356
366
  const t = useT();
357
367
  const displayStatus = inlineRsvp ? currentStatus : attendee.responseStatus;
358
368
  const statusLabel =
359
369
  getLocalizedRsvpStatusLabel(t, displayStatus) ?? t("eventForm.awaiting");
360
370
  const comment = (inlineRsvp ? currentNote : attendee.comment)?.trim();
371
+ const showOptionalMenu =
372
+ canEditOptional && onToggleOptional && !attendee.organizer;
361
373
 
362
374
  return (
363
- <div className="rounded-xl px-1 py-1 transition-colors hover:bg-muted/40">
375
+ <div className="group rounded-xl px-1 py-1 transition-colors hover:bg-muted/40">
364
376
  <AttendeeApolloPopover attendee={attendee}>
365
377
  <div className="flex items-center gap-2.5">
366
378
  <div className="relative shrink-0">
@@ -379,6 +391,11 @@ function AttendeeRow({
379
391
  {t("eventForm.organizer")}
380
392
  </span>
381
393
  )}
394
+ {attendee.optional && !attendee.organizer && (
395
+ <span className="shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
396
+ {t("attendees.optionalBadge")}
397
+ </span>
398
+ )}
382
399
  </div>
383
400
  {attendee.displayName && (
384
401
  <div className="truncate text-[11px] text-muted-foreground/60">
@@ -391,6 +408,38 @@ function AttendeeRow({
391
408
  : statusLabel}
392
409
  </div>
393
410
  </div>
411
+ {showOptionalMenu && (
412
+ <DropdownMenu>
413
+ <DropdownMenuTrigger asChild>
414
+ <Button
415
+ type="button"
416
+ variant="ghost"
417
+ size="icon"
418
+ className="h-7 w-7 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100 data-[state=open]:opacity-100"
419
+ aria-label={t("attendees.guestOptions", {
420
+ email: attendee.email,
421
+ })}
422
+ onClick={(event) => event.stopPropagation()}
423
+ >
424
+ <IconDots className="h-3.5 w-3.5" />
425
+ </Button>
426
+ </DropdownMenuTrigger>
427
+ <DropdownMenuContent
428
+ align="end"
429
+ onClick={(event) => event.stopPropagation()}
430
+ >
431
+ <DropdownMenuItem
432
+ onSelect={() =>
433
+ onToggleOptional(attendee.email, !attendee.optional)
434
+ }
435
+ >
436
+ {attendee.optional
437
+ ? t("attendees.markRequired")
438
+ : t("attendees.markOptional")}
439
+ </DropdownMenuItem>
440
+ </DropdownMenuContent>
441
+ </DropdownMenu>
442
+ )}
394
443
  </div>
395
444
  {comment && (
396
445
  <div className="ml-10 mt-1 flex items-start gap-1.5 rounded-md bg-muted/40 px-2 py-1 text-[11px] leading-relaxed text-muted-foreground">
@@ -425,6 +474,8 @@ function sortAttendees(attendees: Attendee[]) {
425
474
 
426
475
  export function EventAttendeesSection({
427
476
  event,
477
+ canEditOptional = false,
478
+ onToggleOptional,
428
479
  }: {
429
480
  event: Pick<
430
481
  CalendarEvent,
@@ -436,6 +487,8 @@ export function EventAttendeesSection({
436
487
  | "source"
437
488
  | "recurringEventId"
438
489
  >;
490
+ canEditOptional?: boolean;
491
+ onToggleOptional?: (email: string, optional: boolean) => void;
439
492
  }) {
440
493
  const t = useT();
441
494
  const attendees = event.attendees ?? [];
@@ -523,6 +576,8 @@ export function EventAttendeesSection({
523
576
  attendee={attendee}
524
577
  event={event}
525
578
  photoUrl={photos?.[attendee.email.toLowerCase()]}
579
+ canEditOptional={canEditOptional}
580
+ onToggleOptional={onToggleOptional}
526
581
  />
527
582
  ))}
528
583
 
@@ -557,6 +612,8 @@ export function EventAttendeesSection({
557
612
  currentNote={selfNote}
558
613
  onResponseChange={handleSelfResponseChange}
559
614
  isRecurring={!!event.recurringEventId}
615
+ canEditOptional={canEditOptional}
616
+ onToggleOptional={onToggleOptional}
560
617
  />
561
618
  </>
562
619
  )}
@@ -185,6 +185,41 @@ export function EventDetailPanel({
185
185
  })();
186
186
  }, [event, promptGuestNotification, updateEvent]);
187
187
 
188
+ const handleToggleAttendeeOptional = useCallback(
189
+ (email: string, optional: boolean) => {
190
+ if (!event || updateEvent.isPending) return;
191
+ const existing = event.attendees || [];
192
+ const key = email.trim().toLowerCase();
193
+ if (!existing.some((attendee) => attendee.email.toLowerCase() === key)) {
194
+ return;
195
+ }
196
+ const attendees = existing.map((attendee) =>
197
+ attendee.email.toLowerCase() === key
198
+ ? {
199
+ ...attendee,
200
+ optional: optional ? true : undefined,
201
+ }
202
+ : attendee,
203
+ );
204
+ void (async () => {
205
+ const updates = { attendees };
206
+ const guestNotification = await promptGuestNotification({
207
+ event,
208
+ action: "update",
209
+ updates,
210
+ });
211
+ if (!guestNotification) return;
212
+ updateEvent.mutate({
213
+ id: event.id,
214
+ accountEmail: event.accountEmail,
215
+ ...updates,
216
+ ...guestNotification,
217
+ });
218
+ })();
219
+ },
220
+ [event, promptGuestNotification, updateEvent],
221
+ );
222
+
188
223
  return (
189
224
  <TooltipProvider>
190
225
  {isOpen && (
@@ -414,7 +449,11 @@ export function EventDetailPanel({
414
449
 
415
450
  {/* Attendees */}
416
451
  {event.attendees && event.attendees.length > 0 && (
417
- <EventAttendeesSection event={event} />
452
+ <EventAttendeesSection
453
+ event={event}
454
+ canEditOptional={!isOverlay}
455
+ onToggleOptional={handleToggleAttendeeOptional}
456
+ />
418
457
  )}
419
458
 
420
459
  {/* Research Meeting */}
@@ -93,6 +93,51 @@ import {
93
93
  import { markPopoverInteractOutside } from "@/lib/popover-click-guard";
94
94
  import { shortcutModifierLabel } from "@/lib/utils";
95
95
 
96
+ const ZOOM_AFTER_CONNECT_EVENT_ID_KEY = "calendar.zoomAfterConnectEventId";
97
+ const ZOOM_AFTER_CONNECT_MAX_AGE_MS = 10 * 60 * 1000;
98
+
99
+ function getStoredZoomAfterConnectEventId(): string | null {
100
+ if (typeof window === "undefined") return null;
101
+ try {
102
+ const stored = window.sessionStorage.getItem(
103
+ ZOOM_AFTER_CONNECT_EVENT_ID_KEY,
104
+ );
105
+ if (!stored) return null;
106
+ const parsed = JSON.parse(stored) as {
107
+ eventId?: unknown;
108
+ startedAt?: unknown;
109
+ };
110
+ if (
111
+ typeof parsed.eventId === "string" &&
112
+ typeof parsed.startedAt === "number" &&
113
+ Date.now() - parsed.startedAt < ZOOM_AFTER_CONNECT_MAX_AGE_MS
114
+ ) {
115
+ return parsed.eventId;
116
+ }
117
+ window.sessionStorage.removeItem(ZOOM_AFTER_CONNECT_EVENT_ID_KEY);
118
+ return null;
119
+ } catch {
120
+ return null;
121
+ }
122
+ }
123
+
124
+ function setStoredZoomAfterConnectEventId(eventId: string | null): void {
125
+ if (typeof window === "undefined") return;
126
+ try {
127
+ if (eventId) {
128
+ window.sessionStorage.setItem(
129
+ ZOOM_AFTER_CONNECT_EVENT_ID_KEY,
130
+ JSON.stringify({ eventId, startedAt: Date.now() }),
131
+ );
132
+ } else {
133
+ window.sessionStorage.removeItem(ZOOM_AFTER_CONNECT_EVENT_ID_KEY);
134
+ }
135
+ } catch {
136
+ // Storage can be unavailable in locked-down browsers; in-memory state still
137
+ // handles the normal popup path.
138
+ }
139
+ }
140
+
96
141
  function formatDuration(start: string, end: string): string {
97
142
  const totalMinutes = differenceInMinutes(parseISO(end), parseISO(start));
98
143
  const hours = Math.floor(totalMinutes / 60);
@@ -249,6 +294,12 @@ function mergeAttendeesForPrompt(
249
294
  email,
250
295
  displayName: attendee.displayName ?? current?.displayName,
251
296
  photoUrl: attendee.photoUrl ?? current?.photoUrl,
297
+ optional:
298
+ attendee.optional === true
299
+ ? true
300
+ : attendee.optional === false
301
+ ? undefined
302
+ : current?.optional,
252
303
  });
253
304
  }
254
305
 
@@ -403,6 +454,9 @@ export function EventDetailPopover({
403
454
  const [pendingVideoProvider, setPendingVideoProvider] = useState<
404
455
  "meet" | "zoom" | null
405
456
  >(null);
457
+ const [zoomAfterConnectEventId, setZoomAfterConnectEventId] = useState<
458
+ string | null
459
+ >(() => getStoredZoomAfterConnectEventId());
406
460
  const isOverlay = !!event.overlayEmail;
407
461
  const ownerLabel = event.ownerName || event.overlayEmail;
408
462
 
@@ -686,45 +740,73 @@ export function EventDetailPopover({
686
740
  })();
687
741
  }, [event, isDraft, onDraftUpdate, promptGuestNotification, updateEvent]);
688
742
 
743
+ const addZoomToConnectedEvent = useCallback(() => {
744
+ if (!event.id || updateEvent.isPending) return;
745
+
746
+ if (isDraft) {
747
+ onDraftUpdate?.(event.id, { addZoom: true, addGoogleMeet: false });
748
+ return;
749
+ }
750
+
751
+ setPendingVideoProvider("zoom");
752
+ void (async () => {
753
+ const updates = { addZoom: true };
754
+ const guestNotification = await promptGuestNotification({
755
+ event,
756
+ action: "update",
757
+ updates,
758
+ });
759
+ if (!guestNotification) {
760
+ setPendingVideoProvider(null);
761
+ return;
762
+ }
763
+ updateEvent.mutate(
764
+ {
765
+ id: event.id,
766
+ accountEmail: event.accountEmail,
767
+ ...updates,
768
+ ...guestNotification,
769
+ },
770
+ {
771
+ onSuccess: () => toast(t("eventForm.zoomAdded")),
772
+ onError: (error) =>
773
+ toast.error(
774
+ error instanceof Error
775
+ ? error.message
776
+ : t("eventForm.zoomAddFailed"),
777
+ ),
778
+ onSettled: () => setPendingVideoProvider(null),
779
+ },
780
+ );
781
+ })();
782
+ }, [event, isDraft, onDraftUpdate, promptGuestNotification, t, updateEvent]);
783
+
784
+ useEffect(() => {
785
+ if (
786
+ !zoomStatus.data?.connected ||
787
+ !zoomAfterConnectEventId ||
788
+ zoomAfterConnectEventId !== event.id ||
789
+ updateEvent.isPending
790
+ ) {
791
+ return;
792
+ }
793
+
794
+ setZoomAfterConnectEventId(null);
795
+ setStoredZoomAfterConnectEventId(null);
796
+ addZoomToConnectedEvent();
797
+ }, [
798
+ addZoomToConnectedEvent,
799
+ event.id,
800
+ updateEvent.isPending,
801
+ zoomAfterConnectEventId,
802
+ zoomStatus.data?.connected,
803
+ ]);
804
+
689
805
  const handleAddZoom = useCallback(() => {
690
806
  if (!event.id || updateEvent.isPending || connectZoom.isPending) return;
691
807
 
692
808
  if (zoomStatus.data?.connected) {
693
- if (isDraft) {
694
- onDraftUpdate?.(event.id, { addZoom: true, addGoogleMeet: false });
695
- return;
696
- }
697
- setPendingVideoProvider("zoom");
698
- void (async () => {
699
- const updates = { addZoom: true };
700
- const guestNotification = await promptGuestNotification({
701
- event,
702
- action: "update",
703
- updates,
704
- });
705
- if (!guestNotification) {
706
- setPendingVideoProvider(null);
707
- return;
708
- }
709
- updateEvent.mutate(
710
- {
711
- id: event.id,
712
- accountEmail: event.accountEmail,
713
- ...updates,
714
- ...guestNotification,
715
- },
716
- {
717
- onSuccess: () => toast(t("eventForm.zoomAdded")),
718
- onError: (error) =>
719
- toast.error(
720
- error instanceof Error
721
- ? error.message
722
- : t("eventForm.zoomAddFailed"),
723
- ),
724
- onSettled: () => setPendingVideoProvider(null),
725
- },
726
- );
727
- })();
809
+ addZoomToConnectedEvent();
728
810
  return;
729
811
  }
730
812
 
@@ -733,21 +815,25 @@ export function EventDetailPopover({
733
815
  return;
734
816
  }
735
817
 
818
+ setZoomAfterConnectEventId(event.id);
819
+ setStoredZoomAfterConnectEventId(event.id);
736
820
  connectZoom.mutate(undefined, {
737
821
  onSuccess: () => toast(t("eventForm.zoomConnectionOpened")),
738
- onError: (error) =>
822
+ onError: (error) => {
823
+ setZoomAfterConnectEventId(null);
824
+ setStoredZoomAfterConnectEventId(null);
739
825
  toast.error(
740
826
  error instanceof Error
741
827
  ? error.message
742
828
  : t("eventForm.zoomConnectFailed"),
743
- ),
829
+ );
830
+ },
744
831
  });
745
832
  }, [
833
+ addZoomToConnectedEvent,
746
834
  connectZoom,
747
835
  event,
748
- isDraft,
749
- onDraftUpdate,
750
- promptGuestNotification,
836
+ t,
751
837
  updateEvent,
752
838
  zoomStatus.data?.configured,
753
839
  zoomStatus.data?.connected,
@@ -859,6 +945,7 @@ export function EventDetailPopover({
859
945
  email: attendee.email,
860
946
  displayName: attendee.displayName,
861
947
  photoUrl: attendee.photoUrl,
948
+ optional: attendee.optional === true ? true : undefined,
862
949
  })),
863
950
  [event.accountEmail, event.attendees],
864
951
  );
@@ -924,6 +1011,7 @@ export function EventDetailPopover({
924
1011
  email,
925
1012
  displayName: attendee.displayName,
926
1013
  photoUrl: attendee.photoUrl,
1014
+ ...(attendee.optional === true ? { optional: true as const } : {}),
927
1015
  };
928
1016
 
929
1017
  if (isDraft) {
@@ -935,6 +1023,27 @@ export function EventDetailPopover({
935
1023
  [event.attendees, isDraft, saveField],
936
1024
  );
937
1025
 
1026
+ const handleToggleAttendeeOptional = useCallback(
1027
+ (email: string, optional: boolean) => {
1028
+ const existing = event.attendees || [];
1029
+ const key = email.trim().toLowerCase();
1030
+ if (!existing.some((attendee) => attendee.email.toLowerCase() === key)) {
1031
+ return;
1032
+ }
1033
+ saveField({
1034
+ attendees: existing.map((attendee) =>
1035
+ attendee.email.toLowerCase() === key
1036
+ ? {
1037
+ ...attendee,
1038
+ optional: optional ? true : undefined,
1039
+ }
1040
+ : attendee,
1041
+ ),
1042
+ });
1043
+ },
1044
+ [event.attendees, saveField],
1045
+ );
1046
+
938
1047
  const handleSaveMeetingLink = useCallback(() => {
939
1048
  const url = editMeetingLink.trim();
940
1049
  let saved = false;
@@ -1526,7 +1635,11 @@ export function EventDetailPopover({
1526
1635
 
1527
1636
  {/* Attendees — always shown */}
1528
1637
  {event.attendees && event.attendees.length > 0 ? (
1529
- <EventAttendeesSection event={event} />
1638
+ <EventAttendeesSection
1639
+ event={event}
1640
+ canEditOptional={!isOverlay}
1641
+ onToggleOptional={handleToggleAttendeeOptional}
1642
+ />
1530
1643
  ) : !isOverlay ? (
1531
1644
  <div className="px-4 py-1">
1532
1645
  <div className="flex items-start gap-3">
@@ -136,6 +136,12 @@ export function mergeAttendeeLists(
136
136
  email,
137
137
  displayName: attendee.displayName ?? current?.displayName,
138
138
  photoUrl: attendee.photoUrl ?? current?.photoUrl,
139
+ optional:
140
+ attendee.optional === true
141
+ ? true
142
+ : attendee.optional === false
143
+ ? undefined
144
+ : current?.optional,
139
145
  });
140
146
  }
141
147
 
@@ -15,6 +15,8 @@ export interface PeopleSearchResponse {
15
15
 
16
16
  const PEOPLE_CONTACTS_STALE_TIME = 10 * 60_000;
17
17
  const PEOPLE_CONTACTS_GC_TIME = 30 * 60_000;
18
+ const PEOPLE_SEARCH_STALE_TIME = 60_000;
19
+ const PEOPLE_SEARCH_GC_TIME = 5 * 60_000;
18
20
 
19
21
  export const PEOPLE_CONTACTS_QUERY_KEY = [
20
22
  "action",
@@ -48,6 +50,42 @@ function matchRank(person: PeopleSearchResult, query: string) {
48
50
  return 5;
49
51
  }
50
52
 
53
+ export function mergePeopleResults(
54
+ ...groups: Array<PeopleSearchResult[] | undefined>
55
+ ) {
56
+ const people = new Map<string, PeopleSearchResult>();
57
+
58
+ for (const group of groups) {
59
+ for (const person of group ?? []) {
60
+ const email = person.email.trim();
61
+ const key = email.toLowerCase();
62
+ if (!key) continue;
63
+
64
+ const existing = people.get(key);
65
+ if (!existing) {
66
+ people.set(key, { ...person, email });
67
+ continue;
68
+ }
69
+
70
+ if (sourceRank(person.source) < sourceRank(existing.source)) {
71
+ existing.source = person.source;
72
+ }
73
+ if (
74
+ person.name &&
75
+ person.name !== person.email &&
76
+ (!existing.name || existing.name === existing.email)
77
+ ) {
78
+ existing.name = person.name;
79
+ }
80
+ if (!existing.photoUrl && person.photoUrl) {
81
+ existing.photoUrl = person.photoUrl;
82
+ }
83
+ }
84
+ }
85
+
86
+ return Array.from(people.values());
87
+ }
88
+
51
89
  export function filterPeopleResults(
52
90
  people: PeopleSearchResult[],
53
91
  query: string,
@@ -106,3 +144,20 @@ export function usePeopleContacts(enabled = true) {
106
144
  refetchOnWindowFocus: false,
107
145
  });
108
146
  }
147
+
148
+ export function usePeopleSearch(query: string, enabled = true) {
149
+ const q = query.trim();
150
+ return useQuery({
151
+ queryKey: ["action", "search-people", { q, scope: "all" }],
152
+ queryFn: () =>
153
+ callAction<PeopleSearchResponse>(
154
+ "search-people",
155
+ { q, scope: "all" },
156
+ { method: "GET" },
157
+ ),
158
+ enabled: enabled && q.length > 0,
159
+ staleTime: PEOPLE_SEARCH_STALE_TIME,
160
+ gcTime: PEOPLE_SEARCH_GC_TIME,
161
+ refetchOnWindowFocus: false,
162
+ });
163
+ }
@@ -126,7 +126,11 @@ const messages = {
126
126
  contacts: "聯絡人",
127
127
  contactsReconnect: "需要重新連線聯絡人或目錄存取權限。",
128
128
  directory: "目錄",
129
+ guestOptions: "{{email}} 的來賓選項",
129
130
  inviteEmail: "邀請 {{email}}",
131
+ markOptional: "標為可選",
132
+ markRequired: "標為必選",
133
+ optionalBadge: "可選",
130
134
  otherContacts: "其他聯絡人",
131
135
  removeAttendee: "移除 {{email}}",
132
136
  searchingPeople: "正在搜尋人員",
@@ -137,7 +137,11 @@ const enUS = {
137
137
  contacts: "Contacts",
138
138
  contactsReconnect: "Contacts or directory access needs to be reconnected.",
139
139
  directory: "Directory",
140
+ guestOptions: "Guest options for {{email}}",
140
141
  inviteEmail: "Invite {{email}}",
142
+ markOptional: "Mark as optional",
143
+ markRequired: "Mark as required",
144
+ optionalBadge: "Optional",
141
145
  otherContacts: "Other contacts",
142
146
  removeAttendee: "Remove {{email}}",
143
147
  searchingPeople: "Searching people",
@@ -6122,7 +6126,11 @@ const translatedCalendarRemainingRaw = {
6122
6126
  contacts: "联系人",
6123
6127
  contactsReconnect: "需要重新连接联系人或目录访问权限。",
6124
6128
  directory: "目录",
6129
+ guestOptions: "{{email}} 的来宾选项",
6125
6130
  inviteEmail: "邀请 {{email}}",
6131
+ markOptional: "标为可选",
6132
+ markRequired: "标为必选",
6133
+ optionalBadge: "可选",
6126
6134
  otherContacts: "其他联系人",
6127
6135
  removeAttendee: "移除 {{email}}",
6128
6136
  searchingPeople: "正在搜索人员",
@@ -6238,7 +6246,11 @@ const translatedCalendarRemainingRaw = {
6238
6246
  contactsReconnect:
6239
6247
  "Hay que volver a conectar el acceso a contactos o directorio.",
6240
6248
  directory: "Directorio",
6249
+ guestOptions: "Opciones de invitado para {{email}}",
6241
6250
  inviteEmail: "Invitar a {{email}}",
6251
+ markOptional: "Marcar como opcional",
6252
+ markRequired: "Marcar como obligatorio",
6253
+ optionalBadge: "Opcional",
6242
6254
  otherContacts: "Otros contactos",
6243
6255
  removeAttendee: "Quitar {{email}}",
6244
6256
  searchingPeople: "Buscando personas",
@@ -6578,7 +6590,11 @@ const translatedCalendarExactCleanup = {
6578
6590
  contactsReconnect:
6579
6591
  "L’accès aux contacts ou à l’annuaire doit être reconnecté.",
6580
6592
  directory: "Annuaire",
6593
+ guestOptions: "Options d’invité pour {{email}}",
6581
6594
  inviteEmail: "Inviter {{email}}",
6595
+ markOptional: "Marquer comme facultatif",
6596
+ markRequired: "Marquer comme obligatoire",
6597
+ optionalBadge: "Facultatif",
6582
6598
  otherContacts: "Autres contacts",
6583
6599
  removeAttendee: "Retirer {{email}}",
6584
6600
  searchingPeople: "Recherche de personnes",
@@ -6763,7 +6779,11 @@ const translatedCalendarExactCleanup = {
6763
6779
  contactsReconnect:
6764
6780
  "Kontakte oder Verzeichniszugriff müssen erneut verbunden werden.",
6765
6781
  directory: "Verzeichnis",
6782
+ guestOptions: "Gastoptionen für {{email}}",
6766
6783
  inviteEmail: "{{email}} einladen",
6784
+ markOptional: "Als optional markieren",
6785
+ markRequired: "Als erforderlich markieren",
6786
+ optionalBadge: "Optional",
6767
6787
  otherContacts: "Weitere Kontakte",
6768
6788
  removeAttendee: "{{email}} entfernen",
6769
6789
  searchingPeople: "Personen werden gesucht",
@@ -6938,7 +6958,11 @@ const translatedCalendarExactCleanup = {
6938
6958
  contacts: "連絡先",
6939
6959
  contactsReconnect: "連絡先またはディレクトリアクセスの再接続が必要です。",
6940
6960
  directory: "ディレクトリ",
6961
+ guestOptions: "{{email}} のゲストオプション",
6941
6962
  inviteEmail: "{{email}} を招待",
6963
+ markOptional: "任意出席者にする",
6964
+ markRequired: "必須出席者にする",
6965
+ optionalBadge: "任意",
6942
6966
  otherContacts: "その他の連絡先",
6943
6967
  removeAttendee: "{{email}} を削除",
6944
6968
  searchingPeople: "ユーザーを検索中",
@@ -7104,7 +7128,11 @@ const translatedCalendarExactCleanup = {
7104
7128
  contacts: "연락처",
7105
7129
  contactsReconnect: "연락처 또는 디렉터리 액세스를 다시 연결해야 합니다.",
7106
7130
  directory: "디렉터리",
7131
+ guestOptions: "{{email}} 게스트 옵션",
7107
7132
  inviteEmail: "{{email}} 초대",
7133
+ markOptional: "선택으로 표시",
7134
+ markRequired: "필수로 표시",
7135
+ optionalBadge: "선택",
7108
7136
  otherContacts: "기타 연락처",
7109
7137
  removeAttendee: "{{email}} 제거",
7110
7138
  searchingPeople: "사람 검색 중",
@@ -7279,7 +7307,11 @@ const translatedCalendarExactCleanup = {
7279
7307
  contactsReconnect:
7280
7308
  "O acesso a contatos ou diretório precisa ser reconectado.",
7281
7309
  directory: "Diretório",
7310
+ guestOptions: "Opções de convidado para {{email}}",
7282
7311
  inviteEmail: "Convidar {{email}}",
7312
+ markOptional: "Marcar como opcional",
7313
+ markRequired: "Marcar como obrigatório",
7314
+ optionalBadge: "Opcional",
7283
7315
  otherContacts: "Outros contatos",
7284
7316
  removeAttendee: "Remover {{email}}",
7285
7317
  searchingPeople: "Pesquisando pessoas",
@@ -7454,7 +7486,11 @@ const translatedCalendarExactCleanup = {
7454
7486
  contacts: "संपर्क",
7455
7487
  contactsReconnect: "संपर्क या डायरेक्टरी एक्सेस को फिर से कनेक्ट करना होगा।",
7456
7488
  directory: "डायरेक्टरी",
7489
+ guestOptions: "{{email}} के लिए अतिथि विकल्प",
7457
7490
  inviteEmail: "{{email}} को आमंत्रित करें",
7491
+ markOptional: "वैकल्पिक के रूप में चिह्नित करें",
7492
+ markRequired: "आवश्यक के रूप में चिह्नित करें",
7493
+ optionalBadge: "वैकल्पिक",
7458
7494
  otherContacts: "अन्य संपर्क",
7459
7495
  removeAttendee: "{{email}} हटाएं",
7460
7496
  searchingPeople: "लोग खोजे जा रहे हैं",
@@ -7624,7 +7660,11 @@ const translatedCalendarExactCleanup = {
7624
7660
  contacts: "جهات الاتصال",
7625
7661
  contactsReconnect: "يلزم إعادة توصيل الوصول إلى جهات الاتصال أو الدليل.",
7626
7662
  directory: "الدليل",
7663
+ guestOptions: "خيارات الضيف لـ {{email}}",
7627
7664
  inviteEmail: "دعوة {{email}}",
7665
+ markOptional: "تعيين كاختياري",
7666
+ markRequired: "تعيين كإلزامي",
7667
+ optionalBadge: "اختياري",
7628
7668
  otherContacts: "جهات اتصال أخرى",
7629
7669
  removeAttendee: "إزالة {{email}}",
7630
7670
  searchingPeople: "جارٍ البحث عن أشخاص",
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-07
4
+ ---
5
+
6
+ Guest suggestions now find coworkers from your Google Workspace directory as you type.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-07
4
+ ---
5
+
6
+ You can mark event guests as optional while inviting them or later from the guest list