@agent-native/core 0.141.6 → 0.144.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 (501) hide show
  1. package/agent-native.eject.json +9 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
  4. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
  5. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
  6. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
  7. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
  8. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  9. package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
  10. package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  11. package/corpus/templates/analytics/AGENTS.md +37 -40
  12. package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
  13. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
  14. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
  15. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
  16. package/corpus/templates/analytics/actions/navigate.ts +5 -6
  17. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  18. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +46 -13
  19. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  20. package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
  21. package/corpus/templates/analytics/actions/view-screen.ts +0 -20
  22. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  23. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  24. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
  25. package/corpus/templates/analytics/app/i18n-data.ts +682 -90
  26. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  27. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  28. package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
  29. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  30. package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
  31. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
  32. package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
  33. package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
  34. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  35. package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
  36. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  37. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  38. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  39. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  40. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  41. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  42. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  43. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  44. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
  45. package/corpus/templates/analytics/netlify.toml +7 -0
  46. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  47. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
  48. package/corpus/templates/analytics/server/db/index.ts +27 -0
  49. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  50. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
  51. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  52. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1147 -0
  53. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
  54. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
  55. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  56. package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
  57. package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -4
  58. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  59. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  60. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +36 -8
  61. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  62. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
  63. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  64. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  65. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  66. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  67. package/corpus/templates/assets/AGENTS.md +1 -0
  68. package/corpus/templates/assets/actions/_helpers.ts +12 -0
  69. package/corpus/templates/assets/actions/generate-image.ts +9 -3
  70. package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
  71. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  72. package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
  73. package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
  74. package/corpus/templates/assets/app/routes/settings.tsx +5 -0
  75. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  76. package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
  77. package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
  78. package/corpus/templates/assets/server/lib/generation.ts +58 -0
  79. package/corpus/templates/assets/shared/api.ts +12 -0
  80. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  81. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  82. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  83. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  84. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  85. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  86. package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
  87. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  88. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  89. package/corpus/templates/brain/app/routes.ts +1 -1
  90. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  91. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  92. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  93. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  94. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  95. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  96. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  97. package/corpus/templates/calendar/AGENTS.md +11 -32
  98. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  99. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  100. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  101. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  102. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  103. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  104. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  105. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
  106. package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
  107. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  108. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  109. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  110. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  111. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  112. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  113. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  114. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  115. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  116. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  117. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  118. package/corpus/templates/chat/app/root.tsx +1 -1
  119. package/corpus/templates/chat/app/routes/agent.tsx +7 -7
  120. package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
  121. package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
  122. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  123. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  124. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  125. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  126. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  127. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  128. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  129. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  130. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  131. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  132. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  133. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
  134. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
  135. package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
  136. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  137. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  138. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  139. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  140. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  141. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  142. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  143. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  144. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  145. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  146. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  147. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  148. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  149. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  150. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  151. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
  152. package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
  153. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  154. package/corpus/templates/content/e2e/global-setup.ts +1 -1
  155. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  156. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  157. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  158. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  159. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  160. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  161. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  162. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
  163. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  164. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  165. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  166. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  167. package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
  168. package/corpus/templates/design/actions/import-from-url.ts +6 -5
  169. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  170. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
  171. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  172. package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
  173. package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
  174. package/corpus/templates/design/app/routes/team.tsx +1 -1
  175. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  176. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  177. package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
  178. package/corpus/templates/design/e2e/global-setup.ts +1 -1
  179. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  180. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  181. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  182. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  183. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  184. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  185. package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
  186. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  187. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  188. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  189. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  190. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  191. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  192. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  193. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
  194. package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
  195. package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
  196. package/corpus/templates/factory/app/routes/team.tsx +1 -1
  197. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  198. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  199. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  200. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  201. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
  202. package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
  203. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  204. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  205. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  206. package/corpus/templates/forms/shared/navigation.ts +1 -1
  207. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  208. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  209. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  210. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  211. package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
  212. package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
  213. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  214. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  215. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  216. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  217. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  218. package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
  219. package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
  220. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  221. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  222. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  223. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  224. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  225. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  226. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  227. package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
  228. package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
  229. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  230. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  231. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +40 -2
  232. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  233. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  234. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  235. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  236. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  237. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  238. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  239. package/corpus/templates/slides/AGENTS.md +7 -9
  240. package/corpus/templates/slides/_gitignore +1 -0
  241. package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
  242. package/corpus/templates/slides/actions/export-pptx.ts +402 -36
  243. package/corpus/templates/slides/actions/import-file.ts +46 -85
  244. package/corpus/templates/slides/actions/import-from-url.ts +6 -6
  245. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  246. package/corpus/templates/slides/actions/import-pptx.ts +85 -60
  247. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  248. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  249. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  250. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  252. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  253. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  254. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +176 -0
  255. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  256. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  257. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  258. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  259. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  260. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +13 -3
  261. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  262. package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
  263. package/corpus/templates/slides/app/global.css +6 -0
  264. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  265. package/corpus/templates/slides/app/lib/create-deck-generation.ts +10 -6
  266. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  267. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  268. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  269. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  270. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
  271. package/corpus/templates/slides/app/pages/Index.tsx +107 -6
  272. package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
  273. package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
  274. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  275. package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
  276. package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
  277. package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
  278. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  279. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  280. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  281. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  282. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  283. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  284. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  285. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  286. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  287. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  288. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  289. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  290. package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
  291. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  292. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  293. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  294. package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
  295. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  296. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  297. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  298. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  299. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  300. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  301. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  302. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  303. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  304. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  305. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  306. package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
  307. package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
  308. package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
  309. package/dist/agent/engine/ai-sdk-engine.js +49 -3
  310. package/dist/agent/production-agent.d.ts +18 -0
  311. package/dist/agent/production-agent.js +80 -1
  312. package/dist/agent/types.d.ts +7 -0
  313. package/dist/cli/agent-plugin.d.ts +112 -0
  314. package/dist/cli/agent-plugin.js +1081 -0
  315. package/dist/cli/app-skill.js +39 -1
  316. package/dist/cli/code-agent-executor.d.ts +3 -0
  317. package/dist/cli/code-agent-executor.js +51 -13
  318. package/dist/cli/index.js +13 -0
  319. package/dist/cli/templates-meta.js +1 -1
  320. package/dist/client/AgentPanel.d.ts +3 -1
  321. package/dist/client/AgentPanel.js +9 -2
  322. package/dist/client/AssistantChat.d.ts +8 -0
  323. package/dist/client/AssistantChat.js +23 -8
  324. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  325. package/dist/client/agent-chat-adapter.d.ts +1 -1
  326. package/dist/client/agent-chat-adapter.js +153 -7
  327. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
  328. package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
  329. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  330. package/dist/client/assistant-ui-recovery.js +7 -3
  331. package/dist/client/chat/run-recovery.js +5 -1
  332. package/dist/client/embed-auth.js +6 -2
  333. package/dist/client/error-format.js +12 -0
  334. package/dist/client/integrations/IntegrationsPanel.js +40 -6
  335. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  336. package/dist/client/org/OrgSwitcher.js +2 -2
  337. package/dist/client/org/TeamPage.js +92 -72
  338. package/dist/client/require-session.d.ts +1 -1
  339. package/dist/client/require-session.js +4 -4
  340. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  341. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  342. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  343. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  344. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  345. package/dist/client/resources/mcp-integration-logos.js +18 -2
  346. package/dist/client/resources/use-mcp-servers.d.ts +5 -0
  347. package/dist/client/resources/use-mcp-servers.js +36 -0
  348. package/dist/client/settings/AccountSettingsCard.js +42 -36
  349. package/dist/client/settings/AutomationsSection.js +1 -1
  350. package/dist/client/settings/DemoModeSection.d.ts +3 -1
  351. package/dist/client/settings/DemoModeSection.js +4 -1
  352. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  353. package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
  354. package/dist/client/settings/SchedulingTimezoneField.js +9 -5
  355. package/dist/client/settings/SettingsPanel.d.ts +4 -1
  356. package/dist/client/settings/SettingsPanel.js +21 -21
  357. package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
  358. package/dist/client/settings/SettingsTabsPage.js +98 -45
  359. package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
  360. package/dist/client/settings/useSettingsPanelController.js +47 -8
  361. package/dist/collab/routes.d.ts +1 -1
  362. package/dist/db/client.d.ts +9 -0
  363. package/dist/db/client.js +51 -16
  364. package/dist/db/create-get-db.js +2 -2
  365. package/dist/db/ddl-guard.d.ts +11 -10
  366. package/dist/db/ddl-guard.js +40 -12
  367. package/dist/deploy/build.d.ts +2 -0
  368. package/dist/deploy/build.js +97 -4
  369. package/dist/deploy/workspace-deploy.js +0 -2
  370. package/dist/guards/no-env-credentials.js +9 -0
  371. package/dist/ingestion/index.d.ts +1 -1
  372. package/dist/ingestion/pptx.d.ts +68 -0
  373. package/dist/ingestion/pptx.js +660 -213
  374. package/dist/ingestion/website.d.ts +30 -0
  375. package/dist/integrations/plugin.js +9 -6
  376. package/dist/localization/default-messages.d.ts +59 -0
  377. package/dist/localization/default-messages.js +62 -2
  378. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  379. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  380. package/dist/mcp-client/oauth-routes.js +74 -7
  381. package/dist/mcp-client/routes.d.ts +1 -0
  382. package/dist/mcp-client/routes.js +49 -0
  383. package/dist/navigation/index.js +16 -5
  384. package/dist/notifications/routes.d.ts +1 -1
  385. package/dist/observability/routes.d.ts +3 -3
  386. package/dist/onboarding/app-profile.js +11 -0
  387. package/dist/progress/routes.d.ts +1 -1
  388. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  389. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  390. package/dist/resources/store.js +15 -1
  391. package/dist/scripts/call-agent.js +45 -4
  392. package/dist/secrets/routes.d.ts +6 -6
  393. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  394. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  395. package/dist/server/agent-chat-plugin.js +29 -8
  396. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  397. package/dist/server/auth.js +55 -17
  398. package/dist/server/better-auth-instance.js +5 -3
  399. package/dist/server/core-routes-plugin.d.ts +8 -1
  400. package/dist/server/core-routes-plugin.js +28 -3
  401. package/dist/server/credential-provider.d.ts +3 -3
  402. package/dist/server/credential-provider.js +90 -4
  403. package/dist/server/identity-sso.js +2 -1
  404. package/dist/server/onboarding-html.d.ts +2 -0
  405. package/dist/server/onboarding-html.js +171 -62
  406. package/dist/server/realtime-token.d.ts +1 -1
  407. package/dist/server/self-dispatch.d.ts +5 -4
  408. package/dist/server/self-dispatch.js +25 -14
  409. package/dist/server/ssr-handler.d.ts +1 -1
  410. package/dist/server/ssr-handler.js +1 -1
  411. package/dist/server/workspace-provider-oauth.js +1 -1
  412. package/dist/setup-connections/onboarding.js +1 -1
  413. package/dist/shared/cache-control.d.ts +26 -2
  414. package/dist/shared/cache-control.js +43 -2
  415. package/dist/shared/index.d.ts +1 -1
  416. package/dist/shared/index.js +1 -1
  417. package/dist/shared/password-policy.d.ts +3 -0
  418. package/dist/shared/password-policy.js +3 -0
  419. package/dist/shared/sign-in-journey.d.ts +5 -2
  420. package/dist/shared/sign-in-journey.js +10 -4
  421. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  422. package/dist/sharing/registry.d.ts +14 -0
  423. package/dist/styles/agent-native.css +6 -0
  424. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  425. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  426. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  427. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  428. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  429. package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  430. package/dist/templates/chat/app/root.tsx +1 -1
  431. package/dist/templates/chat/app/routes/agent.tsx +7 -7
  432. package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
  433. package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
  434. package/dist/templates/chat/app/routes/team.tsx +1 -1
  435. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  436. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  437. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  438. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  439. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  440. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  441. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  442. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  443. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  444. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  445. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  446. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  447. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  448. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  449. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  450. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  451. package/dist/templates/workspace-root/AGENTS.md +7 -0
  452. package/dist/user-profile/actions/change-password.js +8 -3
  453. package/dist/user-profile/actions/set-password.js +5 -1
  454. package/dist/vite/action-types-plugin.js +59 -0
  455. package/docs/content/authentication.mdx +4 -5
  456. package/docs/content/skills-guide.mdx +13 -0
  457. package/docs/content/template-analytics-developers.mdx +1 -1
  458. package/docs/content/template-calendar-developers.mdx +1 -1
  459. package/docs/content/template-chat-developers.mdx +2 -2
  460. package/docs/content/template-content-developers.mdx +1 -1
  461. package/docs/content/template-mail-developers.mdx +1 -1
  462. package/docs/content/template-plan-developers.mdx +1 -1
  463. package/docs/content/toolkit-command-navigation.mdx +6 -6
  464. package/docs/content/toolkit-org-team.mdx +1 -1
  465. package/docs/content/toolkit-settings.mdx +8 -8
  466. package/docs/content/toolkit-setup-connections.mdx +1 -1
  467. package/package.json +6 -2
  468. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  469. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  470. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  471. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  472. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  473. package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  474. package/src/templates/chat/app/root.tsx +1 -1
  475. package/src/templates/chat/app/routes/agent.tsx +7 -7
  476. package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
  477. package/src/templates/chat/app/routes/settings.$.tsx +1 -0
  478. package/src/templates/chat/app/routes/team.tsx +1 -1
  479. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  480. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  481. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  482. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  483. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  484. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  485. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  486. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  487. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  488. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  489. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  490. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  491. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  492. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  493. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  494. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  495. package/src/templates/workspace-root/AGENTS.md +7 -0
  496. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
  497. package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
  498. package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
  499. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
  500. package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
  501. package/src/templates/default/actions/navigate.spec.ts +0 -53
@@ -3,11 +3,11 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
3
3
  import { Button as ToolkitButton } from "@agent-native/toolkit/ui/button";
4
4
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@agent-native/toolkit/ui/select";
5
5
  import { Switch } from "@agent-native/toolkit/ui/switch";
6
- import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@agent-native/toolkit/ui/table";
7
6
  import { IconUserPlus, IconTrash, IconCrown, IconShieldCheck, IconLoader2, IconCheck, IconPencil, IconAt, IconX, IconKey, IconCopy, IconRefresh, IconEye, IconEyeOff, IconCloudUpload, IconFileImport, IconPlus, IconAlertTriangle, IconUsersGroup, IconHelpCircle, IconExternalLink, } from "@tabler/icons-react";
8
7
  import { forwardRef, useMemo, useRef, useState, } from "react";
9
8
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
10
9
  import { useT } from "../i18n.js";
10
+ import { SettingsGroup, SettingsRow } from "../settings/SettingsRow.js";
11
11
  import { cn } from "../utils.js";
12
12
  import { useOrg, useOrgMembers, useOrgInvitations, useCreateOrg, useUpdateOrg, useBulkInviteMembers, useChangeMemberRole, useAcceptInvitation, useRemoveMember, useDeleteOrg, useSwitchOrg, useSetOrgDomain, useSetOrgWorkspaceUrl, useSetOrgAuthProvider, useRevealA2ASecret, useSetA2ASecret, useSyncA2ASecret, useJoinByDomain, useAppRoles, useSetAppMemberRole, } from "./hooks.js";
13
13
  const Button = forwardRef(({ className, ...props }, ref) => (_jsx(ToolkitButton, { ref: ref, variant: "ghost", className: cn("h-auto p-0 hover:bg-transparent hover:text-inherit active:scale-100 [&_svg]:!size-auto", className), ...props })));
@@ -24,6 +24,12 @@ function ErrorText({ error }) {
24
24
  return null;
25
25
  return (_jsx("p", { className: "text-xs text-destructive", children: error instanceof Error ? error.message : String(error) }));
26
26
  }
27
+ function OrganizationHelpIcon({ content, docsUrl, }) {
28
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", "aria-label": "More information", className: "inline-flex size-3.5 shrink-0 items-center justify-center rounded-full text-muted-foreground/70 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring [&_svg]:!size-3", children: _jsx(IconHelpCircle, { className: "size-3" }) }) }), _jsxs(TooltipContent, { className: "max-w-xs leading-5", children: [_jsx("p", { children: content }), docsUrl ? (_jsx("a", { href: docsUrl, target: "_blank", rel: "noreferrer", className: "mt-1 inline-block underline underline-offset-2", children: "Learn more" })) : null] })] }));
29
+ }
30
+ function OrganizationDescription({ children, help, docsUrl, }) {
31
+ return (_jsxs("span", { className: "inline-flex max-w-full items-center gap-1.5", children: [_jsx("span", { children: children }), help ? _jsx(OrganizationHelpIcon, { content: help, docsUrl: docsUrl }) : null] }));
32
+ }
27
33
  function PendingInvitationsCard() {
28
34
  const t = useT();
29
35
  const { data: org } = useOrg();
@@ -100,7 +106,7 @@ function MembersCard({ appRoles }) {
100
106
  const members = membersData?.members ?? [];
101
107
  const pendingInvites = invitationsData?.invitations ?? [];
102
108
  const hasMultipleOrgs = (org.orgs?.length ?? 0) > 1;
103
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs("section", { className: "rounded-lg border border-border bg-card p-4 space-y-4", children: [_jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsx("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10", children: _jsx(IconUsersGroup, { className: "h-5 w-5 text-primary" }) }), _jsxs("div", { className: "min-w-0", children: [_jsx(OrgNameDisplay, { name: org.orgName ?? "", canEdit: isOwnerOrAdmin }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [t("org.memberCount", { count: members.length }), " \u00B7", " ", t("org.youAreRole", { role: org.role })] })] })] }), hasMultipleOrgs && (_jsxs(Select, { value: org.orgId ?? "", onValueChange: (value) => switchOrg.mutate(value || null), disabled: switchOrg.isPending, children: [_jsx(SelectTrigger, { className: "h-auto w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs sm:w-auto", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: org.orgs.map((o) => (_jsx(SelectItem, { value: o.orgId, children: o.orgName }, o.orgId))) })] }))] }), isOwnerOrAdmin && (_jsxs("div", { className: "grid gap-5 border-t border-border pt-4 lg:grid-cols-2", children: [_jsx(DomainSettingsSection, { domain: org.allowedDomain, ownerEmail: org.email }), _jsx(WorkspaceUrlSettingsSection, { workspaceUrl: org.workspaceUrl }), _jsx(AuthProviderSettingsSection, { requiredAuthProvider: org.requiredAuthProvider }), isOwner && _jsx(A2ASecretSection, { isSet: Boolean(org.a2aSecretSet) })] })), _jsx(ErrorText, { error: switchOrg.error })] }), _jsx(MembersTableCard, { members: members, pendingInvites: pendingInvites, isLoadingMembers: isLoadingMembers, currentUserEmail: org.email, currentUserRole: org.role ?? null, appRoles: appRoles }), isOwner && _jsx(DangerZoneCard, { orgName: org.orgName ?? "" })] }));
109
+ return (_jsxs("div", { className: "space-y-6", children: [_jsxs(SettingsGroup, { title: "Organization", children: [_jsx(SettingsRow, { id: "organization", label: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(IconUsersGroup, { className: "size-4 text-muted-foreground" }), _jsx(OrgNameDisplay, { name: org.orgName ?? "", canEdit: isOwnerOrAdmin })] }), description: `${t("org.memberCount", { count: members.length })} · ${t("org.youAreRole", { role: org.role })}`, control: hasMultipleOrgs ? (_jsxs(Select, { value: org.orgId ?? "", onValueChange: (value) => switchOrg.mutate(value || null), disabled: switchOrg.isPending, children: [_jsx(SelectTrigger, { className: "h-auto w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-xs sm:w-auto", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: org.orgs.map((o) => (_jsx(SelectItem, { value: o.orgId, children: o.orgName }, o.orgId))) })] })) : undefined }), isOwnerOrAdmin && (_jsxs(_Fragment, { children: [_jsx(DomainSettingsSection, { domain: org.allowedDomain, ownerEmail: org.email }), _jsx(WorkspaceUrlSettingsSection, { workspaceUrl: org.workspaceUrl }), _jsx(AuthProviderSettingsSection, { requiredAuthProvider: org.requiredAuthProvider }), isOwner && _jsx(A2ASecretSection, { isSet: Boolean(org.a2aSecretSet) })] })), switchOrg.error && (_jsx("div", { className: "px-5 pb-4", children: _jsx(ErrorText, { error: switchOrg.error }) }))] }), _jsx(MembersTableCard, { members: members, pendingInvites: pendingInvites, isLoadingMembers: isLoadingMembers, currentUserEmail: org.email, currentUserRole: org.role ?? null, appRoles: appRoles }), isOwner && _jsx(DangerZoneCard, { orgName: org.orgName ?? "" })] }));
104
110
  }
105
111
  function MembersTableCard({ members, pendingInvites, isLoadingMembers, currentUserEmail, currentUserRole, appRoles, }) {
106
112
  const t = useT();
@@ -111,8 +117,7 @@ function MembersTableCard({ members, pendingInvites, isLoadingMembers, currentUs
111
117
  a.email.toLowerCase(),
112
118
  a.role,
113
119
  ]));
114
- const columnCount = appRoles ? 5 : 4;
115
- return (_jsxs("section", { className: "rounded-lg border border-border bg-card", children: [_jsxs("div", { className: "flex flex-col gap-3 border-b border-border px-4 py-3 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium", children: t("org.members") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("org.memberCount", { count: members.length }) })] }), canInvite && !showInviteForm && (_jsxs(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: () => setShowInviteForm(true), className: "inline-flex items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90", children: [_jsx(IconUserPlus, { size: 14 }), t("org.inviteMembers")] }))] }), canInvite && showInviteForm && (_jsx("div", { className: "border-b border-border p-4", children: _jsx(BulkInviteForm, { currentUserRole: currentUserRole, onClose: () => setShowInviteForm(false) }) })), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t("org.member") }), _jsx(TableHead, { children: t("org.role") }), appRoles && (_jsx(TableHead, { children: appRoles.label ?? appRoles.appId })), _jsx(TableHead, { children: t("org.status") }), _jsx(TableHead, { className: "text-end", children: t("org.actions") })] }) }), _jsx(TableBody, { children: isLoadingMembers && members.length === 0 ? ([0, 1, 2].map((i) => (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: columnCount, children: _jsx("div", { className: "h-3.5 rounded bg-muted animate-pulse", style: { width: `${180 + i * 48}px` } }) }) }, i)))) : members.length === 0 && pendingInvites.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: columnCount, className: "py-8 text-center text-sm text-muted-foreground", children: t("org.noMembers") }) })) : (_jsxs(_Fragment, { children: [members.map((m) => (_jsx(MemberRow, { email: m.email, role: m.role, isCurrentUser: m.email === currentUserEmail, currentUserRole: currentUserRole, appRoles: appRoles, appRole: appRoleByEmail.get(m.email.toLowerCase()) ?? null, canManageAppRoles: Boolean(appRoleData?.canManage) }, m.email))), pendingInvites.map((inv) => (_jsx(PendingInviteRow, { invite: inv, hasAppRoleColumn: Boolean(appRoles) }, inv.id)))] })) })] })] }));
120
+ return (_jsxs("section", { className: "overflow-hidden rounded-xl border border-border/70 bg-card text-card-foreground", children: [_jsxs("div", { className: "flex flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium", children: t("org.members") }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("org.memberCount", { count: members.length }) })] }), canInvite && !showInviteForm && (_jsxs(Button, { type: "button", intent: "primary", emphasis: "solid", onClick: () => setShowInviteForm(true), className: "inline-flex items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90", children: [_jsx(IconUserPlus, { size: 14 }), t("org.inviteMembers")] }))] }), canInvite && showInviteForm && (_jsx("div", { className: "border-b border-border p-4", children: _jsx(BulkInviteForm, { currentUserRole: currentUserRole, onClose: () => setShowInviteForm(false) }) })), _jsx("div", { className: "divide-y divide-border/60 border-t border-border/60", children: isLoadingMembers && members.length === 0 ? ([0, 1, 2].map((i) => (_jsxs("div", { className: "flex items-center gap-3 px-5 py-4", children: [_jsx("div", { className: "size-8 animate-pulse rounded-full bg-muted" }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-3.5 animate-pulse rounded bg-muted", style: { width: `${180 + i * 48}px` } }), _jsx("div", { className: "h-3 w-20 animate-pulse rounded bg-muted" })] })] }, i)))) : members.length === 0 && pendingInvites.length === 0 ? (_jsx("div", { className: "px-5 py-10 text-center text-sm text-muted-foreground", children: t("org.noMembers") })) : (_jsxs(_Fragment, { children: [members.map((m) => (_jsx(MemberRow, { email: m.email, role: m.role, isCurrentUser: m.email === currentUserEmail, currentUserRole: currentUserRole, appRoles: appRoles, appRole: appRoleByEmail.get(m.email.toLowerCase()) ?? null, canManageAppRoles: Boolean(appRoleData?.canManage) }, m.email))), pendingInvites.map((inv) => (_jsx(PendingInviteRow, { invite: inv }, inv.id)))] })) })] }));
116
121
  }
117
122
  function DangerZoneCard({ orgName }) {
118
123
  const t = useT();
@@ -126,11 +131,11 @@ function DangerZoneCard({ orgName }) {
126
131
  return;
127
132
  deleteOrg.mutate(orgName, { onSuccess: () => setOpen(false) });
128
133
  }
129
- return (_jsxs("section", { className: "rounded-lg border border-destructive/40 bg-card p-4 space-y-3", children: [_jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-destructive" }), _jsxs("div", { className: "space-y-1", children: [_jsx("h3", { className: "text-sm font-medium text-destructive", children: t("org.dangerZone") }), _jsx("p", { className: "text-sm text-muted-foreground", children: t("org.deleteOrgDescription") })] })] }), _jsxs(AlertDialog, { open: open, onOpenChange: (next) => {
130
- setOpen(next);
131
- if (!next)
132
- setConfirmText("");
133
- }, children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "outline", className: "cursor-pointer rounded-md border border-destructive/40 px-3 py-1.5 text-xs font-medium text-destructive hover:bg-destructive/10", children: t("org.deleteOrg") }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("org.deleteOrg") }), _jsx(AlertDialogDescription, { children: t("org.deleteOrgConfirmPrompt", { name: orgName }) })] }), _jsx("input", { type: "text", value: confirmText, onChange: (e) => setConfirmText(e.target.value), placeholder: t("org.deleteOrgConfirmPlaceholder"), className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-destructive", autoFocus: true }), _jsx(ErrorText, { error: deleteOrg.error }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { className: "cursor-pointer", children: t("org.cancel") }), _jsx(AlertDialogAction, { disabled: !canConfirm || deleteOrg.isPending, onClick: handleConfirm, className: "cursor-pointer bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:cursor-not-allowed disabled:opacity-50", children: deleteOrg.isPending ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx(IconLoader2, { size: 14, className: "animate-spin" }), t("org.deleteOrgPending")] })) : (t("org.deleteOrgConfirmCta")) })] })] })] })] }));
134
+ return (_jsx("section", { className: "rounded-lg border border-destructive/40 bg-card p-4 space-y-3", children: _jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx(IconAlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0 text-destructive" }), _jsxs("div", { className: "min-w-0 space-y-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("h3", { className: "text-sm font-medium text-destructive", children: t("org.dangerZone") }), _jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: _jsx(OrganizationDescription, { help: t("org.deleteOrgDescription"), children: "Delete this organization and all of its members." }) })] }), _jsxs(AlertDialog, { open: open, onOpenChange: (next) => {
135
+ setOpen(next);
136
+ if (!next)
137
+ setConfirmText("");
138
+ }, children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "outline", className: "cursor-pointer rounded-md border border-destructive/40 px-3 py-1.5 text-xs font-medium text-destructive hover:bg-destructive/10", children: t("org.deleteOrg") }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("org.deleteOrg") }), _jsx(AlertDialogDescription, { children: t("org.deleteOrgConfirmPrompt", { name: orgName }) })] }), _jsx("input", { type: "text", value: confirmText, onChange: (e) => setConfirmText(e.target.value), placeholder: t("org.deleteOrgConfirmPlaceholder"), className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-destructive", autoFocus: true }), _jsx(ErrorText, { error: deleteOrg.error }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { className: "cursor-pointer", children: t("org.cancel") }), _jsx(AlertDialogAction, { disabled: !canConfirm || deleteOrg.isPending, onClick: handleConfirm, className: "cursor-pointer bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:cursor-not-allowed disabled:opacity-50", children: deleteOrg.isPending ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [_jsx(IconLoader2, { size: 14, className: "animate-spin" }), t("org.deleteOrgPending")] })) : (t("org.deleteOrgConfirmCta")) })] })] })] })] })] }) }));
134
139
  }
135
140
  function roleLabel(role, t) {
136
141
  if (role === "owner")
@@ -143,33 +148,43 @@ function RoleBadge({ role }) {
143
148
  const t = useT();
144
149
  return (_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded border border-border px-2 py-1 text-xs text-muted-foreground", children: [_jsx(RoleIcon, { role: role }), roleLabel(role, t)] }));
145
150
  }
146
- function PendingInviteRow({ invite, hasAppRoleColumn, }) {
151
+ function memberInitials(email) {
152
+ const localPart = email.split("@", 1)[0] ?? email;
153
+ const initials = localPart
154
+ .split(/[._-]+/)
155
+ .filter(Boolean)
156
+ .slice(0, 2)
157
+ .map((part) => part[0]?.toUpperCase())
158
+ .join("");
159
+ return initials || "?";
160
+ }
161
+ function PendingInviteRow({ invite }) {
147
162
  const t = useT();
148
- return (_jsxs(TableRow, { className: "opacity-70", children: [_jsx(TableCell, { className: "min-w-56", children: _jsx("span", { className: "truncate text-sm", children: invite.email }) }), _jsx(TableCell, { children: _jsx(RoleBadge, { role: invite.role }) }), hasAppRoleColumn && (_jsx(TableCell, { children: _jsx("span", { className: "text-muted-foreground", children: "-" }) })), _jsx(TableCell, { children: _jsx("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: t("org.invited") }) }), _jsx(TableCell, { className: "text-end text-muted-foreground", children: "-" })] }));
163
+ return (_jsxs("div", { className: "flex flex-col gap-3 px-5 py-3.5 opacity-70 sm:flex-row sm:items-center", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [_jsx("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-border bg-background text-xs font-medium text-muted-foreground", children: memberInitials(invite.email) }), _jsx("span", { className: "min-w-0 truncate text-sm", children: invite.email })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:justify-end", children: [_jsx(RoleBadge, { role: invite.role }), _jsx("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: t("org.invited") })] })] }));
149
164
  }
150
165
  /** Sentinel for "clear the assignment" — Select cannot carry an empty value. */
151
166
  const UNASSIGNED = "__unassigned__";
152
- function AppRoleCell({ email, appRoles, appRole, canManage, }) {
167
+ function AppRoleControl({ email, appRoles, appRole, canManage, }) {
153
168
  const [editing, setEditing] = useState(false);
154
169
  const setAppRole = useSetAppMemberRole(appRoles.appId);
155
170
  const labelFor = (r) => appRoles.roleLabels?.[r] ?? r;
156
171
  if (editing) {
157
- return (_jsx(TableCell, { children: _jsxs(Select, { defaultOpen: true, value: appRole ?? UNASSIGNED, onOpenChange: (open) => {
158
- if (!open)
159
- setEditing(false);
160
- }, onValueChange: (value) => {
161
- const next = value === UNASSIGNED ? null : value;
162
- if (next === appRole) {
163
- setEditing(false);
164
- return;
165
- }
166
- setAppRole.mutate({ email, role: next }, { onSuccess: () => setEditing(false) });
167
- }, disabled: setAppRole.isPending, children: [_jsx(SelectTrigger, { autoFocus: true, className: "h-auto w-auto rounded-md border border-border bg-background px-1.5 py-0.5 text-[11px]", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: UNASSIGNED, children: appRoles.defaultRole ? labelFor(appRoles.defaultRole) : "—" }), appRoles.roles.map((r) => (_jsx(SelectItem, { value: r, children: labelFor(r) }, r)))] })] }) }));
172
+ return (_jsxs(Select, { defaultOpen: true, value: appRole ?? UNASSIGNED, onOpenChange: (open) => {
173
+ if (!open)
174
+ setEditing(false);
175
+ }, onValueChange: (value) => {
176
+ const next = value === UNASSIGNED ? null : value;
177
+ if (next === appRole) {
178
+ setEditing(false);
179
+ return;
180
+ }
181
+ setAppRole.mutate({ email, role: next }, { onSuccess: () => setEditing(false) });
182
+ }, disabled: setAppRole.isPending, children: [_jsx(SelectTrigger, { autoFocus: true, className: "h-auto w-auto rounded-md border border-border bg-background px-2 py-1 text-xs", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: UNASSIGNED, children: appRoles.defaultRole ? labelFor(appRoles.defaultRole) : "—" }), appRoles.roles.map((r) => (_jsx(SelectItem, { value: r, children: labelFor(r) }, r)))] })] }));
168
183
  }
169
184
  // An unassigned member shows the app's default only as a hint. The default
170
185
  // never satisfies a server guard, so it must not read as a granted role.
171
186
  const display = appRole ? (_jsx("span", { className: "inline-flex items-center rounded border border-border px-2 py-1 text-xs text-muted-foreground", children: labelFor(appRole) })) : (_jsx("span", { className: "text-xs text-muted-foreground/70", children: appRoles.defaultRole ? labelFor(appRoles.defaultRole) : "—" }));
172
- return (_jsx(TableCell, { children: canManage ? (_jsx(Button, { type: "button", onClick: () => setEditing(true), className: "cursor-pointer rounded hover:opacity-80", children: display })) : (display) }));
187
+ return canManage ? (_jsx(Button, { type: "button", onClick: () => setEditing(true), className: "cursor-pointer rounded hover:opacity-80", children: display })) : (display);
173
188
  }
174
189
  function MemberRow({ email, role, isCurrentUser, currentUserRole, appRoles, appRole, canManageAppRoles, }) {
175
190
  const t = useT();
@@ -184,20 +199,20 @@ function MemberRow({ email, role, isCurrentUser, currentUserRole, appRoles, appR
184
199
  !isCurrentUser &&
185
200
  (currentUserRole === "owner" ||
186
201
  (currentUserRole === "admin" && role === "member"));
187
- return (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "min-w-56", children: _jsx("span", { className: "truncate text-sm", children: email }) }), _jsx(TableCell, { children: _jsx(RoleBadge, { role: role }) }), appRoles && (_jsx(AppRoleCell, { email: email, appRoles: appRoles, appRole: appRole ?? null, canManage: Boolean(canManageAppRoles) })), _jsx(TableCell, { children: isCurrentUser ? (_jsx("span", { className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground", children: t("org.you") })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) }), _jsx(TableCell, { children: canManage ? (_jsxs("div", { className: "flex shrink-0 items-center justify-end gap-1", children: [editing ? (_jsxs(Select, { defaultOpen: true, value: role, onOpenChange: (open) => {
188
- if (!open)
189
- setEditing(false);
190
- }, onValueChange: (value) => {
191
- const next = value === "admin" ? "admin" : "member";
192
- if (next !== role) {
193
- changeRole.mutate({ email, role: next }, { onSuccess: () => setEditing(false) });
194
- }
195
- else {
196
- setEditing(false);
197
- }
198
- }, disabled: changeRole.isPending, children: [_jsx(SelectTrigger, { autoFocus: true, className: "h-auto w-auto rounded-md border border-border bg-background px-1.5 py-0.5 text-[11px]", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "member", children: t("org.member") }), _jsx(SelectItem, { value: "admin", children: t("org.admin") })] })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => setEditing(true), className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: t("org.changeRole") })] })), confirmingRemove ? (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { type: "button", intent: "neutral", emphasis: "ghost", onClick: () => setConfirmingRemove(false), className: "rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground", children: t("org.cancel") }), _jsx(Button, { type: "button", intent: "danger", emphasis: "solid", disabled: removeMember.isPending, onClick: () => removeMember.mutate(email, {
199
- onSettled: () => setConfirmingRemove(false),
200
- }), className: "rounded bg-destructive px-1.5 py-0.5 text-[11px] text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50", children: t("org.remove") })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: removeMember.isPending, onClick: () => setConfirmingRemove(true), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconTrash, { size: 14 }) }) }), _jsx(TooltipContent, { children: t("org.removeMember") })] }))] })) : (_jsx("div", { className: "text-end text-muted-foreground", children: "-" })) })] }));
202
+ return (_jsxs("div", { className: "flex flex-col gap-3 px-5 py-3.5 sm:flex-row sm:items-center", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [_jsx("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-border bg-background text-xs font-medium text-muted-foreground", children: memberInitials(email) }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm", children: email }), isCurrentUser && (_jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: t("org.you") }))] })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:justify-end", children: [_jsx(RoleBadge, { role: role }), appRoles && (_jsx(AppRoleControl, { email: email, appRoles: appRoles, appRole: appRole ?? null, canManage: Boolean(canManageAppRoles) })), canManage && (_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [editing ? (_jsxs(Select, { defaultOpen: true, value: role, onOpenChange: (open) => {
203
+ if (!open)
204
+ setEditing(false);
205
+ }, onValueChange: (value) => {
206
+ const next = value === "admin" ? "admin" : "member";
207
+ if (next !== role) {
208
+ changeRole.mutate({ email, role: next }, { onSuccess: () => setEditing(false) });
209
+ }
210
+ else {
211
+ setEditing(false);
212
+ }
213
+ }, disabled: changeRole.isPending, children: [_jsx(SelectTrigger, { autoFocus: true, className: "h-auto w-auto rounded-md border border-border bg-background px-2 py-1 text-xs", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "member", children: t("org.member") }), _jsx(SelectItem, { value: "admin", children: t("org.admin") })] })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => setEditing(true), className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: t("org.changeRole") })] })), confirmingRemove ? (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { type: "button", intent: "neutral", emphasis: "ghost", onClick: () => setConfirmingRemove(false), className: "rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground", children: t("org.cancel") }), _jsx(Button, { type: "button", intent: "danger", emphasis: "solid", disabled: removeMember.isPending, onClick: () => removeMember.mutate(email, {
214
+ onSettled: () => setConfirmingRemove(false),
215
+ }), className: "rounded bg-destructive px-1.5 py-0.5 text-[11px] text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50", children: t("org.remove") })] })) : (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: removeMember.isPending, onClick: () => setConfirmingRemove(true), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconTrash, { size: 14 }) }) }), _jsx(TooltipContent, { children: t("org.removeMember") })] }))] }))] })] }));
201
216
  }
202
217
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
203
218
  function parseEmailList(input) {
@@ -334,18 +349,18 @@ function DomainSettingsSection({ domain, ownerEmail, }) {
334
349
  onSuccess: () => setEditing(false),
335
350
  });
336
351
  }
337
- return (_jsxs("div", { className: "space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: "Email domain auto-join" }), _jsxs("p", { className: "text-[11px] text-muted-foreground", children: ["Anyone who signs up with an email at this domain will join your organization automatically. You can only set your own email domain (", ownDomain || "—", "); free email providers like gmail.com or outlook.com aren't allowed."] }), !editing ? (_jsx("div", { className: "flex items-center gap-2", children: domain ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm", children: [_jsx(IconAt, { className: "h-3.5 w-3.5 text-muted-foreground" }), domain] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => {
338
- setDraft(domain);
339
- setEditing(true);
340
- }, className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Edit domain" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: setOrgDomain.isPending, onClick: () => setOrgDomain.mutate(null), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconX, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Remove domain" })] })] })) : (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => {
341
- setDraft(ownDomain);
342
- setEditing(true);
343
- }, className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconAt, { size: 14 }), "Allow ", ownDomain || "your domain", " to auto-join"] })) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
344
- if (e.key === "Enter")
345
- save();
346
- if (e.key === "Escape")
347
- setEditing(false);
348
- }, placeholder: ownDomain || "example.com", className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: setOrgDomain.isPending, onClick: save, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setOrgDomain.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), _jsx(ErrorText, { error: setOrgDomain.error })] }));
352
+ return (_jsx(SettingsRow, { id: "email-domain", label: "Email domain auto-join", description: _jsx(OrganizationDescription, { help: `Anyone who signs up with an email at this domain joins the organization automatically. Only your own email domain (${ownDomain || "—"}) can be used; free email providers are not allowed.`, docsUrl: "https://www.builder.io/c/docs/agent-native-authentication?utm_source=agent-native&utm_medium=product&utm_campaign=organization_settings&utm_content=domain_auto_join", children: "Automatically add members with your work email." }), control: !editing ? (_jsx("div", { className: "flex flex-wrap items-center justify-end gap-2", children: domain ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm", children: [_jsx(IconAt, { className: "h-3.5 w-3.5 text-muted-foreground" }), domain] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => {
353
+ setDraft(domain);
354
+ setEditing(true);
355
+ }, className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Edit domain" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: setOrgDomain.isPending, onClick: () => setOrgDomain.mutate(null), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconX, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Remove domain" })] })] })) : (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => {
356
+ setDraft(ownDomain);
357
+ setEditing(true);
358
+ }, className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconAt, { size: 14 }), "Set domain"] })) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
359
+ if (e.key === "Enter")
360
+ save();
361
+ if (e.key === "Escape")
362
+ setEditing(false);
363
+ }, placeholder: ownDomain || "example.com", className: "w-44 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: setOrgDomain.isPending, onClick: save, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setOrgDomain.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), children: setOrgDomain.error ? _jsx(ErrorText, { error: setOrgDomain.error }) : null }));
349
364
  }
350
365
  function WorkspaceUrlSettingsSection({ workspaceUrl, }) {
351
366
  const setWorkspaceUrl = useSetOrgWorkspaceUrl();
@@ -361,15 +376,15 @@ function WorkspaceUrlSettingsSection({ workspaceUrl, }) {
361
376
  onSuccess: () => setEditing(false),
362
377
  });
363
378
  }
364
- return (_jsxs("div", { className: "space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: "Your workspace" }), _jsx("p", { className: "text-[11px] text-muted-foreground", children: "If your team runs its own workspace, members who land on a different deployment \u2014 opening a template from the catalog, for instance \u2014 get pointed here instead of an app that looks empty." }), !editing ? (_jsx("div", { className: "flex items-center gap-2", children: workspaceUrl ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm", children: [_jsx(IconExternalLink, { className: "h-3.5 w-3.5 text-muted-foreground" }), workspaceUrl] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => {
365
- setDraft(workspaceUrl);
366
- setEditing(true);
367
- }, className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Edit workspace URL" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: setWorkspaceUrl.isPending, onClick: () => setWorkspaceUrl.mutate(null), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconX, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Remove workspace URL" })] })] })) : (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(true), className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconExternalLink, { size: 14 }), "Set workspace URL"] })) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
368
- if (e.key === "Enter")
369
- save();
370
- if (e.key === "Escape")
371
- setEditing(false);
372
- }, placeholder: "workspace.example.com", className: "rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: setWorkspaceUrl.isPending, onClick: save, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setWorkspaceUrl.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), _jsx(ErrorText, { error: setWorkspaceUrl.error })] }));
379
+ return (_jsx(SettingsRow, { id: "workspace-url", label: "Workspace URL", description: _jsx(OrganizationDescription, { help: "Members who land on another deployment can be sent to this workspace URL instead of an empty app.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment?utm_source=agent-native&utm_medium=product&utm_campaign=organization_settings&utm_content=workspace_url", children: "Send members to this workspace from another deployment." }), control: !editing ? (_jsx("div", { className: "flex flex-wrap items-center justify-end gap-2", children: workspaceUrl ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "inline-flex max-w-72 items-center gap-1.5 truncate rounded-md border border-border bg-background px-2.5 py-1.5 text-sm", children: [_jsx(IconExternalLink, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsx("span", { className: "truncate", children: workspaceUrl })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: () => {
380
+ setDraft(workspaceUrl);
381
+ setEditing(true);
382
+ }, className: "text-muted-foreground hover:text-foreground", children: _jsx(IconPencil, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Edit workspace URL" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", intent: "danger", emphasis: "ghost", disabled: setWorkspaceUrl.isPending, onClick: () => setWorkspaceUrl.mutate(null), className: "text-muted-foreground hover:text-destructive disabled:opacity-50", children: _jsx(IconX, { size: 14 }) }) }), _jsx(TooltipContent, { children: "Remove workspace URL" })] })] })) : (_jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(true), className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: "Set URL" })) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
383
+ if (e.key === "Enter")
384
+ save();
385
+ if (e.key === "Escape")
386
+ setEditing(false);
387
+ }, placeholder: "workspace.example.com", className: "w-56 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: setWorkspaceUrl.isPending, onClick: save, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setWorkspaceUrl.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setEditing(false), className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), children: setWorkspaceUrl.error ? (_jsx(ErrorText, { error: setWorkspaceUrl.error })) : null }));
373
388
  }
374
389
  function AuthProviderSettingsSection({ requiredAuthProvider, }) {
375
390
  const setAuthProvider = useSetOrgAuthProvider();
@@ -382,7 +397,7 @@ function AuthProviderSettingsSection({ requiredAuthProvider, }) {
382
397
  }
383
398
  setAuthProvider.mutate(null);
384
399
  }
385
- return (_jsxs("div", { className: "space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0", children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: "Organization sign-in" }), _jsx("p", { className: "text-[11px] text-muted-foreground", children: "Require Google sign-in for every member of this organization. Enabling this revokes all current sessions, and future password or non-Google sign-ins will be rejected." }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Switch, { checked: enabled, disabled: setAuthProvider.isPending, onCheckedChange: changeProvider, "aria-label": "Require Google sign-in" }), _jsx("span", { className: "text-sm font-medium", children: enabled ? "Google sign-in required" : "Google sign-in optional" })] }), _jsx(ErrorText, { error: setAuthProvider.error }), _jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Require Google sign-in?" }), _jsx(AlertDialogDescription, { children: "Every current session in this organization will be revoked. Members must use their Google Workspace account the next time they sign in. Continue only after Google sign-in is configured for this app." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: setAuthProvider.isPending, children: "Cancel" }), _jsx(AlertDialogAction, { disabled: setAuthProvider.isPending, onClick: () => {
400
+ return (_jsxs(_Fragment, { children: [_jsx(SettingsRow, { id: "organization-sign-in", label: "Organization sign-in", description: _jsx(OrganizationDescription, { help: "Require Google sign-in for every member. Enabling this revokes current sessions and rejects future password or non-Google sign-ins.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication?utm_source=agent-native&utm_medium=product&utm_campaign=organization_settings&utm_content=organization_sign_in", children: "Choose how members sign in." }), control: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm font-medium", children: enabled ? "Google required" : "Google optional" }), _jsx(Switch, { checked: enabled, disabled: setAuthProvider.isPending, onCheckedChange: changeProvider, "aria-label": "Require Google sign-in" })] }), children: setAuthProvider.error ? (_jsx(ErrorText, { error: setAuthProvider.error })) : null }), _jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Require Google sign-in?" }), _jsx(AlertDialogDescription, { children: "Every current session in this organization will be revoked. Members must use their Google Workspace account the next time they sign in. Continue only after Google sign-in is configured for this app." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: setAuthProvider.isPending, children: "Cancel" }), _jsx(AlertDialogAction, { disabled: setAuthProvider.isPending, onClick: () => {
386
401
  setAuthProvider.mutate("google", {
387
402
  onSuccess: () => setConfirmOpen(false),
388
403
  });
@@ -463,19 +478,24 @@ function A2ASecretSection({ isSet }) {
463
478
  });
464
479
  }
465
480
  const masked = isSet ? "••••••••••••" : "Not set";
466
- return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1 text-xs font-medium text-muted-foreground uppercase tracking-wide", children: [_jsx("span", { children: "Cross-app authentication" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: "/docs/a2a-protocol#organization-secret-sync", target: "_blank", rel: "noopener noreferrer", "aria-label": "Read the cross-app authentication documentation", className: "inline-flex size-3.5 items-center justify-center rounded-full text-muted-foreground hover:text-foreground", children: _jsx(IconHelpCircle, { className: "size-3" }) }) }), _jsx(TooltipContent, { children: "Read the cross-app authentication documentation" })] })] }), _jsx("p", { className: "text-[11px] text-muted-foreground", children: "This secret authenticates cross-app delegation (e.g. Dispatch to Analytics). All apps in your organization need the same secret." }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono", children: [_jsx(IconKey, { className: "h-3.5 w-3.5 text-muted-foreground" }), secret ?? masked] }), isSet && (_jsxs(_Fragment, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: toggleReveal, disabled: revealA2ASecret.isPending, className: "text-muted-foreground hover:text-foreground", children: secret ? _jsx(IconEyeOff, { size: 14 }) : _jsx(IconEye, { size: 14 }) }) }), _jsx(TooltipContent, { children: secret ? "Hide secret" : "Reveal secret" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: copyToClipboard, disabled: revealA2ASecret.isPending, className: "text-muted-foreground hover:text-foreground", children: copied ? (_jsx(IconCheck, { size: 14, className: "text-primary" })) : (_jsx(IconCopy, { size: 14 })) }) }), _jsx(TooltipContent, { children: "Copy secret" })] })] })), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, { type: "button", intent: "danger", emphasis: "outline", onClick: regenerate, disabled: setA2ASecret.isPending || syncA2ASecret.isPending, className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50", children: [setA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : (_jsx(IconRefresh, { size: 14 })), "Regenerate"] }) }), _jsx(TooltipContent, { children: "Regenerate secret and sync to connected apps" })] }), isSet && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => syncToApps(), disabled: setA2ASecret.isPending || syncA2ASecret.isPending, className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50", children: [syncA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : (_jsx(IconCloudUpload, { size: 14 })), "Sync to apps"] }) }), _jsx(TooltipContent, { children: "Push this secret to every connected app" })] }))] }), syncA2ASecret.isPending && (_jsx("p", { className: "text-[11px] text-muted-foreground", children: "Syncing to connected apps\u2026" })), syncResult && !syncA2ASecret.isPending && (_jsxs("div", { className: "space-y-1", children: [_jsxs("p", { className: "text-[11px] text-muted-foreground", children: ["Synced to ", syncResult.succeeded, "/", syncResult.total, " app", syncResult.total === 1 ? "" : "s", syncResult.failed > 0 ? ` (${syncResult.failed} failed)` : "", "."] }), syncResult.failed > 0 && (_jsx("ul", { className: "text-[11px] text-destructive list-disc ps-5 space-y-0.5", children: syncResult.results
467
- .filter((r) => !r.ok)
468
- .map((r) => (_jsxs("li", { children: [r.name, ": ", r.error || `HTTP ${r.status ?? "?"}`] }, r.id))) }))] })), !pasteMode ? (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setPasteMode(true), className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconKey, { size: 14 }), "Paste secret from another app"] })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: pasteValue, onChange: (e) => setPasteValue(e.target.value), onKeyDown: (e) => {
469
- if (e.key === "Enter")
470
- saveSecret();
471
- if (e.key === "Escape") {
481
+ return (_jsx(SettingsRow, { id: "cross-app-authentication", label: "Cross-app authentication", description: _jsx(OrganizationDescription, { help: "This secret authenticates cross-app delegation. Every app in the organization must share it.", children: "Share one secret across connected apps." }), control: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono", children: [_jsx(IconKey, { className: "h-3.5 w-3.5 text-muted-foreground" }), secret ?? masked] }), isSet && (_jsxs(_Fragment, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: toggleReveal, disabled: revealA2ASecret.isPending, className: "text-muted-foreground hover:text-foreground", children: secret ? _jsx(IconEyeOff, { size: 14 }) : _jsx(IconEye, { size: 14 }) }) }), _jsx(TooltipContent, { children: secret ? "Hide secret" : "Reveal secret" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", onClick: copyToClipboard, disabled: revealA2ASecret.isPending, className: "text-muted-foreground hover:text-foreground", children: copied ? (_jsx(IconCheck, { size: 14, className: "text-primary" })) : (_jsx(IconCopy, { size: 14 })) }) }), _jsx(TooltipContent, { children: "Copy secret" })] })] })), _jsxs(Button, { type: "button", intent: "danger", emphasis: "outline", onClick: regenerate, disabled: setA2ASecret.isPending || syncA2ASecret.isPending, className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50", children: [setA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : (_jsx(IconRefresh, { size: 14 })), "Regenerate"] }), isSet && (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => syncToApps(), disabled: setA2ASecret.isPending || syncA2ASecret.isPending, className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50 disabled:opacity-50", children: [syncA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : (_jsx(IconCloudUpload, { size: 14 })), "Sync"] })), !pasteMode && (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => setPasteMode(true), className: "inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50", children: [_jsx(IconKey, { size: 14 }), "Paste secret"] }))] }), children: (pasteMode ||
482
+ syncA2ASecret.isPending ||
483
+ syncResult ||
484
+ revealA2ASecret.error ||
485
+ setA2ASecret.error ||
486
+ syncA2ASecret.error) && (_jsxs("div", { className: "space-y-3", children: [syncA2ASecret.isPending && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Syncing to connected apps\u2026" })), syncResult && !syncA2ASecret.isPending && (_jsxs("div", { className: "space-y-1", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Synced to ", syncResult.succeeded, "/", syncResult.total, " app", syncResult.total === 1 ? "" : "s", syncResult.failed > 0 ? ` (${syncResult.failed} failed)` : "", "."] }), syncResult.failed > 0 && (_jsx("ul", { className: "list-disc space-y-0.5 ps-5 text-xs text-destructive", children: syncResult.results
487
+ .filter((r) => !r.ok)
488
+ .map((r) => (_jsxs("li", { children: [r.name, ": ", r.error || `HTTP ${r.status ?? "?"}`] }, r.id))) }))] })), pasteMode ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: pasteValue, onChange: (e) => setPasteValue(e.target.value), onKeyDown: (e) => {
489
+ if (e.key === "Enter")
490
+ saveSecret();
491
+ if (e.key === "Escape") {
492
+ setPasteMode(false);
493
+ setPasteValue("");
494
+ }
495
+ }, placeholder: "Paste A2A secret", className: "min-w-0 flex-1 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: !pasteValue.trim() || setA2ASecret.isPending, onClick: saveSecret, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => {
472
496
  setPasteMode(false);
473
497
  setPasteValue("");
474
- }
475
- }, placeholder: "Paste A2A secret", className: "flex-1 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm font-mono focus:outline-none focus:ring-1 focus:ring-foreground", autoFocus: true }), _jsx(Button, { type: "button", intent: "primary", emphasis: "solid", disabled: !pasteValue.trim() || setA2ASecret.isPending, onClick: saveSecret, className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50", children: setA2ASecret.isPending ? (_jsx(IconLoader2, { size: 14, className: "animate-spin" })) : ("Save") }), _jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: () => {
476
- setPasteMode(false);
477
- setPasteValue("");
478
- }, className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })), _jsx(ErrorText, { error: revealA2ASecret.error }), _jsx(ErrorText, { error: setA2ASecret.error }), _jsx(ErrorText, { error: syncA2ASecret.error })] }));
498
+ }, className: "rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground", children: "Cancel" })] })) : null, _jsx(ErrorText, { error: revealA2ASecret.error }), _jsx(ErrorText, { error: setA2ASecret.error }), _jsx(ErrorText, { error: syncA2ASecret.error })] })) }));
479
499
  }
480
500
  /**
481
501
  * Default Team management page. Templates can route directly to this component
@@ -484,7 +504,7 @@ function A2ASecretSection({ isSet }) {
484
504
  export function TeamPage({ layout, title, showTitle = true, createOrgDescription, className, appRoles, }) {
485
505
  const t = useT();
486
506
  const { data: org, isLoading } = useOrg();
487
- const content = (_jsxs("div", { className: `space-y-6 ${className ?? "max-w-2xl"}`, children: [showTitle ? (_jsx("h2", { className: "text-2xl font-bold tracking-tight", children: title ?? t("org.team") })) : null, isLoading && (_jsx("section", { className: "rounded-lg border border-border bg-card p-6", children: _jsx("div", { className: "text-sm text-muted-foreground", children: t("org.loading") }) })), !isLoading && (_jsxs(_Fragment, { children: [_jsx(PendingInvitationsCard, {}), org?.domainMatches && org.domainMatches.length > 0 && (_jsx(JoinByDomainCard, { matches: org.domainMatches })), !org?.orgId ? (_jsx(CreateOrgCard, { description: createOrgDescription })) : (_jsx(MembersCard, { appRoles: appRoles }))] }))] }));
507
+ const content = (_jsxs("div", { className: `w-full space-y-6 ${className ?? ""}`, children: [showTitle ? (_jsx("h2", { className: "text-2xl font-bold tracking-tight", children: title ?? t("org.team") })) : null, isLoading && (_jsx("section", { className: "rounded-lg border border-border bg-card p-6", children: _jsx("div", { className: "text-sm text-muted-foreground", children: t("org.loading") }) })), !isLoading && (_jsxs(_Fragment, { children: [_jsx(PendingInvitationsCard, {}), org?.domainMatches && org.domainMatches.length > 0 && (_jsx(JoinByDomainCard, { matches: org.domainMatches })), !org?.orgId ? (_jsx(CreateOrgCard, { description: createOrgDescription })) : (_jsx(MembersCard, { appRoles: appRoles }))] }))] }));
488
508
  const wrapped = (_jsx(TooltipProvider, { delayDuration: 200, children: content }));
489
509
  return layout ? _jsx(_Fragment, { children: layout(wrapped) }) : wrapped;
490
510
  }
@@ -37,7 +37,7 @@ export interface RequireSessionProps {
37
37
  fallback?: React.ReactNode;
38
38
  /**
39
39
  * When true (default), unauthenticated visitors are redirected to the
40
- * framework sign-in entry point (`/_agent-native/sign-in`) carrying a `c`
40
+ * framework sign-in entry point (`/sign-in`) carrying a `c`
41
41
  * continuation for the current URL — so they land back here once signed in.
42
42
  * When false, `signedOut` is rendered instead and no navigation happens.
43
43
  */
@@ -29,8 +29,8 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
29
29
  * surfaces that authenticate by another mechanism.
30
30
  */
31
31
  import { useEffect, useRef } from "react";
32
- import { signInJourney } from "../shared/sign-in-journey.js";
33
- import { agentNativePath, appBasePath } from "./api-path.js";
32
+ import { SIGN_IN_ENTRY_PATH, signInJourney, } from "../shared/sign-in-journey.js";
33
+ import { appBasePath, appPath } from "./api-path.js";
34
34
  import { DefaultSpinner } from "./DefaultSpinner.js";
35
35
  import { useSession } from "./use-session.js";
36
36
  /**
@@ -59,7 +59,7 @@ function currentJourney(returnTo) {
59
59
  * directly and honour its `signInHref: null`.
60
60
  */
61
61
  export function buildSignInReturnHref(opts) {
62
- const base = agentNativePath("/_agent-native/sign-in");
62
+ const base = appPath(SIGN_IN_ENTRY_PATH);
63
63
  if (typeof window === "undefined")
64
64
  return base;
65
65
  return currentJourney(opts?.returnTo).signInHref ?? base;
@@ -113,5 +113,5 @@ function ResolvedSessionGate({ children, fallback, redirect = true, signedOut, }
113
113
  return _jsx(_Fragment, { children: children });
114
114
  }
115
115
  function SessionUnavailableNotice({ retry }) {
116
- return (_jsxs("div", { className: "flex h-screen w-full flex-col items-center justify-center gap-4 px-6 text-center", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "We couldn't reach the server to confirm you're signed in. This is usually temporary." }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { type: "button", onClick: retry, className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground", children: "Try again" }), _jsx("button", { type: "button", onClick: () => window.location.reload(), className: "rounded-md border border-border px-3 py-1.5 text-sm font-medium", children: "Reload page" })] })] }));
116
+ return (_jsxs("div", { className: "flex h-screen w-full flex-col items-center justify-center gap-4 px-6 text-center", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "We couldn't reach the server to confirm your session. This is usually temporary." }), _jsx("p", { className: "max-w-md text-xs text-muted-foreground", children: "Retry connection checks your session here. Reload page starts the app over." }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { type: "button", onClick: retry, className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground", children: "Retry connection" }), _jsx("button", { type: "button", onClick: () => window.location.reload(), className: "rounded-md border border-border px-3 py-1.5 text-sm font-medium", children: "Reload page" })] })] }));
117
117
  }
@@ -7,4 +7,5 @@ export interface McpConnectionSuggestionProps {
7
7
  integrations?: DefaultMcpIntegration[];
8
8
  }
9
9
  export declare function findMcpConnectionSuggestionIntegration({ text, contextText, variant, integrations, }: McpConnectionSuggestionProps): DefaultMcpIntegration | null;
10
+ export declare function shouldRenderMcpIntegrationFallback(logoUrl: string, logoLoadFailed: boolean): boolean;
10
11
  export declare function McpConnectionSuggestion({ text, contextText, variant, integrations: integrationOptions, }: McpConnectionSuggestionProps): import("react").JSX.Element | null;
@@ -5,12 +5,15 @@ import { agentNativePath } from "../api-path.js";
5
5
  import { openAgentSettings } from "../CommandMenu.js";
6
6
  import { useT } from "../i18n.js";
7
7
  import { clearMcpConnectionResume, notifyMcpConnectionComplete, saveMcpConnectionResume, } from "./mcp-connection-resume.js";
8
- import { buildMcpOAuthStartUrl, findMcpIntegrationForText, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isMcpConnectionFailureText, navigateToMcpOAuthStart, } from "./mcp-integration-catalog.js";
8
+ import { buildMcpOAuthStartUrl, findMcpIntegrationForText, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isMcpConnectionFailureText, navigateToMcpOAuthStart, shouldOfferMcpIntegrationOrganizationScope, } from "./mcp-integration-catalog.js";
9
9
  import { McpIntegrationDialog } from "./McpIntegrationDialog.js";
10
10
  import { useCreateMcpServer, useMcpServers, } from "./use-mcp-servers.js";
11
11
  export function findMcpConnectionSuggestionIntegration({ text, contextText = "", variant = "composer", integrations = getDefaultMcpIntegrations(), }) {
12
12
  return findMcpIntegrationForText(variant === "response" ? contextText : text, integrations);
13
13
  }
14
+ export function shouldRenderMcpIntegrationFallback(logoUrl, logoLoadFailed) {
15
+ return !logoUrl || logoLoadFailed;
16
+ }
14
17
  function compareUrl(value) {
15
18
  try {
16
19
  const url = new URL(value.trim());
@@ -33,8 +36,9 @@ function returnUrl() {
33
36
  }
34
37
  function canStartOAuth(integration) {
35
38
  return (integration.authMode === "oauth" &&
36
- integration.connectionMode === "oauth" &&
37
- integration.availability === "ready");
39
+ ((integration.connectionMode === "oauth" &&
40
+ integration.availability === "ready") ||
41
+ integration.managedOAuth === true));
38
42
  }
39
43
  function hasApiFallback(apiFallback) {
40
44
  return Boolean(apiFallback);
@@ -47,6 +51,7 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
47
51
  const [dismissedId, setDismissedId] = useState(null);
48
52
  const [connecting, setConnecting] = useState(false);
49
53
  const [error, setError] = useState(null);
54
+ const [logoLoadFailed, setLogoLoadFailed] = useState(false);
50
55
  const integrations = useMemo(() => integrationOptions ?? getDefaultMcpIntegrations(), [integrationOptions]);
51
56
  const integration = useMemo(() => findMcpConnectionSuggestionIntegration({
52
57
  text,
@@ -62,6 +67,12 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
62
67
  ...(mcpServersQuery.data?.org ?? []),
63
68
  ], [mcpServersQuery.data]);
64
69
  const connected = integration ? isConnected(integration, servers) : false;
70
+ const hasOrg = Boolean(mcpServersQuery.data?.orgId);
71
+ const canCreateOrgMcp = Boolean(hasOrg &&
72
+ (mcpServersQuery.data?.role === "owner" ||
73
+ mcpServersQuery.data?.role === "admin"));
74
+ const shouldChooseScope = Boolean(integration &&
75
+ shouldOfferMcpIntegrationOrganizationScope(integration, hasOrg, canCreateOrgMcp));
65
76
  const shouldSuggest = mcpServersQuery.isSuccess &&
66
77
  integration &&
67
78
  !connected &&
@@ -70,7 +81,8 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
70
81
  useEffect(() => {
71
82
  setError(null);
72
83
  setConnecting(false);
73
- }, [integration?.id, variant]);
84
+ setLogoLoadFailed(false);
85
+ }, [integration?.id, integration?.logoUrl, variant]);
74
86
  if (!shouldSuggest)
75
87
  return null;
76
88
  const connect = async () => {
@@ -81,6 +93,11 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
81
93
  openAgentSettings(`secrets:${apiFallback.secretKey}`);
82
94
  return;
83
95
  }
96
+ if (shouldChooseScope) {
97
+ saveMcpConnectionResume(variant === "response" ? contextText : text);
98
+ setDialogOpen(true);
99
+ return;
100
+ }
84
101
  if (canStartOAuth(integration)) {
85
102
  setConnecting(true);
86
103
  saveMcpConnectionResume(variant === "response" ? contextText : text);
@@ -128,20 +145,20 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
128
145
  ? t("mcpIntegrations.viewSetup")
129
146
  : t("mcpIntegrations.connect");
130
147
  return (_jsxs(_Fragment, { children: [_jsxs("div", { className: variant === "response"
131
- ? "mt-3 flex max-w-[520px] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]"
132
- : "mx-auto mb-2 flex w-[min(calc(100%_-_1.5rem),680px)] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]", "data-mcp-connection-suggestion": integration.id, children: [_jsxs("div", { className: "relative flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-md border border-border bg-background text-[10px] font-semibold text-muted-foreground", children: [_jsx("span", { "aria-hidden": "true", children: integration.name.slice(0, 1) }), integration.logoUrl && (_jsx("img", { src: integration.logoUrl, alt: "", className: "absolute h-5 w-5 object-contain", onError: (event) => {
133
- event.currentTarget.hidden = true;
134
- } }))] }), _jsx("span", { className: "min-w-0 flex-1 leading-snug text-foreground", children: t(hasApiFallback(apiFallback)
148
+ ? "agent-mcp-connection-suggestion agent-mcp-connection-suggestion--response mt-3 flex max-w-[520px] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]"
149
+ : "agent-mcp-connection-suggestion agent-mcp-connection-suggestion--composer mx-auto mb-2 flex w-[min(calc(100%_-_1.5rem),684px)] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]", "data-mcp-connection-suggestion": integration.id, "data-mcp-connection-suggestion-variant": variant, children: [_jsxs("div", { className: "relative flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-md border border-border bg-background text-[10px] font-semibold text-muted-foreground", children: [shouldRenderMcpIntegrationFallback(integration.logoUrl, logoLoadFailed) ? (_jsx("span", { "aria-hidden": "true", children: integration.name.slice(0, 1) })) : null, integration.logoUrl && (_jsx("img", { src: integration.logoUrl, alt: "", className: `absolute h-5 w-5 object-contain${logoLoadFailed ? " hidden" : ""}`, onError: () => setLogoLoadFailed(true) }))] }), _jsx("span", { className: "min-w-0 flex-1 leading-snug text-foreground", children: t(hasApiFallback(apiFallback)
135
150
  ? "mcpIntegrations.connectSuggestionWithApiToken"
136
151
  : "mcpIntegrations.connectSuggestion", { name: integration.name }) }), _jsxs("button", { type: "button", onClick: () => void connect(), disabled: connecting, "aria-busy": connecting, className: "inline-flex shrink-0 items-center gap-1 rounded-md bg-primary px-2.5 py-1.5 text-[11px] font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-60", children: [connecting && _jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), !connecting &&
137
152
  canStartOAuth(integration) &&
138
153
  !hasApiFallback(apiFallback) && (_jsx(IconPlugConnected, { className: "h-3 w-3" })), !connecting && hasApiFallback(apiFallback) && (_jsx(IconPlugConnected, { className: "h-3 w-3" })), actionLabel, !connecting &&
139
154
  !canStartOAuth(integration) &&
140
- !hasApiFallback(apiFallback) && (_jsx(IconArrowUpRight, { className: "h-3 w-3" }))] }), _jsx("button", { type: "button", onClick: () => setDismissedId(integration.id), className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": t("mcpIntegrations.dismissSuggestion"), children: _jsx(IconX, { className: "h-3.5 w-3.5" }) })] }), error && (_jsx("div", { className: "mx-auto mb-2 w-[min(100%,680px)] text-[11px] text-destructive", children: error })), _jsx(McpIntegrationDialog, { open: dialogOpen, onOpenChange: (open) => {
155
+ !hasApiFallback(apiFallback) && (_jsx(IconArrowUpRight, { className: "h-3 w-3" }))] }), _jsx("button", { type: "button", onClick: () => setDismissedId(integration.id), className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": t("mcpIntegrations.dismissSuggestion"), children: _jsx(IconX, { className: "h-3.5 w-3.5" }) })] }), error && (_jsx("div", { className: variant === "response"
156
+ ? "agent-mcp-connection-suggestion-error agent-mcp-connection-suggestion-error--response mt-1 max-w-[520px] text-[11px] text-destructive"
157
+ : "agent-mcp-connection-suggestion-error agent-mcp-connection-suggestion-error--composer mx-auto mb-2 w-[min(calc(100%_-_1.5rem),684px)] text-[11px] text-destructive", children: error })), _jsx(McpIntegrationDialog, { open: dialogOpen, onOpenChange: (open) => {
141
158
  setDialogOpen(open);
142
159
  if (!open)
143
160
  clearMcpConnectionResume();
144
- }, initialIntegrationId: integration.id, defaultScope: "user", canCreateOrgMcp: false, hasOrg: Boolean(mcpServersQuery.data?.orgId), onCreateMcpServer: (args) => createMcpServer.mutateAsync(args), onCreated: () => {
161
+ }, initialIntegrationId: integration.id, defaultScope: "user", canCreateOrgMcp: canCreateOrgMcp, hasOrg: hasOrg, onCreateMcpServer: (args) => createMcpServer.mutateAsync(args), onCreated: () => {
145
162
  setDismissedId(integration.id);
146
163
  saveMcpConnectionResume(variant === "response" ? contextText : text);
147
164
  notifyMcpConnectionComplete();