@agent-native/core 0.117.2 → 0.118.0

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 (524) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +30 -0
  3. package/corpus/core/docs/content/custom-design-system.mdx +445 -0
  4. package/corpus/core/docs/content/toolkit-ui.mdx +16 -0
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/a2a/types.ts +1 -0
  7. package/corpus/core/src/agent/types.ts +1 -1
  8. package/corpus/core/src/client/AgentPanel.tsx +90 -107
  9. package/corpus/core/src/client/AssistantChat.tsx +30 -13
  10. package/corpus/core/src/client/CommandMenu.tsx +68 -178
  11. package/corpus/core/src/client/agent-chat-adapter.ts +3 -1
  12. package/corpus/core/src/client/app-providers.tsx +1 -1
  13. package/corpus/core/src/client/chat/message-components.tsx +116 -10
  14. package/corpus/core/src/client/chat/tool-call-display.tsx +26 -5
  15. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +14 -40
  16. package/corpus/core/src/client/components/ui/message-scroller.tsx +15 -1
  17. package/corpus/core/src/client/i18n.tsx +22 -0
  18. package/corpus/core/src/client/index.ts +17 -0
  19. package/corpus/core/src/client/org/TeamPage.tsx +257 -153
  20. package/corpus/core/src/client/progress/RunsTray.tsx +89 -88
  21. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +5 -2
  22. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +34 -13
  23. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +13 -0
  24. package/corpus/core/src/client/settings/DemoModeSection.tsx +6 -18
  25. package/corpus/core/src/client/settings/SecretsSection.tsx +97 -52
  26. package/corpus/core/src/client/settings/SettingsPanel.tsx +202 -246
  27. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +23 -2
  28. package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  29. package/corpus/core/src/client/settings/index.ts +7 -0
  30. package/corpus/core/src/client/settings/useSettingsPanelController.ts +155 -0
  31. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  32. package/corpus/core/src/client/setup-connections/index.ts +10 -0
  33. package/corpus/core/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  34. package/corpus/core/src/client/sharing/ShareButton.tsx +64 -586
  35. package/corpus/core/src/client/sharing/ShareDialog.tsx +299 -633
  36. package/corpus/core/src/client/sharing/index.ts +42 -0
  37. package/corpus/core/src/client/sharing/share-controller-helpers.ts +318 -0
  38. package/corpus/core/src/client/sharing/useShareButtonController.ts +600 -0
  39. package/corpus/core/src/client/sharing/useShareDialogController.ts +559 -0
  40. package/corpus/core/src/client/sse-event-processor.ts +23 -0
  41. package/corpus/core/src/client/tool-display.ts +71 -0
  42. package/corpus/core/src/client/use-agent-engine-configured.ts +12 -19
  43. package/corpus/core/src/client/use-chat-threads.ts +33 -12
  44. package/corpus/core/src/localization/default-messages.ts +5 -0
  45. package/corpus/core/src/mcp-client/oauth-routes.ts +16 -2
  46. package/corpus/core/src/scripts/call-agent.ts +5 -1
  47. package/corpus/core/src/server/realtime-voice.ts +1 -1
  48. package/corpus/core/src/styles/agent-native.css +0 -24
  49. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  50. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  51. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  52. package/corpus/core/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  53. package/corpus/core/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  54. package/corpus/core/src/templates/default/app/design-system.ts +3 -0
  55. package/corpus/core/src/templates/default/app/root.tsx +5 -2
  56. package/corpus/core/src/templates/default/package.json +1 -0
  57. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  58. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  59. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  60. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  61. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  62. package/corpus/core/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  63. package/corpus/core/src/vite/client.ts +39 -0
  64. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  65. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  66. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +22 -2
  67. package/corpus/templates/analytics/.agents/skills/shadcn-ui/SKILL.md +28 -4
  68. package/corpus/templates/analytics/app/components/ui/toolkit-provider.tsx +6 -1
  69. package/corpus/templates/analytics/app/design-system.ts +3 -0
  70. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  71. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  72. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +22 -2
  73. package/corpus/templates/assets/.agents/skills/shadcn-ui/SKILL.md +28 -4
  74. package/corpus/templates/assets/app/components/ui/alert.tsx +1 -0
  75. package/corpus/templates/assets/app/components/ui/toolkit-provider.tsx +6 -1
  76. package/corpus/templates/assets/app/design-system.ts +3 -0
  77. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +26 -30
  78. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  79. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  80. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +22 -2
  81. package/corpus/templates/brain/.agents/skills/shadcn-ui/SKILL.md +28 -4
  82. package/corpus/templates/brain/app/components/ui/dialog.tsx +1 -0
  83. package/corpus/templates/brain/app/components/ui/toolkit-provider.tsx +6 -1
  84. package/corpus/templates/brain/app/design-system.ts +3 -0
  85. package/corpus/templates/brain/app/routes/sources.tsx +8 -8
  86. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  87. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  88. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +22 -2
  89. package/corpus/templates/calendar/.agents/skills/shadcn-ui/SKILL.md +28 -4
  90. package/corpus/templates/calendar/app/components/ui/toolkit-provider.tsx +6 -1
  91. package/corpus/templates/calendar/app/design-system.ts +3 -0
  92. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  93. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  94. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  95. package/corpus/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  96. package/corpus/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  97. package/corpus/templates/chat/app/design-system.ts +3 -0
  98. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  99. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  100. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +22 -2
  101. package/corpus/templates/clips/.agents/skills/shadcn-ui/SKILL.md +28 -4
  102. package/corpus/templates/clips/app/components/ui/toolkit-provider.tsx +6 -1
  103. package/corpus/templates/clips/app/design-system.ts +3 -0
  104. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  105. package/corpus/templates/clips/changelog/2026-07-22-fixed-windows-recordings-aborting-during-the-countdown.md +6 -0
  106. package/corpus/templates/clips/changelog/2026-07-22-permissions-and-rewind-controls-are-now-grouped-with-clearer.md +6 -0
  107. package/corpus/templates/clips/changelog/2026-07-22-the-desktop-popover-opens-centered-under-the-menu-bar-icon-o.md +6 -0
  108. package/corpus/templates/clips/desktop/src/app.tsx +86 -82
  109. package/corpus/templates/clips/desktop/src/styles.css +13 -0
  110. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +10 -1
  111. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +37 -2
  112. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -0
  113. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  114. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  115. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +22 -2
  116. package/corpus/templates/content/.agents/skills/shadcn-ui/SKILL.md +28 -4
  117. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +41 -59
  118. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +41 -41
  119. package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +2 -1
  120. package/corpus/templates/content/app/components/editor/database/ListView.tsx +2 -1
  121. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +9 -9
  122. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +7 -7
  123. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +11 -11
  124. package/corpus/templates/content/app/components/ui/checkbox.tsx +1 -0
  125. package/corpus/templates/content/app/components/ui/collapsible.tsx +1 -0
  126. package/corpus/templates/content/app/components/ui/toolkit-provider.tsx +6 -1
  127. package/corpus/templates/content/app/design-system.ts +3 -0
  128. package/corpus/templates/content/app/global.css +29 -3
  129. package/corpus/templates/content/changelog/2026-07-22-page-actions-are-grouped-into-the-three-dots-menu-for-a-clea.md +6 -0
  130. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  131. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  132. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +10 -10
  133. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +1 -6
  134. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +3 -2
  135. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +13 -12
  136. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +17 -17
  137. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +8 -8
  138. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +3 -8
  139. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +2 -1
  140. package/corpus/templates/crm/app/components/crm/Surface.tsx +3 -2
  141. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +2 -2
  142. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +7 -7
  143. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +1 -1
  144. package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +1 -0
  145. package/corpus/templates/crm/app/components/ui/badge.tsx +1 -0
  146. package/corpus/templates/crm/app/components/ui/button.tsx +1 -0
  147. package/corpus/templates/crm/app/components/ui/card.tsx +1 -0
  148. package/corpus/templates/crm/app/components/ui/dialog.tsx +1 -0
  149. package/corpus/templates/crm/app/components/ui/input.tsx +1 -0
  150. package/corpus/templates/crm/app/components/ui/label.tsx +1 -0
  151. package/corpus/templates/crm/app/components/ui/select.tsx +1 -0
  152. package/corpus/templates/crm/app/components/ui/sheet.tsx +1 -0
  153. package/corpus/templates/crm/app/components/ui/skeleton.tsx +1 -0
  154. package/corpus/templates/crm/app/components/ui/switch.tsx +1 -0
  155. package/corpus/templates/crm/app/components/ui/table.tsx +1 -0
  156. package/corpus/templates/crm/app/components/ui/tabs.tsx +1 -0
  157. package/corpus/templates/crm/app/components/ui/textarea.tsx +1 -0
  158. package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +17 -0
  159. package/corpus/templates/crm/app/design-system.ts +3 -0
  160. package/corpus/templates/crm/app/root.tsx +9 -6
  161. package/corpus/templates/crm/app/routes/dashboard.tsx +1 -1
  162. package/corpus/templates/crm/app/routes/proposals.tsx +13 -13
  163. package/corpus/templates/crm/app/routes/setup.tsx +9 -9
  164. package/corpus/templates/crm/app/routes/tasks.tsx +14 -14
  165. package/corpus/templates/crm/app/routes/views.tsx +16 -16
  166. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  167. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  168. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +22 -2
  169. package/corpus/templates/design/.agents/skills/shadcn-ui/SKILL.md +28 -4
  170. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +8 -8
  171. package/corpus/templates/design/app/components/ui/command.tsx +1 -0
  172. package/corpus/templates/design/app/components/ui/toolkit-provider.tsx +6 -1
  173. package/corpus/templates/design/app/design-system.ts +3 -0
  174. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  175. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  176. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +22 -2
  177. package/corpus/templates/dispatch/.agents/skills/shadcn-ui/SKILL.md +28 -4
  178. package/corpus/templates/dispatch/app/components/ui/button.tsx +1 -0
  179. package/corpus/templates/dispatch/app/components/ui/toolkit-provider.tsx +17 -0
  180. package/corpus/templates/dispatch/app/design-system.ts +3 -0
  181. package/corpus/templates/dispatch/app/root.tsx +10 -7
  182. package/corpus/templates/dispatch/package.json +1 -0
  183. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  184. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  185. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +22 -2
  186. package/corpus/templates/forms/.agents/skills/shadcn-ui/SKILL.md +28 -4
  187. package/corpus/templates/forms/app/components/ui/toolkit-provider.tsx +6 -1
  188. package/corpus/templates/forms/app/design-system.ts +3 -0
  189. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  190. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  191. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +22 -2
  192. package/corpus/templates/macros/.agents/skills/shadcn-ui/SKILL.md +28 -4
  193. package/corpus/templates/macros/app/components/ui/toolkit-provider.tsx +6 -1
  194. package/corpus/templates/macros/app/design-system.ts +3 -0
  195. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  196. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  197. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +22 -2
  198. package/corpus/templates/mail/.agents/skills/shadcn-ui/SKILL.md +28 -4
  199. package/corpus/templates/mail/app/components/email/EmailThread.tsx +134 -93
  200. package/corpus/templates/mail/app/components/email/email-iframe-document.ts +8 -2
  201. package/corpus/templates/mail/app/components/ui/textarea.tsx +1 -21
  202. package/corpus/templates/mail/app/components/ui/toolkit-provider.tsx +6 -1
  203. package/corpus/templates/mail/app/design-system.ts +3 -0
  204. package/corpus/templates/mail/changelog/2026-07-22-email-messages-no-longer-flash-with-an-unstyled-page-while-l.md +6 -0
  205. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  206. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  207. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +22 -2
  208. package/corpus/templates/plan/.agents/skills/shadcn-ui/SKILL.md +28 -4
  209. package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +1 -1
  210. package/corpus/templates/plan/app/components/ui/toolkit-provider.tsx +6 -1
  211. package/corpus/templates/plan/app/design-system.ts +3 -0
  212. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  213. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  214. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +22 -2
  215. package/corpus/templates/slides/.agents/skills/shadcn-ui/SKILL.md +28 -4
  216. package/corpus/templates/slides/app/components/ui/toolkit-provider.tsx +6 -1
  217. package/corpus/templates/slides/app/design-system.ts +3 -0
  218. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  219. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  220. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +22 -2
  221. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +28 -4
  222. package/corpus/templates/tasks/app/components/ui/toolkit-provider.tsx +17 -0
  223. package/corpus/templates/tasks/app/design-system.ts +3 -0
  224. package/corpus/templates/tasks/app/root.tsx +5 -2
  225. package/corpus/toolkit/CHANGELOG.md +14 -0
  226. package/corpus/toolkit/agent-native.eject.json +71 -0
  227. package/corpus/toolkit/package.json +31 -1
  228. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +100 -39
  229. package/corpus/toolkit/src/chat-history/index.ts +9 -0
  230. package/corpus/toolkit/src/chat-history/useChatHistoryRailController.ts +76 -0
  231. package/corpus/toolkit/src/chat-history.css +2 -0
  232. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +11 -8
  233. package/corpus/toolkit/src/composer/PromptComposer.tsx +27 -6
  234. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +107 -22
  235. package/corpus/toolkit/src/conformance/__fixtures__/css-in-js-adapter.tsx +401 -0
  236. package/corpus/toolkit/src/conformance/index.ts +3 -0
  237. package/corpus/toolkit/src/conformance/runner.tsx +710 -0
  238. package/corpus/toolkit/src/conformance/types.ts +45 -0
  239. package/corpus/toolkit/src/conformance/version.ts +22 -0
  240. package/corpus/toolkit/src/design-system/components.tsx +146 -0
  241. package/corpus/toolkit/src/design-system/context.tsx +31 -0
  242. package/corpus/toolkit/src/design-system/default-adapter.tsx +915 -0
  243. package/corpus/toolkit/src/design-system/definition.ts +14 -0
  244. package/corpus/toolkit/src/design-system/error-boundary.tsx +37 -0
  245. package/corpus/toolkit/src/design-system/index.ts +7 -0
  246. package/corpus/toolkit/src/design-system/theme.ts +145 -0
  247. package/corpus/toolkit/src/design-system/types.ts +363 -0
  248. package/corpus/toolkit/src/provider.tsx +98 -5
  249. package/corpus/toolkit/src/ui/button.tsx +95 -6
  250. package/corpus/toolkit/src/ui/dialog.tsx +48 -23
  251. package/corpus/toolkit/src/ui/popover.tsx +16 -2
  252. package/corpus/toolkit/src/ui/select.tsx +7 -3
  253. package/corpus/toolkit/src/ui/sidebar.tsx +47 -48
  254. package/corpus/toolkit/src/ui/tooltip.tsx +7 -3
  255. package/dist/a2a/types.d.ts +1 -1
  256. package/dist/a2a/types.d.ts.map +1 -1
  257. package/dist/a2a/types.js.map +1 -1
  258. package/dist/agent/types.d.ts +1 -1
  259. package/dist/agent/types.d.ts.map +1 -1
  260. package/dist/agent/types.js.map +1 -1
  261. package/dist/client/AgentPanel.d.ts.map +1 -1
  262. package/dist/client/AgentPanel.js +14 -14
  263. package/dist/client/AgentPanel.js.map +1 -1
  264. package/dist/client/AssistantChat.d.ts.map +1 -1
  265. package/dist/client/AssistantChat.js +26 -15
  266. package/dist/client/AssistantChat.js.map +1 -1
  267. package/dist/client/CommandMenu.d.ts.map +1 -1
  268. package/dist/client/CommandMenu.js +18 -106
  269. package/dist/client/CommandMenu.js.map +1 -1
  270. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  271. package/dist/client/agent-chat-adapter.js +2 -1
  272. package/dist/client/agent-chat-adapter.js.map +1 -1
  273. package/dist/client/app-providers.d.ts.map +1 -1
  274. package/dist/client/app-providers.js +1 -1
  275. package/dist/client/app-providers.js.map +1 -1
  276. package/dist/client/chat/message-components.d.ts +9 -1
  277. package/dist/client/chat/message-components.d.ts.map +1 -1
  278. package/dist/client/chat/message-components.js +62 -7
  279. package/dist/client/chat/message-components.js.map +1 -1
  280. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  281. package/dist/client/chat/tool-call-display.js +20 -5
  282. package/dist/client/chat/tool-call-display.js.map +1 -1
  283. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
  284. package/dist/client/chat/widgets/InlineExtensionWidget.js +9 -12
  285. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
  286. package/dist/client/components/ui/message-scroller.d.ts +1 -1
  287. package/dist/client/components/ui/message-scroller.d.ts.map +1 -1
  288. package/dist/client/components/ui/message-scroller.js +4 -3
  289. package/dist/client/components/ui/message-scroller.js.map +1 -1
  290. package/dist/client/i18n.d.ts.map +1 -1
  291. package/dist/client/i18n.js +9 -0
  292. package/dist/client/i18n.js.map +1 -1
  293. package/dist/client/index.d.ts +2 -2
  294. package/dist/client/index.d.ts.map +1 -1
  295. package/dist/client/index.js +2 -2
  296. package/dist/client/index.js.map +1 -1
  297. package/dist/client/org/TeamPage.d.ts.map +1 -1
  298. package/dist/client/org/TeamPage.js +41 -33
  299. package/dist/client/org/TeamPage.js.map +1 -1
  300. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  301. package/dist/client/progress/RunsTray.js +9 -10
  302. package/dist/client/progress/RunsTray.js.map +1 -1
  303. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  304. package/dist/client/resources/McpConnectionSuggestion.js +5 -4
  305. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  306. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  307. package/dist/client/resources/McpIntegrationDialog.js +10 -8
  308. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  309. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  310. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  311. package/dist/client/resources/mcp-integration-catalog.js +13 -0
  312. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  313. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  314. package/dist/client/settings/DemoModeSection.js +2 -5
  315. package/dist/client/settings/DemoModeSection.js.map +1 -1
  316. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  317. package/dist/client/settings/SecretsSection.js +18 -6
  318. package/dist/client/settings/SecretsSection.js.map +1 -1
  319. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  320. package/dist/client/settings/SettingsPanel.js +52 -117
  321. package/dist/client/settings/SettingsPanel.js.map +1 -1
  322. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  323. package/dist/client/settings/SettingsTabsPage.js +16 -1
  324. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  325. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  326. package/dist/client/settings/VoiceTranscriptionSection.js +2 -5
  327. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  328. package/dist/client/settings/index.d.ts +1 -0
  329. package/dist/client/settings/index.d.ts.map +1 -1
  330. package/dist/client/settings/index.js +1 -0
  331. package/dist/client/settings/index.js.map +1 -1
  332. package/dist/client/settings/useSettingsPanelController.d.ts +22 -0
  333. package/dist/client/settings/useSettingsPanelController.d.ts.map +1 -0
  334. package/dist/client/settings/useSettingsPanelController.js +103 -0
  335. package/dist/client/settings/useSettingsPanelController.js.map +1 -0
  336. package/dist/client/setup-connections/BuilderConnectCard.d.ts +14 -6
  337. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
  338. package/dist/client/setup-connections/BuilderConnectCard.js +24 -16
  339. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
  340. package/dist/client/setup-connections/index.d.ts +2 -1
  341. package/dist/client/setup-connections/index.d.ts.map +1 -1
  342. package/dist/client/setup-connections/index.js +2 -1
  343. package/dist/client/setup-connections/index.js.map +1 -1
  344. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts +34 -0
  345. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts.map +1 -0
  346. package/dist/client/setup-connections/useBuilderConnectCardController.js +39 -0
  347. package/dist/client/setup-connections/useBuilderConnectCardController.js.map +1 -0
  348. package/dist/client/sharing/ShareButton.d.ts +2 -1
  349. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  350. package/dist/client/sharing/ShareButton.js +17 -463
  351. package/dist/client/sharing/ShareButton.js.map +1 -1
  352. package/dist/client/sharing/ShareDialog.d.ts +6 -6
  353. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  354. package/dist/client/sharing/ShareDialog.js +69 -283
  355. package/dist/client/sharing/ShareDialog.js.map +1 -1
  356. package/dist/client/sharing/index.d.ts +3 -0
  357. package/dist/client/sharing/index.d.ts.map +1 -1
  358. package/dist/client/sharing/index.js +3 -0
  359. package/dist/client/sharing/index.js.map +1 -1
  360. package/dist/client/sharing/share-controller-helpers.d.ts +70 -0
  361. package/dist/client/sharing/share-controller-helpers.d.ts.map +1 -0
  362. package/dist/client/sharing/share-controller-helpers.js +224 -0
  363. package/dist/client/sharing/share-controller-helpers.js.map +1 -0
  364. package/dist/client/sharing/useShareButtonController.d.ts +91 -0
  365. package/dist/client/sharing/useShareButtonController.d.ts.map +1 -0
  366. package/dist/client/sharing/useShareButtonController.js +397 -0
  367. package/dist/client/sharing/useShareButtonController.js.map +1 -0
  368. package/dist/client/sharing/useShareDialogController.d.ts +109 -0
  369. package/dist/client/sharing/useShareDialogController.d.ts.map +1 -0
  370. package/dist/client/sharing/useShareDialogController.js +348 -0
  371. package/dist/client/sharing/useShareDialogController.js.map +1 -0
  372. package/dist/client/sse-event-processor.d.ts.map +1 -1
  373. package/dist/client/sse-event-processor.js +21 -0
  374. package/dist/client/sse-event-processor.js.map +1 -1
  375. package/dist/client/tool-display.d.ts +16 -0
  376. package/dist/client/tool-display.d.ts.map +1 -1
  377. package/dist/client/tool-display.js +52 -0
  378. package/dist/client/tool-display.js.map +1 -1
  379. package/dist/client/use-agent-engine-configured.d.ts +3 -2
  380. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  381. package/dist/client/use-agent-engine-configured.js +7 -19
  382. package/dist/client/use-agent-engine-configured.js.map +1 -1
  383. package/dist/client/use-chat-threads.d.ts.map +1 -1
  384. package/dist/client/use-chat-threads.js +21 -8
  385. package/dist/client/use-chat-threads.js.map +1 -1
  386. package/dist/localization/default-messages.d.ts +4 -0
  387. package/dist/localization/default-messages.d.ts.map +1 -1
  388. package/dist/localization/default-messages.js +4 -0
  389. package/dist/localization/default-messages.js.map +1 -1
  390. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  391. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  392. package/dist/mcp-client/oauth-routes.js +12 -2
  393. package/dist/mcp-client/oauth-routes.js.map +1 -1
  394. package/dist/observability/routes.d.ts +3 -3
  395. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  396. package/dist/scripts/call-agent.d.ts.map +1 -1
  397. package/dist/scripts/call-agent.js +5 -1
  398. package/dist/scripts/call-agent.js.map +1 -1
  399. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  400. package/dist/server/realtime-voice.js +1 -1
  401. package/dist/server/realtime-voice.js.map +1 -1
  402. package/dist/server/transcribe-voice.d.ts +1 -1
  403. package/dist/styles/agent-native.css +0 -24
  404. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  405. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  406. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  407. package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  408. package/dist/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  409. package/dist/templates/chat/app/design-system.ts +3 -0
  410. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  411. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  412. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  413. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  414. package/dist/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  415. package/dist/templates/default/app/design-system.ts +3 -0
  416. package/dist/templates/default/app/root.tsx +5 -2
  417. package/dist/templates/default/package.json +1 -0
  418. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  419. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  420. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  421. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  422. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  423. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  424. package/dist/vite/client.d.ts +3 -0
  425. package/dist/vite/client.d.ts.map +1 -1
  426. package/dist/vite/client.js +31 -0
  427. package/dist/vite/client.js.map +1 -1
  428. package/docs/content/custom-design-system.mdx +445 -0
  429. package/docs/content/toolkit-ui.mdx +16 -0
  430. package/package.json +2 -2
  431. package/src/a2a/types.ts +1 -0
  432. package/src/agent/types.ts +1 -1
  433. package/src/client/AgentPanel.tsx +90 -107
  434. package/src/client/AssistantChat.tsx +30 -13
  435. package/src/client/CommandMenu.tsx +68 -178
  436. package/src/client/agent-chat-adapter.ts +3 -1
  437. package/src/client/app-providers.tsx +1 -1
  438. package/src/client/chat/message-components.tsx +116 -10
  439. package/src/client/chat/tool-call-display.tsx +26 -5
  440. package/src/client/chat/widgets/InlineExtensionWidget.tsx +14 -40
  441. package/src/client/components/ui/message-scroller.tsx +15 -1
  442. package/src/client/i18n.tsx +22 -0
  443. package/src/client/index.ts +17 -0
  444. package/src/client/org/TeamPage.tsx +257 -153
  445. package/src/client/progress/RunsTray.tsx +89 -88
  446. package/src/client/resources/McpConnectionSuggestion.tsx +5 -2
  447. package/src/client/resources/McpIntegrationDialog.tsx +34 -13
  448. package/src/client/resources/mcp-integration-catalog.ts +13 -0
  449. package/src/client/settings/DemoModeSection.tsx +6 -18
  450. package/src/client/settings/SecretsSection.tsx +97 -52
  451. package/src/client/settings/SettingsPanel.tsx +202 -246
  452. package/src/client/settings/SettingsTabsPage.tsx +23 -2
  453. package/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  454. package/src/client/settings/index.ts +7 -0
  455. package/src/client/settings/useSettingsPanelController.ts +155 -0
  456. package/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  457. package/src/client/setup-connections/index.ts +10 -0
  458. package/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  459. package/src/client/sharing/ShareButton.tsx +64 -586
  460. package/src/client/sharing/ShareDialog.tsx +299 -633
  461. package/src/client/sharing/index.ts +42 -0
  462. package/src/client/sharing/share-controller-helpers.ts +318 -0
  463. package/src/client/sharing/useShareButtonController.ts +600 -0
  464. package/src/client/sharing/useShareDialogController.ts +559 -0
  465. package/src/client/sse-event-processor.ts +23 -0
  466. package/src/client/tool-display.ts +71 -0
  467. package/src/client/use-agent-engine-configured.ts +12 -19
  468. package/src/client/use-chat-threads.ts +33 -12
  469. package/src/localization/default-messages.ts +5 -0
  470. package/src/mcp-client/oauth-routes.ts +16 -2
  471. package/src/scripts/call-agent.ts +5 -1
  472. package/src/server/realtime-voice.ts +1 -1
  473. package/src/styles/agent-native.css +0 -24
  474. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  475. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  476. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  477. package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  478. package/src/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  479. package/src/templates/chat/app/design-system.ts +3 -0
  480. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  481. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  482. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  483. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  484. package/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  485. package/src/templates/default/app/design-system.ts +3 -0
  486. package/src/templates/default/app/root.tsx +5 -2
  487. package/src/templates/default/package.json +1 -0
  488. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  489. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  490. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +37 -2
  491. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  492. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  493. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  494. package/src/vite/client.ts +39 -0
  495. package/corpus/templates/analytics/app/components/ui/calendar.tsx +0 -70
  496. package/corpus/templates/analytics/app/components/ui/chart.tsx +0 -386
  497. package/corpus/templates/calendar/app/components/ui/sonner.tsx +0 -58
  498. package/corpus/templates/forms/app/components/ui/calendar.tsx +0 -214
  499. package/corpus/templates/forms/app/components/ui/chart.tsx +0 -379
  500. package/corpus/templates/forms/app/components/ui/command.tsx +0 -153
  501. package/corpus/templates/forms/app/components/ui/context-menu.tsx +0 -198
  502. package/corpus/templates/forms/app/components/ui/menubar.tsx +0 -254
  503. package/corpus/templates/macros/app/components/ui/menubar.tsx +0 -238
  504. package/corpus/templates/macros/app/components/ui/progress.tsx +0 -26
  505. package/corpus/templates/mail/app/components/ui/calendar.tsx +0 -211
  506. package/corpus/templates/mail/app/components/ui/chart.tsx +0 -379
  507. package/corpus/templates/mail/app/components/ui/command.tsx +0 -153
  508. package/corpus/templates/mail/app/components/ui/context-menu.tsx +0 -198
  509. package/corpus/templates/mail/app/components/ui/menubar.tsx +0 -254
  510. package/corpus/templates/tasks/app/components/ui/accordion.tsx +0 -56
  511. package/corpus/templates/tasks/app/components/ui/aspect-ratio.tsx +0 -5
  512. package/corpus/templates/tasks/app/components/ui/breadcrumb.tsx +0 -115
  513. package/corpus/templates/tasks/app/components/ui/calendar.tsx +0 -70
  514. package/corpus/templates/tasks/app/components/ui/carousel.tsx +0 -260
  515. package/corpus/templates/tasks/app/components/ui/chart.tsx +0 -379
  516. package/corpus/templates/tasks/app/components/ui/form.tsx +0 -177
  517. package/corpus/templates/tasks/app/components/ui/hover-card.tsx +0 -27
  518. package/corpus/templates/tasks/app/components/ui/input-otp.tsx +0 -69
  519. package/corpus/templates/tasks/app/components/ui/menubar.tsx +0 -254
  520. package/corpus/templates/tasks/app/components/ui/navigation-menu.tsx +0 -128
  521. package/corpus/templates/tasks/app/components/ui/pagination.tsx +0 -121
  522. package/corpus/templates/tasks/app/components/ui/resizable.tsx +0 -43
  523. package/corpus/templates/tasks/app/components/ui/sidebar.tsx +0 -782
  524. package/corpus/templates/tasks/app/components/ui/toggle.tsx +0 -43
@@ -12,13 +12,10 @@ import {
12
12
  IconShare3,
13
13
  IconUsersGroup,
14
14
  } from "@tabler/icons-react";
15
- import { useQueryClient } from "@tanstack/react-query";
16
15
  import {
17
- useCallback,
18
16
  type ComponentPropsWithoutRef,
19
17
  useEffect,
20
18
  useId,
21
- useMemo,
22
19
  useRef,
23
20
  useState,
24
21
  type ReactNode,
@@ -28,7 +25,6 @@ import type {
28
25
  UIEvent as ReactUIEvent,
29
26
  } from "react";
30
27
 
31
- import { agentNativePath } from "../api-path.js";
32
28
  import { writeClipboardText } from "../clipboard.js";
33
29
  import {
34
30
  Popover,
@@ -36,8 +32,16 @@ import {
36
32
  PopoverContent,
37
33
  PopoverTrigger,
38
34
  } from "../components/ui/popover.js";
39
- import { useActionQuery, useActionMutation } from "../use-action.js";
40
35
  import { cn } from "../utils.js";
36
+ import {
37
+ useShareButtonController,
38
+ type ShareButtonController,
39
+ type ShareButtonOrgMember,
40
+ type ShareButtonOrgMemberSearch,
41
+ type ShareButtonShare,
42
+ type ShareButtonRole,
43
+ type ShareButtonVisibility,
44
+ } from "./useShareButtonController.js";
41
45
 
42
46
  export interface ShareButtonProps {
43
47
  resourceType: string;
@@ -133,34 +137,13 @@ export interface ShareButtonProps {
133
137
  popoverClassName?: string;
134
138
  }
135
139
 
136
- type Visibility = "private" | "org" | "public";
137
- type Role = "viewer" | "editor" | "admin";
140
+ type Visibility = ShareButtonVisibility;
141
+ type Role = ShareButtonRole;
138
142
  type HideInSearchControl = NonNullable<ShareButtonProps["hideInSearchControl"]>;
143
+ type OrgMember = ShareButtonOrgMember;
144
+ type OrgMemberSearch = ShareButtonOrgMemberSearch;
139
145
 
140
- interface Share {
141
- id: string;
142
- principalType: "user" | "org";
143
- principalId: string;
144
- displayName?: string | null;
145
- role: Role;
146
- }
147
-
148
- interface SharesPolicy {
149
- /** When false, the visibility picker hides "Public". Default: true. */
150
- allowPublic: boolean;
151
- /** When true, individual user shares must target an org member or pending invitee. Default: false. */
152
- requireOrgMemberForUserShares: boolean;
153
- }
154
-
155
- interface SharesResponse {
156
- ownerEmail: string | null;
157
- orgId: string | null;
158
- visibility: Visibility | null;
159
- role?: "owner" | Role;
160
- shares: Share[];
161
- /** Server-declared policy for what visibilities and share targets are allowed. */
162
- policy?: SharesPolicy;
163
- }
146
+ type Share = ShareButtonShare;
164
147
 
165
148
  // Match shadcn's <Button size="sm" variant="outline"> sizing so the trigger
166
149
  // sits flush next to other controls while staying transparent at rest.
@@ -182,9 +165,6 @@ const SHARE_POPOVER_SURFACE =
182
165
  "border border-border bg-popover text-popover-foreground";
183
166
  const SHARE_NESTED_OVERLAY_ATTR = "data-agent-native-share-overlay";
184
167
  const SHARE_NESTED_OVERLAY_Z = "z-[100020]";
185
- const MEMBER_SUGGESTION_LIMIT = 25;
186
- const MEMBER_SEARCH_DEBOUNCE_MS = 140;
187
-
188
168
  const VIS_META: Record<
189
169
  Visibility,
190
170
  { label: string; description: string; Icon: typeof IconLock }
@@ -259,113 +239,16 @@ function handleSharePopoverInteractOutside(
259
239
  * dark mode in any shadcn template.
260
240
  */
261
241
  export function ShareButton(props: ShareButtonProps) {
262
- const [open, setOpen] = useState(false);
263
- const [inviteEmail, setInviteEmail] = useState("");
264
- const shareTabDefaultValue = props.shareTabs?.defaultValue ?? "share";
265
- const [activeShareTab, setActiveShareTab] = useState(shareTabDefaultValue);
266
- const [pendingVisibility, setPendingVisibility] = useState<Visibility | null>(
267
- null,
268
- );
269
- const appliedDefaultOpenRef = useRef(false);
270
- const visibilityRequestId = useRef(0);
271
- const queryClient = useQueryClient();
272
- const shareQueryParams = useMemo(
273
- () => ({
274
- resourceType: props.resourceType,
275
- resourceId: props.resourceId,
276
- }),
277
- [props.resourceType, props.resourceId],
278
- );
279
- const shareQueryKey = useMemo(
280
- () => ["action", "list-resource-shares", shareQueryParams] as const,
281
- [shareQueryParams],
282
- );
283
- const setVisibility = useActionMutation("set-resource-visibility");
284
- const sharesQuery = useActionQuery<SharesResponse>(
285
- "list-resource-shares",
286
- shareQueryParams,
287
- );
288
- const handleOpenChange = (v: boolean) => {
289
- setOpen(v);
290
- props.onOpenChange?.(v);
291
- if (v) {
292
- setActiveShareTab(shareTabDefaultValue);
293
- props.shareTabs?.onValueChange?.(shareTabDefaultValue);
294
- if (pendingVisibility === null) sharesQuery.refetch();
295
- }
296
- };
297
-
298
- useEffect(() => {
299
- setInviteEmail("");
300
- }, [props.resourceType, props.resourceId]);
301
-
302
- const handleShareTabChange = (value: string) => {
303
- setActiveShareTab(value);
304
- props.shareTabs?.onValueChange?.(value);
305
- };
306
-
307
- useEffect(() => {
308
- if (!props.defaultOpen || appliedDefaultOpenRef.current) return;
309
- appliedDefaultOpenRef.current = true;
310
- handleOpenChange(true);
242
+ const controller = useShareButtonController({
243
+ resourceType: props.resourceType,
244
+ resourceId: props.resourceId,
245
+ defaultOpen: props.defaultOpen,
246
+ onOpenChange: props.onOpenChange,
247
+ shareTabs: props.shareTabs,
248
+ shareUrl: props.shareUrl,
249
+ hideInSearchControl: props.hideInSearchControl,
311
250
  });
312
-
313
- const updateCachedVisibility = (visibility: Visibility) => {
314
- queryClient.setQueryData<SharesResponse>(shareQueryKey, (prev) =>
315
- prev ? { ...prev, visibility } : prev,
316
- );
317
- };
318
-
319
- const handleVisibilityChange = (next: Visibility): Promise<void> => {
320
- const requestId = ++visibilityRequestId.current;
321
- const previous = queryClient.getQueryData<SharesResponse>(shareQueryKey);
322
- setPendingVisibility(next);
323
- updateCachedVisibility(next);
324
- return new Promise((resolve, reject) => {
325
- setVisibility.mutate(
326
- {
327
- resourceType: props.resourceType,
328
- resourceId: props.resourceId,
329
- visibility: next,
330
- } as any,
331
- {
332
- onSuccess: (result: any) => {
333
- if (requestId === visibilityRequestId.current) {
334
- updateCachedVisibility(
335
- (result?.visibility as Visibility | undefined) ?? next,
336
- );
337
- }
338
- sharesQuery
339
- .refetch()
340
- .then(() => resolve())
341
- .catch(reject)
342
- .finally(() => {
343
- if (requestId === visibilityRequestId.current) {
344
- setPendingVisibility(null);
345
- }
346
- });
347
- },
348
- onError: (error) => {
349
- if (requestId === visibilityRequestId.current) {
350
- setPendingVisibility(null);
351
- if (previous) {
352
- queryClient.setQueryData(shareQueryKey, previous);
353
- } else {
354
- queryClient.invalidateQueries({ queryKey: shareQueryKey });
355
- }
356
- }
357
- reject(error);
358
- },
359
- },
360
- );
361
- });
362
- };
363
-
364
- const triggerVisibility =
365
- pendingVisibility ??
366
- (sharesQuery.data
367
- ? ((sharesQuery.data.visibility as Visibility | null) ?? "private")
368
- : null);
251
+ const triggerVisibility = controller.triggerVisibility;
369
252
  const triggerMeta = triggerVisibility
370
253
  ? visibilityMeta(triggerVisibility, props.visibilityCopy)
371
254
  : null;
@@ -376,7 +259,7 @@ export function ShareButton(props: ShareButtonProps) {
376
259
  iconOnly && triggerMeta ? `Share (${triggerMeta.label})` : "Share";
377
260
 
378
261
  return (
379
- <Popover open={open} onOpenChange={handleOpenChange}>
262
+ <Popover open={controller.open} onOpenChange={controller.handleOpenChange}>
380
263
  <PopoverTrigger asChild>
381
264
  <button
382
265
  type="button"
@@ -403,250 +286,51 @@ export function ShareButton(props: ShareButtonProps) {
403
286
  onOpenAutoFocus={(e) => e.preventDefault()}
404
287
  onInteractOutside={handleSharePopoverInteractOutside}
405
288
  >
406
- <SharePanel
407
- {...props}
408
- inviteEmail={inviteEmail}
409
- onInviteEmailChange={setInviteEmail}
410
- sharesQuery={sharesQuery}
411
- visibilityOverride={pendingVisibility}
412
- onVisibilityChange={handleVisibilityChange}
413
- onClose={() => handleOpenChange(false)}
414
- activeTab={activeShareTab}
415
- onTabChange={handleShareTabChange}
416
- />
289
+ <SharePanel {...props} controller={controller} />
417
290
  </PopoverContent>
418
291
  </Popover>
419
292
  );
420
293
  }
421
294
 
422
- interface OrgMember {
423
- email: string;
424
- name?: string | null;
425
- role?: string | null;
426
- joinedAt?: number | null;
427
- }
428
-
429
- interface OrgMembersResponse {
430
- members: OrgMember[];
431
- hasMore?: boolean;
432
- nextOffset?: number | null;
433
- }
434
-
435
- interface OrgMemberSearch {
436
- members: OrgMember[];
437
- isLoading: boolean;
438
- isLoadingMore: boolean;
439
- hasMore: boolean;
440
- error: boolean;
441
- loadMore: () => void;
442
- }
443
-
444
- function useOrgMemberSearch(query: string, enabled: boolean): OrgMemberSearch {
445
- const search = query.trim();
446
- const [members, setMembers] = useState<OrgMember[]>([]);
447
- const [nextOffset, setNextOffset] = useState<number | null>(null);
448
- const [hasMore, setHasMore] = useState(false);
449
- const [isLoading, setIsLoading] = useState(false);
450
- const [isLoadingMore, setIsLoadingMore] = useState(false);
451
- const [error, setError] = useState(false);
452
- const requestIdRef = useRef(0);
453
- const abortRef = useRef<AbortController | null>(null);
454
-
455
- const fetchPage = useCallback(
456
- (offset: number, append: boolean) => {
457
- if (!enabled) return;
458
- const requestId = ++requestIdRef.current;
459
- abortRef.current?.abort();
460
- const controller = new AbortController();
461
- abortRef.current = controller;
462
- if (append) {
463
- setIsLoadingMore(true);
464
- } else {
465
- setIsLoading(true);
466
- setMembers([]);
467
- setNextOffset(null);
468
- setHasMore(false);
469
- }
470
- setError(false);
471
-
472
- const params = new URLSearchParams();
473
- if (search) params.set("search", search);
474
- params.set("limit", String(MEMBER_SUGGESTION_LIMIT));
475
- params.set("offset", String(offset));
476
-
477
- fetch(`${agentNativePath("/_agent-native/org/members")}?${params}`, {
478
- credentials: "include",
479
- signal: controller.signal,
480
- })
481
- .then((response) => {
482
- if (!response.ok) throw new Error("Could not load people");
483
- return response.json() as Promise<OrgMembersResponse>;
484
- })
485
- .then((data) => {
486
- if (controller.signal.aborted || requestId !== requestIdRef.current)
487
- return;
488
- const nextMembers = normalizeMembers(data?.members);
489
- setMembers((prev) =>
490
- append ? mergeMembers(prev, nextMembers) : nextMembers,
491
- );
492
- setHasMore(data?.hasMore === true);
493
- setNextOffset(
494
- typeof data?.nextOffset === "number" ? data.nextOffset : null,
495
- );
496
- })
497
- .catch((err) => {
498
- if (controller.signal.aborted || requestId !== requestIdRef.current)
499
- return;
500
- setError(true);
501
- setHasMore(false);
502
- setNextOffset(null);
503
- if (!append) setMembers([]);
504
- if (process.env.NODE_ENV === "development") {
505
- console.warn("[ShareButton] org member search failed", err);
506
- }
507
- })
508
- .finally(() => {
509
- if (controller.signal.aborted || requestId !== requestIdRef.current)
510
- return;
511
- if (append) setIsLoadingMore(false);
512
- else setIsLoading(false);
513
- });
514
- },
515
- [enabled, search],
516
- );
517
-
518
- useEffect(() => {
519
- if (!enabled) {
520
- abortRef.current?.abort();
521
- setMembers([]);
522
- setNextOffset(null);
523
- setHasMore(false);
524
- setIsLoading(false);
525
- setIsLoadingMore(false);
526
- setError(false);
527
- return;
528
- }
529
- const timeout = setTimeout(
530
- () => fetchPage(0, false),
531
- search ? MEMBER_SEARCH_DEBOUNCE_MS : 0,
532
- );
533
- return () => {
534
- clearTimeout(timeout);
535
- abortRef.current?.abort();
536
- };
537
- }, [enabled, fetchPage, search]);
538
-
539
- const loadMore = useCallback(() => {
540
- if (!enabled || !hasMore || nextOffset === null) return;
541
- if (isLoading || isLoadingMore) return;
542
- fetchPage(nextOffset, true);
543
- }, [enabled, fetchPage, hasMore, isLoading, isLoadingMore, nextOffset]);
544
-
545
- return {
546
- members,
547
- isLoading,
548
- isLoadingMore,
549
- hasMore,
550
- error,
551
- loadMore,
552
- };
553
- }
554
-
555
- function normalizeMembers(value: unknown): OrgMember[] {
556
- if (!Array.isArray(value)) return [];
557
- return value
558
- .map((m: any) => ({
559
- email: typeof m?.email === "string" ? m.email : "",
560
- name: typeof m?.name === "string" ? m.name : null,
561
- role: typeof m?.role === "string" ? m.role : null,
562
- joinedAt:
563
- typeof m?.joinedAt === "number"
564
- ? m.joinedAt
565
- : typeof m?.joined_at === "number"
566
- ? m.joined_at
567
- : null,
568
- }))
569
- .filter((m) => m.email);
570
- }
571
-
572
- function mergeMembers(existing: OrgMember[], next: OrgMember[]): OrgMember[] {
573
- const seen = new Set(existing.map((m) => m.email.toLowerCase()));
574
- const merged = [...existing];
575
- for (const member of next) {
576
- const key = member.email.toLowerCase();
577
- if (seen.has(key)) continue;
578
- seen.add(key);
579
- merged.push(member);
580
- }
581
- return merged;
582
- }
583
-
584
295
  function SharePanel(
585
296
  props: ShareButtonProps & {
586
- inviteEmail: string;
587
- onInviteEmailChange: (email: string) => void;
588
- sharesQuery: ReturnType<typeof useActionQuery<SharesResponse>>;
589
- visibilityOverride: Visibility | null;
590
- onVisibilityChange: (visibility: Visibility) => Promise<void>;
591
- onClose: () => void;
592
- activeTab: string;
593
- onTabChange: (value: string) => void;
297
+ controller: ShareButtonController;
594
298
  },
595
299
  ) {
300
+ const { resourceTitle, controller } = props;
596
301
  const {
597
- resourceType,
598
- resourceId,
599
- resourceTitle,
600
- sharesQuery,
601
- visibilityOverride,
602
- onVisibilityChange,
603
- onClose,
604
302
  inviteEmail,
605
- onInviteEmailChange,
606
- } = props;
607
-
608
- const share = useActionMutation("share-resource");
609
- const unshare = useActionMutation("unshare-resource");
610
-
611
- const [role, setRole] = useState<Role>("viewer");
612
- const [notifyPeople, setNotifyPeople] = useState(true);
613
- const [shareError, setShareError] = useState<string | null>(null);
614
- const [suggestionsOpen, setSuggestionsOpen] = useState(false);
303
+ setInviteEmail: onInviteEmailChange,
304
+ handleOpenChange,
305
+ activeShareTab,
306
+ handleShareTabChange,
307
+ data,
308
+ policy,
309
+ visibility,
310
+ canManage,
311
+ role,
312
+ setRole,
313
+ notifyPeople,
314
+ setNotifyPeople,
315
+ shareError,
316
+ setShareError,
317
+ suggestionsOpen,
318
+ setSuggestionsOpen,
319
+ inFlight,
320
+ memberSearch,
321
+ memberSuggestions,
322
+ knownMembers,
323
+ shares,
324
+ handleVisibility,
325
+ handleHideInSearch,
326
+ handleAdd,
327
+ handleChangeRole,
328
+ handleRemove,
329
+ handleDone,
330
+ } = controller;
615
331
  const hasInviteEmail = inviteEmail.trim().length > 0;
616
332
 
617
- // Optimistic overlays so clicks feel instant.
618
- const [pendingAdds, setPendingAdds] = useState<Share[]>([]);
619
- const [pendingRemoves, setPendingRemoves] = useState<Set<string>>(new Set());
620
- const [roleOverrides, setRoleOverrides] = useState<Record<string, Role>>({});
621
- // Principals with an in-flight share/unshare mutation. We disable the
622
- // role dropdown and the trash button for any share in this set so a
623
- // user can't race a role-change against a remove (which would otherwise
624
- // let the upsert silently re-grant access after the delete landed), and
625
- // can't rapid-fire two creates for the same pending add.
626
- const [inFlight, setInFlight] = useState<Set<string>>(new Set());
627
- const addInFlight = (k: string) =>
628
- setInFlight((prev) => new Set(prev).add(k));
629
- const clearInFlight = (k: string) =>
630
- setInFlight((prev) => {
631
- const next = new Set(prev);
632
- next.delete(k);
633
- return next;
634
- });
635
-
636
- useEffect(() => {
637
- sharesQuery.refetch();
638
- // eslint-disable-next-line react-hooks/exhaustive-deps
639
- }, []);
640
-
641
- const data = sharesQuery.data;
642
333
  const isLoading = data === undefined;
643
- const policy: SharesPolicy = data?.policy ?? {
644
- allowPublic: true,
645
- requireOrgMemberForUserShares: false,
646
- };
647
- const visibility: Visibility =
648
- visibilityOverride ?? (data?.visibility as Visibility | null) ?? "private";
649
- const canManage = data?.role === "owner" || data?.role === "admin";
650
334
  const meta = visibilityMeta(visibility, props.visibilityCopy);
651
335
  const peopleAccessLabel = props.peopleAccessLabel ?? "People with access";
652
336
  const generalAccessLabel = props.generalAccessLabel ?? "General access";
@@ -689,188 +373,9 @@ function SharePanel(
689
373
  const hasTabs = extraTabs.length > 0;
690
374
  const shareTabLabel = props.shareTabs?.shareLabel ?? "Share link";
691
375
 
692
- const serverShares = data?.shares ?? [];
693
- const shares: Share[] = [
694
- ...serverShares
695
- .filter((s) => !pendingRemoves.has(keyOf(s)))
696
- .map((s) => ({ ...s, role: roleOverrides[keyOf(s)] ?? s.role })),
697
- ...pendingAdds,
698
- ];
699
- const memberSearch = useOrgMemberSearch(
700
- inviteEmail,
701
- canManage && suggestionsOpen,
702
- );
703
- const excludedMemberEmails = new Set<string>();
704
- if (data?.ownerEmail) excludedMemberEmails.add(data.ownerEmail.toLowerCase());
705
- for (const s of shares) {
706
- if (s.principalType === "user") {
707
- excludedMemberEmails.add(s.principalId.toLowerCase());
708
- }
709
- }
710
- const memberSuggestions = memberSearch.members.filter(
711
- (m) => !excludedMemberEmails.has(m.email.toLowerCase()),
712
- );
713
- const knownMembers = memberSearch.members;
714
-
715
- const handleVisibility = (next: Visibility) => {
716
- if (next === visibility) return;
717
- if (!canManage) {
718
- setShareError("Only owners and admins can change access.");
719
- return;
720
- }
721
- setShareError(null);
722
- void onVisibilityChange(next).catch((err) => {
723
- setShareError(extractShareErrorMessage(err));
724
- });
725
- };
726
-
727
- const handleHideInSearch = () => {
728
- const control = props.hideInSearchControl;
729
- if (!control || control.pending || !canManage) return;
730
- setShareError(null);
731
- try {
732
- Promise.resolve(control.onCheckedChange(!control.checked)).catch(
733
- (err) => {
734
- setShareError(extractShareErrorMessage(err));
735
- },
736
- );
737
- } catch (err) {
738
- setShareError(extractShareErrorMessage(err));
739
- }
740
- };
741
-
742
- const handleAdd = () => {
743
- const trimmed = inviteEmail.trim();
744
- if (!trimmed) return;
745
- const optimistic: Share = {
746
- id: `pending-${trimmed}`,
747
- principalType: "user",
748
- principalId: trimmed,
749
- role,
750
- };
751
- const k = keyOf(optimistic);
752
- // Ignore duplicate submits while an add for the same principal is in flight.
753
- if (inFlight.has(k)) return;
754
- setShareError(null);
755
- setPendingAdds((p) => [...p, optimistic]);
756
- onInviteEmailChange("");
757
- setSuggestionsOpen(false);
758
- addInFlight(k);
759
- share.mutate(
760
- {
761
- resourceType,
762
- resourceId,
763
- principalType: "user",
764
- principalId: trimmed,
765
- role,
766
- notify: notifyPeople,
767
- resourceUrl: getNotificationUrl(props.shareUrl),
768
- } as any,
769
- {
770
- onSuccess: () => {
771
- sharesQuery.refetch().then(() => {
772
- setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));
773
- clearInFlight(k);
774
- });
775
- },
776
- onError: (err: any) => {
777
- setPendingAdds((p) => p.filter((s) => s.id !== optimistic.id));
778
- clearInFlight(k);
779
- onInviteEmailChange(trimmed);
780
- setShareError(extractShareErrorMessage(err));
781
- },
782
- },
783
- );
784
- };
785
-
786
- const handleChangeRole = (s: Share, next: Role) => {
787
- if (s.role === next) return;
788
- const k = keyOf(s);
789
- // Don't stack a role change on top of an in-flight add/remove/role
790
- // change for the same principal — it can race with unshare and end up
791
- // re-granting access after a delete. UI already disables the control,
792
- // but belt-and-suspenders here too.
793
- if (inFlight.has(k)) return;
794
- setRoleOverrides((prev) => ({ ...prev, [k]: next }));
795
- addInFlight(k);
796
- // share-resource is upsert: calling with same principal + new role
797
- // updates the existing share row. See sharing/actions/share-resource.ts.
798
- share.mutate(
799
- {
800
- resourceType,
801
- resourceId,
802
- principalType: s.principalType,
803
- principalId: s.principalId,
804
- role: next,
805
- notify: false,
806
- } as any,
807
- {
808
- onSuccess: () => {
809
- sharesQuery.refetch().then(() => {
810
- setRoleOverrides((prev) => {
811
- const { [k]: _, ...rest } = prev;
812
- return rest;
813
- });
814
- clearInFlight(k);
815
- });
816
- },
817
- onError: () => {
818
- setRoleOverrides((prev) => {
819
- const { [k]: _, ...rest } = prev;
820
- return rest;
821
- });
822
- clearInFlight(k);
823
- },
824
- },
825
- );
826
- };
827
-
828
- const handleRemove = (s: Share) => {
829
- const k = keyOf(s);
830
- // If any other mutation is in flight for this principal, don't start a
831
- // remove — it can interleave with an upsert and leave the row in place.
832
- // The UI already disables the trash button when inFlight.has(k).
833
- if (inFlight.has(k)) return;
834
- setPendingRemoves((prev) => new Set(prev).add(k));
835
- addInFlight(k);
836
- unshare.mutate(
837
- {
838
- resourceType,
839
- resourceId,
840
- principalType: s.principalType,
841
- principalId: s.principalId,
842
- } as any,
843
- {
844
- onSuccess: () => {
845
- sharesQuery.refetch().then(() => {
846
- setPendingRemoves((prev) => {
847
- const next = new Set(prev);
848
- next.delete(k);
849
- return next;
850
- });
851
- clearInFlight(k);
852
- });
853
- },
854
- onError: () => {
855
- setPendingRemoves((prev) => {
856
- const next = new Set(prev);
857
- next.delete(k);
858
- return next;
859
- });
860
- clearInFlight(k);
861
- },
862
- },
863
- );
864
- };
865
-
866
- const handleDone = () => {
867
- if (canManage && hasInviteEmail) handleAdd();
868
- onClose();
869
- };
870
-
871
376
  const titleText = resourceTitle
872
377
  ? `Share "${resourceTitle}"`
873
- : `Share ${resourceType}`;
378
+ : `Share ${props.resourceType}`;
874
379
 
875
380
  const sharePanel = isLoading ? (
876
381
  <div>
@@ -889,7 +394,11 @@ function SharePanel(
889
394
  <div className="mb-4 h-9 rounded-md bg-muted animate-pulse" />
890
395
  {showDoneButton ? (
891
396
  <div className="mt-2 flex justify-end">
892
- <button type="button" onClick={onClose} className={BUTTON_PRIMARY_SM}>
397
+ <button
398
+ type="button"
399
+ onClick={() => handleOpenChange(false)}
400
+ className={BUTTON_PRIMARY_SM}
401
+ >
893
402
  Done
894
403
  </button>
895
404
  </div>
@@ -1096,8 +605,8 @@ function SharePanel(
1096
605
  },
1097
606
  ...extraTabs,
1098
607
  ];
1099
- const activeTab = tabs.some((tab) => tab.value === props.activeTab)
1100
- ? props.activeTab
608
+ const activeTab = tabs.some((tab) => tab.value === activeShareTab)
609
+ ? activeShareTab
1101
610
  : "share";
1102
611
 
1103
612
  return (
@@ -1116,7 +625,7 @@ function SharePanel(
1116
625
  role="tab"
1117
626
  aria-selected={active}
1118
627
  disabled={tab.disabled}
1119
- onClick={() => props.onTabChange(tab.value)}
628
+ onClick={() => handleShareTabChange(tab.value)}
1120
629
  className={cn(
1121
630
  "h-11 min-w-0 flex-1 rounded-lg px-3 text-sm font-medium text-muted-foreground transition-colors hover:bg-background/70 hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
1122
631
  active &&
@@ -1695,37 +1204,6 @@ function keyOf(s: Share): string {
1695
1204
  return `${s.principalType}:${s.principalId}`;
1696
1205
  }
1697
1206
 
1698
- /**
1699
- * Pull a user-readable error message out of a failed action call. Action
1700
- * routes surface server-side errors as a JSON `{ error: string }` body that
1701
- * the `useActionMutation` wrapper re-throws as
1702
- * `Error("Action <name> failed: <message>")`. Strip the framework prefix so
1703
- * what reaches the user is the underlying server message.
1704
- */
1705
- function extractShareErrorMessage(err: unknown): string {
1706
- const fallback = "Could not update sharing — please try again.";
1707
- const pickRaw = (): string | null => {
1708
- if (!err) return null;
1709
- if (err instanceof Error) return err.message?.trim() || null;
1710
- if (typeof err === "string") return err.trim() || null;
1711
- if (typeof err === "object") {
1712
- const any = err as { error?: unknown; message?: unknown };
1713
- if (typeof any.error === "string" && any.error.trim()) return any.error;
1714
- if (typeof any.message === "string" && any.message.trim())
1715
- return any.message;
1716
- }
1717
- return null;
1718
- };
1719
- const raw = pickRaw();
1720
- if (!raw || raw.toLowerCase() === "failed to fetch") return fallback;
1721
- const stripped = raw.replace(/^Action\s+[\w-]+\s+failed:\s*/i, "");
1722
- return stripped || fallback;
1723
- }
1724
- function getNotificationUrl(explicit?: string): string | undefined {
1725
- if (explicit) return explicit;
1726
- if (typeof window === "undefined") return undefined;
1727
- return window.location.href;
1728
- }
1729
1207
  function cap(s: string): string {
1730
1208
  return s.charAt(0).toUpperCase() + s.slice(1);
1731
1209
  }