@agent-native/core 0.117.1 → 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 (815) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +40 -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 +2 -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/cli/context-xray-local.ts +1 -1
  9. package/corpus/core/src/client/AgentPanel.tsx +90 -107
  10. package/corpus/core/src/client/AssistantChat.tsx +30 -13
  11. package/corpus/core/src/client/CommandMenu.tsx +68 -178
  12. package/corpus/core/src/client/agent-chat-adapter.ts +3 -1
  13. package/corpus/core/src/client/app-providers.tsx +1 -1
  14. package/corpus/core/src/client/chat/message-components.tsx +116 -10
  15. package/corpus/core/src/client/chat/tool-call-display.tsx +26 -5
  16. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +14 -40
  17. package/corpus/core/src/client/components/ui/message-scroller.tsx +15 -1
  18. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +4 -4
  19. package/corpus/core/src/client/extensions/ExtensionsSidebarSection.tsx +11 -11
  20. package/corpus/core/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  21. package/corpus/core/src/client/extensions/delete-extension.ts +2 -2
  22. package/corpus/core/src/client/i18n.tsx +22 -0
  23. package/corpus/core/src/client/index.ts +17 -0
  24. package/corpus/core/src/client/org/OrgSwitcher.tsx +25 -1
  25. package/corpus/core/src/client/org/TeamPage.tsx +257 -153
  26. package/corpus/core/src/client/progress/RunsTray.tsx +89 -88
  27. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +5 -2
  28. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +34 -13
  29. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +13 -0
  30. package/corpus/core/src/client/settings/DemoModeSection.tsx +6 -18
  31. package/corpus/core/src/client/settings/SecretsSection.tsx +97 -52
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +302 -254
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +23 -2
  34. package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  35. package/corpus/core/src/client/settings/index.ts +7 -0
  36. package/corpus/core/src/client/settings/useSettingsPanelController.ts +155 -0
  37. package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  38. package/corpus/core/src/client/setup-connections/index.ts +10 -0
  39. package/corpus/core/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  40. package/corpus/core/src/client/sharing/ShareButton.tsx +71 -592
  41. package/corpus/core/src/client/sharing/ShareDialog.tsx +299 -633
  42. package/corpus/core/src/client/sharing/index.ts +42 -0
  43. package/corpus/core/src/client/sharing/share-controller-helpers.ts +318 -0
  44. package/corpus/core/src/client/sharing/useShareButtonController.ts +600 -0
  45. package/corpus/core/src/client/sharing/useShareDialogController.ts +559 -0
  46. package/corpus/core/src/client/sse-event-processor.ts +23 -0
  47. package/corpus/core/src/client/tool-display.ts +71 -0
  48. package/corpus/core/src/client/use-agent-engine-configured.ts +12 -19
  49. package/corpus/core/src/client/use-chat-threads.ts +33 -12
  50. package/corpus/core/src/db/client.ts +13 -10
  51. package/corpus/core/src/extensions/actions.ts +13 -5
  52. package/corpus/core/src/extensions/local.ts +1 -0
  53. package/corpus/core/src/extensions/routes.ts +10 -5
  54. package/corpus/core/src/extensions/schema.ts +5 -0
  55. package/corpus/core/src/extensions/slots/store.ts +14 -4
  56. package/corpus/core/src/extensions/store.ts +55 -19
  57. package/corpus/core/src/extensions/theme.ts +1 -1
  58. package/corpus/core/src/file-upload/registry.ts +9 -0
  59. package/corpus/core/src/index.browser.ts +5 -0
  60. package/corpus/core/src/index.ts +1 -0
  61. package/corpus/core/src/localization/default-messages.ts +28 -6
  62. package/corpus/core/src/mcp-client/oauth-routes.ts +16 -2
  63. package/corpus/core/src/scripts/call-agent.ts +5 -1
  64. package/corpus/core/src/server/action-discovery.ts +8 -0
  65. package/corpus/core/src/server/better-auth-instance.ts +7 -2
  66. package/corpus/core/src/server/email-template.ts +18 -0
  67. package/corpus/core/src/server/email-templates.ts +3 -0
  68. package/corpus/core/src/server/email.ts +40 -4
  69. package/corpus/core/src/server/realtime-voice.ts +1 -1
  70. package/corpus/core/src/sharing/actions/share-resource.ts +1 -0
  71. package/corpus/core/src/styles/agent-native.css +0 -24
  72. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  73. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  74. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  75. package/corpus/core/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  76. package/corpus/core/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  77. package/corpus/core/src/templates/default/app/design-system.ts +3 -0
  78. package/corpus/core/src/templates/default/app/global.css +1 -1
  79. package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +6 -6
  80. package/corpus/core/src/templates/default/app/i18n/de-DE.ts +6 -6
  81. package/corpus/core/src/templates/default/app/i18n/en-US.ts +6 -6
  82. package/corpus/core/src/templates/default/app/i18n/es-ES.ts +6 -6
  83. package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +6 -6
  84. package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +6 -6
  85. package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +6 -6
  86. package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +6 -6
  87. package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +6 -6
  88. package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +7 -7
  89. package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +7 -7
  90. package/corpus/core/src/templates/default/app/root.tsx +5 -2
  91. package/corpus/core/src/templates/default/package.json +1 -0
  92. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  93. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  94. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  95. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  96. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  97. package/corpus/core/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  98. package/corpus/core/src/user-profile/actions/get-user-profile.ts +16 -0
  99. package/corpus/core/src/user-profile/actions/update-user-profile.ts +24 -0
  100. package/corpus/core/src/user-profile/index.ts +5 -0
  101. package/corpus/core/src/user-profile/shared.ts +14 -0
  102. package/corpus/core/src/user-profile/store.ts +50 -0
  103. package/corpus/core/src/vite/client.ts +39 -0
  104. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  105. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  106. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +22 -2
  107. package/corpus/templates/analytics/.agents/skills/shadcn-ui/SKILL.md +28 -4
  108. package/corpus/templates/analytics/app/components/ui/toolkit-provider.tsx +6 -1
  109. package/corpus/templates/analytics/app/design-system.ts +3 -0
  110. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  111. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  112. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +22 -2
  113. package/corpus/templates/assets/.agents/skills/shadcn-ui/SKILL.md +28 -4
  114. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -2
  115. package/corpus/templates/assets/app/components/ui/alert.tsx +1 -0
  116. package/corpus/templates/assets/app/components/ui/toolkit-provider.tsx +6 -1
  117. package/corpus/templates/assets/app/design-system.ts +3 -0
  118. package/corpus/templates/assets/app/global.css +1 -1
  119. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +26 -30
  120. package/corpus/templates/assets/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  121. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  122. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  123. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +22 -2
  124. package/corpus/templates/brain/.agents/skills/shadcn-ui/SKILL.md +28 -4
  125. package/corpus/templates/brain/app/components/ui/dialog.tsx +1 -0
  126. package/corpus/templates/brain/app/components/ui/toolkit-provider.tsx +6 -1
  127. package/corpus/templates/brain/app/design-system.ts +3 -0
  128. package/corpus/templates/brain/app/global.css +2 -2
  129. package/corpus/templates/brain/app/lib/brain.ts +2 -2
  130. package/corpus/templates/brain/app/root.tsx +2 -2
  131. package/corpus/templates/brain/app/routes/sources.tsx +8 -8
  132. package/corpus/templates/brain/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  133. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  134. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  135. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +22 -2
  136. package/corpus/templates/calendar/.agents/skills/shadcn-ui/SKILL.md +28 -4
  137. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +6 -2
  138. package/corpus/templates/calendar/app/components/ui/toolkit-provider.tsx +6 -1
  139. package/corpus/templates/calendar/app/design-system.ts +3 -0
  140. package/corpus/templates/calendar/app/global.css +1 -1
  141. package/corpus/templates/calendar/app/root.tsx +2 -2
  142. package/corpus/templates/calendar/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  143. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  144. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  145. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  146. package/corpus/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  147. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +2 -2
  148. package/corpus/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  149. package/corpus/templates/chat/app/design-system.ts +3 -0
  150. package/corpus/templates/chat/app/global.css +1 -1
  151. package/corpus/templates/chat/app/root.tsx +2 -2
  152. package/corpus/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  153. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  154. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  155. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +22 -2
  156. package/corpus/templates/clips/.agents/skills/shadcn-ui/SKILL.md +28 -4
  157. package/corpus/templates/clips/actions/export-to-brain.ts +1 -1
  158. package/corpus/templates/clips/actions/invite-member.ts +1 -0
  159. package/corpus/templates/clips/app/components/library/library-layout.tsx +2 -2
  160. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +20 -11
  161. package/corpus/templates/clips/app/components/ui/toolkit-provider.tsx +6 -1
  162. package/corpus/templates/clips/app/design-system.ts +3 -0
  163. package/corpus/templates/clips/app/global.css +1 -1
  164. package/corpus/templates/clips/app/root.tsx +7 -2
  165. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  166. package/corpus/templates/clips/app/routes/record.tsx +2 -88
  167. package/corpus/templates/clips/changelog/2026-07-22-builder-connected-recordings-start-resumable-upload-sessions.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-22-clip-thumbnails-now-come-from-the-recording-instead-of-the-p.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-22-clips-emails-now-render-the-agent-native-logo-in-gmail-and-o.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-22-dismissed-zoom-and-teams-meeting-note-prompts-now-stay-dismi.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-22-fixed-windows-recordings-aborting-during-the-countdown.md +6 -0
  172. package/corpus/templates/clips/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  173. package/corpus/templates/clips/changelog/2026-07-22-permissions-and-rewind-controls-are-now-grouped-with-clearer.md +6 -0
  174. package/corpus/templates/clips/changelog/2026-07-22-quieter-permissions-and-rewind-controls.md +6 -0
  175. package/corpus/templates/clips/changelog/2026-07-22-the-desktop-popover-opens-centered-under-the-menu-bar-icon-o.md +6 -0
  176. package/corpus/templates/clips/desktop/src/app.tsx +100 -62
  177. package/corpus/templates/clips/desktop/src/lib/meeting-notification-dismissal.ts +31 -0
  178. package/corpus/templates/clips/desktop/src/lib/recorder.ts +4 -167
  179. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +10 -1
  180. package/corpus/templates/clips/desktop/src/styles.css +111 -36
  181. package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +67 -4
  182. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +11 -2
  183. package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +51 -0
  184. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +5 -1
  185. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +0 -189
  186. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +62 -0
  187. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +37 -2
  188. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -0
  189. package/corpus/templates/clips/server/plugins/db.ts +6 -2
  190. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  191. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  192. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +22 -2
  193. package/corpus/templates/content/.agents/skills/shadcn-ui/SKILL.md +28 -4
  194. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +41 -59
  195. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +41 -41
  196. package/corpus/templates/content/app/components/editor/database/GalleryView.tsx +2 -1
  197. package/corpus/templates/content/app/components/editor/database/ListView.tsx +2 -1
  198. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +9 -9
  199. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +7 -7
  200. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +11 -11
  201. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +3 -3
  202. package/corpus/templates/content/app/components/ui/checkbox.tsx +1 -0
  203. package/corpus/templates/content/app/components/ui/collapsible.tsx +1 -0
  204. package/corpus/templates/content/app/components/ui/toolkit-provider.tsx +6 -1
  205. package/corpus/templates/content/app/design-system.ts +3 -0
  206. package/corpus/templates/content/app/global.css +30 -4
  207. package/corpus/templates/content/app/root.tsx +2 -2
  208. package/corpus/templates/content/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  209. package/corpus/templates/content/changelog/2026-07-22-page-actions-are-grouped-into-the-three-dots-menu-for-a-clea.md +6 -0
  210. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  211. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  212. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +10 -10
  213. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +1 -6
  214. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +3 -2
  215. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +13 -12
  216. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +17 -17
  217. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +8 -8
  218. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +3 -8
  219. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +2 -1
  220. package/corpus/templates/crm/app/components/crm/Surface.tsx +3 -2
  221. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +2 -2
  222. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +7 -7
  223. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +1 -1
  224. package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +1 -0
  225. package/corpus/templates/crm/app/components/ui/badge.tsx +1 -0
  226. package/corpus/templates/crm/app/components/ui/button.tsx +1 -0
  227. package/corpus/templates/crm/app/components/ui/card.tsx +1 -0
  228. package/corpus/templates/crm/app/components/ui/dialog.tsx +1 -0
  229. package/corpus/templates/crm/app/components/ui/input.tsx +1 -0
  230. package/corpus/templates/crm/app/components/ui/label.tsx +1 -0
  231. package/corpus/templates/crm/app/components/ui/select.tsx +1 -0
  232. package/corpus/templates/crm/app/components/ui/sheet.tsx +1 -0
  233. package/corpus/templates/crm/app/components/ui/skeleton.tsx +1 -0
  234. package/corpus/templates/crm/app/components/ui/switch.tsx +1 -0
  235. package/corpus/templates/crm/app/components/ui/table.tsx +1 -0
  236. package/corpus/templates/crm/app/components/ui/tabs.tsx +1 -0
  237. package/corpus/templates/crm/app/components/ui/textarea.tsx +1 -0
  238. package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +17 -0
  239. package/corpus/templates/crm/app/design-system.ts +3 -0
  240. package/corpus/templates/crm/app/global.css +1 -1
  241. package/corpus/templates/crm/app/root.tsx +9 -6
  242. package/corpus/templates/crm/app/routes/dashboard.tsx +1 -1
  243. package/corpus/templates/crm/app/routes/proposals.tsx +13 -13
  244. package/corpus/templates/crm/app/routes/setup.tsx +9 -9
  245. package/corpus/templates/crm/app/routes/tasks.tsx +14 -14
  246. package/corpus/templates/crm/app/routes/views.tsx +16 -16
  247. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  248. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  249. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +22 -2
  250. package/corpus/templates/design/.agents/skills/shadcn-ui/SKILL.md +28 -4
  251. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +19 -1
  252. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -1
  253. package/corpus/templates/design/app/components/design/EditPanel.tsx +177 -52
  254. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +179 -59
  255. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +74 -27
  256. package/corpus/templates/design/app/components/design/multi-screen/types.ts +2 -0
  257. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +8 -8
  258. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  259. package/corpus/templates/design/app/components/ui/command.tsx +1 -0
  260. package/corpus/templates/design/app/components/ui/toolkit-provider.tsx +6 -1
  261. package/corpus/templates/design/app/design-system.ts +3 -0
  262. package/corpus/templates/design/app/global.css +1 -1
  263. package/corpus/templates/design/app/hooks/use-navigation-state.ts +6 -5
  264. package/corpus/templates/design/app/root.tsx +2 -2
  265. package/corpus/templates/design/changelog/2026-07-22-design-owners-can-keep-editing-their-designs-after-switching.md +6 -0
  266. package/corpus/templates/design/changelog/2026-07-22-inspector-tabs-keep-their-text-labels-at-narrow-widths.md +6 -0
  267. package/corpus/templates/design/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  268. package/corpus/templates/design/changelog/2026-07-22-narrow-breakpoint-previews-keep-their-device-labels-readable.md +6 -0
  269. package/corpus/templates/design/changelog/2026-07-22-removed-the-draft-status-chip-from-the-design-editor.md +6 -0
  270. package/corpus/templates/design/changelog/2026-07-22-responsive-breakpoint-controls-stay-within-narrow-sidebars.md +6 -0
  271. package/corpus/templates/design/changelog/2026-07-22-responsive-peers-now-use-a-softer-selection-highlight-withou.md +6 -0
  272. package/corpus/templates/design/changelog/2026-07-22-rotate-from-context-menu.md +6 -0
  273. package/corpus/templates/design/changelog/2026-07-22-the-selection-outline-now-stays-attached-while-moving-screen.md +6 -0
  274. package/corpus/templates/design/changelog/2026-07-22-view-only-designs-now-support-figma-style-layer-inspection-w.md +6 -0
  275. package/corpus/templates/design/server/db/index.ts +4 -0
  276. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  277. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  278. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +22 -2
  279. package/corpus/templates/dispatch/.agents/skills/shadcn-ui/SKILL.md +28 -4
  280. package/corpus/templates/dispatch/app/components/ui/button.tsx +1 -0
  281. package/corpus/templates/dispatch/app/components/ui/toolkit-provider.tsx +17 -0
  282. package/corpus/templates/dispatch/app/design-system.ts +3 -0
  283. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +2 -2
  284. package/corpus/templates/dispatch/app/global.css +1 -1
  285. package/corpus/templates/dispatch/app/root.tsx +12 -9
  286. package/corpus/templates/dispatch/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  287. package/corpus/templates/dispatch/package.json +1 -0
  288. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  289. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  290. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +22 -2
  291. package/corpus/templates/forms/.agents/skills/shadcn-ui/SKILL.md +28 -4
  292. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -1
  293. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +3 -3
  294. package/corpus/templates/forms/app/components/ui/toolkit-provider.tsx +6 -1
  295. package/corpus/templates/forms/app/design-system.ts +3 -0
  296. package/corpus/templates/forms/app/global.css +1 -1
  297. package/corpus/templates/forms/app/hooks/use-forms.ts +55 -2
  298. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  299. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +3 -3
  300. package/corpus/templates/forms/app/pages/FormsListPage.tsx +23 -6
  301. package/corpus/templates/forms/app/root.tsx +2 -2
  302. package/corpus/templates/forms/changelog/2026-07-22-forms-now-archive-with-optimistic-feedback.md +6 -0
  303. package/corpus/templates/forms/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  304. package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -1
  305. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  306. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  307. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +22 -2
  308. package/corpus/templates/macros/.agents/skills/shadcn-ui/SKILL.md +28 -4
  309. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  310. package/corpus/templates/macros/app/components/ui/toolkit-provider.tsx +6 -1
  311. package/corpus/templates/macros/app/design-system.ts +3 -0
  312. package/corpus/templates/macros/app/root.tsx +2 -2
  313. package/corpus/templates/macros/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  314. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  315. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  316. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +22 -2
  317. package/corpus/templates/mail/.agents/skills/shadcn-ui/SKILL.md +28 -4
  318. package/corpus/templates/mail/app/components/email/EmailThread.tsx +134 -93
  319. package/corpus/templates/mail/app/components/email/email-iframe-document.ts +8 -2
  320. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +3 -3
  321. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +2 -2
  322. package/corpus/templates/mail/app/components/ui/textarea.tsx +1 -21
  323. package/corpus/templates/mail/app/components/ui/toolkit-provider.tsx +6 -1
  324. package/corpus/templates/mail/app/design-system.ts +3 -0
  325. package/corpus/templates/mail/app/global.css +1 -1
  326. package/corpus/templates/mail/changelog/2026-07-22-email-messages-no-longer-flash-with-an-unstyled-page-while-l.md +6 -0
  327. package/corpus/templates/mail/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  328. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  329. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  330. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +22 -2
  331. package/corpus/templates/plan/.agents/skills/shadcn-ui/SKILL.md +28 -4
  332. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +2 -2
  333. package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +1 -1
  334. package/corpus/templates/plan/app/components/ui/toolkit-provider.tsx +6 -1
  335. package/corpus/templates/plan/app/design-system.ts +3 -0
  336. package/corpus/templates/plan/app/global.css +1 -1
  337. package/corpus/templates/plan/app/root.tsx +2 -2
  338. package/corpus/templates/plan/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  339. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  340. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  341. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +22 -2
  342. package/corpus/templates/slides/.agents/skills/shadcn-ui/SKILL.md +28 -4
  343. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +2 -2
  344. package/corpus/templates/slides/app/components/ui/toolkit-provider.tsx +6 -1
  345. package/corpus/templates/slides/app/design-system.ts +3 -0
  346. package/corpus/templates/slides/app/root.tsx +2 -2
  347. package/corpus/templates/slides/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  348. package/corpus/templates/slides/changelog/2026-07-22-slides-no-longer-fail-intermittently-on-fresh-server-instances.md +6 -0
  349. package/corpus/templates/slides/changelog/2026-07-22-uploaded-screenshots-can-now-be-analyzed-and-recreated-as-ed.md +6 -0
  350. package/corpus/templates/slides/server/lib/chat-attachments.ts +7 -3
  351. package/corpus/templates/slides/server/plugins/db.ts +44 -17
  352. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  353. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  354. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +22 -2
  355. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +28 -4
  356. package/corpus/templates/tasks/app/components/ui/toolkit-provider.tsx +17 -0
  357. package/corpus/templates/tasks/app/design-system.ts +3 -0
  358. package/corpus/templates/tasks/app/global.css +1 -1
  359. package/corpus/templates/tasks/app/root.tsx +5 -2
  360. package/corpus/toolkit/CHANGELOG.md +14 -0
  361. package/corpus/toolkit/agent-native.eject.json +71 -0
  362. package/corpus/toolkit/package.json +31 -1
  363. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +100 -39
  364. package/corpus/toolkit/src/chat-history/index.ts +9 -0
  365. package/corpus/toolkit/src/chat-history/useChatHistoryRailController.ts +76 -0
  366. package/corpus/toolkit/src/chat-history.css +2 -0
  367. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +11 -8
  368. package/corpus/toolkit/src/composer/PromptComposer.tsx +27 -6
  369. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +107 -22
  370. package/corpus/toolkit/src/conformance/__fixtures__/css-in-js-adapter.tsx +401 -0
  371. package/corpus/toolkit/src/conformance/index.ts +3 -0
  372. package/corpus/toolkit/src/conformance/runner.tsx +710 -0
  373. package/corpus/toolkit/src/conformance/types.ts +45 -0
  374. package/corpus/toolkit/src/conformance/version.ts +22 -0
  375. package/corpus/toolkit/src/design-system/components.tsx +146 -0
  376. package/corpus/toolkit/src/design-system/context.tsx +31 -0
  377. package/corpus/toolkit/src/design-system/default-adapter.tsx +915 -0
  378. package/corpus/toolkit/src/design-system/definition.ts +14 -0
  379. package/corpus/toolkit/src/design-system/error-boundary.tsx +37 -0
  380. package/corpus/toolkit/src/design-system/index.ts +7 -0
  381. package/corpus/toolkit/src/design-system/theme.ts +145 -0
  382. package/corpus/toolkit/src/design-system/types.ts +363 -0
  383. package/corpus/toolkit/src/provider.tsx +98 -5
  384. package/corpus/toolkit/src/ui/button.tsx +95 -6
  385. package/corpus/toolkit/src/ui/dialog.tsx +48 -23
  386. package/corpus/toolkit/src/ui/popover.tsx +16 -2
  387. package/corpus/toolkit/src/ui/select.tsx +7 -3
  388. package/corpus/toolkit/src/ui/sidebar.tsx +47 -48
  389. package/corpus/toolkit/src/ui/tooltip.tsx +7 -3
  390. package/dist/a2a/types.d.ts +1 -1
  391. package/dist/a2a/types.d.ts.map +1 -1
  392. package/dist/a2a/types.js.map +1 -1
  393. package/dist/agent/types.d.ts +1 -1
  394. package/dist/agent/types.d.ts.map +1 -1
  395. package/dist/agent/types.js.map +1 -1
  396. package/dist/cli/context-xray-local.js +1 -1
  397. package/dist/cli/context-xray-local.js.map +1 -1
  398. package/dist/client/AgentPanel.d.ts.map +1 -1
  399. package/dist/client/AgentPanel.js +14 -14
  400. package/dist/client/AgentPanel.js.map +1 -1
  401. package/dist/client/AssistantChat.d.ts.map +1 -1
  402. package/dist/client/AssistantChat.js +26 -15
  403. package/dist/client/AssistantChat.js.map +1 -1
  404. package/dist/client/CommandMenu.d.ts.map +1 -1
  405. package/dist/client/CommandMenu.js +18 -106
  406. package/dist/client/CommandMenu.js.map +1 -1
  407. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  408. package/dist/client/agent-chat-adapter.js +2 -1
  409. package/dist/client/agent-chat-adapter.js.map +1 -1
  410. package/dist/client/app-providers.d.ts.map +1 -1
  411. package/dist/client/app-providers.js +1 -1
  412. package/dist/client/app-providers.js.map +1 -1
  413. package/dist/client/chat/message-components.d.ts +9 -1
  414. package/dist/client/chat/message-components.d.ts.map +1 -1
  415. package/dist/client/chat/message-components.js +62 -7
  416. package/dist/client/chat/message-components.js.map +1 -1
  417. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  418. package/dist/client/chat/tool-call-display.js +20 -5
  419. package/dist/client/chat/tool-call-display.js.map +1 -1
  420. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
  421. package/dist/client/chat/widgets/InlineExtensionWidget.js +9 -12
  422. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
  423. package/dist/client/components/ui/message-scroller.d.ts +1 -1
  424. package/dist/client/components/ui/message-scroller.d.ts.map +1 -1
  425. package/dist/client/components/ui/message-scroller.js +4 -3
  426. package/dist/client/components/ui/message-scroller.js.map +1 -1
  427. package/dist/client/extensions/ExtensionViewer.js +2 -2
  428. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  429. package/dist/client/extensions/ExtensionsSidebarSection.js +11 -11
  430. package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
  431. package/dist/client/extensions/agent-native-extension-runtime.js +1 -1
  432. package/dist/client/extensions/agent-native-extension-runtime.js.map +1 -1
  433. package/dist/client/extensions/delete-extension.d.ts +1 -1
  434. package/dist/client/extensions/delete-extension.d.ts.map +1 -1
  435. package/dist/client/extensions/delete-extension.js +1 -1
  436. package/dist/client/extensions/delete-extension.js.map +1 -1
  437. package/dist/client/i18n.d.ts.map +1 -1
  438. package/dist/client/i18n.js +9 -0
  439. package/dist/client/i18n.js.map +1 -1
  440. package/dist/client/index.d.ts +2 -2
  441. package/dist/client/index.d.ts.map +1 -1
  442. package/dist/client/index.js +2 -2
  443. package/dist/client/index.js.map +1 -1
  444. package/dist/client/org/OrgSwitcher.d.ts +3 -1
  445. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  446. package/dist/client/org/OrgSwitcher.js +12 -4
  447. package/dist/client/org/OrgSwitcher.js.map +1 -1
  448. package/dist/client/org/TeamPage.d.ts.map +1 -1
  449. package/dist/client/org/TeamPage.js +41 -33
  450. package/dist/client/org/TeamPage.js.map +1 -1
  451. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  452. package/dist/client/progress/RunsTray.js +9 -10
  453. package/dist/client/progress/RunsTray.js.map +1 -1
  454. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  455. package/dist/client/resources/McpConnectionSuggestion.js +5 -4
  456. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  457. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  458. package/dist/client/resources/McpIntegrationDialog.js +10 -8
  459. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  460. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  461. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  462. package/dist/client/resources/mcp-integration-catalog.js +13 -0
  463. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  464. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  465. package/dist/client/settings/DemoModeSection.js +2 -5
  466. package/dist/client/settings/DemoModeSection.js.map +1 -1
  467. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  468. package/dist/client/settings/SecretsSection.js +18 -6
  469. package/dist/client/settings/SecretsSection.js.map +1 -1
  470. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  471. package/dist/client/settings/SettingsPanel.js +87 -119
  472. package/dist/client/settings/SettingsPanel.js.map +1 -1
  473. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  474. package/dist/client/settings/SettingsTabsPage.js +16 -1
  475. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  476. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  477. package/dist/client/settings/VoiceTranscriptionSection.js +2 -5
  478. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  479. package/dist/client/settings/index.d.ts +1 -0
  480. package/dist/client/settings/index.d.ts.map +1 -1
  481. package/dist/client/settings/index.js +1 -0
  482. package/dist/client/settings/index.js.map +1 -1
  483. package/dist/client/settings/useSettingsPanelController.d.ts +22 -0
  484. package/dist/client/settings/useSettingsPanelController.d.ts.map +1 -0
  485. package/dist/client/settings/useSettingsPanelController.js +103 -0
  486. package/dist/client/settings/useSettingsPanelController.js.map +1 -0
  487. package/dist/client/setup-connections/BuilderConnectCard.d.ts +14 -6
  488. package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
  489. package/dist/client/setup-connections/BuilderConnectCard.js +24 -16
  490. package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
  491. package/dist/client/setup-connections/index.d.ts +2 -1
  492. package/dist/client/setup-connections/index.d.ts.map +1 -1
  493. package/dist/client/setup-connections/index.js +2 -1
  494. package/dist/client/setup-connections/index.js.map +1 -1
  495. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts +34 -0
  496. package/dist/client/setup-connections/useBuilderConnectCardController.d.ts.map +1 -0
  497. package/dist/client/setup-connections/useBuilderConnectCardController.js +39 -0
  498. package/dist/client/setup-connections/useBuilderConnectCardController.js.map +1 -0
  499. package/dist/client/sharing/ShareButton.d.ts +5 -5
  500. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  501. package/dist/client/sharing/ShareButton.js +19 -464
  502. package/dist/client/sharing/ShareButton.js.map +1 -1
  503. package/dist/client/sharing/ShareDialog.d.ts +6 -6
  504. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  505. package/dist/client/sharing/ShareDialog.js +69 -283
  506. package/dist/client/sharing/ShareDialog.js.map +1 -1
  507. package/dist/client/sharing/index.d.ts +3 -0
  508. package/dist/client/sharing/index.d.ts.map +1 -1
  509. package/dist/client/sharing/index.js +3 -0
  510. package/dist/client/sharing/index.js.map +1 -1
  511. package/dist/client/sharing/share-controller-helpers.d.ts +70 -0
  512. package/dist/client/sharing/share-controller-helpers.d.ts.map +1 -0
  513. package/dist/client/sharing/share-controller-helpers.js +224 -0
  514. package/dist/client/sharing/share-controller-helpers.js.map +1 -0
  515. package/dist/client/sharing/useShareButtonController.d.ts +91 -0
  516. package/dist/client/sharing/useShareButtonController.d.ts.map +1 -0
  517. package/dist/client/sharing/useShareButtonController.js +397 -0
  518. package/dist/client/sharing/useShareButtonController.js.map +1 -0
  519. package/dist/client/sharing/useShareDialogController.d.ts +109 -0
  520. package/dist/client/sharing/useShareDialogController.d.ts.map +1 -0
  521. package/dist/client/sharing/useShareDialogController.js +348 -0
  522. package/dist/client/sharing/useShareDialogController.js.map +1 -0
  523. package/dist/client/sse-event-processor.d.ts.map +1 -1
  524. package/dist/client/sse-event-processor.js +21 -0
  525. package/dist/client/sse-event-processor.js.map +1 -1
  526. package/dist/client/tool-display.d.ts +16 -0
  527. package/dist/client/tool-display.d.ts.map +1 -1
  528. package/dist/client/tool-display.js +52 -0
  529. package/dist/client/tool-display.js.map +1 -1
  530. package/dist/client/use-agent-engine-configured.d.ts +3 -2
  531. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  532. package/dist/client/use-agent-engine-configured.js +7 -19
  533. package/dist/client/use-agent-engine-configured.js.map +1 -1
  534. package/dist/client/use-chat-threads.d.ts.map +1 -1
  535. package/dist/client/use-chat-threads.js +21 -8
  536. package/dist/client/use-chat-threads.js.map +1 -1
  537. package/dist/collab/awareness.d.ts +2 -2
  538. package/dist/collab/awareness.d.ts.map +1 -1
  539. package/dist/db/client.d.ts +7 -7
  540. package/dist/db/client.d.ts.map +1 -1
  541. package/dist/db/client.js +13 -10
  542. package/dist/db/client.js.map +1 -1
  543. package/dist/extensions/actions.d.ts.map +1 -1
  544. package/dist/extensions/actions.js +8 -5
  545. package/dist/extensions/actions.js.map +1 -1
  546. package/dist/extensions/local.d.ts.map +1 -1
  547. package/dist/extensions/local.js +1 -0
  548. package/dist/extensions/local.js.map +1 -1
  549. package/dist/extensions/routes.d.ts.map +1 -1
  550. package/dist/extensions/routes.js +9 -4
  551. package/dist/extensions/routes.js.map +1 -1
  552. package/dist/extensions/schema.d.ts +23 -2
  553. package/dist/extensions/schema.d.ts.map +1 -1
  554. package/dist/extensions/schema.js +5 -0
  555. package/dist/extensions/schema.js.map +1 -1
  556. package/dist/extensions/slots/store.d.ts +1 -1
  557. package/dist/extensions/slots/store.d.ts.map +1 -1
  558. package/dist/extensions/slots/store.js +4 -4
  559. package/dist/extensions/slots/store.js.map +1 -1
  560. package/dist/extensions/store.d.ts +1 -0
  561. package/dist/extensions/store.d.ts.map +1 -1
  562. package/dist/extensions/store.js +38 -21
  563. package/dist/extensions/store.js.map +1 -1
  564. package/dist/extensions/theme.js +1 -1
  565. package/dist/extensions/theme.js.map +1 -1
  566. package/dist/file-upload/registry.d.ts.map +1 -1
  567. package/dist/file-upload/registry.js +9 -0
  568. package/dist/file-upload/registry.js.map +1 -1
  569. package/dist/index.browser.d.ts +1 -0
  570. package/dist/index.browser.d.ts.map +1 -1
  571. package/dist/index.browser.js +1 -0
  572. package/dist/index.browser.js.map +1 -1
  573. package/dist/index.d.ts +1 -0
  574. package/dist/index.d.ts.map +1 -1
  575. package/dist/index.js +1 -0
  576. package/dist/index.js.map +1 -1
  577. package/dist/localization/default-messages.d.ts +20 -0
  578. package/dist/localization/default-messages.d.ts.map +1 -1
  579. package/dist/localization/default-messages.js +26 -6
  580. package/dist/localization/default-messages.js.map +1 -1
  581. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  582. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  583. package/dist/mcp-client/oauth-routes.js +12 -2
  584. package/dist/mcp-client/oauth-routes.js.map +1 -1
  585. package/dist/observability/routes.d.ts +3 -3
  586. package/dist/provider-api/actions/custom-provider-registration.d.ts +3 -3
  587. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  588. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  589. package/dist/scripts/call-agent.d.ts.map +1 -1
  590. package/dist/scripts/call-agent.js +5 -1
  591. package/dist/scripts/call-agent.js.map +1 -1
  592. package/dist/secrets/routes.d.ts +6 -6
  593. package/dist/server/action-discovery.d.ts.map +1 -1
  594. package/dist/server/action-discovery.js +8 -0
  595. package/dist/server/action-discovery.js.map +1 -1
  596. package/dist/server/better-auth-instance.d.ts +7 -2
  597. package/dist/server/better-auth-instance.d.ts.map +1 -1
  598. package/dist/server/better-auth-instance.js.map +1 -1
  599. package/dist/server/email-template.d.ts +3 -0
  600. package/dist/server/email-template.d.ts.map +1 -1
  601. package/dist/server/email-template.js +13 -0
  602. package/dist/server/email-template.js.map +1 -1
  603. package/dist/server/email-templates.d.ts.map +1 -1
  604. package/dist/server/email-templates.js +3 -0
  605. package/dist/server/email-templates.js.map +1 -1
  606. package/dist/server/email.d.ts.map +1 -1
  607. package/dist/server/email.js +27 -4
  608. package/dist/server/email.js.map +1 -1
  609. package/dist/server/realtime-voice.js +1 -1
  610. package/dist/server/realtime-voice.js.map +1 -1
  611. package/dist/server/transcribe-voice.d.ts +1 -1
  612. package/dist/sharing/actions/share-resource.js +1 -0
  613. package/dist/sharing/actions/share-resource.js.map +1 -1
  614. package/dist/styles/agent-native.css +0 -24
  615. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  616. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  617. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  618. package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  619. package/dist/templates/chat/app/components/layout/Sidebar.tsx +2 -2
  620. package/dist/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  621. package/dist/templates/chat/app/design-system.ts +3 -0
  622. package/dist/templates/chat/app/global.css +1 -1
  623. package/dist/templates/chat/app/root.tsx +2 -2
  624. package/dist/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  625. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  626. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  627. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  628. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  629. package/dist/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  630. package/dist/templates/default/app/design-system.ts +3 -0
  631. package/dist/templates/default/app/global.css +1 -1
  632. package/dist/templates/default/app/i18n/ar-SA.ts +6 -6
  633. package/dist/templates/default/app/i18n/de-DE.ts +6 -6
  634. package/dist/templates/default/app/i18n/en-US.ts +6 -6
  635. package/dist/templates/default/app/i18n/es-ES.ts +6 -6
  636. package/dist/templates/default/app/i18n/fr-FR.ts +6 -6
  637. package/dist/templates/default/app/i18n/hi-IN.ts +6 -6
  638. package/dist/templates/default/app/i18n/ja-JP.ts +6 -6
  639. package/dist/templates/default/app/i18n/ko-KR.ts +6 -6
  640. package/dist/templates/default/app/i18n/pt-BR.ts +6 -6
  641. package/dist/templates/default/app/i18n/zh-CN.ts +7 -7
  642. package/dist/templates/default/app/i18n/zh-TW.ts +7 -7
  643. package/dist/templates/default/app/root.tsx +5 -2
  644. package/dist/templates/default/package.json +1 -0
  645. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  646. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  647. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  648. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  649. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  650. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  651. package/dist/user-profile/actions/get-user-profile.d.ts +4 -0
  652. package/dist/user-profile/actions/get-user-profile.d.ts.map +1 -0
  653. package/dist/user-profile/actions/get-user-profile.js +14 -0
  654. package/dist/user-profile/actions/get-user-profile.js.map +1 -0
  655. package/dist/user-profile/actions/update-user-profile.d.ts +6 -0
  656. package/dist/user-profile/actions/update-user-profile.d.ts.map +1 -0
  657. package/dist/user-profile/actions/update-user-profile.js +20 -0
  658. package/dist/user-profile/actions/update-user-profile.js.map +1 -0
  659. package/dist/user-profile/index.d.ts +2 -0
  660. package/dist/user-profile/index.d.ts.map +1 -0
  661. package/dist/user-profile/index.js +2 -0
  662. package/dist/user-profile/index.js.map +1 -0
  663. package/dist/user-profile/shared.d.ts +7 -0
  664. package/dist/user-profile/shared.d.ts.map +1 -0
  665. package/dist/user-profile/shared.js +6 -0
  666. package/dist/user-profile/shared.js.map +1 -0
  667. package/dist/user-profile/store.d.ts +4 -0
  668. package/dist/user-profile/store.d.ts.map +1 -0
  669. package/dist/user-profile/store.js +38 -0
  670. package/dist/user-profile/store.js.map +1 -0
  671. package/dist/vite/client.d.ts +3 -0
  672. package/dist/vite/client.d.ts.map +1 -1
  673. package/dist/vite/client.js +31 -0
  674. package/dist/vite/client.js.map +1 -1
  675. package/docs/content/custom-design-system.mdx +445 -0
  676. package/docs/content/toolkit-ui.mdx +16 -0
  677. package/package.json +3 -2
  678. package/src/a2a/types.ts +1 -0
  679. package/src/agent/types.ts +1 -1
  680. package/src/cli/context-xray-local.ts +1 -1
  681. package/src/client/AgentPanel.tsx +90 -107
  682. package/src/client/AssistantChat.tsx +30 -13
  683. package/src/client/CommandMenu.tsx +68 -178
  684. package/src/client/agent-chat-adapter.ts +3 -1
  685. package/src/client/app-providers.tsx +1 -1
  686. package/src/client/chat/message-components.tsx +116 -10
  687. package/src/client/chat/tool-call-display.tsx +26 -5
  688. package/src/client/chat/widgets/InlineExtensionWidget.tsx +14 -40
  689. package/src/client/components/ui/message-scroller.tsx +15 -1
  690. package/src/client/extensions/ExtensionViewer.tsx +4 -4
  691. package/src/client/extensions/ExtensionsSidebarSection.tsx +11 -11
  692. package/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  693. package/src/client/extensions/delete-extension.ts +2 -2
  694. package/src/client/i18n.tsx +22 -0
  695. package/src/client/index.ts +17 -0
  696. package/src/client/org/OrgSwitcher.tsx +25 -1
  697. package/src/client/org/TeamPage.tsx +257 -153
  698. package/src/client/progress/RunsTray.tsx +89 -88
  699. package/src/client/resources/McpConnectionSuggestion.tsx +5 -2
  700. package/src/client/resources/McpIntegrationDialog.tsx +34 -13
  701. package/src/client/resources/mcp-integration-catalog.ts +13 -0
  702. package/src/client/settings/DemoModeSection.tsx +6 -18
  703. package/src/client/settings/SecretsSection.tsx +97 -52
  704. package/src/client/settings/SettingsPanel.tsx +302 -254
  705. package/src/client/settings/SettingsTabsPage.tsx +23 -2
  706. package/src/client/settings/VoiceTranscriptionSection.tsx +7 -18
  707. package/src/client/settings/index.ts +7 -0
  708. package/src/client/settings/useSettingsPanelController.ts +155 -0
  709. package/src/client/setup-connections/BuilderConnectCard.tsx +116 -51
  710. package/src/client/setup-connections/index.ts +10 -0
  711. package/src/client/setup-connections/useBuilderConnectCardController.ts +82 -0
  712. package/src/client/sharing/ShareButton.tsx +71 -592
  713. package/src/client/sharing/ShareDialog.tsx +299 -633
  714. package/src/client/sharing/index.ts +42 -0
  715. package/src/client/sharing/share-controller-helpers.ts +318 -0
  716. package/src/client/sharing/useShareButtonController.ts +600 -0
  717. package/src/client/sharing/useShareDialogController.ts +559 -0
  718. package/src/client/sse-event-processor.ts +23 -0
  719. package/src/client/tool-display.ts +71 -0
  720. package/src/client/use-agent-engine-configured.ts +12 -19
  721. package/src/client/use-chat-threads.ts +33 -12
  722. package/src/db/client.ts +13 -10
  723. package/src/extensions/actions.ts +13 -5
  724. package/src/extensions/local.ts +1 -0
  725. package/src/extensions/routes.ts +10 -5
  726. package/src/extensions/schema.ts +5 -0
  727. package/src/extensions/slots/store.ts +14 -4
  728. package/src/extensions/store.ts +55 -19
  729. package/src/extensions/theme.ts +1 -1
  730. package/src/file-upload/registry.ts +9 -0
  731. package/src/index.browser.ts +5 -0
  732. package/src/index.ts +1 -0
  733. package/src/localization/default-messages.ts +28 -6
  734. package/src/mcp-client/oauth-routes.ts +16 -2
  735. package/src/scripts/call-agent.ts +5 -1
  736. package/src/server/action-discovery.ts +8 -0
  737. package/src/server/better-auth-instance.ts +7 -2
  738. package/src/server/email-template.ts +18 -0
  739. package/src/server/email-templates.ts +3 -0
  740. package/src/server/email.ts +40 -4
  741. package/src/server/realtime-voice.ts +1 -1
  742. package/src/sharing/actions/share-resource.ts +1 -0
  743. package/src/styles/agent-native.css +0 -24
  744. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  745. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  746. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +22 -2
  747. package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +28 -4
  748. package/src/templates/chat/app/components/layout/Sidebar.tsx +2 -2
  749. package/src/templates/chat/app/components/ui/toolkit-provider.tsx +6 -1
  750. package/src/templates/chat/app/design-system.ts +3 -0
  751. package/src/templates/chat/app/global.css +1 -1
  752. package/src/templates/chat/app/root.tsx +2 -2
  753. package/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  754. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  755. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  756. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +22 -2
  757. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +28 -4
  758. package/src/templates/default/app/components/ui/toolkit-provider.tsx +10 -0
  759. package/src/templates/default/app/design-system.ts +3 -0
  760. package/src/templates/default/app/global.css +1 -1
  761. package/src/templates/default/app/i18n/ar-SA.ts +6 -6
  762. package/src/templates/default/app/i18n/de-DE.ts +6 -6
  763. package/src/templates/default/app/i18n/en-US.ts +6 -6
  764. package/src/templates/default/app/i18n/es-ES.ts +6 -6
  765. package/src/templates/default/app/i18n/fr-FR.ts +6 -6
  766. package/src/templates/default/app/i18n/hi-IN.ts +6 -6
  767. package/src/templates/default/app/i18n/ja-JP.ts +6 -6
  768. package/src/templates/default/app/i18n/ko-KR.ts +6 -6
  769. package/src/templates/default/app/i18n/pt-BR.ts +6 -6
  770. package/src/templates/default/app/i18n/zh-CN.ts +7 -7
  771. package/src/templates/default/app/i18n/zh-TW.ts +7 -7
  772. package/src/templates/default/app/root.tsx +5 -2
  773. package/src/templates/default/package.json +1 -0
  774. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  775. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  776. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +43 -2
  777. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +86 -11
  778. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +22 -2
  779. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +28 -4
  780. package/src/user-profile/actions/get-user-profile.ts +16 -0
  781. package/src/user-profile/actions/update-user-profile.ts +24 -0
  782. package/src/user-profile/index.ts +5 -0
  783. package/src/user-profile/shared.ts +14 -0
  784. package/src/user-profile/store.ts +50 -0
  785. package/src/vite/client.ts +39 -0
  786. package/corpus/templates/analytics/app/components/ui/calendar.tsx +0 -70
  787. package/corpus/templates/analytics/app/components/ui/chart.tsx +0 -386
  788. package/corpus/templates/calendar/app/components/ui/sonner.tsx +0 -58
  789. package/corpus/templates/forms/app/components/ui/calendar.tsx +0 -214
  790. package/corpus/templates/forms/app/components/ui/chart.tsx +0 -379
  791. package/corpus/templates/forms/app/components/ui/command.tsx +0 -153
  792. package/corpus/templates/forms/app/components/ui/context-menu.tsx +0 -198
  793. package/corpus/templates/forms/app/components/ui/menubar.tsx +0 -254
  794. package/corpus/templates/macros/app/components/ui/menubar.tsx +0 -238
  795. package/corpus/templates/macros/app/components/ui/progress.tsx +0 -26
  796. package/corpus/templates/mail/app/components/ui/calendar.tsx +0 -211
  797. package/corpus/templates/mail/app/components/ui/chart.tsx +0 -379
  798. package/corpus/templates/mail/app/components/ui/command.tsx +0 -153
  799. package/corpus/templates/mail/app/components/ui/context-menu.tsx +0 -198
  800. package/corpus/templates/mail/app/components/ui/menubar.tsx +0 -254
  801. package/corpus/templates/tasks/app/components/ui/accordion.tsx +0 -56
  802. package/corpus/templates/tasks/app/components/ui/aspect-ratio.tsx +0 -5
  803. package/corpus/templates/tasks/app/components/ui/breadcrumb.tsx +0 -115
  804. package/corpus/templates/tasks/app/components/ui/calendar.tsx +0 -70
  805. package/corpus/templates/tasks/app/components/ui/carousel.tsx +0 -260
  806. package/corpus/templates/tasks/app/components/ui/chart.tsx +0 -379
  807. package/corpus/templates/tasks/app/components/ui/form.tsx +0 -177
  808. package/corpus/templates/tasks/app/components/ui/hover-card.tsx +0 -27
  809. package/corpus/templates/tasks/app/components/ui/input-otp.tsx +0 -69
  810. package/corpus/templates/tasks/app/components/ui/menubar.tsx +0 -254
  811. package/corpus/templates/tasks/app/components/ui/navigation-menu.tsx +0 -128
  812. package/corpus/templates/tasks/app/components/ui/pagination.tsx +0 -121
  813. package/corpus/templates/tasks/app/components/ui/resizable.tsx +0 -43
  814. package/corpus/templates/tasks/app/components/ui/sidebar.tsx +0 -782
  815. package/corpus/templates/tasks/app/components/ui/toggle.tsx +0 -43
@@ -1,25 +1,35 @@
1
- import * as Select from "@radix-ui/react-select";
2
1
  import {
3
- IconX,
4
- IconTrash,
5
- IconLock,
6
- IconWorld,
2
+ ActionButton,
3
+ Avatar as DesignSystemAvatar,
4
+ Dialog as DesignSystemDialog,
5
+ IconButton,
6
+ Picker,
7
+ Status,
8
+ TextArea,
9
+ TextField,
10
+ } from "@agent-native/toolkit/design-system";
11
+ import {
7
12
  IconCheck,
13
+ IconCode,
8
14
  IconCopy,
9
15
  IconLink,
16
+ IconLock,
10
17
  IconMail,
11
- IconCode,
12
- IconChevronDown,
18
+ IconTrash,
13
19
  IconUsersGroup,
20
+ IconWorld,
14
21
  } from "@tabler/icons-react";
15
- import { useEffect, useState, type ReactNode } from "react";
16
- import { createPortal } from "react-dom";
22
+ import type { ReactNode } from "react";
17
23
 
18
- import { agentNativePath } from "../api-path.js";
19
- import { writeClipboardText } from "../clipboard.js";
20
- import { useT } from "../i18n.js";
21
- import { useActionQuery, useActionMutation } from "../use-action.js";
22
24
  import { cn } from "../utils.js";
25
+ import {
26
+ useShareDialogController,
27
+ type ResourceShare,
28
+ type ShareDialogController,
29
+ type ShareDialogPerson,
30
+ type ShareDialogTab,
31
+ type ShareVisibility,
32
+ } from "./useShareDialogController.js";
23
33
 
24
34
  export interface ShareDialogProps {
25
35
  open: boolean;
@@ -45,138 +55,52 @@ export interface ShareDialogProps {
45
55
  linkTabExtras?: ReactNode;
46
56
  }
47
57
 
48
- type Visibility = "private" | "org" | "public";
49
- type Role = "viewer" | "editor" | "admin";
50
-
51
- interface Share {
52
- id: string;
53
- principalType: "user" | "org";
54
- principalId: string;
55
- displayName?: string | null;
56
- role: Role;
57
- }
58
-
59
- interface SharesResponse {
60
- ownerEmail: string | null;
61
- orgId: string | null;
62
- visibility: Visibility | null;
63
- role?: "owner" | Role;
64
- shares: Share[];
65
- }
66
-
67
- interface OrgMember {
68
- email: string;
69
- name?: string | null;
70
- }
71
-
72
- function useOrgMembers(): OrgMember[] {
73
- const [members, setMembers] = useState<OrgMember[]>([]);
74
- useEffect(() => {
75
- let cancelled = false;
76
- fetch(agentNativePath("/_agent-native/org/members"))
77
- .then((r) => (r.ok ? r.json() : null))
78
- .then((data) => {
79
- if (cancelled || !data) return;
80
- const list = Array.isArray(data?.members) ? data.members : [];
81
- setMembers(
82
- list
83
- .map((m: any) => ({
84
- email: typeof m?.email === "string" ? m.email : "",
85
- name: typeof m?.name === "string" ? m.name : null,
86
- }))
87
- .filter((m: OrgMember) => m.email),
88
- );
89
- })
90
- .catch(() => {});
91
- return () => {
92
- cancelled = true;
93
- };
94
- }, []);
95
- return members;
96
- }
97
-
98
- function displayName(email: string, members: OrgMember[]): string {
99
- const normalized = email.trim().toLowerCase();
100
- const match = members.find((m) => m.email.toLowerCase() === normalized);
101
- if (match?.name && match.name.trim()) return match.name;
102
- return normalized.includes("@") ? email : "Unknown person";
103
- }
104
-
105
58
  const BUTTON_BASE =
106
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0";
59
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors active:!scale-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0";
107
60
  const BUTTON_OUTLINE_SM = cn(
108
61
  BUTTON_BASE,
109
- "h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground",
62
+ "!h-9 !px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground",
110
63
  );
111
64
  const BUTTON_PRIMARY_SM = cn(
112
65
  BUTTON_BASE,
113
- "h-9 px-4 bg-primary text-primary-foreground hover:bg-primary/90",
66
+ "!h-9 !px-4 bg-primary text-primary-foreground hover:bg-primary/90",
114
67
  );
115
68
  const BUTTON_GHOST_ICON = cn(
116
69
  BUTTON_BASE,
117
- "h-8 w-8 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
70
+ "!h-8 !w-8 !p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
118
71
  );
119
72
 
120
- const VIS_ICONS: Record<Visibility, typeof IconLock> = {
73
+ const VIS_ICONS: Record<ShareVisibility, typeof IconLock> = {
121
74
  private: IconLock,
122
75
  org: IconUsersGroup,
123
76
  public: IconWorld,
124
77
  };
125
78
 
126
- function useVisibilityMeta() {
127
- const t = useT();
128
- return {
129
- private: {
130
- label: t("share.private"),
131
- description: t("share.privateDescription"),
132
- Icon: VIS_ICONS.private,
133
- },
134
- org: {
135
- label: t("share.organization"),
136
- description: t("share.organizationDescription"),
137
- Icon: VIS_ICONS.org,
138
- },
139
- public: {
140
- label: t("share.public"),
141
- description: t("share.publicDescription"),
142
- Icon: VIS_ICONS.public,
143
- },
144
- } satisfies Record<
145
- Visibility,
146
- { label: string; description: string; Icon: typeof IconLock }
147
- >;
148
- }
149
-
150
- function useRoleOptions() {
151
- const t = useT();
152
- return [
153
- {
154
- value: "viewer",
155
- label: t("share.viewer"),
156
- description: t("share.viewerDescription"),
157
- },
158
- {
159
- value: "editor",
160
- label: t("share.editor"),
161
- description: t("share.editorDescription"),
162
- },
163
- {
164
- value: "admin",
165
- label: t("share.admin"),
166
- description: t("share.adminDescription"),
167
- },
168
- ] satisfies Array<{ value: Role; label: string; description: string }>;
169
- }
79
+ const TAB_ICONS: Record<ShareDialogTab, typeof IconLink> = {
80
+ link: IconLink,
81
+ invite: IconMail,
82
+ embed: IconCode,
83
+ };
170
84
 
171
85
  /**
172
86
  * Framework share dialog. Drop into any template via
173
- * `<ShareDialog open onClose resourceType resourceId />`. Passing
174
- * `shareUrl` lights up a Link tab with a copy field; passing `embedUrl`
175
- * lights up an Embed tab. With neither prop, renders a single Invite +
176
- * general-access panel (Google-Docs-lite).
87
+ * `<ShareDialog open onClose resourceType resourceId />`. Passing `shareUrl`
88
+ * lights up a Link tab with a copy field; passing `embedUrl` lights up an
89
+ * Embed tab. With neither prop, renders a single Invite + general-access
90
+ * panel (Google-Docs-lite).
177
91
  */
178
- export function ShareDialog(props: ShareDialogProps) {
179
- const {
92
+ export function ShareDialog({
93
+ open,
94
+ onClose,
95
+ resourceType,
96
+ resourceId,
97
+ resourceTitle,
98
+ shareUrl,
99
+ embedUrl,
100
+ embedTabContent,
101
+ linkTabExtras,
102
+ }: ShareDialogProps) {
103
+ const controller = useShareDialogController({
180
104
  open,
181
105
  onClose,
182
106
  resourceType,
@@ -184,349 +108,194 @@ export function ShareDialog(props: ShareDialogProps) {
184
108
  resourceTitle,
185
109
  shareUrl,
186
110
  embedUrl,
187
- embedTabContent,
188
- linkTabExtras,
189
- } = props;
190
- const t = useT();
191
-
192
- const sharesQuery = useActionQuery<SharesResponse>("list-resource-shares", {
193
- resourceType,
194
- resourceId,
195
111
  });
196
- const orgMembers = useOrgMembers();
197
-
198
- const hasLinkTab = Boolean(shareUrl);
199
- const hasEmbedTab = Boolean(embedUrl);
200
- const tabsEnabled = hasLinkTab || hasEmbedTab;
201
-
202
- const [tab, setTab] = useState<"link" | "invite" | "embed">(
203
- hasLinkTab ? "link" : "invite",
204
- );
205
-
206
- useEffect(() => {
207
- if (!open) return;
208
- setTab(hasLinkTab ? "link" : "invite");
209
- }, [open, hasLinkTab]);
210
-
211
- useEffect(() => {
212
- if (!open) return;
213
- const onKey = (e: KeyboardEvent) => {
214
- if (e.key === "Escape") onClose();
215
- };
216
- window.addEventListener("keydown", onKey);
217
- return () => window.removeEventListener("keydown", onKey);
218
- }, [open, onClose]);
219
-
220
112
  if (!open) return null;
221
113
 
222
- const titleText = resourceTitle
223
- ? t("share.titleWithResource", { title: resourceTitle })
224
- : t("share.titleWithType", { type: resourceType });
225
-
226
- return createPortal(
227
- <div
228
- className="fixed inset-0 z-[2000] flex items-start justify-center bg-black/40 p-4 sm:items-center"
229
- onClick={onClose}
114
+ return (
115
+ <DesignSystemDialog
116
+ open={controller.open}
117
+ onOpenChange={controller.onOpenChange}
118
+ title={
119
+ <span
120
+ className="truncate !text-base !leading-normal !tracking-normal !text-inherit"
121
+ title={controller.title}
122
+ >
123
+ {controller.title}
124
+ </span>
125
+ }
126
+ closeLabel={controller.labels.close}
127
+ size="large"
128
+ className="!top-4 !z-[2010] !block !max-h-none !w-[calc(100vw-2rem)] !max-w-lg !translate-y-0 !gap-0 !overflow-visible !rounded-xl !border-border !bg-popover !p-0 !text-popover-foreground !shadow-2xl sm:!top-1/2 sm:!-translate-y-1/2"
129
+ aria-label={controller.title}
230
130
  >
231
- <div
232
- role="dialog"
233
- aria-modal="true"
234
- aria-label={titleText}
235
- className="w-full max-w-lg rounded-xl border border-border bg-popover text-popover-foreground shadow-2xl outline-none"
236
- onClick={(e) => e.stopPropagation()}
237
- >
238
- <div className="flex items-start justify-between gap-3 px-5 pt-4 pb-3">
239
- <div className="min-w-0 flex-1">
240
- <div className="truncate text-base font-semibold" title={titleText}>
241
- {titleText}
242
- </div>
243
- {sharesQuery.data?.ownerEmail ? (
244
- <div className="mt-0.5 truncate text-xs text-muted-foreground">
245
- {t("share.owner", {
246
- name: displayName(sharesQuery.data.ownerEmail, orgMembers),
247
- })}
248
- </div>
249
- ) : null}
131
+ <div className="px-5 pt-0 pb-3">
132
+ {controller.ownerLabel ? (
133
+ <div className="truncate text-xs text-muted-foreground">
134
+ {controller.ownerLabel}
250
135
  </div>
251
- <button
252
- type="button"
253
- aria-label={t("share.close")}
254
- onClick={onClose}
255
- className={BUTTON_GHOST_ICON}
256
- >
257
- <IconX size={16} />
258
- </button>
259
- </div>
136
+ ) : null}
137
+ </div>
260
138
 
261
- {tabsEnabled ? (
262
- <div
263
- role="tablist"
264
- aria-label={t("share.shareOptions")}
265
- className="mx-5 mt-1 flex gap-1 border-b border-border"
266
- >
267
- {hasLinkTab ? (
268
- <TabTrigger
269
- active={tab === "link"}
270
- onClick={() => setTab("link")}
271
- icon={<IconLink size={14} strokeWidth={1.75} />}
272
- label={t("share.link")}
273
- />
274
- ) : null}
275
- <TabTrigger
276
- active={tab === "invite"}
277
- onClick={() => setTab("invite")}
278
- icon={<IconMail size={14} strokeWidth={1.75} />}
279
- label={t("share.invite")}
280
- />
281
- {hasEmbedTab ? (
139
+ {controller.tabsEnabled ? (
140
+ <div
141
+ role="tablist"
142
+ aria-label={controller.labels.shareOptions}
143
+ className="mx-5 mt-1 flex gap-1 border-b border-border"
144
+ >
145
+ {controller.tabs.map((tab) => {
146
+ const Icon = TAB_ICONS[tab.value];
147
+ return (
282
148
  <TabTrigger
283
- active={tab === "embed"}
284
- onClick={() => setTab("embed")}
285
- icon={<IconCode size={14} strokeWidth={1.75} />}
286
- label={t("share.embed")}
149
+ key={tab.value}
150
+ active={controller.activeTab === tab.value}
151
+ onClick={() => controller.setActiveTab(tab.value)}
152
+ icon={<Icon size={14} strokeWidth={1.75} />}
153
+ label={tab.label}
287
154
  />
288
- ) : null}
289
- </div>
290
- ) : null}
291
-
292
- <div className="px-5 py-4">
293
- {tabsEnabled && tab === "link" && hasLinkTab ? (
294
- <LinkTab
295
- resourceType={resourceType}
296
- resourceId={resourceId}
297
- shareUrl={shareUrl!}
298
- sharesQuery={sharesQuery}
299
- extras={linkTabExtras}
300
- />
301
- ) : null}
302
- {!tabsEnabled || tab === "invite" ? (
303
- <InviteTab
304
- resourceType={resourceType}
305
- resourceId={resourceId}
306
- shareUrl={shareUrl}
307
- sharesQuery={sharesQuery}
308
- showVisibility={!tabsEnabled}
309
- orgMembers={orgMembers}
310
- />
311
- ) : null}
312
- {tabsEnabled && tab === "embed" && hasEmbedTab
313
- ? (embedTabContent ?? <DefaultEmbedBody embedUrl={embedUrl!} />)
314
- : null}
155
+ );
156
+ })}
315
157
  </div>
158
+ ) : null}
316
159
 
317
- <div className="flex justify-end border-t border-border px-5 py-3">
318
- <button type="button" onClick={onClose} className={BUTTON_PRIMARY_SM}>
319
- {t("share.done")}
320
- </button>
321
- </div>
160
+ <div className="px-5 py-4">
161
+ {controller.tabsEnabled && controller.activeTab === "link" ? (
162
+ <LinkTab controller={controller} extras={linkTabExtras} />
163
+ ) : null}
164
+ {!controller.tabsEnabled || controller.activeTab === "invite" ? (
165
+ <InviteTab
166
+ controller={controller}
167
+ showVisibility={!controller.tabsEnabled}
168
+ />
169
+ ) : null}
170
+ {controller.tabsEnabled && controller.activeTab === "embed"
171
+ ? (embedTabContent ?? <DefaultEmbedBody controller={controller} />)
172
+ : null}
173
+ </div>
174
+
175
+ <div className="flex justify-end border-t border-border px-5 py-3">
176
+ <ActionButton
177
+ type="button"
178
+ intent="primary"
179
+ emphasis="solid"
180
+ onPress={controller.close}
181
+ className={BUTTON_PRIMARY_SM}
182
+ >
183
+ {controller.labels.done}
184
+ </ActionButton>
322
185
  </div>
323
- </div>,
324
- document.body,
186
+ </DesignSystemDialog>
325
187
  );
326
188
  }
327
189
 
328
- // ---------------------------------------------------------------------------
329
- // Tabs
330
- // ---------------------------------------------------------------------------
331
-
332
- function TabTrigger(props: {
190
+ function TabTrigger({
191
+ active,
192
+ onClick,
193
+ icon,
194
+ label,
195
+ }: {
333
196
  active: boolean;
334
197
  onClick: () => void;
335
198
  icon: ReactNode;
336
199
  label: string;
337
200
  }) {
338
201
  return (
339
- <button
202
+ <ActionButton
340
203
  type="button"
341
- role="tab"
342
- aria-selected={props.active}
343
- onClick={props.onClick}
204
+ emphasis="ghost"
205
+ aria-pressed={active}
206
+ onPress={onClick}
344
207
  className={cn(
345
- "inline-flex items-center gap-1.5 border-b-2 px-3 py-2 text-sm font-medium transition-colors",
346
- props.active
208
+ "inline-flex !h-auto items-center gap-1.5 !rounded-none border-b-2 !px-3 !py-2 text-sm font-medium transition-colors hover:!bg-transparent active:!scale-100 focus-visible:!ring-0 focus-visible:!ring-offset-0 [&_svg]:!size-auto",
209
+ active
347
210
  ? "border-foreground text-foreground"
348
211
  : "border-transparent text-muted-foreground hover:text-foreground",
349
212
  )}
350
213
  >
351
- {props.icon}
352
- {props.label}
353
- </button>
214
+ {icon}
215
+ {label}
216
+ </ActionButton>
354
217
  );
355
218
  }
356
219
 
357
- // ---------------------------------------------------------------------------
358
- // Link tab — visibility picker + copy-link field + optional extras
359
- // ---------------------------------------------------------------------------
360
-
361
- function LinkTab(props: {
362
- resourceType: string;
363
- resourceId: string;
364
- shareUrl: string;
365
- sharesQuery: ReturnType<typeof useActionQuery<SharesResponse>>;
220
+ function LinkTab({
221
+ controller,
222
+ extras,
223
+ }: {
224
+ controller: ShareDialogController;
366
225
  extras?: ReactNode;
367
226
  }) {
368
- const { resourceType, resourceId, shareUrl, sharesQuery, extras } = props;
369
- const t = useT();
370
- const visibilityMeta = useVisibilityMeta();
371
-
372
- const setVisibility = useActionMutation("set-resource-visibility");
373
- const data = sharesQuery.data;
374
- const visibility: Visibility =
375
- (data?.visibility as Visibility | null) ?? "private";
376
- const canManage = data?.role === "owner" || data?.role === "admin";
377
- const meta = visibilityMeta[visibility];
378
-
379
- const handleVisibility = (next: Visibility) => {
380
- if (next === visibility) return;
381
- if (!canManage) return;
382
- setVisibility.mutate(
383
- { resourceType, resourceId, visibility: next } as any,
384
- { onSuccess: () => sharesQuery.refetch() },
385
- );
386
- };
387
-
227
+ const Icon = VIS_ICONS[controller.visibility.value];
388
228
  return (
389
229
  <div className="space-y-4">
390
230
  <div>
391
231
  <div className="mb-2 text-sm font-semibold">
392
- {t("share.generalAccess")}
232
+ {controller.labels.generalAccess}
393
233
  </div>
394
234
  <div className="flex items-center gap-3">
395
235
  <span
396
236
  aria-hidden
397
237
  className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground"
398
238
  >
399
- <meta.Icon size={16} strokeWidth={1.75} />
239
+ <Icon size={16} strokeWidth={1.75} />
400
240
  </span>
401
241
  <div className="min-w-0 flex-1">
402
- <VisibilitySelect
403
- value={visibility}
404
- onChange={handleVisibility}
405
- disabled={!canManage}
406
- />
242
+ <VisibilitySelect controller={controller} />
407
243
  <div className="mt-0.5 text-xs text-muted-foreground">
408
- {meta.description}
244
+ {controller.visibility.description}
409
245
  </div>
410
246
  </div>
411
247
  </div>
412
248
  </div>
413
-
414
- <CopyField label={t("share.shareLink")} value={shareUrl} />
415
-
249
+ <CopyField
250
+ field="share-link"
251
+ label={controller.labels.shareLink}
252
+ value={controller.shareUrl!}
253
+ controller={controller}
254
+ />
416
255
  {extras}
417
256
  </div>
418
257
  );
419
258
  }
420
259
 
421
- // ---------------------------------------------------------------------------
422
- // Invite tab — invite-by-email + shares list + (optional) visibility
423
- // ---------------------------------------------------------------------------
424
-
425
- function InviteTab(props: {
426
- resourceType: string;
427
- resourceId: string;
428
- shareUrl?: string;
429
- sharesQuery: ReturnType<typeof useActionQuery<SharesResponse>>;
260
+ function InviteTab({
261
+ controller,
262
+ showVisibility,
263
+ }: {
264
+ controller: ShareDialogController;
430
265
  showVisibility: boolean;
431
- orgMembers: OrgMember[];
432
266
  }) {
433
- const {
434
- resourceType,
435
- resourceId,
436
- shareUrl,
437
- sharesQuery,
438
- showVisibility,
439
- orgMembers,
440
- } = props;
441
- const t = useT();
442
- const visibilityMeta = useVisibilityMeta();
443
-
444
- const share = useActionMutation("share-resource");
445
- const unshare = useActionMutation("unshare-resource");
446
- const setVisibility = useActionMutation("set-resource-visibility");
447
-
448
- const [email, setEmail] = useState("");
449
- const [role, setRole] = useState<Role>("viewer");
450
- const [notifyPeople, setNotifyPeople] = useState(true);
451
- const hasInviteEmail = email.trim().length > 0;
452
-
453
- const data = sharesQuery.data;
454
- const shares = data?.shares ?? [];
455
- const visibility: Visibility =
456
- (data?.visibility as Visibility | null) ?? "private";
457
- const canManage = data?.role === "owner" || data?.role === "admin";
458
- const meta = visibilityMeta[visibility];
459
-
460
- const handleAdd = () => {
461
- const trimmed = email.trim();
462
- if (!trimmed) return;
463
- share.mutate(
464
- {
465
- resourceType,
466
- resourceId,
467
- principalType: "user",
468
- principalId: trimmed,
469
- role,
470
- notify: notifyPeople,
471
- resourceUrl: getNotificationUrl(shareUrl),
472
- } as any,
473
- {
474
- onSuccess: () => {
475
- setEmail("");
476
- sharesQuery.refetch();
477
- },
478
- },
479
- );
480
- };
481
-
482
- const handleRemove = (s: Share) => {
483
- unshare.mutate(
484
- {
485
- resourceType,
486
- resourceId,
487
- principalType: s.principalType,
488
- principalId: s.principalId,
489
- } as any,
490
- { onSuccess: () => sharesQuery.refetch() },
491
- );
492
- };
493
-
494
- const handleVisibility = (next: Visibility) => {
495
- if (next === visibility) return;
496
- if (!canManage) return;
497
- setVisibility.mutate(
498
- { resourceType, resourceId, visibility: next } as any,
499
- { onSuccess: () => sharesQuery.refetch() },
500
- );
501
- };
502
-
267
+ const Icon = VIS_ICONS[controller.visibility.value];
503
268
  return (
504
269
  <div className="space-y-4">
505
- {canManage ? (
270
+ {controller.canManage ? (
506
271
  <div className="space-y-2">
507
272
  <div className="flex items-stretch gap-2">
508
273
  <input
509
274
  type="email"
510
- placeholder={t("share.addPeopleByEmail")}
511
- value={email}
512
- onChange={(e) => setEmail(e.target.value)}
513
- onKeyDown={(e) => {
514
- if (e.key === "Enter") handleAdd();
275
+ placeholder={controller.labels.addPeopleByEmail}
276
+ value={controller.invite.email}
277
+ onChange={(event) =>
278
+ controller.invite.setEmail(event.currentTarget.value)
279
+ }
280
+ onKeyDown={(event) => {
281
+ if (event.key === "Enter") controller.invite.submit();
515
282
  }}
516
283
  autoComplete="off"
517
284
  className="flex-1 min-w-0 h-9 rounded-md border border-input bg-background px-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background"
518
285
  />
519
- <RoleSelect value={role} onChange={setRole} />
286
+ <RoleSelect controller={controller} />
520
287
  </div>
521
- {hasInviteEmail ? (
288
+ {controller.invite.showNotifyPeople ? (
522
289
  <label className="inline-flex items-center gap-2 text-xs text-muted-foreground">
523
290
  <input
524
291
  type="checkbox"
525
- checked={notifyPeople}
526
- onChange={(e) => setNotifyPeople(e.target.checked)}
292
+ checked={controller.invite.notifyPeople}
293
+ onChange={(event) =>
294
+ controller.invite.setNotifyPeople(event.currentTarget.checked)
295
+ }
527
296
  className="h-4 w-4 rounded border-input accent-primary"
528
297
  />
529
- {t("share.notifyPeople")}
298
+ {controller.labels.notifyPeople}
530
299
  </label>
531
300
  ) : null}
532
301
  </div>
@@ -534,50 +303,21 @@ function InviteTab(props: {
534
303
 
535
304
  <div>
536
305
  <div className="mb-2 text-sm font-semibold">
537
- {t("share.peopleWithAccess")}
306
+ {controller.labels.peopleWithAccess}
538
307
  </div>
539
308
  <ul className="flex flex-col gap-1 list-none p-0 m-0">
540
- {data?.ownerEmail ? (
541
- <li className="flex items-center gap-3 px-1 py-1.5 text-sm">
542
- <Avatar label={displayName(data.ownerEmail, orgMembers)} />
543
- <span className="flex-1 min-w-0 truncate">
544
- {displayName(data.ownerEmail, orgMembers)}
545
- </span>
546
- <span className="text-xs text-muted-foreground">
547
- {t("share.ownerRole")}
548
- </span>
549
- </li>
550
- ) : null}
551
- {shares.map((s) => (
552
- <li
553
- key={`${s.principalType}:${s.principalId}`}
554
- className="flex items-center gap-3 px-1 py-1.5 text-sm"
555
- >
556
- <Avatar
557
- label={principalLabel(s, orgMembers)}
558
- org={s.principalType === "org"}
559
- />
560
- <span className="flex-1 min-w-0 truncate">
561
- {principalLabel(s, orgMembers)}
562
- </span>
563
- <span className="text-xs text-muted-foreground">
564
- {cap(s.role)}
565
- </span>
566
- {canManage ? (
567
- <button
568
- type="button"
569
- aria-label={t("share.remove")}
570
- onClick={() => handleRemove(s)}
571
- className={BUTTON_GHOST_ICON}
572
- >
573
- <IconTrash size={14} />
574
- </button>
575
- ) : null}
576
- </li>
309
+ {controller.people.map((person) => (
310
+ <PersonRow
311
+ key={person.key}
312
+ person={person}
313
+ canManage={controller.canManage}
314
+ removeLabel={controller.labels.remove}
315
+ onRemove={controller.removeShare}
316
+ />
577
317
  ))}
578
- {!shares.length && !data?.ownerEmail ? (
318
+ {!controller.people.length ? (
579
319
  <li className="px-1 py-1.5 text-sm text-muted-foreground">
580
- {t("share.noAccess")}
320
+ {controller.labels.noAccess}
581
321
  </li>
582
322
  ) : null}
583
323
  </ul>
@@ -586,23 +326,19 @@ function InviteTab(props: {
586
326
  {showVisibility ? (
587
327
  <div>
588
328
  <div className="mb-2 text-sm font-semibold">
589
- {t("share.generalAccess")}
329
+ {controller.labels.generalAccess}
590
330
  </div>
591
331
  <div className="flex items-center gap-3">
592
332
  <span
593
333
  aria-hidden
594
334
  className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground"
595
335
  >
596
- <meta.Icon size={16} strokeWidth={1.75} />
336
+ <Icon size={16} strokeWidth={1.75} />
597
337
  </span>
598
338
  <div className="min-w-0 flex-1">
599
- <VisibilitySelect
600
- value={visibility}
601
- onChange={handleVisibility}
602
- disabled={!canManage}
603
- />
339
+ <VisibilitySelect controller={controller} />
604
340
  <div className="mt-0.5 text-xs text-muted-foreground">
605
- {meta.description}
341
+ {controller.visibility.description}
606
342
  </div>
607
343
  </div>
608
344
  </div>
@@ -612,44 +348,93 @@ function InviteTab(props: {
612
348
  );
613
349
  }
614
350
 
615
- // ---------------------------------------------------------------------------
616
- // Default Embed body (simple responsive iframe snippet)
617
- // ---------------------------------------------------------------------------
351
+ function PersonRow({
352
+ person,
353
+ canManage,
354
+ removeLabel,
355
+ onRemove,
356
+ }: {
357
+ person: ShareDialogPerson;
358
+ canManage: boolean;
359
+ removeLabel: string;
360
+ onRemove: (share: ResourceShare) => void;
361
+ }) {
362
+ return (
363
+ <li className="flex items-center gap-3 px-1 py-1.5 text-sm">
364
+ <DesignSystemAvatar
365
+ name={person.label}
366
+ fallback={
367
+ person.principalType === "org" ? (
368
+ <IconUsersGroup size={14} strokeWidth={1.75} />
369
+ ) : (
370
+ person.avatarText
371
+ )
372
+ }
373
+ size="compact"
374
+ className="inline-flex h-7 w-7 shrink-0 text-[11px] font-semibold"
375
+ />
376
+ <span className="flex-1 min-w-0 truncate">{person.label}</span>
377
+ <Status
378
+ tone="neutral"
379
+ size="compact"
380
+ className="border-0 bg-transparent px-0 text-xs text-muted-foreground"
381
+ >
382
+ {person.roleLabel}
383
+ </Status>
384
+ {canManage && person.share ? (
385
+ <IconButton
386
+ intent="danger"
387
+ emphasis="ghost"
388
+ size="compact"
389
+ icon={<IconTrash size={14} />}
390
+ label={removeLabel}
391
+ aria-label={removeLabel}
392
+ onPress={() => onRemove(person.share!)}
393
+ className={cn(BUTTON_GHOST_ICON, "[&_svg]:!size-auto")}
394
+ />
395
+ ) : null}
396
+ </li>
397
+ );
398
+ }
618
399
 
619
- function DefaultEmbedBody({ embedUrl }: { embedUrl: string }) {
620
- const t = useT();
621
- const code = `<div style="position:relative;padding-bottom:56.25%;height:0"><iframe src="${embedUrl}" frameborder="0" allowfullscreen allow="autoplay; picture-in-picture" style="position:absolute;inset:0;width:100%;height:100%"></iframe></div>`;
400
+ function DefaultEmbedBody({
401
+ controller,
402
+ }: {
403
+ controller: ShareDialogController;
404
+ }) {
622
405
  return (
623
406
  <div className="space-y-3">
624
- <CopyField label={t("share.embedUrl")} value={embedUrl} />
625
- <CopyField label={t("share.embedCode")} value={code} multiline />
407
+ <CopyField
408
+ field="embed-url"
409
+ label={controller.labels.embedUrl}
410
+ value={controller.embedUrl!}
411
+ controller={controller}
412
+ />
413
+ <CopyField
414
+ field="embed-code"
415
+ label={controller.labels.embedCode}
416
+ value={controller.embedCode!}
417
+ controller={controller}
418
+ multiline
419
+ />
626
420
  </div>
627
421
  );
628
422
  }
629
423
 
630
- // ---------------------------------------------------------------------------
631
- // Primitives
632
- // ---------------------------------------------------------------------------
633
-
634
424
  function CopyField({
425
+ field,
635
426
  label,
636
427
  value,
428
+ controller,
637
429
  multiline,
638
430
  }: {
431
+ field: string;
639
432
  label: string;
640
433
  value: string;
434
+ controller: ShareDialogController;
641
435
  multiline?: boolean;
642
436
  }) {
643
- const [copied, setCopied] = useState(false);
644
- const t = useT();
645
- const copy = async () => {
646
- if (!(await writeClipboardText(value))) {
647
- setCopied(false);
648
- return;
649
- }
650
- setCopied(true);
651
- setTimeout(() => setCopied(false), 1400);
652
- };
437
+ const copied = controller.copiedField === field;
653
438
  return (
654
439
  <div>
655
440
  <div className="mb-1 text-xs font-medium text-muted-foreground">
@@ -657,190 +442,71 @@ function CopyField({
657
442
  </div>
658
443
  <div className="flex items-stretch gap-2">
659
444
  {multiline ? (
660
- <textarea
445
+ <TextArea
661
446
  readOnly
662
447
  value={value}
663
- className="flex-1 h-20 rounded-md border border-input bg-background px-3 py-2 text-xs font-mono text-foreground resize-none focus:outline-none focus:ring-2 focus:ring-ring"
448
+ onChange={() => undefined}
449
+ aria-label={label}
450
+ className="flex-1 h-20 text-xs font-mono"
664
451
  />
665
452
  ) : (
666
- <input
453
+ <TextField
667
454
  readOnly
668
455
  value={value}
669
- className="flex-1 min-w-0 h-9 rounded-md border border-input bg-background px-3 text-xs font-mono text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
456
+ onChange={() => undefined}
457
+ aria-label={label}
458
+ className="flex-1 min-w-0 text-xs font-mono"
670
459
  />
671
460
  )}
672
- <button
673
- type="button"
674
- onClick={copy}
675
- aria-label={t("share.copy")}
676
- className={cn(BUTTON_OUTLINE_SM, "w-9 px-0")}
677
- >
678
- {copied ? <IconCheck size={14} /> : <IconCopy size={14} />}
679
- </button>
461
+ <IconButton
462
+ emphasis="outline"
463
+ size="compact"
464
+ icon={copied ? <IconCheck size={14} /> : <IconCopy size={14} />}
465
+ label={controller.labels.copy}
466
+ onPress={() => void controller.copy(field, value)}
467
+ aria-label={controller.labels.copy}
468
+ className={cn(BUTTON_OUTLINE_SM, "!w-9 !px-0 [&_svg]:!size-auto")}
469
+ />
680
470
  </div>
681
471
  </div>
682
472
  );
683
473
  }
684
474
 
685
- const selectContentClass =
686
- "z-[2100] min-w-[12rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md";
687
- const selectItemClass =
688
- "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm py-2 ps-8 pe-3 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
689
-
690
- function SelectItems({
691
- items,
692
- }: {
693
- items: Array<{ value: string; label: string; description?: string }>;
694
- }) {
695
- return (
696
- <>
697
- {items.map((it) => (
698
- <Select.Item
699
- key={it.value}
700
- value={it.value}
701
- className={selectItemClass}
702
- >
703
- <span className="absolute start-2 top-2 flex h-4 w-4 items-center justify-center">
704
- <Select.ItemIndicator>
705
- <IconCheck size={14} />
706
- </Select.ItemIndicator>
707
- </span>
708
- <span className="flex flex-col">
709
- <Select.ItemText>{it.label}</Select.ItemText>
710
- {it.description ? (
711
- <span className="text-xs text-muted-foreground">
712
- {it.description}
713
- </span>
714
- ) : null}
715
- </span>
716
- </Select.Item>
717
- ))}
718
- </>
719
- );
720
- }
721
-
722
- function RoleSelect(props: { value: Role; onChange: (v: Role) => void }) {
723
- const t = useT();
724
- const roleOptions = useRoleOptions();
725
- const current =
726
- roleOptions.find((o) => o.value === props.value) ?? roleOptions[0];
475
+ function RoleSelect({ controller }: { controller: ShareDialogController }) {
727
476
  return (
728
- <Select.Root
729
- value={props.value}
730
- onValueChange={(v) => props.onChange(v as Role)}
731
- >
732
- <Select.Trigger
733
- aria-label={t("share.role")}
734
- className={cn(
735
- BUTTON_BASE,
736
- "h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground",
737
- )}
738
- >
739
- <Select.Value>{current.label}</Select.Value>
740
- <Select.Icon>
741
- <IconChevronDown size={14} />
742
- </Select.Icon>
743
- </Select.Trigger>
744
- <Select.Portal>
745
- <Select.Content
746
- className={selectContentClass}
747
- position="popper"
748
- sideOffset={4}
749
- >
750
- <Select.Viewport>
751
- <SelectItems items={roleOptions} />
752
- </Select.Viewport>
753
- </Select.Content>
754
- </Select.Portal>
755
- </Select.Root>
477
+ <Picker
478
+ mode="select"
479
+ options={controller.invite.roleOptions}
480
+ value={controller.invite.role}
481
+ onChange={(value) => {
482
+ if (value === "viewer" || value === "editor" || value === "admin") {
483
+ controller.invite.setRole(value);
484
+ }
485
+ }}
486
+ aria-label={controller.labels.role}
487
+ className="w-auto"
488
+ />
756
489
  );
757
490
  }
758
491
 
759
- function VisibilitySelect(props: {
760
- value: Visibility;
761
- onChange: (v: Visibility) => void;
762
- disabled?: boolean;
763
- allowPrivate?: boolean;
764
- allowPublic?: boolean;
492
+ function VisibilitySelect({
493
+ controller,
494
+ }: {
495
+ controller: ShareDialogController;
765
496
  }) {
766
- const t = useT();
767
- const visibilityMeta = useVisibilityMeta();
768
- const current = visibilityMeta[props.value];
769
- const allowPrivate = props.allowPrivate !== false;
770
- const allowPublic = props.allowPublic !== false;
771
- const options = (Object.keys(VIS_ICONS) as Visibility[]).filter((k) => {
772
- if (k === props.value) return true;
773
- if (k === "private" && !allowPrivate) return false;
774
- if (k === "public" && !allowPublic) return false;
775
- return true;
776
- });
777
- return (
778
- <Select.Root
779
- value={props.value}
780
- onValueChange={(v) => props.onChange(v as Visibility)}
781
- disabled={props.disabled}
782
- >
783
- <Select.Trigger
784
- aria-label={t("share.generalAccess")}
785
- className={cn(
786
- BUTTON_BASE,
787
- "h-7 px-1 -ms-1 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground",
788
- )}
789
- >
790
- <Select.Value>{current.label}</Select.Value>
791
- <Select.Icon>
792
- <IconChevronDown size={14} />
793
- </Select.Icon>
794
- </Select.Trigger>
795
- <Select.Portal>
796
- <Select.Content
797
- className={selectContentClass}
798
- position="popper"
799
- sideOffset={4}
800
- >
801
- <Select.Viewport>
802
- <SelectItems
803
- items={options.map((k) => ({
804
- value: k,
805
- label: visibilityMeta[k].label,
806
- description: visibilityMeta[k].description,
807
- }))}
808
- />
809
- </Select.Viewport>
810
- </Select.Content>
811
- </Select.Portal>
812
- </Select.Root>
813
- );
814
- }
815
-
816
- function Avatar({ label, org }: { label: string; org?: boolean }) {
817
497
  return (
818
- <span
819
- aria-hidden
820
- className="inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-muted text-[11px] font-semibold text-muted-foreground"
821
- >
822
- {org ? (
823
- <IconUsersGroup size={14} strokeWidth={1.75} />
824
- ) : (
825
- (label.split("@")[0]?.[0] ?? label[0] ?? "?").toUpperCase()
826
- )}
827
- </span>
498
+ <Picker
499
+ mode="select"
500
+ options={controller.visibility.options}
501
+ value={controller.visibility.value}
502
+ onChange={(value) => {
503
+ if (value === "private" || value === "org" || value === "public") {
504
+ controller.visibility.set(value);
505
+ }
506
+ }}
507
+ disabled={controller.visibility.disabled}
508
+ aria-label={controller.labels.generalAccess}
509
+ className="-ms-1 w-auto"
510
+ />
828
511
  );
829
512
  }
830
-
831
- function getNotificationUrl(explicit?: string): string | undefined {
832
- if (explicit) return explicit;
833
- if (typeof window === "undefined") return undefined;
834
- return window.location.href;
835
- }
836
-
837
- function cap(s: string): string {
838
- return s.charAt(0).toUpperCase() + s.slice(1);
839
- }
840
-
841
- function principalLabel(share: Share, members: OrgMember[]): string {
842
- const serverLabel = share.displayName?.trim();
843
- if (serverLabel) return serverLabel;
844
- if (share.principalType === "org") return "Organization";
845
- return displayName(share.principalId, members);
846
- }