@agent-native/core 0.92.0 → 0.92.1

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 (363) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/application-state/store.ts +12 -1
  5. package/corpus/core/src/client/AssistantChat.tsx +27 -14
  6. package/corpus/core/src/client/PoweredByBadge.tsx +1 -8
  7. package/corpus/core/src/client/agent-chat-adapter.ts +37 -10
  8. package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +52 -1
  9. package/corpus/core/src/client/db-admin/TableEditor.tsx +49 -0
  10. package/corpus/core/src/client/db-admin/export-utils.ts +13 -4
  11. package/corpus/core/src/client/db-admin/useAgentSync.ts +72 -0
  12. package/corpus/core/src/client/error-capture.ts +69 -7
  13. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +5 -1
  14. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +53 -8
  15. package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +5 -1
  16. package/corpus/core/src/client/extensions/portable-extension.ts +1 -0
  17. package/corpus/core/src/client/org/OrgSwitcher.tsx +12 -9
  18. package/corpus/core/src/client/org/TeamPage.tsx +77 -71
  19. package/corpus/core/src/client/settings/SettingsPanel.tsx +205 -52
  20. package/corpus/core/src/client/settings/SettingsSection.tsx +8 -1
  21. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +25 -9
  22. package/corpus/core/src/db-admin/agent-tools.ts +8 -2
  23. package/corpus/core/src/db-admin/operations.ts +116 -4
  24. package/corpus/core/src/db-admin/routes.ts +1 -0
  25. package/corpus/core/src/db-admin/types.ts +4 -0
  26. package/corpus/core/src/extensions/html-shell.ts +5 -4
  27. package/corpus/core/src/extensions/routes.ts +10 -0
  28. package/corpus/core/src/navigation/index.ts +1 -1
  29. package/corpus/core/src/resources/handlers.ts +10 -8
  30. package/corpus/core/src/server/poll.ts +293 -8
  31. package/corpus/core/src/styles/agent-native.css +27 -0
  32. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
  33. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  34. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  35. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +7 -0
  36. package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  37. package/corpus/core/src/templates/default/AGENTS.md +4 -2
  38. package/corpus/core/src/templates/headless/AGENTS.md +4 -0
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  40. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  41. package/corpus/core/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  42. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  43. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  44. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  45. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  46. package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  47. package/corpus/core/src/templates/workspace-core/AGENTS.md +7 -1
  48. package/corpus/core/src/templates/workspace-root/AGENTS.md +7 -1
  49. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +5 -0
  50. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  51. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  52. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +7 -0
  53. package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +5 -1
  54. package/corpus/templates/analytics/AGENTS.md +33 -14
  55. package/corpus/templates/analytics/actions/capture-test-error.ts +4 -0
  56. package/corpus/templates/analytics/actions/get-analytics-alert-rule-defaults.ts +23 -0
  57. package/corpus/templates/analytics/actions/get-error-issue.ts +1 -1
  58. package/corpus/templates/analytics/actions/list-analysis-revisions.ts +40 -0
  59. package/corpus/templates/analytics/actions/list-dashboard-revisions.ts +40 -0
  60. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +299 -0
  61. package/corpus/templates/analytics/actions/navigate.ts +4 -2
  62. package/corpus/templates/analytics/actions/restore-analysis-revision.ts +43 -0
  63. package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +68 -0
  64. package/corpus/templates/analytics/actions/save-analytics-alert-rule.ts +14 -0
  65. package/corpus/templates/analytics/actions/save-monitor.ts +1 -1
  66. package/corpus/templates/analytics/actions/view-screen.ts +24 -0
  67. package/corpus/templates/analytics/app/components/analysis/AnalysisHistoryPanel.tsx +181 -0
  68. package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +184 -0
  69. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +22 -16
  70. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
  71. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +27 -21
  72. package/corpus/templates/analytics/app/hooks/use-analysis-revisions.ts +43 -0
  73. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +110 -0
  74. package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +43 -0
  75. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +8 -3
  76. package/corpus/templates/analytics/app/i18n/zh-TW.ts +64 -2
  77. package/corpus/templates/analytics/app/i18n-data.ts +783 -3
  78. package/corpus/templates/analytics/app/pages/Agents.tsx +359 -19
  79. package/corpus/templates/analytics/app/pages/Settings.tsx +3 -2
  80. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +34 -1
  81. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +28 -0
  82. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +18 -1
  83. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +7 -10
  84. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +479 -23
  85. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +0 -9
  86. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +11 -0
  87. package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +9 -1
  88. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +6 -3
  89. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +26 -30
  90. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -99
  91. package/corpus/templates/analytics/app/pages/settings/AlertRulesSettingsCard.tsx +262 -104
  92. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  93. package/corpus/templates/analytics/changelog/2026-07-08-admins-can-audit-dashboard-usage-ownership-and-cleanup-signa.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-08-agent-monitoring-stays-available-to-non-admins.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-08-alert-rules-are-easier-to-scan-expand-and-edit-from-settings.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-forms-remember-last-email-recipients.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-rules-can-now-use-per-rule-slack-and-webhook.md +6 -0
  98. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +5 -0
  99. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-usage-now-counts-explorer-dashboard-traffic.md +6 -0
  100. package/corpus/templates/analytics/changelog/2026-07-08-demo-mode-session-emails-are-filtered-and-anonymized.md +6 -0
  101. package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-adds-stack-traces-and-frequency-bars.md +6 -0
  102. package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-now-shows-the-latest-occurrence-message-a.md +6 -0
  103. package/corpus/templates/analytics/changelog/2026-07-08-monitoring-errors-only-show-test-action-when-empty.md +6 -0
  104. package/corpus/templates/analytics/changelog/2026-07-08-production-session-replay-now-requires-private-blob-storage-.md +6 -0
  105. package/corpus/templates/analytics/changelog/2026-07-08-shared-extension-links-now-show-a-clear-message-when-you-do-.md +6 -0
  106. package/corpus/templates/analytics/changelog/2026-07-08-team-settings-show-access-controls-next-to-member-lists.md +6 -0
  107. package/corpus/templates/analytics/changelog/2026-07-08-uptime-monitors-now-use-a-10-second-request-timeout-by-defau.md +6 -0
  108. package/corpus/templates/analytics/server/db/schema-monitoring.ts +1 -1
  109. package/corpus/templates/analytics/server/db/schema.ts +56 -0
  110. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +92 -0
  111. package/corpus/templates/analytics/server/lib/dashboards-store.ts +334 -5
  112. package/corpus/templates/analytics/server/lib/error-capture.ts +231 -36
  113. package/corpus/templates/analytics/server/lib/session-replay.ts +114 -8
  114. package/corpus/templates/analytics/server/lib/uptime-monitors.ts +5 -4
  115. package/corpus/templates/analytics/server/plugins/db.ts +112 -2
  116. package/corpus/templates/analytics/server/routes/api/dashboard-agent-context.json.get.ts +1 -0
  117. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +5 -0
  118. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  119. package/corpus/templates/assets/.agents/skills/security/SKILL.md +7 -0
  120. package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +5 -1
  121. package/corpus/templates/assets/AGENTS.md +4 -0
  122. package/corpus/templates/assets/app/routes/settings.tsx +1 -1
  123. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  124. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +5 -0
  125. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +5 -0
  126. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  127. package/corpus/templates/brain/.agents/skills/security/SKILL.md +7 -0
  128. package/corpus/templates/brain/AGENTS.md +4 -0
  129. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  130. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +5 -0
  131. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  132. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +7 -0
  133. package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +5 -1
  134. package/corpus/templates/calendar/AGENTS.md +4 -0
  135. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +11 -2
  136. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +21 -8
  137. package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +7 -1
  138. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -2
  139. package/corpus/templates/calendar/app/lib/popover-click-guard.ts +48 -4
  140. package/corpus/templates/calendar/app/pages/Settings.tsx +1 -1
  141. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  142. package/corpus/templates/calendar/changelog/2026-07-08-clicking-empty-calendar-space-closes-an-open-event-popover-b.md +6 -0
  143. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +5 -0
  144. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +5 -0
  145. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  146. package/corpus/templates/chat/.agents/skills/security/SKILL.md +7 -0
  147. package/corpus/templates/chat/AGENTS.md +4 -0
  148. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  149. package/corpus/templates/chat/app/routes/settings.tsx +2 -2
  150. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  151. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +5 -0
  152. package/corpus/templates/clips/.agents/skills/security/SKILL.md +7 -0
  153. package/corpus/templates/clips/AGENTS.md +4 -0
  154. package/corpus/templates/clips/actions/finalize-recording.ts +9 -3
  155. package/corpus/templates/clips/actions/set-thumbnail.ts +11 -2
  156. package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +1 -7
  157. package/corpus/templates/clips/app/components/player/player-controls.tsx +21 -13
  158. package/corpus/templates/clips/app/components/player/video-player.tsx +30 -75
  159. package/corpus/templates/clips/app/i18n/ar-SA.ts +6 -5
  160. package/corpus/templates/clips/app/i18n/de-DE.ts +6 -6
  161. package/corpus/templates/clips/app/i18n/en-US.ts +6 -5
  162. package/corpus/templates/clips/app/i18n/es-ES.ts +6 -5
  163. package/corpus/templates/clips/app/i18n/fr-FR.ts +6 -6
  164. package/corpus/templates/clips/app/i18n/hi-IN.ts +6 -5
  165. package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -5
  166. package/corpus/templates/clips/app/i18n/ko-KR.ts +6 -5
  167. package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -5
  168. package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -5
  169. package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -5
  170. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +51 -118
  171. package/corpus/templates/clips/changelog/2026-07-08-hosted-clip-uploads-now-clear-failed-buffered-chunks.md +6 -0
  172. package/corpus/templates/clips/changelog/2026-07-08-hosted-recording-uploads-now-avoid-sql-chunk-storage.md +6 -0
  173. package/corpus/templates/clips/changelog/2026-07-08-meeting-recaps-now-keep-summaries-action-items-and-transcrip.md +6 -0
  174. package/corpus/templates/clips/changelog/2026-07-08-video-playback-controls-now-match-loom-style-5-second-skips-.md +6 -0
  175. package/corpus/templates/clips/server/lib/recording-upload-state.ts +63 -0
  176. package/corpus/templates/clips/server/lib/video-storage.ts +4 -0
  177. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +19 -13
  178. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +40 -1
  179. package/corpus/templates/content/.agents/skills/actions/SKILL.md +5 -0
  180. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  181. package/corpus/templates/content/.agents/skills/security/SKILL.md +7 -0
  182. package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +5 -1
  183. package/corpus/templates/content/AGENTS.md +4 -0
  184. package/corpus/templates/content/app/routes/_app.settings.tsx +2 -2
  185. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  186. package/corpus/templates/design/.agents/skills/actions/SKILL.md +5 -0
  187. package/corpus/templates/design/.agents/skills/security/SKILL.md +7 -0
  188. package/corpus/templates/design/AGENTS.md +4 -0
  189. package/corpus/templates/design/actions/take-design-screenshot.ts +12 -9
  190. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +57 -13
  191. package/corpus/templates/design/app/routes/team.tsx +1 -1
  192. package/corpus/templates/design/changelog/2026-07-08-local-images-added-to-designs-now-upload-to-file-storage-ins.md +6 -0
  193. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +5 -0
  194. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +7 -0
  195. package/corpus/templates/dispatch/AGENTS.md +4 -0
  196. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  197. package/corpus/templates/dispatch/app/routes/settings.tsx +2 -2
  198. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  199. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +5 -0
  200. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  201. package/corpus/templates/forms/.agents/skills/security/SKILL.md +7 -0
  202. package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +5 -1
  203. package/corpus/templates/forms/AGENTS.md +4 -0
  204. package/corpus/templates/forms/app/routes/_app.settings.tsx +2 -2
  205. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  206. package/corpus/templates/forms/shared/navigation.ts +1 -1
  207. package/corpus/templates/macros/.agents/skills/security/SKILL.md +7 -0
  208. package/corpus/templates/macros/AGENTS.md +4 -0
  209. package/corpus/templates/macros/app/routes/settings.tsx +2 -2
  210. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  211. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +5 -0
  212. package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +1 -1
  213. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  214. package/corpus/templates/mail/.agents/skills/security/SKILL.md +7 -0
  215. package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +5 -1
  216. package/corpus/templates/mail/AGENTS.md +4 -0
  217. package/corpus/templates/mail/changelog/2026-07-08-mail-attachments-in-hosted-environments-now-require-file-sto.md +6 -0
  218. package/corpus/templates/mail/server/handlers/media.ts +26 -1
  219. package/corpus/templates/mail/server/lib/outgoing-email.ts +24 -1
  220. package/corpus/templates/mail/server/lib/upload-store.ts +2 -1
  221. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +5 -0
  222. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +5 -0
  223. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  224. package/corpus/templates/plan/.agents/skills/security/SKILL.md +7 -0
  225. package/corpus/templates/plan/AGENTS.md +4 -0
  226. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  227. package/corpus/templates/plan/app/routes/settings.tsx +2 -2
  228. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  229. package/corpus/templates/plan/changelog/2026-07-08-hosted-plan-images-now-require-connected-storage.md +6 -0
  230. package/corpus/templates/plan/server/lib/plan-assets.ts +33 -4
  231. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +5 -0
  232. package/corpus/templates/slides/.agents/skills/security/SKILL.md +7 -0
  233. package/corpus/templates/slides/AGENTS.md +4 -0
  234. package/corpus/templates/slides/actions/generate-image-api.ts +15 -3
  235. package/corpus/templates/slides/app/routes/settings.tsx +2 -2
  236. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  237. package/corpus/templates/slides/changelog/2026-07-08-generated-slide-images-now-return-hosted-file-storage-urls-i.md +6 -0
  238. package/corpus/templates/slides/shared/api.ts +1 -1
  239. package/dist/application-state/store.d.ts.map +1 -1
  240. package/dist/application-state/store.js +8 -2
  241. package/dist/application-state/store.js.map +1 -1
  242. package/dist/client/AssistantChat.d.ts.map +1 -1
  243. package/dist/client/AssistantChat.js +24 -13
  244. package/dist/client/AssistantChat.js.map +1 -1
  245. package/dist/client/PoweredByBadge.d.ts +1 -1
  246. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  247. package/dist/client/PoweredByBadge.js +3 -9
  248. package/dist/client/PoweredByBadge.js.map +1 -1
  249. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  250. package/dist/client/agent-chat-adapter.js +28 -9
  251. package/dist/client/agent-chat-adapter.js.map +1 -1
  252. package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
  253. package/dist/client/chat/widgets/DataTableWidget.js +19 -2
  254. package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
  255. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  256. package/dist/client/db-admin/TableEditor.js +19 -2
  257. package/dist/client/db-admin/TableEditor.js.map +1 -1
  258. package/dist/client/db-admin/export-utils.d.ts +2 -0
  259. package/dist/client/db-admin/export-utils.d.ts.map +1 -1
  260. package/dist/client/db-admin/export-utils.js +11 -3
  261. package/dist/client/db-admin/export-utils.js.map +1 -1
  262. package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
  263. package/dist/client/db-admin/useAgentSync.js +63 -0
  264. package/dist/client/db-admin/useAgentSync.js.map +1 -1
  265. package/dist/client/error-capture.d.ts.map +1 -1
  266. package/dist/client/error-capture.js +41 -7
  267. package/dist/client/error-capture.js.map +1 -1
  268. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  269. package/dist/client/extensions/EmbeddedExtension.js +3 -1
  270. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  271. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  272. package/dist/client/extensions/ExtensionViewer.js +32 -5
  273. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  274. package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
  275. package/dist/client/extensions/InlineExtensionFrame.js +3 -1
  276. package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
  277. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  278. package/dist/client/extensions/portable-extension.js +1 -0
  279. package/dist/client/extensions/portable-extension.js.map +1 -1
  280. package/dist/client/org/OrgSwitcher.d.ts +1 -1
  281. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  282. package/dist/client/org/OrgSwitcher.js +11 -6
  283. package/dist/client/org/OrgSwitcher.js.map +1 -1
  284. package/dist/client/org/TeamPage.d.ts.map +1 -1
  285. package/dist/client/org/TeamPage.js +5 -5
  286. package/dist/client/org/TeamPage.js.map +1 -1
  287. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  288. package/dist/client/settings/SettingsPanel.js +37 -14
  289. package/dist/client/settings/SettingsPanel.js.map +1 -1
  290. package/dist/client/settings/SettingsSection.js +1 -1
  291. package/dist/client/settings/SettingsSection.js.map +1 -1
  292. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  293. package/dist/client/settings/SettingsTabsPage.js +21 -10
  294. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  295. package/dist/collab/routes.d.ts +1 -1
  296. package/dist/db-admin/agent-tools.d.ts.map +1 -1
  297. package/dist/db-admin/agent-tools.js +7 -2
  298. package/dist/db-admin/agent-tools.js.map +1 -1
  299. package/dist/db-admin/operations.d.ts.map +1 -1
  300. package/dist/db-admin/operations.js +90 -4
  301. package/dist/db-admin/operations.js.map +1 -1
  302. package/dist/db-admin/routes.d.ts.map +1 -1
  303. package/dist/db-admin/routes.js +1 -0
  304. package/dist/db-admin/routes.js.map +1 -1
  305. package/dist/db-admin/types.d.ts +4 -0
  306. package/dist/db-admin/types.d.ts.map +1 -1
  307. package/dist/db-admin/types.js.map +1 -1
  308. package/dist/extensions/html-shell.d.ts +5 -4
  309. package/dist/extensions/html-shell.d.ts.map +1 -1
  310. package/dist/extensions/html-shell.js.map +1 -1
  311. package/dist/extensions/routes.d.ts.map +1 -1
  312. package/dist/extensions/routes.js +8 -0
  313. package/dist/extensions/routes.js.map +1 -1
  314. package/dist/navigation/index.d.ts +1 -1
  315. package/dist/navigation/index.d.ts.map +1 -1
  316. package/dist/navigation/index.js +1 -1
  317. package/dist/navigation/index.js.map +1 -1
  318. package/dist/notifications/routes.d.ts +1 -1
  319. package/dist/observability/routes.d.ts +1 -1
  320. package/dist/resources/handlers.d.ts +6 -1
  321. package/dist/resources/handlers.d.ts.map +1 -1
  322. package/dist/resources/handlers.js +9 -8
  323. package/dist/resources/handlers.js.map +1 -1
  324. package/dist/server/poll.d.ts +12 -4
  325. package/dist/server/poll.d.ts.map +1 -1
  326. package/dist/server/poll.js +236 -9
  327. package/dist/server/poll.js.map +1 -1
  328. package/dist/styles/agent-native.css +27 -0
  329. package/dist/templates/default/.agents/skills/actions/SKILL.md +5 -0
  330. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  331. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  332. package/dist/templates/default/.agents/skills/security/SKILL.md +7 -0
  333. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  334. package/dist/templates/default/AGENTS.md +4 -2
  335. package/dist/templates/headless/AGENTS.md +4 -0
  336. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  337. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  338. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  339. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  340. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  341. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  342. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  343. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  344. package/dist/templates/workspace-core/AGENTS.md +7 -1
  345. package/dist/templates/workspace-root/AGENTS.md +7 -1
  346. package/package.json +1 -1
  347. package/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
  348. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  349. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  350. package/src/templates/default/.agents/skills/security/SKILL.md +7 -0
  351. package/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  352. package/src/templates/default/AGENTS.md +4 -2
  353. package/src/templates/headless/AGENTS.md +4 -0
  354. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  355. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  356. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  357. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  358. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  359. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  360. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  361. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  362. package/src/templates/workspace-core/AGENTS.md +7 -1
  363. package/src/templates/workspace-root/AGENTS.md +7 -1
@@ -317,6 +317,72 @@ function signatureOf(type: string, message: string, stack?: string): string {
317
317
  return `${type}|${message}|${firstStackLine(stack)}`;
318
318
  }
319
319
 
320
+ function normalizeGlobalErrorEvent(event: ErrorEvent): {
321
+ type: string;
322
+ message: string;
323
+ stack?: string;
324
+ } {
325
+ const error = event?.error;
326
+ const normalized = error
327
+ ? normalizeCapturedError(error)
328
+ : {
329
+ type: "Error",
330
+ message: String(event?.message ?? "Uncaught error"),
331
+ };
332
+
333
+ if (!normalized.stack && event?.filename) {
334
+ const line = event.lineno ?? 0;
335
+ const col = event.colno ?? 0;
336
+ normalized.stack = `at ${event.filename}:${line}:${col}`;
337
+ }
338
+
339
+ return normalized;
340
+ }
341
+
342
+ function shouldIgnoreAutoCapturedError(normalized: {
343
+ type: string;
344
+ message: string;
345
+ stack?: string;
346
+ }): boolean {
347
+ const message = (normalized.message || "").trim();
348
+ const stack = normalized.stack || "";
349
+
350
+ if (
351
+ /^ResizeObserver loop (?:limit exceeded|completed with undelivered notifications\.?)$/i.test(
352
+ message,
353
+ )
354
+ ) {
355
+ return true;
356
+ }
357
+
358
+ if (
359
+ normalized.type === "InvalidStateError" &&
360
+ /^Transition was aborted because of invalid state$/i.test(message)
361
+ ) {
362
+ return true;
363
+ }
364
+
365
+ if (
366
+ /^This script should only be loaded in a browser extension\.?$/i.test(
367
+ message,
368
+ )
369
+ ) {
370
+ return true;
371
+ }
372
+
373
+ const hasExtensionFrame =
374
+ /\b(?:chrome|moz|safari|webkit)-extension:\/\//i.test(stack) ||
375
+ /\binjectScriptAdjust\.js\b/i.test(stack);
376
+ if (
377
+ hasExtensionFrame &&
378
+ /^(?:TypeError:\s*)?Failed to fetch$/i.test(message)
379
+ ) {
380
+ return true;
381
+ }
382
+
383
+ return false;
384
+ }
385
+
320
386
  function shouldDedupe(
321
387
  runtime: ErrorCaptureRuntime,
322
388
  signature: string,
@@ -540,13 +606,8 @@ export function installErrorCapture(
540
606
  if (runtime.config.captureGlobalErrors) {
541
607
  const onError = (event: ErrorEvent) => {
542
608
  try {
543
- const error = event?.error;
544
- const normalized = error
545
- ? normalizeCapturedError(error)
546
- : {
547
- type: "Error",
548
- message: String(event?.message ?? "Uncaught error"),
549
- };
609
+ const normalized = normalizeGlobalErrorEvent(event);
610
+ if (shouldIgnoreAutoCapturedError(normalized)) return;
550
611
  // Global errors are already logged by the session replay recorder, so
551
612
  // don't re-emit them onto the replay timeline (avoid double-counting).
552
613
  dispatch(
@@ -575,6 +636,7 @@ export function installErrorCapture(
575
636
  if (!normalized.type || normalized.type === "Error") {
576
637
  normalized.type = "UnhandledRejection";
577
638
  }
639
+ if (shouldIgnoreAutoCapturedError(normalized)) return;
578
640
  dispatch(
579
641
  runtime,
580
642
  buildEvent(runtime, normalized, {
@@ -41,6 +41,7 @@ import {
41
41
  type BridgePolicyContext,
42
42
  type ExtensionBridgeRole,
43
43
  } from "./iframe-bridge.js";
44
+ import { normalizeAgentNativeExtensionSandbox } from "./portable-extension.js";
44
45
 
45
46
  interface Extension {
46
47
  id: string;
@@ -55,6 +56,9 @@ interface Extension {
55
56
  };
56
57
  }
57
58
 
59
+ const EXTENSION_IFRAME_SANDBOX =
60
+ normalizeAgentNativeExtensionSandbox(undefined);
61
+
58
62
  // Read the host app's *actual* computed theme values for the shared token set
59
63
  // (THEME_VAR_NAMES). The iframe ships with a generic baked palette
60
64
  // (getThemeVars); syncing the live values keeps embedded extensions visually
@@ -392,7 +396,7 @@ export function EmbeddedExtension({
392
396
  key={`${extensionId}-${extension.updatedAt ?? ""}`}
393
397
  src={iframeSrc}
394
398
  title={extension.name}
395
- sandbox="allow-scripts allow-forms"
399
+ sandbox={EXTENSION_IFRAME_SANDBOX}
396
400
  style={{ width: "100%", border: 0, height, display: "block" }}
397
401
  onLoad={() => {
398
402
  iframeRef.current?.contentWindow?.postMessage(
@@ -51,6 +51,7 @@ import {
51
51
  type BridgePolicyContext,
52
52
  type ExtensionBridgeRole,
53
53
  } from "./iframe-bridge.js";
54
+ import { normalizeAgentNativeExtensionSandbox } from "./portable-extension.js";
54
55
 
55
56
  const THEME_CSS_VARS = [
56
57
  "--background",
@@ -83,6 +84,9 @@ const THEME_CSS_VARS = [
83
84
  "--sidebar-ring",
84
85
  ];
85
86
 
87
+ const EXTENSION_IFRAME_SANDBOX =
88
+ normalizeAgentNativeExtensionSandbox(undefined);
89
+
86
90
  function getParentThemeVars(): Record<string, string> {
87
91
  const computed = getComputedStyle(document.documentElement);
88
92
  const vars: Record<string, string> = {};
@@ -261,6 +265,40 @@ function compactDiffLines(
261
265
  return result;
262
266
  }
263
267
 
268
+ function ExtensionUnavailableState({ status }: { status?: number }) {
269
+ const sessionExpired = status === 401;
270
+ const accessDenied = status === 403;
271
+ const unavailable = status === 404;
272
+ const title = sessionExpired
273
+ ? "Session expired"
274
+ : accessDenied
275
+ ? "Extension is not shared"
276
+ : unavailable
277
+ ? "Extension is unavailable"
278
+ : "Extension not found";
279
+ const message = sessionExpired
280
+ ? "Sign in again to view this extension."
281
+ : accessDenied
282
+ ? "You do not have access to this extension. Ask the owner to share it with your organization or open a different extension."
283
+ : "This extension may not be shared with you, may have been deleted, or is not available to your account.";
284
+ return (
285
+ <div className="flex h-full min-h-[20rem] items-center justify-center bg-muted/20 p-6">
286
+ <div className="w-full max-w-md rounded-lg border border-border bg-background p-6 text-center shadow-sm">
287
+ <p className="text-sm font-semibold text-foreground">{title}</p>
288
+ <p className="mt-2 text-sm leading-6 text-muted-foreground">
289
+ {message}
290
+ </p>
291
+ <Link
292
+ to="/extensions"
293
+ className="mt-4 inline-flex h-9 items-center justify-center rounded-md border border-input px-3 text-sm font-medium text-foreground hover:bg-accent hover:text-accent-foreground"
294
+ >
295
+ Back to extensions
296
+ </Link>
297
+ </div>
298
+ </div>
299
+ );
300
+ }
301
+
264
302
  function diffLineClass(line: CompactDiffLine): string {
265
303
  switch (line.type) {
266
304
  case "insert":
@@ -1071,6 +1109,7 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1071
1109
  const {
1072
1110
  data: extension,
1073
1111
  error: extensionError,
1112
+ failureReason: extensionFailureReason,
1074
1113
  isFetching,
1075
1114
  isLoading,
1076
1115
  } = useQuery<Extension>({
@@ -1079,6 +1118,9 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1079
1118
  const res = await fetch(
1080
1119
  agentNativePath(`/_agent-native/extensions/${extensionId}`),
1081
1120
  );
1121
+ if (res.status === 401) {
1122
+ throw extensionLoadError(401, "Session expired");
1123
+ }
1082
1124
  if (res.status === 404) {
1083
1125
  throw extensionLoadError(404, "Extension not found");
1084
1126
  }
@@ -1092,6 +1134,7 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1092
1134
  },
1093
1135
  retry: shouldRetryExtensionLoad,
1094
1136
  retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 4000),
1137
+ refetchOnMount: "always",
1095
1138
  });
1096
1139
 
1097
1140
  toolRef.current = extension ?? null;
@@ -1130,6 +1173,13 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1130
1173
  if (!extension?.content || !isEmbedMcpChatBridgeActive()) return undefined;
1131
1174
  return buildExtensionViewerSrcDoc(extension, isDark);
1132
1175
  }, [extension, isDark]);
1176
+ const unavailableStatus = extensionLoadErrorStatus(
1177
+ extensionError ?? extensionFailureReason,
1178
+ );
1179
+ const latestFetchDenied =
1180
+ unavailableStatus === 401 ||
1181
+ unavailableStatus === 403 ||
1182
+ unavailableStatus === 404;
1133
1183
 
1134
1184
  useEffect(() => {
1135
1185
  setIframeReady(false);
@@ -1187,13 +1237,8 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1187
1237
  );
1188
1238
  }
1189
1239
 
1190
- if (!extension) {
1191
- const status = extensionLoadErrorStatus(extensionError);
1192
- return (
1193
- <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
1194
- {status === 403 ? "Extension access denied" : "Extension not found"}
1195
- </div>
1196
- );
1240
+ if (latestFetchDenied || !extension) {
1241
+ return <ExtensionUnavailableState status={unavailableStatus} />;
1197
1242
  }
1198
1243
 
1199
1244
  const isLocalExtension = extension.source?.mode === "local-files";
@@ -1334,7 +1379,7 @@ export function ExtensionViewer({ extensionId }: ExtensionViewerProps) {
1334
1379
  src={iframeSrcDoc ? undefined : iframeSrc}
1335
1380
  srcDoc={iframeSrcDoc}
1336
1381
  className="h-full w-full border-0"
1337
- sandbox="allow-scripts allow-forms"
1382
+ sandbox={EXTENSION_IFRAME_SANDBOX}
1338
1383
  title={extension.name}
1339
1384
  style={{
1340
1385
  pointerEvents: openPopoverCount > 0 ? "none" : "auto",
@@ -11,6 +11,7 @@ import {
11
11
  type BridgePolicyContext,
12
12
  type ExtensionBridgeRole,
13
13
  } from "./iframe-bridge.js";
14
+ import { normalizeAgentNativeExtensionSandbox } from "./portable-extension.js";
14
15
 
15
16
  const THEME_CSS_VARS = [
16
17
  "--background",
@@ -43,6 +44,9 @@ const THEME_CSS_VARS = [
43
44
  "--sidebar-ring",
44
45
  ];
45
46
 
47
+ const EXTENSION_IFRAME_SANDBOX =
48
+ normalizeAgentNativeExtensionSandbox(undefined);
49
+
46
50
  interface InlineExtensionSource {
47
51
  mode?: "database" | "local-files";
48
52
  permissions?: BridgePolicyContext["permissions"];
@@ -642,7 +646,7 @@ export function InlineExtensionFrame({
642
646
  src={iframeSrc}
643
647
  srcDoc={srcDoc}
644
648
  title={extension.name}
645
- sandbox="allow-scripts allow-forms"
649
+ sandbox={EXTENSION_IFRAME_SANDBOX}
646
650
  style={{ width: "100%", border: 0, height, display: "block" }}
647
651
  onLoad={() => {
648
652
  sendThemeToIframe();
@@ -447,6 +447,7 @@ export function normalizeAgentNativeExtensionSandbox(
447
447
  );
448
448
  tokens.delete("allow-same-origin");
449
449
  tokens.add("allow-scripts");
450
+ tokens.add("allow-downloads");
450
451
  return Array.from(tokens).join(" ");
451
452
  }
452
453
 
@@ -62,7 +62,7 @@ export interface OrgSwitcherProps {
62
62
  reserveSpace?: boolean;
63
63
  /**
64
64
  * Path to navigate to when the user clicks "Organization settings".
65
- * Defaults to the standard Team tab inside Settings. Templates with an
65
+ * Defaults to the Organization tab inside Settings. Templates with an
66
66
  * established org surface can pass their own path; pass `null` to only open
67
67
  * the in-sidebar settings panel.
68
68
  */
@@ -98,7 +98,7 @@ const APP_SUBMENU_CONTENT_CLASS =
98
98
  const SWITCHER_BUTTON_CLASS =
99
99
  "flex w-full items-center gap-2 rounded-md border border-border/70 px-2.5 py-1.5 text-xs font-medium text-muted-foreground hover:bg-accent/50 hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-60 cursor-pointer";
100
100
 
101
- const DEFAULT_ORGANIZATION_SETTINGS_PATH = "/settings#team";
101
+ const DEFAULT_ORGANIZATION_SETTINGS_PATH = "/settings#organization";
102
102
 
103
103
  const APP_ICON_MAP: Record<string, typeof IconApps> = {
104
104
  Mail: IconMail,
@@ -130,7 +130,9 @@ function appMenuIcon(app: OrgSwitcherAppLink): typeof IconApps {
130
130
  }
131
131
 
132
132
  function organizationSettingsPath(path: string): string {
133
- return path.includes("#") ? path : `${path}#team`;
133
+ if (path.includes("#")) return path;
134
+ const pathname = path.split("?")[0]?.replace(/\/+$/, "");
135
+ return pathname === "/settings" ? `${path}#organization` : path;
134
136
  }
135
137
 
136
138
  function AppMenuLink({
@@ -547,14 +549,15 @@ export function OrgSwitcher({
547
549
  type="button"
548
550
  onClick={() => {
549
551
  setOpen(false);
550
- window.dispatchEvent(new CustomEvent("agent-panel:open"));
551
- window.dispatchEvent(
552
- new CustomEvent("agent-panel:open-settings", {
553
- detail: { section: "workspace-settings" },
554
- }),
555
- );
556
552
  if (organizationSettingsHref) {
557
553
  navigate(organizationSettingsHref);
554
+ } else {
555
+ window.dispatchEvent(new CustomEvent("agent-panel:open"));
556
+ window.dispatchEvent(
557
+ new CustomEvent("agent-panel:open-settings", {
558
+ detail: { section: "workspace-settings" },
559
+ }),
560
+ );
558
561
  }
559
562
  }}
560
563
  className={`${ITEM_CLASS} cursor-pointer`}
@@ -350,81 +350,87 @@ function MembersCard() {
350
350
  )}
351
351
  </div>
352
352
 
353
- <div className="border-t border-border pt-3 space-y-1">
354
- <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
355
- {t("org.members")}
356
- </div>
357
- {isLoadingMembers && members.length === 0 && (
358
- <>
359
- {[0, 1, 2].map((i) => (
353
+ <div className="grid gap-5 border-t border-border pt-3 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,22rem)]">
354
+ <div className="min-w-0 space-y-4">
355
+ <div className="space-y-1">
356
+ <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2">
357
+ {t("org.members")}
358
+ </div>
359
+ {isLoadingMembers && members.length === 0 && (
360
+ <>
361
+ {[0, 1, 2].map((i) => (
362
+ <div
363
+ key={i}
364
+ className="flex items-center justify-between py-1.5 px-2"
365
+ >
366
+ <div className="flex items-center gap-2">
367
+ <div
368
+ className="h-3.5 rounded bg-muted animate-pulse"
369
+ style={{ width: `${140 + i * 30}px` }}
370
+ />
371
+ <div className="h-3.5 w-3.5 rounded bg-muted animate-pulse" />
372
+ </div>
373
+ </div>
374
+ ))}
375
+ </>
376
+ )}
377
+ {members.map((m) => (
378
+ <MemberRow
379
+ key={m.email}
380
+ email={m.email}
381
+ role={m.role}
382
+ isCurrentUser={m.email === org.email}
383
+ currentUserRole={org.role ?? null}
384
+ />
385
+ ))}
386
+ {pendingInvites.map((inv) => (
360
387
  <div
361
- key={i}
362
- className="flex items-center justify-between py-1.5 px-2"
388
+ key={inv.id}
389
+ className="flex items-center justify-between gap-2 py-1.5 px-2 opacity-60"
363
390
  >
364
- <div className="flex items-center gap-2">
365
- <div
366
- className="h-3.5 rounded bg-muted animate-pulse"
367
- style={{ width: `${140 + i * 30}px` }}
368
- />
369
- <div className="h-3.5 w-3.5 rounded bg-muted animate-pulse" />
391
+ <div className="flex min-w-0 items-center gap-2">
392
+ <span className="truncate text-sm">{inv.email}</span>
393
+ <RoleIcon role={inv.role} />
394
+ <span className="rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground">
395
+ Invited{inv.role === "admin" ? " · admin" : ""}
396
+ </span>
370
397
  </div>
371
398
  </div>
372
399
  ))}
373
- </>
374
- )}
375
- {members.map((m) => (
376
- <MemberRow
377
- key={m.email}
378
- email={m.email}
379
- role={m.role}
380
- isCurrentUser={m.email === org.email}
381
- currentUserRole={org.role ?? null}
382
- />
383
- ))}
384
- {pendingInvites.map((inv) => (
385
- <div
386
- key={inv.id}
387
- className="flex items-center justify-between py-1.5 px-2 opacity-60"
388
- >
389
- <div className="flex items-center gap-2">
390
- <span className="text-sm">{inv.email}</span>
391
- <RoleIcon role={inv.role} />
392
- <span className="rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground">
393
- Invited{inv.role === "admin" ? " · admin" : ""}
394
- </span>
395
- </div>
396
400
  </div>
397
- ))}
398
- </div>
399
401
 
400
- {isOwnerOrAdmin && (
401
- <div className="border-t border-border pt-3">
402
- {!showInviteForm ? (
403
- <button
404
- type="button"
405
- onClick={() => setShowInviteForm(true)}
406
- 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"
407
- >
408
- <IconUserPlus className="h-3.5 w-3.5" />
409
- Invite members
410
- </button>
411
- ) : (
412
- <BulkInviteForm
413
- currentUserRole={org.role}
414
- onClose={() => setShowInviteForm(false)}
415
- />
402
+ {isOwnerOrAdmin && (
403
+ <div className="border-t border-border pt-3">
404
+ {!showInviteForm ? (
405
+ <button
406
+ type="button"
407
+ onClick={() => setShowInviteForm(true)}
408
+ 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"
409
+ >
410
+ <IconUserPlus className="h-3.5 w-3.5" />
411
+ Invite members
412
+ </button>
413
+ ) : (
414
+ <BulkInviteForm
415
+ currentUserRole={org.role}
416
+ onClose={() => setShowInviteForm(false)}
417
+ />
418
+ )}
419
+ </div>
416
420
  )}
417
421
  </div>
418
- )}
419
422
 
420
- {isOwnerOrAdmin && (
421
- <DomainSettingsSection
422
- domain={org.allowedDomain}
423
- ownerEmail={org.email}
424
- />
425
- )}
423
+ {isOwnerOrAdmin && (
424
+ <div className="min-w-0 space-y-3 border-t border-border pt-3 lg:border-s lg:border-t-0 lg:ps-5 lg:pt-0">
425
+ <DomainSettingsSection
426
+ domain={org.allowedDomain}
427
+ ownerEmail={org.email}
428
+ />
426
429
 
427
- {isOwner && <A2ASecretSection secret={org.a2aSecret} />}
430
+ {isOwner && <A2ASecretSection secret={org.a2aSecret} />}
431
+ </div>
432
+ )}
433
+ </div>
428
434
 
429
435
  <ErrorText error={removeMember.error} />
430
436
  <ErrorText error={switchOrg.error} />
@@ -459,9 +465,9 @@ function MemberRow({
459
465
  (currentUserRole === "admin" && role === "member"));
460
466
 
461
467
  return (
462
- <div className="flex items-center justify-between py-1.5 px-2 rounded hover:bg-accent/30">
463
- <div className="flex items-center gap-2">
464
- <span className="text-sm">{email}</span>
468
+ <div className="flex items-center justify-between gap-2 py-1.5 px-2 rounded hover:bg-accent/30">
469
+ <div className="flex min-w-0 items-center gap-2">
470
+ <span className="truncate text-sm">{email}</span>
465
471
  <RoleIcon role={role} />
466
472
  {isCurrentUser && (
467
473
  <span className="rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground">
@@ -475,7 +481,7 @@ function MemberRow({
475
481
  )}
476
482
  </div>
477
483
  {canManage && (
478
- <div className="flex items-center gap-1">
484
+ <div className="flex shrink-0 items-center gap-1">
479
485
  {editing ? (
480
486
  <select
481
487
  autoFocus
@@ -917,7 +923,7 @@ function DomainSettingsSection({
917
923
  }
918
924
 
919
925
  return (
920
- <div className="border-t border-border pt-3 space-y-2">
926
+ <div className="space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0">
921
927
  <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
922
928
  Email domain auto-join
923
929
  </div>
@@ -1078,7 +1084,7 @@ function A2ASecretSection({ secret }: { secret: string | null | undefined }) {
1078
1084
  const masked = secret ? "****" + secret.slice(-8) : "Not set";
1079
1085
 
1080
1086
  return (
1081
- <div className="border-t border-border pt-3 space-y-2">
1087
+ <div className="space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0">
1082
1088
  <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
1083
1089
  Cross-app authentication
1084
1090
  </div>
@@ -1273,7 +1279,7 @@ export function TeamPage({
1273
1279
  const { data: org, isLoading } = useOrg();
1274
1280
 
1275
1281
  const content = (
1276
- <div className={`space-y-6 max-w-2xl ${className ?? ""}`}>
1282
+ <div className={`space-y-6 ${className ?? "max-w-2xl"}`}>
1277
1283
  {showTitle ? (
1278
1284
  <h2 className="text-2xl font-bold tracking-tight">
1279
1285
  {title ?? t("org.team")}