@agent-native/core 0.90.2 → 0.90.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. package/bin/agent-native.js +25 -3
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +21 -0
  4. package/corpus/core/bin/agent-native.js +25 -3
  5. package/corpus/core/docs/content/agent-native-toolkit.mdx +87 -80
  6. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  7. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  8. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  9. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  10. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  11. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  12. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  13. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  14. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  15. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  16. package/corpus/core/docs/content/toolkit-agent-ux.mdx +43 -0
  17. package/corpus/core/docs/content/toolkit-app-adapters.mdx +9 -0
  18. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +12 -0
  19. package/corpus/core/docs/content/toolkit-collaboration.mdx +74 -0
  20. package/corpus/core/docs/content/toolkit-command-navigation.mdx +106 -0
  21. package/corpus/core/docs/content/toolkit-comments-review.mdx +98 -0
  22. package/corpus/core/docs/content/toolkit-history.mdx +95 -0
  23. package/corpus/core/docs/content/toolkit-observability.mdx +41 -0
  24. package/corpus/core/docs/content/toolkit-org-team.mdx +80 -0
  25. package/corpus/core/docs/content/toolkit-resources.mdx +57 -0
  26. package/corpus/core/docs/content/toolkit-settings.mdx +65 -0
  27. package/corpus/core/docs/content/toolkit-setup-connections.mdx +109 -0
  28. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +18 -6
  29. package/corpus/core/docs/content/toolkit-sharing.mdx +81 -0
  30. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +9 -0
  31. package/corpus/core/docs/content/toolkit-ui.mdx +9 -0
  32. package/corpus/core/package.json +35 -1
  33. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +19 -1
  34. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -1
  35. package/corpus/core/src/agent/engine/index.ts +1 -0
  36. package/corpus/core/src/agent/engine/registry.ts +86 -18
  37. package/corpus/core/src/agent/production-agent.ts +37 -6
  38. package/corpus/core/src/cli/create.ts +35 -0
  39. package/corpus/core/src/cli/design-connect.ts +248 -0
  40. package/corpus/core/src/cli/index.ts +84 -7
  41. package/corpus/core/src/cli/workspacify.ts +34 -0
  42. package/corpus/core/src/client/command-navigation/index.ts +15 -0
  43. package/corpus/core/src/client/comments-review/index.ts +1 -0
  44. package/corpus/core/src/client/history/VersionHistoryPanel.tsx +175 -0
  45. package/corpus/core/src/client/history/index.ts +21 -0
  46. package/corpus/core/src/client/history/use-history.ts +114 -0
  47. package/corpus/core/src/client/index.ts +84 -9
  48. package/corpus/core/src/client/org/OrgSwitcher.tsx +6 -6
  49. package/corpus/core/src/client/org/RequireActiveOrg.tsx +2 -2
  50. package/corpus/core/src/client/org/TeamPage.tsx +3 -3
  51. package/corpus/core/src/client/org/hooks.ts +32 -0
  52. package/corpus/core/src/client/org/index.ts +30 -1
  53. package/corpus/core/src/client/org-team/index.ts +1 -0
  54. package/corpus/core/src/client/review/ReviewStatusBadge.tsx +39 -0
  55. package/corpus/core/src/client/review/ReviewThreadPanel.tsx +278 -0
  56. package/corpus/core/src/client/review/index.ts +30 -0
  57. package/corpus/core/src/client/review/use-review.ts +152 -0
  58. package/corpus/core/src/client/settings/index.ts +11 -1
  59. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +94 -0
  60. package/corpus/core/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  61. package/corpus/core/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  62. package/corpus/core/src/client/setup-connections/index.ts +46 -0
  63. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -14
  64. package/corpus/core/src/client/sharing/ShareDialog.tsx +3 -3
  65. package/corpus/core/src/command-navigation/actions.ts +100 -0
  66. package/corpus/core/src/command-navigation/index.ts +12 -0
  67. package/corpus/core/src/comments-review/index.ts +1 -0
  68. package/corpus/core/src/file-upload/builder.ts +24 -3
  69. package/corpus/core/src/file-upload/types.ts +3 -1
  70. package/corpus/core/src/history/actions/create-resource-version.ts +92 -0
  71. package/corpus/core/src/history/actions/get-resource-version.ts +60 -0
  72. package/corpus/core/src/history/actions/list-resource-history.ts +53 -0
  73. package/corpus/core/src/history/actions/list-resource-versions.ts +43 -0
  74. package/corpus/core/src/history/actions/restore-resource-version.ts +96 -0
  75. package/corpus/core/src/history/index.ts +26 -0
  76. package/corpus/core/src/history/registry.ts +111 -0
  77. package/corpus/core/src/history/store.ts +379 -0
  78. package/corpus/core/src/history/types.ts +69 -0
  79. package/corpus/core/src/index.ts +10 -0
  80. package/corpus/core/src/navigation/index.ts +170 -0
  81. package/corpus/core/src/org/index.ts +8 -0
  82. package/corpus/core/src/org/permissions.ts +30 -0
  83. package/corpus/core/src/org-team/index.ts +1 -0
  84. package/corpus/core/src/private-blob/registry.ts +1 -0
  85. package/corpus/core/src/review/actions/consume-review-feedback.ts +48 -0
  86. package/corpus/core/src/review/actions/create-review-comment.ts +107 -0
  87. package/corpus/core/src/review/actions/delete-review-comment.ts +67 -0
  88. package/corpus/core/src/review/actions/get-review-feedback.ts +54 -0
  89. package/corpus/core/src/review/actions/list-review-comments.ts +53 -0
  90. package/corpus/core/src/review/actions/reply-review-comment.ts +107 -0
  91. package/corpus/core/src/review/actions/resolve-review-thread.ts +67 -0
  92. package/corpus/core/src/review/actions/set-review-status.ts +58 -0
  93. package/corpus/core/src/review/index.ts +31 -0
  94. package/corpus/core/src/review/mentions.ts +44 -0
  95. package/corpus/core/src/review/registry.ts +111 -0
  96. package/corpus/core/src/review/store.ts +690 -0
  97. package/corpus/core/src/review/types.ts +97 -0
  98. package/corpus/core/src/server/action-discovery.ts +54 -0
  99. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  100. package/corpus/core/src/server/agent-engine-api-key-route.ts +5 -0
  101. package/corpus/core/src/server/credential-provider.ts +118 -0
  102. package/corpus/core/src/setup-connections/index.ts +89 -0
  103. package/corpus/core/src/setup-connections/onboarding.ts +47 -0
  104. package/corpus/core/src/transcription/builder-transcription.ts +9 -2
  105. package/corpus/core/src/vite/action-types-plugin.ts +52 -0
  106. package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -1
  107. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +2 -2
  108. package/corpus/templates/analytics/app/global.css +22 -10
  109. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -1
  110. package/corpus/templates/analytics/app/i18n-data.ts +81 -13
  111. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
  112. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  113. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +528 -108
  114. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +466 -183
  115. package/corpus/templates/analytics/changelog/2026-07-07-session-replays-load-sooner-show-clearer-activity-timelines-.md +6 -0
  116. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +11 -11
  117. package/corpus/templates/assets/actions/generate-image.ts +64 -28
  118. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +1 -1
  119. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +91 -74
  120. package/corpus/templates/assets/server/lib/generation.ts +29 -4
  121. package/corpus/templates/assets/server/lib/image-processing.ts +131 -0
  122. package/corpus/templates/brain/app/routes/settings.tsx +2 -2
  123. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +24 -2
  124. package/corpus/templates/calendar/AGENTS.md +3 -0
  125. package/corpus/templates/calendar/actions/create-event.ts +8 -34
  126. package/corpus/templates/calendar/actions/event-action-helpers.ts +52 -0
  127. package/corpus/templates/calendar/actions/manage-event-draft.ts +7 -34
  128. package/corpus/templates/calendar/actions/update-event.ts +10 -23
  129. package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +79 -6
  130. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +23 -0
  131. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +59 -2
  132. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +40 -1
  133. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +154 -41
  134. package/corpus/templates/calendar/app/hooks/use-events.ts +6 -0
  135. package/corpus/templates/calendar/app/hooks/use-people.ts +55 -0
  136. package/corpus/templates/calendar/app/i18n/zh-TW.ts +4 -0
  137. package/corpus/templates/calendar/app/i18n-data.ts +40 -0
  138. package/corpus/templates/calendar/changelog/2026-07-07-guest-suggestions-now-find-coworkers-from-your-google-worksp.md +6 -0
  139. package/corpus/templates/calendar/changelog/2026-07-07-you-can-mark-event-guests-as-optional-while-inviting-them-or.md +6 -0
  140. package/corpus/templates/calendar/changelog/2026-07-07-zoom-stays-selected-after-connecting-it-from-a-draft-event.md +6 -0
  141. package/corpus/templates/calendar/server/handlers/events.ts +1 -0
  142. package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -0
  143. package/corpus/templates/calendar/server/plugins/agent-chat.ts +1 -1
  144. package/corpus/templates/calendar/shared/api.ts +2 -0
  145. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +29 -3
  146. package/corpus/templates/clips/actions/create-recording.ts +5 -1
  147. package/corpus/templates/clips/actions/finalize-recording.ts +140 -1
  148. package/corpus/templates/clips/actions/generate-workflow.ts +19 -8
  149. package/corpus/templates/clips/actions/get-clips-ai-prefs.ts +36 -0
  150. package/corpus/templates/clips/actions/import-loom-recording.ts +1 -0
  151. package/corpus/templates/clips/actions/lib/clips-ai-prefs.ts +28 -0
  152. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +1 -0
  153. package/corpus/templates/clips/actions/regenerate-chapters.ts +21 -7
  154. package/corpus/templates/clips/actions/regenerate-summary.ts +26 -8
  155. package/corpus/templates/clips/actions/regenerate-title.ts +44 -7
  156. package/corpus/templates/clips/actions/request-transcript.ts +31 -0
  157. package/corpus/templates/clips/actions/set-thumbnail.ts +2 -0
  158. package/corpus/templates/clips/actions/update-clips-ai-prefs.ts +50 -0
  159. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  160. package/corpus/templates/clips/app/components/meetings/meeting-card.tsx +7 -2
  161. package/corpus/templates/clips/app/components/player/scrubber-position.ts +9 -0
  162. package/corpus/templates/clips/app/components/player/scrubber.tsx +5 -2
  163. package/corpus/templates/clips/app/components/player/share-dialog.tsx +69 -41
  164. package/corpus/templates/clips/app/components/player/video-player.tsx +38 -1
  165. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -3
  166. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +9 -19
  167. package/corpus/templates/clips/app/hooks/use-auto-title.ts +25 -10
  168. package/corpus/templates/clips/app/i18n/ar-SA.ts +28 -6
  169. package/corpus/templates/clips/app/i18n/de-DE.ts +28 -6
  170. package/corpus/templates/clips/app/i18n/en-US.ts +29 -6
  171. package/corpus/templates/clips/app/i18n/es-ES.ts +29 -6
  172. package/corpus/templates/clips/app/i18n/fr-FR.ts +30 -6
  173. package/corpus/templates/clips/app/i18n/hi-IN.ts +26 -6
  174. package/corpus/templates/clips/app/i18n/ja-JP.ts +27 -6
  175. package/corpus/templates/clips/app/i18n/ko-KR.ts +28 -6
  176. package/corpus/templates/clips/app/i18n/pt-BR.ts +28 -6
  177. package/corpus/templates/clips/app/i18n/zh-CN.ts +26 -6
  178. package/corpus/templates/clips/app/i18n/zh-TW.ts +25 -6
  179. package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +73 -0
  180. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +1 -0
  181. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +79 -5
  182. package/corpus/templates/clips/app/routes/record.tsx +21 -12
  183. package/corpus/templates/clips/changelog/2026-07-02-recordings-now-wait-for-storage-media-to-serve-before-finishing.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-07-a-pending-app-update-no-longer-blocks-screen-recording-updat.md +6 -0
  185. package/corpus/templates/clips/changelog/2026-07-07-ai-tools-can-include-the-full-video-not-just-the-transcript-.md +6 -0
  186. package/corpus/templates/clips/changelog/2026-07-07-chrome-extension-recordings-keep-audio-after-refreshing-tab.md +6 -0
  187. package/corpus/templates/clips/changelog/2026-07-07-clip-playback-progress-now-starts-and-finishes-at-the-right-times.md +6 -0
  188. package/corpus/templates/clips/changelog/2026-07-07-clips-desktop-now-surfaces-meetings-and-dictate-directly-in-.md +6 -0
  189. package/corpus/templates/clips/changelog/2026-07-07-meeting-notes-now-explain-exactly-how-to-start-granola-style.md +6 -0
  190. package/corpus/templates/clips/changelog/2026-07-07-meeting-start-alerts-now-include-separate-start-notes-and-jo.md +6 -0
  191. package/corpus/templates/clips/changelog/2026-07-07-recordings-start-more-predictably-and-newly-saved-clips-refr.md +6 -0
  192. package/corpus/templates/clips/changelog/2026-07-07-sharing-public-clips-now-stays-focused-on-the-normal-link-wi.md +6 -0
  193. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  194. package/corpus/templates/clips/chrome-extension/src/background.ts +18 -0
  195. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +23 -8
  196. package/corpus/templates/clips/desktop/src/app.tsx +475 -108
  197. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +19 -7
  198. package/corpus/templates/clips/desktop/src/lib/permissions.ts +2 -0
  199. package/corpus/templates/clips/desktop/src/lib/recorder.ts +27 -21
  200. package/corpus/templates/clips/desktop/src/lib/updater.ts +25 -2
  201. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -22
  202. package/corpus/templates/clips/desktop/src/styles.css +167 -2
  203. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +8 -1
  204. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -7
  205. package/corpus/templates/clips/desktop/src-tauri/src/tray_meetings.rs +5 -4
  206. package/corpus/templates/clips/server/routes/_agent-native/clips/user-prefs.put.ts +16 -8
  207. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +1 -0
  208. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +22 -5
  209. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +8 -0
  210. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +13 -6
  211. package/corpus/templates/clips/shared/clips-ai-prefs.ts +81 -0
  212. package/corpus/templates/clips/shared/finalize-recovery.ts +12 -0
  213. package/corpus/templates/content/actions/delete-document.ts +337 -52
  214. package/corpus/templates/content/changelog/2026-07-07-permanently-deleting-trashed-databases-now-finishes-reliably.md +6 -0
  215. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +16 -1
  216. package/corpus/templates/design/actions/add-localhost-screens.ts +1 -0
  217. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +345 -11
  218. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +89 -14
  219. package/corpus/templates/design/app/components/design/bridge-security.ts +7 -1
  220. package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -1
  221. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  222. package/corpus/templates/design/app/i18n-data.ts +41 -0
  223. package/corpus/templates/design/changelog/2026-07-07-local-visual-edit-uses-live-app-iframes-for-click-to-edit-pr.md +6 -0
  224. package/corpus/templates/slides/app/pages/DeckEditor.tsx +2 -2
  225. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  226. package/dist/agent/engine/ai-sdk-engine.js +15 -1
  227. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  228. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  229. package/dist/agent/engine/anthropic-engine.js +20 -1
  230. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  231. package/dist/agent/engine/index.d.ts +1 -1
  232. package/dist/agent/engine/index.d.ts.map +1 -1
  233. package/dist/agent/engine/index.js +1 -1
  234. package/dist/agent/engine/index.js.map +1 -1
  235. package/dist/agent/engine/registry.d.ts +14 -0
  236. package/dist/agent/engine/registry.d.ts.map +1 -1
  237. package/dist/agent/engine/registry.js +78 -16
  238. package/dist/agent/engine/registry.js.map +1 -1
  239. package/dist/agent/production-agent.d.ts.map +1 -1
  240. package/dist/agent/production-agent.js +27 -7
  241. package/dist/agent/production-agent.js.map +1 -1
  242. package/dist/cli/create.d.ts.map +1 -1
  243. package/dist/cli/create.js +31 -0
  244. package/dist/cli/create.js.map +1 -1
  245. package/dist/cli/design-connect.d.ts.map +1 -1
  246. package/dist/cli/design-connect.js +186 -0
  247. package/dist/cli/design-connect.js.map +1 -1
  248. package/dist/cli/index.js +76 -9
  249. package/dist/cli/index.js.map +1 -1
  250. package/dist/cli/workspacify.d.ts.map +1 -1
  251. package/dist/cli/workspacify.js +30 -0
  252. package/dist/cli/workspacify.js.map +1 -1
  253. package/dist/client/command-navigation/index.d.ts +4 -0
  254. package/dist/client/command-navigation/index.d.ts.map +1 -0
  255. package/dist/client/command-navigation/index.js +4 -0
  256. package/dist/client/command-navigation/index.js.map +1 -0
  257. package/dist/client/comments-review/index.d.ts +2 -0
  258. package/dist/client/comments-review/index.d.ts.map +1 -0
  259. package/dist/client/comments-review/index.js +2 -0
  260. package/dist/client/comments-review/index.js.map +1 -0
  261. package/dist/client/history/VersionHistoryPanel.d.ts +18 -0
  262. package/dist/client/history/VersionHistoryPanel.d.ts.map +1 -0
  263. package/dist/client/history/VersionHistoryPanel.js +31 -0
  264. package/dist/client/history/VersionHistoryPanel.js.map +1 -0
  265. package/dist/client/history/index.d.ts +3 -0
  266. package/dist/client/history/index.d.ts.map +1 -0
  267. package/dist/client/history/index.js +3 -0
  268. package/dist/client/history/index.js.map +1 -0
  269. package/dist/client/history/use-history.d.ts +58 -0
  270. package/dist/client/history/use-history.d.ts.map +1 -0
  271. package/dist/client/history/use-history.js +24 -0
  272. package/dist/client/history/use-history.js.map +1 -0
  273. package/dist/client/index.d.ts +6 -4
  274. package/dist/client/index.d.ts.map +1 -1
  275. package/dist/client/index.js +6 -4
  276. package/dist/client/index.js.map +1 -1
  277. package/dist/client/org/OrgSwitcher.js +5 -5
  278. package/dist/client/org/OrgSwitcher.js.map +1 -1
  279. package/dist/client/org/RequireActiveOrg.js +2 -2
  280. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  281. package/dist/client/org/TeamPage.js +3 -3
  282. package/dist/client/org/TeamPage.js.map +1 -1
  283. package/dist/client/org/hooks.d.ts +12 -1
  284. package/dist/client/org/hooks.d.ts.map +1 -1
  285. package/dist/client/org/hooks.js +15 -0
  286. package/dist/client/org/hooks.js.map +1 -1
  287. package/dist/client/org/index.d.ts +4 -2
  288. package/dist/client/org/index.d.ts.map +1 -1
  289. package/dist/client/org/index.js +3 -1
  290. package/dist/client/org/index.js.map +1 -1
  291. package/dist/client/org-team/index.d.ts +2 -0
  292. package/dist/client/org-team/index.d.ts.map +1 -0
  293. package/dist/client/org-team/index.js +2 -0
  294. package/dist/client/org-team/index.js.map +1 -0
  295. package/dist/client/review/ReviewStatusBadge.d.ts +7 -0
  296. package/dist/client/review/ReviewStatusBadge.d.ts.map +1 -0
  297. package/dist/client/review/ReviewStatusBadge.js +19 -0
  298. package/dist/client/review/ReviewStatusBadge.js.map +1 -0
  299. package/dist/client/review/ReviewThreadPanel.d.ts +20 -0
  300. package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -0
  301. package/dist/client/review/ReviewThreadPanel.js +84 -0
  302. package/dist/client/review/ReviewThreadPanel.js.map +1 -0
  303. package/dist/client/review/index.d.ts +4 -0
  304. package/dist/client/review/index.d.ts.map +1 -0
  305. package/dist/client/review/index.js +4 -0
  306. package/dist/client/review/index.js.map +1 -0
  307. package/dist/client/review/use-review.d.ts +91 -0
  308. package/dist/client/review/use-review.d.ts.map +1 -0
  309. package/dist/client/review/use-review.js +30 -0
  310. package/dist/client/review/use-review.js.map +1 -0
  311. package/dist/client/settings/index.d.ts +1 -1
  312. package/dist/client/settings/index.d.ts.map +1 -1
  313. package/dist/client/settings/index.js +1 -1
  314. package/dist/client/settings/index.js.map +1 -1
  315. package/dist/client/setup-connections/BuilderConnectCard.d.ts +9 -0
  316. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -0
  317. package/dist/client/setup-connections/BuilderConnectCard.js +25 -0
  318. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -0
  319. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts +8 -0
  320. package/dist/client/setup-connections/ProviderReadinessBadge.d.ts.map +1 -0
  321. package/dist/client/setup-connections/ProviderReadinessBadge.js +32 -0
  322. package/dist/client/setup-connections/ProviderReadinessBadge.js.map +1 -0
  323. package/dist/client/setup-connections/SetupConnectionsPage.d.ts +17 -0
  324. package/dist/client/setup-connections/SetupConnectionsPage.d.ts.map +1 -0
  325. package/dist/client/setup-connections/SetupConnectionsPage.js +10 -0
  326. package/dist/client/setup-connections/SetupConnectionsPage.js.map +1 -0
  327. package/dist/client/setup-connections/index.d.ts +7 -0
  328. package/dist/client/setup-connections/index.d.ts.map +1 -0
  329. package/dist/client/setup-connections/index.js +7 -0
  330. package/dist/client/setup-connections/index.js.map +1 -0
  331. package/dist/client/sharing/ShareButton.d.ts +4 -4
  332. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  333. package/dist/client/sharing/ShareButton.js +13 -7
  334. package/dist/client/sharing/ShareButton.js.map +1 -1
  335. package/dist/client/sharing/ShareDialog.js +3 -3
  336. package/dist/client/sharing/ShareDialog.js.map +1 -1
  337. package/dist/collab/awareness.d.ts +2 -2
  338. package/dist/collab/awareness.d.ts.map +1 -1
  339. package/dist/collab/routes.d.ts +1 -1
  340. package/dist/collab/struct-routes.d.ts +1 -1
  341. package/dist/command-navigation/actions.d.ts +25 -0
  342. package/dist/command-navigation/actions.d.ts.map +1 -0
  343. package/dist/command-navigation/actions.js +64 -0
  344. package/dist/command-navigation/actions.js.map +1 -0
  345. package/dist/command-navigation/index.d.ts +4 -0
  346. package/dist/command-navigation/index.d.ts.map +1 -0
  347. package/dist/command-navigation/index.js +4 -0
  348. package/dist/command-navigation/index.js.map +1 -0
  349. package/dist/comments-review/index.d.ts +2 -0
  350. package/dist/comments-review/index.d.ts.map +1 -0
  351. package/dist/comments-review/index.js +2 -0
  352. package/dist/comments-review/index.js.map +1 -0
  353. package/dist/file-upload/builder.d.ts.map +1 -1
  354. package/dist/file-upload/builder.js +18 -2
  355. package/dist/file-upload/builder.js.map +1 -1
  356. package/dist/file-upload/types.d.ts +3 -0
  357. package/dist/file-upload/types.d.ts.map +1 -1
  358. package/dist/file-upload/types.js.map +1 -1
  359. package/dist/history/actions/create-resource-version.d.ts +10 -0
  360. package/dist/history/actions/create-resource-version.d.ts.map +1 -0
  361. package/dist/history/actions/create-resource-version.js +68 -0
  362. package/dist/history/actions/create-resource-version.js.map +1 -0
  363. package/dist/history/actions/get-resource-version.d.ts +10 -0
  364. package/dist/history/actions/get-resource-version.d.ts.map +1 -0
  365. package/dist/history/actions/get-resource-version.js +38 -0
  366. package/dist/history/actions/get-resource-version.js.map +1 -0
  367. package/dist/history/actions/list-resource-history.d.ts +10 -0
  368. package/dist/history/actions/list-resource-history.d.ts.map +1 -0
  369. package/dist/history/actions/list-resource-history.js +45 -0
  370. package/dist/history/actions/list-resource-history.js.map +1 -0
  371. package/dist/history/actions/list-resource-versions.d.ts +10 -0
  372. package/dist/history/actions/list-resource-versions.d.ts.map +1 -0
  373. package/dist/history/actions/list-resource-versions.js +35 -0
  374. package/dist/history/actions/list-resource-versions.js.map +1 -0
  375. package/dist/history/actions/restore-resource-version.d.ts +11 -0
  376. package/dist/history/actions/restore-resource-version.d.ts.map +1 -0
  377. package/dist/history/actions/restore-resource-version.js +59 -0
  378. package/dist/history/actions/restore-resource-version.js.map +1 -0
  379. package/dist/history/index.d.ts +4 -0
  380. package/dist/history/index.d.ts.map +1 -0
  381. package/dist/history/index.js +3 -0
  382. package/dist/history/index.js.map +1 -0
  383. package/dist/history/registry.d.ts +10 -0
  384. package/dist/history/registry.d.ts.map +1 -0
  385. package/dist/history/registry.js +63 -0
  386. package/dist/history/registry.js.map +1 -0
  387. package/dist/history/store.d.ts +34 -0
  388. package/dist/history/store.d.ts.map +1 -0
  389. package/dist/history/store.js +290 -0
  390. package/dist/history/store.js.map +1 -0
  391. package/dist/history/types.d.ts +55 -0
  392. package/dist/history/types.d.ts.map +1 -0
  393. package/dist/history/types.js +2 -0
  394. package/dist/history/types.js.map +1 -0
  395. package/dist/index.d.ts +6 -0
  396. package/dist/index.d.ts.map +1 -1
  397. package/dist/index.js +6 -0
  398. package/dist/index.js.map +1 -1
  399. package/dist/navigation/index.d.ts +53 -0
  400. package/dist/navigation/index.d.ts.map +1 -0
  401. package/dist/navigation/index.js +105 -0
  402. package/dist/navigation/index.js.map +1 -0
  403. package/dist/observability/routes.d.ts +3 -3
  404. package/dist/org/index.d.ts +1 -0
  405. package/dist/org/index.d.ts.map +1 -1
  406. package/dist/org/index.js +1 -0
  407. package/dist/org/index.js.map +1 -1
  408. package/dist/org/permissions.d.ts +7 -0
  409. package/dist/org/permissions.d.ts.map +1 -0
  410. package/dist/org/permissions.js +21 -0
  411. package/dist/org/permissions.js.map +1 -0
  412. package/dist/org-team/index.d.ts +2 -0
  413. package/dist/org-team/index.d.ts.map +1 -0
  414. package/dist/org-team/index.js +2 -0
  415. package/dist/org-team/index.js.map +1 -0
  416. package/dist/private-blob/registry.d.ts.map +1 -1
  417. package/dist/private-blob/registry.js +1 -0
  418. package/dist/private-blob/registry.js.map +1 -1
  419. package/dist/progress/routes.d.ts +1 -1
  420. package/dist/resources/handlers.d.ts +2 -2
  421. package/dist/review/actions/consume-review-feedback.d.ts +10 -0
  422. package/dist/review/actions/consume-review-feedback.d.ts.map +1 -0
  423. package/dist/review/actions/consume-review-feedback.js +35 -0
  424. package/dist/review/actions/consume-review-feedback.js.map +1 -0
  425. package/dist/review/actions/create-review-comment.d.ts +18 -0
  426. package/dist/review/actions/create-review-comment.d.ts.map +1 -0
  427. package/dist/review/actions/create-review-comment.js +81 -0
  428. package/dist/review/actions/create-review-comment.js.map +1 -0
  429. package/dist/review/actions/delete-review-comment.d.ts +11 -0
  430. package/dist/review/actions/delete-review-comment.d.ts.map +1 -0
  431. package/dist/review/actions/delete-review-comment.js +53 -0
  432. package/dist/review/actions/delete-review-comment.js.map +1 -0
  433. package/dist/review/actions/get-review-feedback.d.ts +10 -0
  434. package/dist/review/actions/get-review-feedback.d.ts.map +1 -0
  435. package/dist/review/actions/get-review-feedback.js +45 -0
  436. package/dist/review/actions/get-review-feedback.js.map +1 -0
  437. package/dist/review/actions/list-review-comments.d.ts +13 -0
  438. package/dist/review/actions/list-review-comments.d.ts.map +1 -0
  439. package/dist/review/actions/list-review-comments.js +44 -0
  440. package/dist/review/actions/list-review-comments.js.map +1 -0
  441. package/dist/review/actions/reply-review-comment.d.ts +16 -0
  442. package/dist/review/actions/reply-review-comment.d.ts.map +1 -0
  443. package/dist/review/actions/reply-review-comment.js +84 -0
  444. package/dist/review/actions/reply-review-comment.js.map +1 -0
  445. package/dist/review/actions/resolve-review-thread.d.ts +12 -0
  446. package/dist/review/actions/resolve-review-thread.d.ts.map +1 -0
  447. package/dist/review/actions/resolve-review-thread.js +49 -0
  448. package/dist/review/actions/resolve-review-thread.js.map +1 -0
  449. package/dist/review/actions/set-review-status.d.ts +9 -0
  450. package/dist/review/actions/set-review-status.d.ts.map +1 -0
  451. package/dist/review/actions/set-review-status.js +43 -0
  452. package/dist/review/actions/set-review-status.js.map +1 -0
  453. package/dist/review/index.d.ts +5 -0
  454. package/dist/review/index.d.ts.map +1 -0
  455. package/dist/review/index.js +4 -0
  456. package/dist/review/index.js.map +1 -0
  457. package/dist/review/mentions.d.ts +4 -0
  458. package/dist/review/mentions.d.ts.map +1 -0
  459. package/dist/review/mentions.js +39 -0
  460. package/dist/review/mentions.js.map +1 -0
  461. package/dist/review/registry.d.ts +10 -0
  462. package/dist/review/registry.d.ts.map +1 -0
  463. package/dist/review/registry.js +63 -0
  464. package/dist/review/registry.js.map +1 -0
  465. package/dist/review/store.d.ts +63 -0
  466. package/dist/review/store.d.ts.map +1 -0
  467. package/dist/review/store.js +561 -0
  468. package/dist/review/store.js.map +1 -0
  469. package/dist/review/types.d.ts +77 -0
  470. package/dist/review/types.d.ts.map +1 -0
  471. package/dist/review/types.js +2 -0
  472. package/dist/review/types.js.map +1 -0
  473. package/dist/secrets/routes.d.ts +9 -9
  474. package/dist/server/action-discovery.d.ts.map +1 -1
  475. package/dist/server/action-discovery.js +54 -0
  476. package/dist/server/action-discovery.js.map +1 -1
  477. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  478. package/dist/server/agent-chat-plugin.js +5 -0
  479. package/dist/server/agent-chat-plugin.js.map +1 -1
  480. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  481. package/dist/server/agent-engine-api-key-route.d.ts.map +1 -1
  482. package/dist/server/agent-engine-api-key-route.js +5 -0
  483. package/dist/server/agent-engine-api-key-route.js.map +1 -1
  484. package/dist/server/credential-provider.d.ts +28 -0
  485. package/dist/server/credential-provider.d.ts.map +1 -1
  486. package/dist/server/credential-provider.js +92 -0
  487. package/dist/server/credential-provider.js.map +1 -1
  488. package/dist/setup-connections/index.d.ts +6 -0
  489. package/dist/setup-connections/index.d.ts.map +1 -0
  490. package/dist/setup-connections/index.js +6 -0
  491. package/dist/setup-connections/index.js.map +1 -0
  492. package/dist/setup-connections/onboarding.d.ts +14 -0
  493. package/dist/setup-connections/onboarding.d.ts.map +1 -0
  494. package/dist/setup-connections/onboarding.js +23 -0
  495. package/dist/setup-connections/onboarding.js.map +1 -0
  496. package/dist/transcription/builder-transcription.d.ts +1 -0
  497. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  498. package/dist/transcription/builder-transcription.js +5 -2
  499. package/dist/transcription/builder-transcription.js.map +1 -1
  500. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  501. package/dist/vite/action-types-plugin.js +52 -0
  502. package/dist/vite/action-types-plugin.js.map +1 -1
  503. package/docs/content/agent-native-toolkit.mdx +87 -80
  504. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +89 -80
  505. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +89 -80
  506. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +89 -80
  507. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +89 -80
  508. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +89 -80
  509. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +89 -80
  510. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +89 -80
  511. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +89 -80
  512. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +89 -80
  513. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +89 -80
  514. package/docs/content/toolkit-agent-ux.mdx +43 -0
  515. package/docs/content/toolkit-app-adapters.mdx +9 -0
  516. package/docs/content/toolkit-collaboration-ui.mdx +12 -0
  517. package/docs/content/toolkit-collaboration.mdx +74 -0
  518. package/docs/content/toolkit-command-navigation.mdx +106 -0
  519. package/docs/content/toolkit-comments-review.mdx +98 -0
  520. package/docs/content/toolkit-history.mdx +95 -0
  521. package/docs/content/toolkit-observability.mdx +41 -0
  522. package/docs/content/toolkit-org-team.mdx +80 -0
  523. package/docs/content/toolkit-resources.mdx +57 -0
  524. package/docs/content/toolkit-settings.mdx +65 -0
  525. package/docs/content/toolkit-setup-connections.mdx +109 -0
  526. package/docs/content/toolkit-sharing-ui.mdx +18 -6
  527. package/docs/content/toolkit-sharing.mdx +81 -0
  528. package/docs/content/toolkit-shell-hooks.mdx +9 -0
  529. package/docs/content/toolkit-ui.mdx +9 -0
  530. package/package.json +36 -2
@@ -10,12 +10,12 @@ import {
10
10
  import { TeamPage } from "@agent-native/core/client/org";
11
11
  import {
12
12
  IconAdjustments,
13
- IconBuilding,
14
13
  IconDeviceFloppy,
15
14
  IconFileText,
16
15
  IconGauge,
17
16
  IconMessageCircle,
18
17
  IconShieldCheck,
18
+ IconUsersGroup,
19
19
  } from "@tabler/icons-react";
20
20
  import { useEffect, useMemo, useState } from "react";
21
21
 
@@ -152,7 +152,7 @@ export default function SettingsRoute() {
152
152
  <Card>
153
153
  <CardHeader>
154
154
  <CardTitle className="flex items-center gap-2 text-base">
155
- <IconBuilding className="size-4 text-primary" />
155
+ <IconUsersGroup className="size-4 text-primary" />
156
156
  {t("settings.identityTitle")}
157
157
  </CardTitle>
158
158
  <CardDescription>
@@ -125,6 +125,16 @@ Use only one generated video provider per event: `--addGoogleMeet=true` or `--ad
125
125
 
126
126
  `--attendees` accepts a comma- or space-separated list of email addresses. When attendees are provided, Google sends email invitations automatically (`sendUpdates=all`). Use `--sendUpdates=none` to suppress emails.
127
127
 
128
+ To mark a guest optional, pass attendees as a JSON array with `optional: true`:
129
+
130
+ ```bash
131
+ pnpm action create-event \
132
+ --title "Q2 planning" \
133
+ --start 2026-04-03T14:00:00 \
134
+ --end 2026-04-03T15:00:00 \
135
+ --attendees '[{"email":"alice@example.com"},{"email":"bob@example.com","optional":true}]'
136
+ ```
137
+
128
138
  Use `--startTimeZone` / `--endTimeZone` with IANA timezone names when the event should be anchored to a specific timezone, e.g. `--startTimeZone America/Los_Angeles`.
129
139
 
130
140
  Use `--reminders '[{"method":"popup","minutes":10},{"method":"email","minutes":1440}]'` for multiple alerts. Use `--remindersUseDefault false --reminders '[]'` for no alerts.
@@ -174,6 +184,17 @@ pnpm action update-event \
174
184
  --id google-event-id \
175
185
  --attendees "alice@example.com,bob@example.com,carol@example.com"
176
186
 
187
+ # Prefer addAttendees when inviting more people so existing RSVP metadata is preserved
188
+ pnpm action update-event \
189
+ --id google-event-id \
190
+ --addAttendees '[{"email":"dana@example.com","optional":true}]'
191
+
192
+ # Mark an existing guest optional without resetting RSVPs — fetch via get-event,
193
+ # then pass the full attendees list with optional:true on that guest
194
+ pnpm action update-event \
195
+ --id google-event-id \
196
+ --attendees '[{"email":"alice@example.com"},{"email":"bob@example.com","optional":true}]'
197
+
177
198
  # Suppress invitation emails
178
199
  pnpm action update-event --id google-event-id --attendees "alice@example.com" --sendUpdates none
179
200
 
@@ -189,7 +210,7 @@ pnpm action update-event \
189
210
  --attachments '[{"fileUrl":"https://drive.google.com/...","title":"Agenda"}]'
190
211
  ```
191
212
 
192
- `--attendees` REPLACES the entire attendee list — to add someone, fetch the existing attendees first via `get-event` and pass the merged list. Pass an empty string to clear all attendees.
213
+ `--attendees` REPLACES the entire attendee list — to add someone, prefer `addAttendees` so existing RSVP notes/statuses are preserved. To change whether a guest is optional or required after the fact, fetch the current list via `get-event` and pass the full `attendees` array with `optional: true` or omit/false for required. Pass an empty string to clear all attendees.
193
214
 
194
215
  For "add Zoom to this meeting", fetch or use the visible event id and call `update-event --addZoom=true`. Do not create an extension for Zoom; Zoom is a first-party calendar integration handled by the event actions and the Settings page.
195
216
 
@@ -246,7 +267,8 @@ Events require a connected Google Calendar account. Check with `GET /_agent-nati
246
267
  "location": "Conference Room A",
247
268
  "allDay": false,
248
269
  "attendees": [
249
- { "email": "alice@example.com", "displayName": "Alice", "responseStatus": "accepted" }
270
+ { "email": "alice@example.com", "displayName": "Alice", "responseStatus": "accepted" },
271
+ { "email": "bob@example.com", "displayName": "Bob", "responseStatus": "needsAction", "optional": true }
250
272
  ],
251
273
  "conferenceData": { ... },
252
274
  "hangoutLink": "https://meet.google.com/...",
@@ -50,6 +50,9 @@ Detailed event, availability, booking, storage, and UI rules live in
50
50
  `addAttendees` so existing RSVP notes/statuses are preserved. Use
51
51
  `scope: "all"` only when the user wants a recurring-event guest change applied
52
52
  to the whole series.
53
+ - Pass `optional: true` on an attendee object to mark someone optional when
54
+ creating, drafting, or adding guests. To change optional/required after the
55
+ fact, replace the full `attendees` list with `optional` set on that guest.
53
56
 
54
57
  ## Application State
55
58
 
@@ -13,11 +13,13 @@ import type { CalendarEvent } from "../shared/api.js";
13
13
  import {
14
14
  availabilityInput,
15
15
  attachmentsInput,
16
+ attendeesInput,
16
17
  buildReminderOverrides,
17
18
  buildStatusEventFields,
18
19
  cliBoolean,
19
20
  eventTypeInput,
20
21
  googleColorIdInput,
22
+ normalizeAttendees,
21
23
  reminderMethodInput,
22
24
  reminderMinutesInput,
23
25
  remindersInput,
@@ -25,36 +27,6 @@ import {
25
27
  workingLocationTypeInput,
26
28
  } from "./event-action-helpers.js";
27
29
 
28
- // Accept attendees as either an array of {email, displayName?} objects (when
29
- // invoked via JSON) or a comma/whitespace-separated string of emails (when
30
- // invoked from the CLI as `--attendees alice@x.com,bob@y.com`).
31
- const attendeesInput = z
32
- .union([
33
- z.array(
34
- z.object({
35
- email: z.string(),
36
- displayName: z.string().optional(),
37
- }),
38
- ),
39
- z.string(),
40
- ])
41
- .optional();
42
-
43
- function normalizeAttendees(
44
- input: z.infer<typeof attendeesInput>,
45
- ): Array<{ email: string; displayName?: string }> | undefined {
46
- if (!input) return undefined;
47
- if (typeof input === "string") {
48
- const emails = input
49
- .split(/[\s,;]+/)
50
- .map((s) => s.trim())
51
- .filter((s) => s.length > 0 && s.includes("@"));
52
- if (emails.length === 0) return undefined;
53
- return emails.map((email) => ({ email }));
54
- }
55
- return input.filter((a) => a.email && a.email.includes("@"));
56
- }
57
-
58
30
  export default defineAction({
59
31
  description: "Create a calendar event on Google Calendar",
60
32
  schema: z.object({
@@ -118,9 +90,11 @@ export default defineAction({
118
90
  .describe(
119
91
  "Create and attach a Zoom meeting link to the event. Requires Zoom to be connected in Settings.",
120
92
  ),
121
- attendees: attendeesInput.describe(
122
- "Invitees — either an array of {email, displayName?} or a comma-separated string of emails",
123
- ),
93
+ attendees: attendeesInput
94
+ .optional()
95
+ .describe(
96
+ "Invitees — either an array of {email, displayName?, optional?} or a comma-separated string of emails. Set optional:true to mark a guest optional.",
97
+ ),
124
98
  sendUpdates: z
125
99
  .enum(["all", "externalOnly", "none"])
126
100
  .optional()
@@ -214,7 +188,7 @@ export default defineAction({
214
188
 
215
189
  const result = await googleCalendar.createEvent(calEvent, {
216
190
  addGoogleMeet: args.addGoogleMeet,
217
- sendUpdates: args.sendUpdates ?? (attendees ? "all" : undefined),
191
+ sendUpdates: args.sendUpdates ?? (attendees?.length ? "all" : undefined),
218
192
  });
219
193
  if (result.id) {
220
194
  calEvent.id = `google-${result.id}`;
@@ -60,6 +60,58 @@ export const workingLocationTypeInput = z
60
60
  .enum(["homeOffice", "officeLocation", "customLocation"])
61
61
  .optional();
62
62
 
63
+ export const attendeeObjectInput = z.object({
64
+ email: z.string(),
65
+ displayName: z.string().optional(),
66
+ optional: cliBoolean.optional(),
67
+ comment: z.string().optional(),
68
+ responseStatus: z
69
+ .enum(["accepted", "declined", "tentative", "needsAction"])
70
+ .optional(),
71
+ organizer: cliBoolean.optional(),
72
+ self: cliBoolean.optional(),
73
+ });
74
+
75
+ export const attendeesInput = z.union([
76
+ z.array(attendeeObjectInput),
77
+ z.string(),
78
+ ]);
79
+
80
+ export type NormalizedAttendee = {
81
+ email: string;
82
+ displayName?: string;
83
+ optional?: boolean;
84
+ comment?: string;
85
+ responseStatus?: "accepted" | "declined" | "tentative" | "needsAction";
86
+ organizer?: boolean;
87
+ self?: boolean;
88
+ };
89
+
90
+ export function normalizeAttendees(
91
+ input: z.infer<typeof attendeesInput> | undefined,
92
+ ): NormalizedAttendee[] | undefined {
93
+ if (input === undefined) return undefined;
94
+ if (typeof input === "string") {
95
+ const emails = input
96
+ .split(/[\s,;]+/)
97
+ .map((s) => s.trim())
98
+ .filter((s) => s.length > 0 && s.includes("@"));
99
+ if (emails.length === 0) return [];
100
+ return emails.map((email) => ({ email }));
101
+ }
102
+ return input
103
+ .filter((a) => a.email && a.email.includes("@"))
104
+ .map((a) => ({
105
+ email: a.email,
106
+ ...(a.displayName ? { displayName: a.displayName } : {}),
107
+ ...(a.optional === true ? { optional: true } : {}),
108
+ ...(a.comment ? { comment: a.comment } : {}),
109
+ ...(a.responseStatus ? { responseStatus: a.responseStatus } : {}),
110
+ ...(a.organizer === true ? { organizer: true } : {}),
111
+ ...(a.self === true ? { self: true } : {}),
112
+ }));
113
+ }
114
+
63
115
  export function requireActionUserEmail(): string {
64
116
  const email = getRequestUserEmail();
65
117
  if (!email) throw new Error("no authenticated user");
@@ -11,11 +11,13 @@ import { z } from "zod";
11
11
  import type { CalendarEventDraft } from "../shared/api.js";
12
12
  import {
13
13
  attachmentsInput,
14
+ attendeesInput,
14
15
  availabilityInput,
15
16
  buildReminderOverrides,
16
17
  cliBoolean,
17
18
  eventTypeInput,
18
19
  googleColorIdInput,
20
+ normalizeAttendees,
19
21
  reminderMethodInput,
20
22
  reminderMinutesInput,
21
23
  remindersInput,
@@ -25,18 +27,6 @@ import {
25
27
 
26
28
  const DRAFT_PREFIX = "calendar-draft-";
27
29
 
28
- const attendeesInput = z
29
- .union([
30
- z.array(
31
- z.object({
32
- email: z.string(),
33
- displayName: z.string().optional(),
34
- }),
35
- ),
36
- z.string(),
37
- ])
38
- .optional();
39
-
40
30
  function sanitizeDraftId(id: string): string | null {
41
31
  return /^[a-zA-Z0-9_-]{1,64}$/.test(id) ? id : null;
42
32
  }
@@ -45,25 +35,6 @@ function draftKey(id: string) {
45
35
  return `${DRAFT_PREFIX}${id}`;
46
36
  }
47
37
 
48
- function normalizeAttendees(
49
- input: z.infer<typeof attendeesInput>,
50
- ): CalendarEventDraft["attendees"] | undefined {
51
- if (input === undefined) return undefined;
52
- if (typeof input === "string") {
53
- const emails = input
54
- .split(/[\s,;]+/)
55
- .map((s) => s.trim())
56
- .filter((s) => s.length > 0 && s.includes("@"));
57
- return emails.map((email) => ({ email }));
58
- }
59
- return input
60
- .filter((a) => a.email && a.email.includes("@"))
61
- .map((a) => ({
62
- email: a.email,
63
- ...(a.displayName ? { displayName: a.displayName } : {}),
64
- }));
65
- }
66
-
67
38
  /**
68
39
  * Deep link that reopens an unsent calendar event draft.
69
40
  *
@@ -166,9 +137,11 @@ export default defineAction({
166
137
  .optional()
167
138
  .describe("Preselect Google Meet for this draft"),
168
139
  addZoom: cliBoolean.optional().describe("Preselect Zoom for this draft"),
169
- attendees: attendeesInput.describe(
170
- "Invitees — either an array of {email, displayName?} or a comma-separated string of emails",
171
- ),
140
+ attendees: attendeesInput
141
+ .optional()
142
+ .describe(
143
+ "Invitees — either an array of {email, displayName?, optional?} or a comma-separated string of emails. Set optional:true to mark a guest optional.",
144
+ ),
172
145
  accountEmail: z
173
146
  .string()
174
147
  .optional()
@@ -11,9 +11,11 @@ import type { CalendarEvent } from "../shared/api.js";
11
11
  import {
12
12
  availabilityInput,
13
13
  attachmentsInput,
14
+ attendeesInput,
14
15
  buildReminderOverrides,
15
16
  cliBoolean,
16
17
  googleColorIdInput,
18
+ normalizeAttendees,
17
19
  normalizeGoogleEventId,
18
20
  normalizeRecurrence,
19
21
  reminderMethodInput,
@@ -24,27 +26,6 @@ import {
24
26
  visibilityInput,
25
27
  } from "./event-action-helpers.js";
26
28
 
27
- const attendeeInput = z.object({
28
- email: z.string(),
29
- displayName: z.string().optional(),
30
- });
31
-
32
- const attendeesInput = z.union([z.array(attendeeInput), z.string()]);
33
-
34
- function normalizeAttendees(
35
- input: z.infer<typeof attendeesInput> | undefined,
36
- ): CalendarEvent["attendees"] | undefined {
37
- if (input === undefined) return undefined;
38
- if (typeof input === "string") {
39
- const emails = input
40
- .split(/[\s,;]+/)
41
- .map((s) => s.trim())
42
- .filter((s) => s.length > 0 && s.includes("@"));
43
- return emails.map((email) => ({ email }));
44
- }
45
- return input.filter((a) => a.email && a.email.includes("@"));
46
- }
47
-
48
29
  function mergeAttendees(
49
30
  existing: CalendarEvent["attendees"] | undefined,
50
31
  additions: CalendarEvent["attendees"] | undefined,
@@ -71,6 +52,12 @@ function mergeAttendees(
71
52
  email,
72
53
  displayName: attendee.displayName ?? current?.displayName,
73
54
  photoUrl: attendee.photoUrl ?? current?.photoUrl,
55
+ optional:
56
+ attendee.optional === true
57
+ ? true
58
+ : attendee.optional === false
59
+ ? undefined
60
+ : current?.optional,
74
61
  });
75
62
  }
76
63
 
@@ -157,12 +144,12 @@ export default defineAction({
157
144
  attendees: attendeesInput
158
145
  .optional()
159
146
  .describe(
160
- "Replace the event's attendee list. Accepts an array of {email, displayName?} or a comma-separated string of emails. Pass an empty array to clear all attendees.",
147
+ "Replace the event's attendee list. Accepts an array of {email, displayName?, optional?} or a comma-separated string of emails. Pass an empty array to clear all attendees. Set optional:true to mark a guest optional.",
161
148
  ),
162
149
  addAttendees: attendeesInput
163
150
  .optional()
164
151
  .describe(
165
- "Add invitees without dropping or resetting existing attendees. Accepts an array of {email, displayName?} or a comma-separated string of emails.",
152
+ "Add invitees without dropping or resetting existing attendees. Accepts an array of {email, displayName?, optional?} or a comma-separated string of emails. Set optional:true to mark a newly added guest optional.",
166
153
  ),
167
154
  sendUpdates: z
168
155
  .enum(["all", "none"])
@@ -1,9 +1,10 @@
1
1
  import { useT } from "@agent-native/core/client";
2
2
  import {
3
3
  IconAddressBook,
4
- IconBuilding,
4
+ IconDots,
5
5
  IconLoader2,
6
6
  IconUserCircle,
7
+ IconUsersGroup,
7
8
  IconX,
8
9
  } from "@tabler/icons-react";
9
10
  import {
@@ -18,6 +19,12 @@ import {
18
19
  } from "react";
19
20
 
20
21
  import { Button } from "@/components/ui/button";
22
+ import {
23
+ DropdownMenu,
24
+ DropdownMenuContent,
25
+ DropdownMenuItem,
26
+ DropdownMenuTrigger,
27
+ } from "@/components/ui/dropdown-menu";
21
28
  import {
22
29
  Popover,
23
30
  PopoverAnchor,
@@ -25,7 +32,9 @@ import {
25
32
  } from "@/components/ui/popover";
26
33
  import {
27
34
  filterPeopleResults,
35
+ mergePeopleResults,
28
36
  usePeopleContacts,
37
+ usePeopleSearch,
29
38
  type PeopleSearchResult,
30
39
  } from "@/hooks/use-people";
31
40
  import { isMcpEmbedSurface } from "@/lib/mcp-embed";
@@ -37,6 +46,7 @@ export interface AttendeeRecipient {
37
46
  email: string;
38
47
  displayName?: string;
39
48
  photoUrl?: string;
49
+ optional?: boolean;
40
50
  }
41
51
 
42
52
  export interface AttendeeAutocompleteHandle {
@@ -48,6 +58,7 @@ interface AttendeeAutocompleteProps {
48
58
  selectedEmails?: string[];
49
59
  onAdd: (attendee: AttendeeRecipient) => void;
50
60
  onRemove?: (email: string) => void;
61
+ onToggleOptional?: (email: string, optional: boolean) => void;
51
62
  inputId?: string;
52
63
  placeholder?: string;
53
64
  autoFocus?: boolean;
@@ -87,7 +98,7 @@ function sourceLabel(
87
98
 
88
99
  function SourceIcon({ source }: { source?: PeopleSearchResult["source"] }) {
89
100
  if (source === "directory") {
90
- return <IconBuilding className="h-3 w-3" />;
101
+ return <IconUsersGroup className="h-3 w-3" />;
91
102
  }
92
103
  return <IconAddressBook className="h-3 w-3" />;
93
104
  }
@@ -114,6 +125,7 @@ export const AttendeeAutocomplete = forwardRef<
114
125
  selectedEmails,
115
126
  onAdd,
116
127
  onRemove,
128
+ onToggleOptional,
117
129
  inputId,
118
130
  placeholder = "Add guests",
119
131
  autoFocus,
@@ -129,10 +141,15 @@ export const AttendeeAutocomplete = forwardRef<
129
141
  ) {
130
142
  const t = useT();
131
143
  const [inputValue, setInputValue] = useState("");
144
+ const [searchQuery, setSearchQuery] = useState("");
132
145
  const [open, setOpen] = useState(false);
133
146
  const [activeIndex, setActiveIndex] = useState(0);
134
147
  const inputRef = useRef<HTMLInputElement>(null);
135
148
  const contacts = usePeopleContacts();
149
+ const peopleSearch = usePeopleSearch(
150
+ searchQuery,
151
+ inputValue.trim().length > 0,
152
+ );
136
153
 
137
154
  const selectedEmailSet = useMemo(
138
155
  () =>
@@ -144,19 +161,38 @@ export const AttendeeAutocomplete = forwardRef<
144
161
  [attendees, selectedEmails],
145
162
  );
146
163
 
164
+ useEffect(() => {
165
+ const timeout = window.setTimeout(
166
+ () => setSearchQuery(inputValue),
167
+ inputValue.trim() ? 300 : 0,
168
+ );
169
+ return () => window.clearTimeout(timeout);
170
+ }, [inputValue]);
171
+
147
172
  const visibleResults = useMemo(
148
173
  () =>
149
174
  filterPeopleResults(
150
- contacts.data?.results ?? [],
175
+ mergePeopleResults(contacts.data?.results, peopleSearch.data?.results),
151
176
  inputValue,
152
177
  selectedEmailSet,
153
178
  ),
154
- [contacts.data?.results, inputValue, selectedEmailSet],
179
+ [
180
+ contacts.data?.results,
181
+ inputValue,
182
+ peopleSearch.data?.results,
183
+ selectedEmailSet,
184
+ ],
155
185
  );
156
186
 
157
187
  const canAddManual = parseEmails(inputValue).length > 0;
158
- const searching = contacts.isLoading || contacts.isFetching;
159
- const scopeRequired = Boolean(contacts.data?.scopeRequired);
188
+ const searching =
189
+ contacts.isLoading ||
190
+ contacts.isFetching ||
191
+ peopleSearch.isLoading ||
192
+ peopleSearch.isFetching;
193
+ const scopeRequired = Boolean(
194
+ contacts.data?.scopeRequired || peopleSearch.data?.scopeRequired,
195
+ );
160
196
  const shouldShowPopover =
161
197
  open &&
162
198
  inputValue.trim().length > 0 &&
@@ -182,6 +218,8 @@ export const AttendeeAutocomplete = forwardRef<
182
218
  email,
183
219
  displayName,
184
220
  photoUrl: person.photoUrl,
221
+ optional:
222
+ "optional" in person && person.optional === true ? true : undefined,
185
223
  });
186
224
  setInputValue("");
187
225
  setOpen(false);
@@ -322,6 +360,41 @@ export const AttendeeAutocomplete = forwardRef<
322
360
  <span className="truncate">
323
361
  {attendee.displayName || attendee.email}
324
362
  </span>
363
+ {attendee.optional && (
364
+ <span className="shrink-0 text-[10px] text-muted-foreground">
365
+ {t("attendees.optionalBadge")}
366
+ </span>
367
+ )}
368
+ {onToggleOptional && (
369
+ <DropdownMenu>
370
+ <DropdownMenuTrigger asChild>
371
+ <button
372
+ type="button"
373
+ onClick={(event) => event.stopPropagation()}
374
+ className="text-muted-foreground hover:text-foreground"
375
+ aria-label={t("attendees.guestOptions", {
376
+ email: attendee.email,
377
+ })}
378
+ >
379
+ <IconDots className="h-3 w-3" />
380
+ </button>
381
+ </DropdownMenuTrigger>
382
+ <DropdownMenuContent
383
+ align="start"
384
+ onClick={(event) => event.stopPropagation()}
385
+ >
386
+ <DropdownMenuItem
387
+ onSelect={() =>
388
+ onToggleOptional(attendee.email, !attendee.optional)
389
+ }
390
+ >
391
+ {attendee.optional
392
+ ? t("attendees.markRequired")
393
+ : t("attendees.markOptional")}
394
+ </DropdownMenuItem>
395
+ </DropdownMenuContent>
396
+ </DropdownMenu>
397
+ )}
325
398
  {onRemove && (
326
399
  <button
327
400
  type="button"
@@ -111,6 +111,12 @@ function uniqueAttendees(attendees: AttendeeRecipient[]) {
111
111
  email,
112
112
  displayName: existing?.displayName ?? attendee.displayName,
113
113
  photoUrl: existing?.photoUrl ?? attendee.photoUrl,
114
+ optional:
115
+ attendee.optional === true
116
+ ? true
117
+ : existing?.optional === true
118
+ ? true
119
+ : undefined,
114
120
  });
115
121
  }
116
122
  return Array.from(byEmail.values());
@@ -304,6 +310,7 @@ export function CreateEventPopover({
304
310
  email: attendee.email,
305
311
  displayName: attendee.displayName,
306
312
  photoUrl: attendee.photoUrl,
313
+ optional: attendee.optional === true ? true : undefined,
307
314
  })),
308
315
  ),
309
316
  );
@@ -393,6 +400,7 @@ export function CreateEventPopover({
393
400
  ? attendees.map((attendee) => ({
394
401
  email: attendee.email,
395
402
  displayName: attendee.displayName,
403
+ ...(attendee.optional === true ? { optional: true } : {}),
396
404
  }))
397
405
  : undefined,
398
406
  addGoogleMeet: videoProvider === "google_meet",
@@ -494,6 +502,19 @@ export function CreateEventPopover({
494
502
  );
495
503
  }
496
504
 
505
+ function toggleAttendeeOptional(email: string, optional: boolean) {
506
+ setAttendees((prev) =>
507
+ prev.map((attendee) =>
508
+ attendee.email.toLowerCase() === email.toLowerCase()
509
+ ? {
510
+ ...attendee,
511
+ optional: optional ? true : undefined,
512
+ }
513
+ : attendee,
514
+ ),
515
+ );
516
+ }
517
+
497
518
  const effectiveAllDay = allDay && !timedOnlyStatus;
498
519
  const currentStartISO =
499
520
  !effectiveAllDay && date && startTime
@@ -639,6 +660,7 @@ export function CreateEventPopover({
639
660
  ? finalAttendees.map((attendee) => ({
640
661
  email: attendee.email,
641
662
  displayName: attendee.displayName,
663
+ ...(attendee.optional === true ? { optional: true } : {}),
642
664
  }))
643
665
  : undefined,
644
666
  };
@@ -925,6 +947,7 @@ export function CreateEventPopover({
925
947
  attendees={attendees}
926
948
  onAdd={addAttendee}
927
949
  onRemove={removeAttendee}
950
+ onToggleOptional={toggleAttendeeOptional}
928
951
  inputId="event-attendees"
929
952
  placeholder={t("eventForm.attendeesPlaceholder")}
930
953
  onEmptyEnter={() => formRef.current?.requestSubmit()}